1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-25 00:02:41 +01:00

(stable) Promote 2016 Week 15

This commit is contained in:
epriestley 2016-04-08 16:36:26 -07:00
commit bf10fbdf6f
269 changed files with 4730 additions and 3246 deletions

View file

@ -80,9 +80,30 @@ class SimpleEmailService
* @return void
*/
public function __construct($accessKey = null, $secretKey = null, $host = 'email.us-east-1.amazonaws.com') {
if (!function_exists('simplexml_load_string')) {
throw new Exception(
pht(
'The PHP SimpleXML extension is not available, but this '.
'extension is required to send mail via Amazon SES, because '.
'Amazon SES returns API responses in XML format. Install or '.
'enable the SimpleXML extension.'));
}
// Catch mistakes with reading the wrong column out of the SES
// documentation. See T10728.
if (preg_match('(-smtp)', $host)) {
throw new Exception(
pht(
'Amazon SES is not configured correctly: the configured SES '.
'endpoint ("%s") is an SMTP endpoint. Instead, use an API (HTTPS) '.
'endpoint.',
$host));
}
if ($accessKey !== null && $secretKey !== null) {
$this->setAuth($accessKey, $secretKey);
}
$this->__host = $host;
}
@ -108,13 +129,6 @@ class SimpleEmailService
$rest->setParameter('Action', 'ListVerifiedEmailAddresses');
$rest = $rest->getResponse();
if($rest->error === false && $rest->code !== 200) {
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
}
if($rest->error !== false) {
$this->__triggerError('listVerifiedEmailAddresses', $rest->error);
return false;
}
$response = array();
if(!isset($rest->body)) {
@ -148,13 +162,6 @@ class SimpleEmailService
$rest->setParameter('EmailAddress', $email);
$rest = $rest->getResponse();
if($rest->error === false && $rest->code !== 200) {
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
}
if($rest->error !== false) {
$this->__triggerError('verifyEmailAddress', $rest->error);
return false;
}
$response['RequestId'] = (string)$rest->body->ResponseMetadata->RequestId;
return $response;
@ -172,13 +179,6 @@ class SimpleEmailService
$rest->setParameter('EmailAddress', $email);
$rest = $rest->getResponse();
if($rest->error === false && $rest->code !== 200) {
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
}
if($rest->error !== false) {
$this->__triggerError('deleteVerifiedEmailAddress', $rest->error);
return false;
}
$response['RequestId'] = (string)$rest->body->ResponseMetadata->RequestId;
return $response;
@ -195,13 +195,6 @@ class SimpleEmailService
$rest->setParameter('Action', 'GetSendQuota');
$rest = $rest->getResponse();
if($rest->error === false && $rest->code !== 200) {
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
}
if($rest->error !== false) {
$this->__triggerError('getSendQuota', $rest->error);
return false;
}
$response = array();
if(!isset($rest->body)) {
@ -227,13 +220,6 @@ class SimpleEmailService
$rest->setParameter('Action', 'GetSendStatistics');
$rest = $rest->getResponse();
if($rest->error === false && $rest->code !== 200) {
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
}
if($rest->error !== false) {
$this->__triggerError('getSendStatistics', $rest->error);
return false;
}
$response = array();
if(!isset($rest->body)) {
@ -265,13 +251,6 @@ class SimpleEmailService
$rest->setParameter('RawMessage.Data', base64_encode($raw));
$rest = $rest->getResponse();
if($rest->error === false && $rest->code !== 200) {
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
}
if($rest->error !== false) {
$this->__triggerError('sendRawEmail', $rest->error);
return false;
}
$response['MessageId'] = (string)$rest->body->SendEmailResult->MessageId;
$response['RequestId'] = (string)$rest->body->ResponseMetadata->RequestId;
@ -351,13 +330,6 @@ class SimpleEmailService
}
$rest = $rest->getResponse();
if($rest->error === false && $rest->code !== 200) {
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
}
if($rest->error !== false) {
$this->__triggerError('sendEmail', $rest->error);
return false;
}
$response['MessageId'] = (string)$rest->body->SendEmailResult->MessageId;
$response['RequestId'] = (string)$rest->body->ResponseMetadata->RequestId;
@ -523,15 +495,22 @@ final class SimpleEmailServiceRequest
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
// Execute, grab errors
if (curl_exec($curl)) {
$this->response->code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
} else {
$this->response->error = array(
'curl' => true,
'code' => curl_errno($curl),
'message' => curl_error($curl),
'resource' => $this->resource
);
if (!curl_exec($curl)) {
throw new SimpleEmailServiceException(
pht(
'Encountered an error while making an HTTP request to Amazon SES '.
'(cURL Error #%d): %s',
curl_errno($curl),
curl_error($curl)));
}
$this->response->code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($this->response->code != 200) {
throw new SimpleEmailServiceException(
pht(
'Unexpected HTTP status while making request to Amazon SES: '.
'expected 200, got %s.',
$this->response->code));
}
@curl_close($curl);

View file

@ -7,7 +7,7 @@
*/
return array(
'names' => array(
'core.pkg.css' => '2d0339fc',
'core.pkg.css' => '82cefddc',
'core.pkg.js' => 'e5484f37',
'darkconsole.pkg.js' => 'e7393ebb',
'differential.pkg.css' => '7ba78475',
@ -25,7 +25,7 @@ return array(
'rsrc/css/aphront/notification.css' => '7f684b62',
'rsrc/css/aphront/panel-view.css' => '8427b78d',
'rsrc/css/aphront/phabricator-nav-view.css' => 'ac79a758',
'rsrc/css/aphront/table-view.css' => '036b6cdc',
'rsrc/css/aphront/table-view.css' => '9258e19f',
'rsrc/css/aphront/tokenizer.css' => '056da01b',
'rsrc/css/aphront/tooltip.css' => '1a07aea8',
'rsrc/css/aphront/typeahead-browse.css' => 'd8581d2c',
@ -54,7 +54,7 @@ return array(
'rsrc/css/application/contentsource/content-source-view.css' => '4b8b05d4',
'rsrc/css/application/countdown/timer.css' => '96696f21',
'rsrc/css/application/daemon/bulk-job.css' => 'df9c1d4a',
'rsrc/css/application/dashboard/dashboard.css' => 'eb458607',
'rsrc/css/application/dashboard/dashboard.css' => 'bc6f2127',
'rsrc/css/application/diff/inline-comment-summary.css' => '51efda3a',
'rsrc/css/application/differential/add-comment.css' => 'c47f8c40',
'rsrc/css/application/differential/changeset-view.css' => '3e3b0b76',
@ -123,12 +123,12 @@ return array(
'rsrc/css/phui/phui-action-panel.css' => '91c7b835',
'rsrc/css/phui/phui-badge.css' => 'f25c3476',
'rsrc/css/phui/phui-big-info-view.css' => 'bd903741',
'rsrc/css/phui/phui-box.css' => 'b2d49bae',
'rsrc/css/phui/phui-box.css' => 'd909ea3d',
'rsrc/css/phui/phui-button.css' => 'a64a8de6',
'rsrc/css/phui/phui-chart.css' => '6bf6f78e',
'rsrc/css/phui/phui-crumbs-view.css' => '79d536e5',
'rsrc/css/phui/phui-crumbs-view.css' => '1a1265d4',
'rsrc/css/phui/phui-curtain-view.css' => '7148ae25',
'rsrc/css/phui/phui-document-pro.css' => '92d5b648',
'rsrc/css/phui/phui-document-pro.css' => '73e45fd2',
'rsrc/css/phui/phui-document-summary.css' => '9ca48bdf',
'rsrc/css/phui/phui-document.css' => '9c71d2bf',
'rsrc/css/phui/phui-feed-story.css' => '04aec08f',
@ -156,7 +156,7 @@ return array(
'rsrc/css/phui/phui-status.css' => '37309046',
'rsrc/css/phui/phui-tag-view.css' => '6bbd83e2',
'rsrc/css/phui/phui-timeline-view.css' => '6e342216',
'rsrc/css/phui/phui-two-column-view.css' => '691fec04',
'rsrc/css/phui/phui-two-column-view.css' => 'b9538af1',
'rsrc/css/phui/workboards/phui-workboard-color.css' => 'ac6fe6a7',
'rsrc/css/phui/workboards/phui-workboard.css' => 'e6d89647',
'rsrc/css/phui/workboards/phui-workcard.css' => '3646fb96',
@ -515,7 +515,7 @@ return array(
'rsrc/js/phuix/PHUIXActionView.js' => '8cf6d262',
'rsrc/js/phuix/PHUIXAutocomplete.js' => '9196fb06',
'rsrc/js/phuix/PHUIXDropdownMenu.js' => 'bd4c8dca',
'rsrc/js/phuix/PHUIXFormControl.js' => 'a7763e11',
'rsrc/js/phuix/PHUIXFormControl.js' => 'e15869a8',
'rsrc/js/phuix/PHUIXIconView.js' => 'bff6884b',
),
'symbols' => array(
@ -526,7 +526,7 @@ return array(
'aphront-list-filter-view-css' => '5d6f0526',
'aphront-multi-column-view-css' => 'fd18389d',
'aphront-panel-view-css' => '8427b78d',
'aphront-table-view-css' => '036b6cdc',
'aphront-table-view-css' => '9258e19f',
'aphront-tokenizer-control-css' => '056da01b',
'aphront-tooltip-css' => '1a07aea8',
'aphront-typeahead-control-css' => 'd4f16145',
@ -753,7 +753,7 @@ return array(
'phabricator-content-source-view-css' => '4b8b05d4',
'phabricator-core-css' => 'd0801452',
'phabricator-countdown-css' => '96696f21',
'phabricator-dashboard-css' => 'eb458607',
'phabricator-dashboard-css' => 'bc6f2127',
'phabricator-drag-and-drop-file-upload' => '81f182b5',
'phabricator-draggable-list' => '5a13c79f',
'phabricator-fatal-config-template-css' => '8e6c6fcd',
@ -805,18 +805,18 @@ return array(
'phui-action-panel-css' => '91c7b835',
'phui-badge-view-css' => 'f25c3476',
'phui-big-info-view-css' => 'bd903741',
'phui-box-css' => 'b2d49bae',
'phui-box-css' => 'd909ea3d',
'phui-button-css' => 'a64a8de6',
'phui-calendar-css' => 'ccabe893',
'phui-calendar-day-css' => 'd1cf6f93',
'phui-calendar-list-css' => 'c1c7f338',
'phui-calendar-month-css' => '476be7e0',
'phui-chart-css' => '6bf6f78e',
'phui-crumbs-view-css' => '79d536e5',
'phui-crumbs-view-css' => '1a1265d4',
'phui-curtain-view-css' => '7148ae25',
'phui-document-summary-view-css' => '9ca48bdf',
'phui-document-view-css' => '9c71d2bf',
'phui-document-view-pro-css' => '92d5b648',
'phui-document-view-pro-css' => '73e45fd2',
'phui-feed-story-css' => '04aec08f',
'phui-font-icon-base-css' => '6449bce8',
'phui-fontkit-css' => '9cda225e',
@ -846,7 +846,7 @@ return array(
'phui-tag-view-css' => '6bbd83e2',
'phui-theme-css' => '027ba77e',
'phui-timeline-view-css' => '6e342216',
'phui-two-column-view-css' => '691fec04',
'phui-two-column-view-css' => 'b9538af1',
'phui-workboard-color-css' => 'ac6fe6a7',
'phui-workboard-view-css' => 'e6d89647',
'phui-workcard-view-css' => '3646fb96',
@ -855,7 +855,7 @@ return array(
'phuix-action-view' => '8cf6d262',
'phuix-autocomplete' => '9196fb06',
'phuix-dropdown-menu' => 'bd4c8dca',
'phuix-form-control-view' => 'a7763e11',
'phuix-form-control-view' => 'e15869a8',
'phuix-icon-view' => 'bff6884b',
'policy-css' => '957ea14c',
'policy-edit-css' => '815c66f7',
@ -1659,10 +1659,6 @@ return array(
'javelin-uri',
'phabricator-notification',
),
'a7763e11' => array(
'javelin-install',
'javelin-dom',
),
'a80d0378' => array(
'javelin-behavior',
'javelin-stratcom',
@ -1964,6 +1960,10 @@ return array(
'javelin-dom',
'phabricator-prefab',
),
'e15869a8' => array(
'javelin-install',
'javelin-dom',
),
'e1d25dfb' => array(
'javelin-behavior',
'javelin-stratcom',

View file

@ -0,0 +1,19 @@
CREATE TABLE {$NAMESPACE}_oauth_server.oauth_server_transaction (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
phid VARBINARY(64) NOT NULL,
authorPHID VARBINARY(64) NOT NULL,
objectPHID VARBINARY(64) NOT NULL,
viewPolicy VARBINARY(64) NOT NULL,
editPolicy VARBINARY(64) NOT NULL,
commentPHID VARBINARY(64) DEFAULT NULL,
commentVersion INT UNSIGNED NOT NULL,
transactionType VARCHAR(32) COLLATE {$COLLATE_TEXT} NOT NULL,
oldValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
newValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
contentSource LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
metadata LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
dateCreated INT UNSIGNED NOT NULL,
dateModified INT UNSIGNED NOT NULL,
UNIQUE KEY `key_phid` (`phid`),
KEY `key_object` (`objectPHID`)
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};

View file

@ -0,0 +1,2 @@
ALTER TABLE {$NAMESPACE}_oauth_server.oauth_server_oauthserverclient
ADD isDisabled BOOL NOT NULL;

View file

@ -0,0 +1,11 @@
<?php
$table = new PhabricatorBadgesBadge();
foreach (new LiskMigrationIterator($table) as $badge) {
PhabricatorSearchWorker::queueDocumentForIndexing(
$badge->getPHID(),
array(
'force' => true,
));
}

View file

@ -0,0 +1,7 @@
CREATE TABLE {$NAMESPACE}_badges.badges_badgename_ngrams (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
objectID INT UNSIGNED NOT NULL,
ngram CHAR(3) NOT NULL COLLATE {$COLLATE_TEXT},
KEY `key_object` (objectID),
KEY `key_ngram` (ngram, objectID)
) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};

View file

@ -0,0 +1,84 @@
<?php
$table = new ManiphestTransaction();
$conn_w = $table->establishConnection('w');
foreach (new LiskMigrationIterator($table) as $xaction) {
$type = $xaction->getTransactionType();
$id = $xaction->getID();
// This is an old ManiphestTransaction::TYPE_COLUMN. It did not do anything
// on its own and was hidden from the UI, so we're just going to remove it.
if ($type == 'column') {
queryfx(
$conn_w,
'DELETE FROM %T WHERE id = %d',
$table->getTableName(),
$id);
continue;
}
// This is an old ManiphestTransaction::TYPE_PROJECT_COLUMN. It moved
// tasks between board columns; we're going to replace it with a modern
// PhabricatorTransactions::TYPE_COLUMNS transaction.
if ($type == 'projectcolumn') {
try {
$new = $xaction->getNewValue();
if (!$new || !is_array($new)) {
continue;
}
$column_phids = idx($new, 'columnPHIDs');
if (!is_array($column_phids) || !$column_phids) {
continue;
}
$column_phid = head($column_phids);
if (!$column_phid) {
continue;
}
$board_phid = idx($new, 'projectPHID');
if (!$board_phid) {
continue;
}
$before_phid = idx($new, 'beforePHID');
$after_phid = idx($new, 'afterPHID');
$old = $xaction->getOldValue();
if ($old && is_array($old)) {
$from_phids = idx($old, 'columnPHIDs');
$from_phids = array_values($from_phids);
} else {
$from_phids = array();
}
$replacement = array(
'columnPHID' => $column_phid,
'boardPHID' => $board_phid,
'fromColumnPHIDs' => $from_phids,
);
if ($before_phid) {
$replacement['beforePHID'] = $before_phid;
} else if ($after_phid) {
$replacement['afterPHID'] = $after_phid;
}
queryfx(
$conn_w,
'UPDATE %T SET transactionType = %s, oldValue = %s, newValue = %s
WHERE id = %d',
$table->getTableName(),
PhabricatorTransactions::TYPE_COLUMNS,
'null',
phutil_json_encode(array($replacement)),
$id);
} catch (Exception $ex) {
// If anything went awry, just move on.
}
}
}

View file

@ -139,6 +139,7 @@ phutil_register_library_map(array(
'AphrontDefaultApplicationConfiguration' => 'aphront/configuration/AphrontDefaultApplicationConfiguration.php',
'AphrontDialogResponse' => 'aphront/response/AphrontDialogResponse.php',
'AphrontDialogView' => 'view/AphrontDialogView.php',
'AphrontEpochHTTPParameterType' => 'aphront/httpparametertype/AphrontEpochHTTPParameterType.php',
'AphrontException' => 'aphront/exception/AphrontException.php',
'AphrontFileResponse' => 'aphront/response/AphrontFileResponse.php',
'AphrontFormCheckboxControl' => 'view/form/control/AphrontFormCheckboxControl.php',
@ -253,6 +254,7 @@ phutil_register_library_map(array(
'ConduitBoolParameterType' => 'applications/conduit/parametertype/ConduitBoolParameterType.php',
'ConduitCall' => 'applications/conduit/call/ConduitCall.php',
'ConduitCallTestCase' => 'applications/conduit/call/__tests__/ConduitCallTestCase.php',
'ConduitColumnsParameterType' => 'applications/conduit/parametertype/ConduitColumnsParameterType.php',
'ConduitConnectConduitAPIMethod' => 'applications/conduit/method/ConduitConnectConduitAPIMethod.php',
'ConduitEpochParameterType' => 'applications/conduit/parametertype/ConduitEpochParameterType.php',
'ConduitException' => 'applications/conduit/protocol/exception/ConduitException.php',
@ -1807,6 +1809,7 @@ phutil_register_library_map(array(
'PhabricatorAuthListController' => 'applications/auth/controller/config/PhabricatorAuthListController.php',
'PhabricatorAuthLoginController' => 'applications/auth/controller/PhabricatorAuthLoginController.php',
'PhabricatorAuthLoginHandler' => 'applications/auth/handler/PhabricatorAuthLoginHandler.php',
'PhabricatorAuthLogoutConduitAPIMethod' => 'applications/auth/conduit/PhabricatorAuthLogoutConduitAPIMethod.php',
'PhabricatorAuthMainMenuBarExtension' => 'applications/auth/extension/PhabricatorAuthMainMenuBarExtension.php',
'PhabricatorAuthManagementCachePKCS8Workflow' => 'applications/auth/management/PhabricatorAuthManagementCachePKCS8Workflow.php',
'PhabricatorAuthManagementLDAPWorkflow' => 'applications/auth/management/PhabricatorAuthManagementLDAPWorkflow.php',
@ -1847,6 +1850,8 @@ phutil_register_library_map(array(
'PhabricatorAuthSSHPublicKey' => 'applications/auth/sshkey/PhabricatorAuthSSHPublicKey.php',
'PhabricatorAuthSession' => 'applications/auth/storage/PhabricatorAuthSession.php',
'PhabricatorAuthSessionEngine' => 'applications/auth/engine/PhabricatorAuthSessionEngine.php',
'PhabricatorAuthSessionEngineExtension' => 'applications/auth/engine/PhabricatorAuthSessionEngineExtension.php',
'PhabricatorAuthSessionEngineExtensionModule' => 'applications/auth/engine/PhabricatorAuthSessionEngineExtensionModule.php',
'PhabricatorAuthSessionGarbageCollector' => 'applications/auth/garbagecollector/PhabricatorAuthSessionGarbageCollector.php',
'PhabricatorAuthSessionQuery' => 'applications/auth/query/PhabricatorAuthSessionQuery.php',
'PhabricatorAuthSetupCheck' => 'applications/config/check/PhabricatorAuthSetupCheck.php',
@ -1870,11 +1875,13 @@ phutil_register_library_map(array(
'PhabricatorBadgesAwardController' => 'applications/badges/controller/PhabricatorBadgesAwardController.php',
'PhabricatorBadgesAwardQuery' => 'applications/badges/query/PhabricatorBadgesAwardQuery.php',
'PhabricatorBadgesBadge' => 'applications/badges/storage/PhabricatorBadgesBadge.php',
'PhabricatorBadgesBadgeNameNgrams' => 'applications/badges/storage/PhabricatorBadgesBadgeNameNgrams.php',
'PhabricatorBadgesCommentController' => 'applications/badges/controller/PhabricatorBadgesCommentController.php',
'PhabricatorBadgesController' => 'applications/badges/controller/PhabricatorBadgesController.php',
'PhabricatorBadgesCreateCapability' => 'applications/badges/capability/PhabricatorBadgesCreateCapability.php',
'PhabricatorBadgesDAO' => 'applications/badges/storage/PhabricatorBadgesDAO.php',
'PhabricatorBadgesDefaultEditCapability' => 'applications/badges/capability/PhabricatorBadgesDefaultEditCapability.php',
'PhabricatorBadgesEditConduitAPIMethod' => 'applications/badges/conduit/PhabricatorBadgesEditConduitAPIMethod.php',
'PhabricatorBadgesEditController' => 'applications/badges/controller/PhabricatorBadgesEditController.php',
'PhabricatorBadgesEditEngine' => 'applications/badges/editor/PhabricatorBadgesEditEngine.php',
'PhabricatorBadgesEditRecipientsController' => 'applications/badges/controller/PhabricatorBadgesEditRecipientsController.php',
@ -1889,6 +1896,7 @@ phutil_register_library_map(array(
'PhabricatorBadgesRemoveRecipientsController' => 'applications/badges/controller/PhabricatorBadgesRemoveRecipientsController.php',
'PhabricatorBadgesReplyHandler' => 'applications/badges/mail/PhabricatorBadgesReplyHandler.php',
'PhabricatorBadgesSchemaSpec' => 'applications/badges/storage/PhabricatorBadgesSchemaSpec.php',
'PhabricatorBadgesSearchConduitAPIMethod' => 'applications/badges/conduit/PhabricatorBadgesSearchConduitAPIMethod.php',
'PhabricatorBadgesSearchEngine' => 'applications/badges/query/PhabricatorBadgesSearchEngine.php',
'PhabricatorBadgesTransaction' => 'applications/badges/storage/PhabricatorBadgesTransaction.php',
'PhabricatorBadgesTransactionComment' => 'applications/badges/storage/PhabricatorBadgesTransactionComment.php',
@ -1979,6 +1987,7 @@ phutil_register_library_map(array(
'PhabricatorChunkedFileStorageEngine' => 'applications/files/engine/PhabricatorChunkedFileStorageEngine.php',
'PhabricatorClusterConfigOptions' => 'applications/config/option/PhabricatorClusterConfigOptions.php',
'PhabricatorColumnProxyInterface' => 'applications/project/interface/PhabricatorColumnProxyInterface.php',
'PhabricatorColumnsEditField' => 'applications/transactions/editfield/PhabricatorColumnsEditField.php',
'PhabricatorCommentEditEngineExtension' => 'applications/transactions/engineextension/PhabricatorCommentEditEngineExtension.php',
'PhabricatorCommentEditField' => 'applications/transactions/editfield/PhabricatorCommentEditField.php',
'PhabricatorCommentEditType' => 'applications/transactions/edittype/PhabricatorCommentEditType.php',
@ -2092,7 +2101,6 @@ phutil_register_library_map(array(
'PhabricatorCoreConfigOptions' => 'applications/config/option/PhabricatorCoreConfigOptions.php',
'PhabricatorCountdown' => 'applications/countdown/storage/PhabricatorCountdown.php',
'PhabricatorCountdownApplication' => 'applications/countdown/application/PhabricatorCountdownApplication.php',
'PhabricatorCountdownCommentController' => 'applications/countdown/controller/PhabricatorCountdownCommentController.php',
'PhabricatorCountdownController' => 'applications/countdown/controller/PhabricatorCountdownController.php',
'PhabricatorCountdownCountdownPHIDType' => 'applications/countdown/phid/PhabricatorCountdownCountdownPHIDType.php',
'PhabricatorCountdownDAO' => 'applications/countdown/storage/PhabricatorCountdownDAO.php',
@ -2100,6 +2108,7 @@ phutil_register_library_map(array(
'PhabricatorCountdownDefaultViewCapability' => 'applications/countdown/capability/PhabricatorCountdownDefaultViewCapability.php',
'PhabricatorCountdownDeleteController' => 'applications/countdown/controller/PhabricatorCountdownDeleteController.php',
'PhabricatorCountdownEditController' => 'applications/countdown/controller/PhabricatorCountdownEditController.php',
'PhabricatorCountdownEditEngine' => 'applications/countdown/editor/PhabricatorCountdownEditEngine.php',
'PhabricatorCountdownEditor' => 'applications/countdown/editor/PhabricatorCountdownEditor.php',
'PhabricatorCountdownListController' => 'applications/countdown/controller/PhabricatorCountdownListController.php',
'PhabricatorCountdownMailReceiver' => 'applications/countdown/mail/PhabricatorCountdownMailReceiver.php',
@ -2183,7 +2192,6 @@ phutil_register_library_map(array(
'PhabricatorDashboardDashboardHasPanelEdgeType' => 'applications/dashboard/edge/PhabricatorDashboardDashboardHasPanelEdgeType.php',
'PhabricatorDashboardDashboardPHIDType' => 'applications/dashboard/phid/PhabricatorDashboardDashboardPHIDType.php',
'PhabricatorDashboardEditController' => 'applications/dashboard/controller/PhabricatorDashboardEditController.php',
'PhabricatorDashboardHistoryController' => 'applications/dashboard/controller/PhabricatorDashboardHistoryController.php',
'PhabricatorDashboardInstall' => 'applications/dashboard/storage/PhabricatorDashboardInstall.php',
'PhabricatorDashboardInstallController' => 'applications/dashboard/controller/PhabricatorDashboardInstallController.php',
'PhabricatorDashboardLayoutConfig' => 'applications/dashboard/layoutconfig/PhabricatorDashboardLayoutConfig.php',
@ -2272,6 +2280,7 @@ phutil_register_library_map(array(
'PhabricatorEdgesDestructionEngineExtension' => 'infrastructure/edges/engineextension/PhabricatorEdgesDestructionEngineExtension.php',
'PhabricatorEditEngine' => 'applications/transactions/editengine/PhabricatorEditEngine.php',
'PhabricatorEditEngineAPIMethod' => 'applications/transactions/editengine/PhabricatorEditEngineAPIMethod.php',
'PhabricatorEditEngineColumnsCommentAction' => 'applications/transactions/commentaction/PhabricatorEditEngineColumnsCommentAction.php',
'PhabricatorEditEngineCommentAction' => 'applications/transactions/commentaction/PhabricatorEditEngineCommentAction.php',
'PhabricatorEditEngineConfiguration' => 'applications/transactions/storage/PhabricatorEditEngineConfiguration.php',
'PhabricatorEditEngineConfigurationDefaultCreateController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationDefaultCreateController.php',
@ -2317,6 +2326,7 @@ phutil_register_library_map(array(
'PhabricatorEmptyQueryException' => 'infrastructure/query/PhabricatorEmptyQueryException.php',
'PhabricatorEnv' => 'infrastructure/env/PhabricatorEnv.php',
'PhabricatorEnvTestCase' => 'infrastructure/env/__tests__/PhabricatorEnvTestCase.php',
'PhabricatorEpochEditField' => 'applications/transactions/editfield/PhabricatorEpochEditField.php',
'PhabricatorEvent' => 'infrastructure/events/PhabricatorEvent.php',
'PhabricatorEventEngine' => 'infrastructure/events/PhabricatorEventEngine.php',
'PhabricatorEventListener' => 'infrastructure/events/PhabricatorEventListener.php',
@ -2371,7 +2381,6 @@ phutil_register_library_map(array(
'PhabricatorFeedStoryPublisher' => 'applications/feed/PhabricatorFeedStoryPublisher.php',
'PhabricatorFeedStoryReference' => 'applications/feed/storage/PhabricatorFeedStoryReference.php',
'PhabricatorFile' => 'applications/files/storage/PhabricatorFile.php',
'PhabricatorFileAccessTemporaryTokenType' => 'applications/files/temporarytoken/PhabricatorFileAccessTemporaryTokenType.php',
'PhabricatorFileBundleLoader' => 'applications/files/query/PhabricatorFileBundleLoader.php',
'PhabricatorFileChunk' => 'applications/files/storage/PhabricatorFileChunk.php',
'PhabricatorFileChunkIterator' => 'applications/files/engine/PhabricatorFileChunkIterator.php',
@ -2702,10 +2711,11 @@ phutil_register_library_map(array(
'PhabricatorOAuthClientAuthorization' => 'applications/oauthserver/storage/PhabricatorOAuthClientAuthorization.php',
'PhabricatorOAuthClientAuthorizationQuery' => 'applications/oauthserver/query/PhabricatorOAuthClientAuthorizationQuery.php',
'PhabricatorOAuthClientController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientController.php',
'PhabricatorOAuthClientDeleteController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientDeleteController.php',
'PhabricatorOAuthClientDisableController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientDisableController.php',
'PhabricatorOAuthClientEditController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientEditController.php',
'PhabricatorOAuthClientListController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientListController.php',
'PhabricatorOAuthClientSecretController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientSecretController.php',
'PhabricatorOAuthClientTestController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientTestController.php',
'PhabricatorOAuthClientViewController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientViewController.php',
'PhabricatorOAuthResponse' => 'applications/oauthserver/PhabricatorOAuthResponse.php',
'PhabricatorOAuthServer' => 'applications/oauthserver/PhabricatorOAuthServer.php',
@ -2722,10 +2732,13 @@ phutil_register_library_map(array(
'PhabricatorOAuthServerController' => 'applications/oauthserver/controller/PhabricatorOAuthServerController.php',
'PhabricatorOAuthServerCreateClientsCapability' => 'applications/oauthserver/capability/PhabricatorOAuthServerCreateClientsCapability.php',
'PhabricatorOAuthServerDAO' => 'applications/oauthserver/storage/PhabricatorOAuthServerDAO.php',
'PhabricatorOAuthServerEditEngine' => 'applications/oauthserver/editor/PhabricatorOAuthServerEditEngine.php',
'PhabricatorOAuthServerEditor' => 'applications/oauthserver/editor/PhabricatorOAuthServerEditor.php',
'PhabricatorOAuthServerScope' => 'applications/oauthserver/PhabricatorOAuthServerScope.php',
'PhabricatorOAuthServerTestCase' => 'applications/oauthserver/__tests__/PhabricatorOAuthServerTestCase.php',
'PhabricatorOAuthServerTestController' => 'applications/oauthserver/controller/PhabricatorOAuthServerTestController.php',
'PhabricatorOAuthServerTokenController' => 'applications/oauthserver/controller/PhabricatorOAuthServerTokenController.php',
'PhabricatorOAuthServerTransaction' => 'applications/oauthserver/storage/PhabricatorOAuthServerTransaction.php',
'PhabricatorOAuthServerTransactionQuery' => 'applications/oauthserver/query/PhabricatorOAuthServerTransactionQuery.php',
'PhabricatorObjectHandle' => 'applications/phid/PhabricatorObjectHandle.php',
'PhabricatorObjectHasAsanaSubtaskEdgeType' => 'applications/doorkeeper/edge/PhabricatorObjectHasAsanaSubtaskEdgeType.php',
'PhabricatorObjectHasAsanaTaskEdgeType' => 'applications/doorkeeper/edge/PhabricatorObjectHasAsanaTaskEdgeType.php',
@ -4250,6 +4263,7 @@ phutil_register_library_map(array(
'AphrontView',
'AphrontResponseProducerInterface',
),
'AphrontEpochHTTPParameterType' => 'AphrontHTTPParameterType',
'AphrontException' => 'Exception',
'AphrontFileResponse' => 'AphrontResponse',
'AphrontFormCheckboxControl' => 'AphrontFormControl',
@ -4372,6 +4386,7 @@ phutil_register_library_map(array(
'ConduitBoolParameterType' => 'ConduitListParameterType',
'ConduitCall' => 'Phobject',
'ConduitCallTestCase' => 'PhabricatorTestCase',
'ConduitColumnsParameterType' => 'ConduitParameterType',
'ConduitConnectConduitAPIMethod' => 'ConduitAPIMethod',
'ConduitEpochParameterType' => 'ConduitListParameterType',
'ConduitException' => 'Exception',
@ -6150,6 +6165,7 @@ phutil_register_library_map(array(
'PhabricatorAuthListController' => 'PhabricatorAuthProviderConfigController',
'PhabricatorAuthLoginController' => 'PhabricatorAuthController',
'PhabricatorAuthLoginHandler' => 'Phobject',
'PhabricatorAuthLogoutConduitAPIMethod' => 'PhabricatorAuthConduitAPIMethod',
'PhabricatorAuthMainMenuBarExtension' => 'PhabricatorMainMenuBarExtension',
'PhabricatorAuthManagementCachePKCS8Workflow' => 'PhabricatorAuthManagementWorkflow',
'PhabricatorAuthManagementLDAPWorkflow' => 'PhabricatorAuthManagementWorkflow',
@ -6201,6 +6217,8 @@ phutil_register_library_map(array(
'PhabricatorPolicyInterface',
),
'PhabricatorAuthSessionEngine' => 'Phobject',
'PhabricatorAuthSessionEngineExtension' => 'Phobject',
'PhabricatorAuthSessionEngineExtensionModule' => 'PhabricatorConfigModule',
'PhabricatorAuthSessionGarbageCollector' => 'PhabricatorGarbageCollector',
'PhabricatorAuthSessionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorAuthSetupCheck' => 'PhabricatorSetupCheck',
@ -6238,12 +6256,16 @@ phutil_register_library_map(array(
'PhabricatorTokenReceiverInterface',
'PhabricatorFlaggableInterface',
'PhabricatorDestructibleInterface',
'PhabricatorConduitResultInterface',
'PhabricatorNgramsInterface',
),
'PhabricatorBadgesBadgeNameNgrams' => 'PhabricatorSearchNgrams',
'PhabricatorBadgesCommentController' => 'PhabricatorBadgesController',
'PhabricatorBadgesController' => 'PhabricatorController',
'PhabricatorBadgesCreateCapability' => 'PhabricatorPolicyCapability',
'PhabricatorBadgesDAO' => 'PhabricatorLiskDAO',
'PhabricatorBadgesDefaultEditCapability' => 'PhabricatorPolicyCapability',
'PhabricatorBadgesEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod',
'PhabricatorBadgesEditController' => 'PhabricatorBadgesController',
'PhabricatorBadgesEditEngine' => 'PhabricatorEditEngine',
'PhabricatorBadgesEditRecipientsController' => 'PhabricatorBadgesController',
@ -6258,6 +6280,7 @@ phutil_register_library_map(array(
'PhabricatorBadgesRemoveRecipientsController' => 'PhabricatorBadgesController',
'PhabricatorBadgesReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
'PhabricatorBadgesSchemaSpec' => 'PhabricatorConfigSchemaSpec',
'PhabricatorBadgesSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
'PhabricatorBadgesSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhabricatorBadgesTransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorBadgesTransactionComment' => 'PhabricatorApplicationTransactionComment',
@ -6369,6 +6392,7 @@ phutil_register_library_map(array(
'PhabricatorChatLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorChunkedFileStorageEngine' => 'PhabricatorFileStorageEngine',
'PhabricatorClusterConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorColumnsEditField' => 'PhabricatorPHIDListEditField',
'PhabricatorCommentEditEngineExtension' => 'PhabricatorEditEngineExtension',
'PhabricatorCommentEditField' => 'PhabricatorEditField',
'PhabricatorCommentEditType' => 'PhabricatorEditType',
@ -6504,7 +6528,6 @@ phutil_register_library_map(array(
'PhabricatorProjectInterface',
),
'PhabricatorCountdownApplication' => 'PhabricatorApplication',
'PhabricatorCountdownCommentController' => 'PhabricatorCountdownController',
'PhabricatorCountdownController' => 'PhabricatorController',
'PhabricatorCountdownCountdownPHIDType' => 'PhabricatorPHIDType',
'PhabricatorCountdownDAO' => 'PhabricatorLiskDAO',
@ -6512,6 +6535,7 @@ phutil_register_library_map(array(
'PhabricatorCountdownDefaultViewCapability' => 'PhabricatorPolicyCapability',
'PhabricatorCountdownDeleteController' => 'PhabricatorCountdownController',
'PhabricatorCountdownEditController' => 'PhabricatorCountdownController',
'PhabricatorCountdownEditEngine' => 'PhabricatorEditEngine',
'PhabricatorCountdownEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorCountdownListController' => 'PhabricatorCountdownController',
'PhabricatorCountdownMailReceiver' => 'PhabricatorObjectMailReceiver',
@ -6604,7 +6628,6 @@ phutil_register_library_map(array(
'PhabricatorDashboardDashboardHasPanelEdgeType' => 'PhabricatorEdgeType',
'PhabricatorDashboardDashboardPHIDType' => 'PhabricatorPHIDType',
'PhabricatorDashboardEditController' => 'PhabricatorDashboardController',
'PhabricatorDashboardHistoryController' => 'PhabricatorDashboardController',
'PhabricatorDashboardInstall' => 'PhabricatorDashboardDAO',
'PhabricatorDashboardInstallController' => 'PhabricatorDashboardController',
'PhabricatorDashboardLayoutConfig' => 'Phobject',
@ -6706,6 +6729,7 @@ phutil_register_library_map(array(
'PhabricatorPolicyInterface',
),
'PhabricatorEditEngineAPIMethod' => 'ConduitAPIMethod',
'PhabricatorEditEngineColumnsCommentAction' => 'PhabricatorEditEngineCommentAction',
'PhabricatorEditEngineCommentAction' => 'Phobject',
'PhabricatorEditEngineConfiguration' => array(
'PhabricatorSearchDAO',
@ -6755,6 +6779,7 @@ phutil_register_library_map(array(
'PhabricatorEmptyQueryException' => 'Exception',
'PhabricatorEnv' => 'Phobject',
'PhabricatorEnvTestCase' => 'PhabricatorTestCase',
'PhabricatorEpochEditField' => 'PhabricatorEditField',
'PhabricatorEvent' => 'PhutilEvent',
'PhabricatorEventEngine' => 'Phobject',
'PhabricatorEventListener' => 'PhutilEventListener',
@ -6823,7 +6848,6 @@ phutil_register_library_map(array(
'PhabricatorPolicyInterface',
'PhabricatorDestructibleInterface',
),
'PhabricatorFileAccessTemporaryTokenType' => 'PhabricatorAuthTemporaryTokenType',
'PhabricatorFileBundleLoader' => 'Phobject',
'PhabricatorFileChunk' => array(
'PhabricatorFileDAO',
@ -7190,10 +7214,11 @@ phutil_register_library_map(array(
),
'PhabricatorOAuthClientAuthorizationQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorOAuthClientController' => 'PhabricatorOAuthServerController',
'PhabricatorOAuthClientDeleteController' => 'PhabricatorOAuthClientController',
'PhabricatorOAuthClientDisableController' => 'PhabricatorOAuthClientController',
'PhabricatorOAuthClientEditController' => 'PhabricatorOAuthClientController',
'PhabricatorOAuthClientListController' => 'PhabricatorOAuthClientController',
'PhabricatorOAuthClientSecretController' => 'PhabricatorOAuthClientController',
'PhabricatorOAuthClientTestController' => 'PhabricatorOAuthClientController',
'PhabricatorOAuthClientViewController' => 'PhabricatorOAuthClientController',
'PhabricatorOAuthResponse' => 'AphrontResponse',
'PhabricatorOAuthServer' => 'Phobject',
@ -7205,6 +7230,7 @@ phutil_register_library_map(array(
'PhabricatorOAuthServerClient' => array(
'PhabricatorOAuthServerDAO',
'PhabricatorPolicyInterface',
'PhabricatorApplicationTransactionInterface',
'PhabricatorDestructibleInterface',
),
'PhabricatorOAuthServerClientAuthorizationPHIDType' => 'PhabricatorPHIDType',
@ -7214,10 +7240,13 @@ phutil_register_library_map(array(
'PhabricatorOAuthServerController' => 'PhabricatorController',
'PhabricatorOAuthServerCreateClientsCapability' => 'PhabricatorPolicyCapability',
'PhabricatorOAuthServerDAO' => 'PhabricatorLiskDAO',
'PhabricatorOAuthServerEditEngine' => 'PhabricatorEditEngine',
'PhabricatorOAuthServerEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorOAuthServerScope' => 'Phobject',
'PhabricatorOAuthServerTestCase' => 'PhabricatorTestCase',
'PhabricatorOAuthServerTestController' => 'PhabricatorOAuthServerController',
'PhabricatorOAuthServerTokenController' => 'PhabricatorOAuthServerController',
'PhabricatorOAuthServerTransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorOAuthServerTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorObjectHandle' => array(
'Phobject',
'PhabricatorPolicyInterface',

View file

@ -756,6 +756,7 @@ final class AphrontRequest extends Phobject {
foreach ($_SERVER as $key => $value) {
if (preg_match('/^HTTP_/', $key)) {
// Unmangle the header as best we can.
$key = substr($key, strlen('HTTP_'));
$key = str_replace('_', ' ', $key);
$key = strtolower($key);
$key = ucwords($key);

View file

@ -0,0 +1,37 @@
<?php
final class AphrontEpochHTTPParameterType
extends AphrontHTTPParameterType {
protected function getParameterExists(AphrontRequest $request, $key) {
return $request->getExists($key) ||
$request->getExists($key.'_d');
}
protected function getParameterValue(AphrontRequest $request, $key) {
return AphrontFormDateControlValue::newFromRequest($request, $key);
}
protected function getParameterTypeName() {
return 'epoch';
}
protected function getParameterFormatDescriptions() {
return array(
pht('An epoch timestamp, as an integer.'),
pht('An absolute date, as a string.'),
pht('A relative date, as a string.'),
pht('Separate date and time inputs, as strings.'),
);
}
protected function getParameterExamples() {
return array(
'v=1460050737',
'v=2022-01-01',
'v=yesterday',
'v_d=2022-01-01&v_t=12:34',
);
}
}

View file

@ -11,7 +11,6 @@ final class AphrontFileResponse extends AphrontResponse {
private $rangeMin;
private $rangeMax;
private $allowOrigins = array();
private $fileToken;
public function addAllowOrigin($origin) {
$this->allowOrigins[] = $origin;
@ -76,15 +75,6 @@ final class AphrontFileResponse extends AphrontResponse {
return $this;
}
public function setTemporaryFileToken(PhabricatorAuthTemporaryToken $token) {
$this->fileToken = $token;
return $this;
}
public function getTemporaryFileToken() {
return $this->fileToken;
}
public function getHeaders() {
$headers = array(
array('Content-Type', $this->getMimeType()),
@ -128,15 +118,4 @@ final class AphrontFileResponse extends AphrontResponse {
return $headers;
}
public function didCompleteWrite($aborted) {
if (!$aborted) {
$token = $this->getTemporaryFileToken();
if ($token) {
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
$token->delete();
unset($unguarded);
}
}
}
}

View file

@ -39,6 +39,11 @@ abstract class AphrontProxyResponse
return $this;
}
public function setCanCDN($can_cdn) {
$this->getProxy()->setCanCDN($can_cdn);
return $this;
}
public function setLastModified($epoch_timestamp) {
$this->getProxy()->setLastModified($epoch_timestamp);
return $this;

View file

@ -4,6 +4,7 @@ abstract class AphrontResponse extends Phobject {
private $request;
private $cacheable = false;
private $canCDN;
private $responseCode = 200;
private $lastModified = null;
@ -66,6 +67,11 @@ abstract class AphrontResponse extends Phobject {
return $this;
}
public function setCanCDN($can_cdn) {
$this->canCDN = $can_cdn;
return $this;
}
public function setLastModified($epoch_timestamp) {
$this->lastModified = $epoch_timestamp;
return $this;
@ -186,6 +192,20 @@ abstract class AphrontResponse extends Phobject {
public function getCacheHeaders() {
$headers = array();
if ($this->cacheable) {
$cache_control = array();
$cache_control[] = sprintf('max-age=%d', $this->cacheable);
if ($this->canCDN) {
$cache_control[] = 'public';
} else {
$cache_control[] = 'private';
}
$headers[] = array(
'Cache-Control',
implode(', ', $cache_control),
);
$headers[] = array(
'Expires',
$this->formatEpochTimestampForHTTPHeader(time() + $this->cacheable),
@ -193,11 +213,7 @@ abstract class AphrontResponse extends Phobject {
} else {
$headers[] = array(
'Cache-Control',
'private, no-cache, no-store, must-revalidate',
);
$headers[] = array(
'Pragma',
'no-cache',
'no-store',
);
$headers[] = array(
'Expires',

View file

@ -68,7 +68,7 @@ final class AlmanacBindingViewController
$this->buildAlmanacPropertiesTable($binding),
$timeline,
))
->addPropertySection(pht('DETAILS'), $details);
->addPropertySection(pht('Details'), $details);
return $this->newPage()
->setTitle($title)

View file

@ -158,7 +158,7 @@ abstract class AlmanacController
->setIcon('fa-plus');
$header = id(new PHUIHeaderView())
->setHeader(pht('PROPERTIES'))
->setHeader(pht('Properties'))
->addActionLink($add_button);
return id(new PHUIObjectBoxView())

View file

@ -81,7 +81,7 @@ final class AlmanacServiceViewController
$service->getServiceImplementation()->getServiceTypeShortName());
return id(new PHUIObjectBoxView())
->setHeaderText(pht('DETAILS'))
->setHeaderText(pht('Details'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->appendChild($properties);
}

View file

@ -0,0 +1,51 @@
<?php
final class PhabricatorAuthLogoutConduitAPIMethod
extends PhabricatorAuthConduitAPIMethod {
public function getAPIMethodName() {
return 'auth.logout';
}
public function getMethodSummary() {
return pht('Terminate all login sessions.');
}
public function getMethodDescription() {
return pht(
'Terminate all web login sessions. If called via OAuth, also terminate '.
'the current OAuth token.'.
"\n\n".
'WARNING: This method does what it claims on the label. If you call '.
'this method via the test console in the web UI, it will log you out!');
}
protected function defineParamTypes() {
return array();
}
protected function defineReturnType() {
return 'void';
}
public function getRequiredScope() {
return self::SCOPE_ALWAYS;
}
protected function execute(ConduitAPIRequest $request) {
$viewer = $request->getUser();
// Destroy all web sessions.
$engine = id(new PhabricatorAuthSessionEngine());
$engine->terminateLoginSessions($viewer);
// If we were called via OAuth, destroy the OAuth token.
$oauth_token = $request->getOAuthToken();
if ($oauth_token) {
$oauth_token->delete();
}
return null;
}
}

View file

@ -29,6 +29,7 @@ final class PhabricatorAuthStartController
// it and warn the user they may need to nuke their cookies.
$session_token = $request->getCookie(PhabricatorCookies::COOKIE_SESSION);
$did_clear = $request->getStr('cleared');
if (strlen($session_token)) {
$kind = PhabricatorAuthSessionEngine::getSessionKindFromToken(
@ -39,18 +40,34 @@ final class PhabricatorAuthStartController
// be logged in, so we can just continue.
break;
default:
// The session cookie is invalid, so clear it.
// The session cookie is invalid, so try to clear it.
$request->clearCookie(PhabricatorCookies::COOKIE_USERNAME);
$request->clearCookie(PhabricatorCookies::COOKIE_SESSION);
return $this->renderError(
pht(
'Your login session is invalid. Try reloading the page and '.
'logging in again. If that does not work, clear your browser '.
'cookies.'));
// We've previously tried to clear the cookie but we ended up back
// here, so it didn't work. Hard fatal instead of trying again.
if ($did_clear) {
return $this->renderError(
pht(
'Your login session is invalid, and clearing the session '.
'cookie was unsuccessful. Try clearing your browser cookies.'));
}
$redirect_uri = $request->getRequestURI();
$redirect_uri->setQueryParam('cleared', 1);
return id(new AphrontRedirectResponse())->setURI($redirect_uri);
}
}
// If we just cleared the session cookie and it worked, clean up after
// ourselves by redirecting to get rid of the "cleared" parameter. The
// the workflow will continue normally.
if ($did_clear) {
$redirect_uri = $request->getRequestURI();
$redirect_uri->setQueryParam('cleared', null);
return id(new AphrontRedirectResponse())->setURI($redirect_uri);
}
$providers = PhabricatorAuthProvider::getAllEnabledProviders();
foreach ($providers as $key => $provider) {
if (!$provider->shouldAllowLogin()) {

View file

@ -29,13 +29,6 @@ final class PhabricatorLogoutController
$viewer = $this->getViewer();
if ($request->isFormPost()) {
$log = PhabricatorUserLog::initializeNewLog(
$viewer,
$viewer->getPHID(),
PhabricatorUserLog::ACTION_LOGOUT);
$log->save();
// Destroy the user's session in the database so logout works even if
// their cookies have some issues. We'll detect cookie issues when they
// try to login again and tell them to clear any junk.
@ -45,8 +38,10 @@ final class PhabricatorLogoutController
->setViewer($viewer)
->withSessionKeys(array($phsid))
->executeOne();
if ($session) {
$session->delete();
$engine = new PhabricatorAuthSessionEngine();
$engine->logoutSession($viewer, $session);
}
}
$request->clearCookie(PhabricatorCookies::COOKIE_SESSION);

View file

@ -297,6 +297,24 @@ final class PhabricatorAuthSessionEngine extends Phobject {
}
}
public function logoutSession(
PhabricatorUser $user,
PhabricatorAuthSession $session) {
$log = PhabricatorUserLog::initializeNewLog(
$user,
$user->getPHID(),
PhabricatorUserLog::ACTION_LOGOUT);
$log->save();
$extensions = PhabricatorAuthSessionEngineExtension::getAllExtensions();
foreach ($extensions as $extension) {
$extension->didLogout($user, array($session));
}
$session->delete();
}
/* -( High Security )------------------------------------------------------ */

View file

@ -0,0 +1,23 @@
<?php
abstract class PhabricatorAuthSessionEngineExtension
extends Phobject {
final public function getExtensionKey() {
return $this->getPhobjectClassConstant('EXTENSIONKEY');
}
final public static function getAllExtensions() {
return id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
->setUniqueMethod('getExtensionKey')
->execute();
}
abstract public function getExtensionName();
public function didLogout(PhabricatorUser $user, array $sessions) {
return;
}
}

View file

@ -0,0 +1,49 @@
<?php
final class PhabricatorAuthSessionEngineExtensionModule
extends PhabricatorConfigModule {
public function getModuleKey() {
return 'sessionengine';
}
public function getModuleName() {
return pht('Engine: Session');
}
public function renderModuleStatus(AphrontRequest $request) {
$viewer = $request->getViewer();
$extensions = PhabricatorAuthSessionEngineExtension::getAllExtensions();
$rows = array();
foreach ($extensions as $extension) {
$rows[] = array(
get_class($extension),
$extension->getExtensionKey(),
$extension->getExtensionName(),
);
}
$table = id(new AphrontTableView($rows))
->setNoDataString(
pht('There are no registered session engine extensions.'))
->setHeaders(
array(
pht('Class'),
pht('Key'),
pht('Name'),
))
->setColumnClasses(
array(
null,
null,
'wide pri',
));
return id(new PHUIObjectBoxView())
->setHeaderText(pht('SessionEngine Extensions'))
->setTable($table);
}
}

View file

@ -201,4 +201,9 @@ final class PhabricatorPhabricatorAuthProvider
return true;
}
public function getPhabricatorURI() {
$config = $this->getProviderConfig();
return $config->getProperty(self::PROPERTY_PHABRICATOR_URI);
}
}

View file

@ -62,19 +62,12 @@ final class PhabricatorExternalAccountQuery
return $this;
}
public function newResultObject() {
return new PhabricatorExternalAccount();
}
protected function loadPage() {
$table = new PhabricatorExternalAccount();
$conn_r = $table->establishConnection('r');
$data = queryfx_all(
$conn_r,
'SELECT * FROM %T %Q %Q %Q',
$table->getTableName(),
$this->buildWhereClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
return $table->loadAllFromArray($data);
return $this->loadStandardPage($this->newResultObject());
}
protected function willFilterPage(array $accounts) {
@ -116,61 +109,59 @@ final class PhabricatorExternalAccountQuery
return $accounts;
}
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
$where = parent::buildWhereClauseParts($conn);
$where[] = $this->buildPagingClause($conn_r);
if ($this->ids) {
if ($this->ids !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
if ($this->phids !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'phid IN (%Ls)',
$this->phids);
}
if ($this->accountTypes) {
if ($this->accountTypes !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'accountType IN (%Ls)',
$this->accountTypes);
}
if ($this->accountDomains) {
if ($this->accountDomains !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'accountDomain IN (%Ls)',
$this->accountDomains);
}
if ($this->accountIDs) {
if ($this->accountIDs !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'accountID IN (%Ls)',
$this->accountIDs);
}
if ($this->userPHIDs) {
if ($this->userPHIDs !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'userPHID IN (%Ls)',
$this->userPHIDs);
}
if ($this->accountSecrets) {
if ($this->accountSecrets !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'accountSecret IN (%Ls)',
$this->accountSecrets);
}
return $this->formatWhereClause($where);
return $where;
}
public function getQueryApplicationClass() {

View file

@ -0,0 +1,19 @@
<?php
final class PhabricatorBadgesEditConduitAPIMethod
extends PhabricatorEditEngineAPIMethod {
public function getAPIMethodName() {
return 'badges.edit';
}
public function newEditEngine() {
return new PhabricatorBadgesEditEngine();
}
public function getMethodSummary() {
return pht(
'Apply transactions to create a new badge or edit an existing one.');
}
}

View file

@ -0,0 +1,18 @@
<?php
final class PhabricatorBadgesSearchConduitAPIMethod
extends PhabricatorSearchEngineAPIMethod {
public function getAPIMethodName() {
return 'badges.search';
}
public function newSearchEngine() {
return new PhabricatorBadgesSearchEngine();
}
public function getMethodSummary() {
return pht('Read information about badges.');
}
}

View file

@ -72,7 +72,7 @@ final class PhabricatorBadgesViewController
$timeline,
$comment_view,
))
->addPropertySection(pht('DESCRIPTION'), $details);
->addPropertySection(pht('Description'), $details);
return $this->newPage()
->setTitle($title)

View file

@ -81,12 +81,14 @@ final class PhabricatorBadgesEditEngine
->setKey('name')
->setLabel(pht('Name'))
->setDescription(pht('Badge name.'))
->setConduitTypeDescription(pht('New badge name.'))
->setTransactionType(PhabricatorBadgesTransaction::TYPE_NAME)
->setValue($object->getName()),
id(new PhabricatorTextEditField())
->setKey('flavor')
->setLabel(pht('Flavor text'))
->setDescription(pht('Short description of the badge.'))
->setConduitTypeDescription(pht('New badge flavor.'))
->setValue($object->getFlavor())
->setTransactionType(PhabricatorBadgesTransaction::TYPE_FLAVOR),
id(new PhabricatorIconSetEditField())
@ -100,6 +102,8 @@ final class PhabricatorBadgesEditEngine
id(new PhabricatorSelectEditField())
->setKey('quality')
->setLabel(pht('Quality'))
->setDescription(pht('Color and rarity of the badge.'))
->setConduitTypeDescription(pht('New badge quality.'))
->setValue($object->getQuality())
->setTransactionType(PhabricatorBadgesTransaction::TYPE_QUALITY)
->setOptions(PhabricatorBadgesQuality::getDropdownQualityMap()),
@ -107,6 +111,7 @@ final class PhabricatorBadgesEditEngine
->setKey('description')
->setLabel(pht('Description'))
->setDescription(pht('Badge long description.'))
->setConduitTypeDescription(pht('New badge description.'))
->setTransactionType(PhabricatorBadgesTransaction::TYPE_DESCRIPTION)
->setValue($object->getDescription()),
);

View file

@ -11,6 +11,10 @@ final class PhabricatorBadgesEditor
return pht('Badges');
}
protected function supportsSearch() {
return true;
}
public function getTransactionTypes() {
$types = parent::getTransactionTypes();

View file

@ -36,6 +36,12 @@ final class PhabricatorBadgesQuery
return $this;
}
public function withNameNgrams($ngrams) {
return $this->withNgramsConstraint(
id(new PhabricatorBadgesBadgeNameNgrams()),
$ngrams);
}
public function needRecipients($need_recipients) {
$this->needRecipients = $need_recipients;
return $this;
@ -45,6 +51,10 @@ final class PhabricatorBadgesQuery
return $this->loadStandardPage($this->newResultObject());
}
protected function getPrimaryTableAlias() {
return 'badges';
}
public function newResultObject() {
return new PhabricatorBadgesBadge();
}
@ -73,28 +83,28 @@ final class PhabricatorBadgesQuery
if ($this->ids !== null) {
$where[] = qsprintf(
$conn,
'id IN (%Ld)',
'badges.id IN (%Ld)',
$this->ids);
}
if ($this->phids !== null) {
$where[] = qsprintf(
$conn,
'phid IN (%Ls)',
'badges.phid IN (%Ls)',
$this->phids);
}
if ($this->qualities !== null) {
$where[] = qsprintf(
$conn,
'quality IN (%Ls)',
'badges.quality IN (%Ls)',
$this->qualities);
}
if ($this->statuses !== null) {
$where[] = qsprintf(
$conn,
'status IN (%Ls)',
'badges.status IN (%Ls)',
$this->statuses);
}

View file

@ -15,22 +15,12 @@ final class PhabricatorBadgesSearchEngine
return new PhabricatorBadgesQuery();
}
public function buildSavedQueryFromRequest(AphrontRequest $request) {
$saved = new PhabricatorSavedQuery();
$saved->setParameter(
'statuses',
$this->readListFromRequest($request, 'statuses'));
$saved->setParameter(
'qualities',
$this->readListFromRequest($request, 'qualities'));
return $saved;
}
protected function buildCustomSearchFields() {
return array(
id(new PhabricatorSearchTextField())
->setLabel(pht('Name Contains'))
->setKey('name')
->setDescription(pht('Search for badges by name substring.')),
id(new PhabricatorSearchCheckboxesField())
->setKey('qualities')
->setLabel(pht('Quality'))
@ -55,6 +45,10 @@ final class PhabricatorBadgesSearchEngine
$query->withQualities($map['qualities']);
}
if ($map['name'] !== null) {
$query->withNameNgrams($map['name']);
}
return $query;
}

View file

@ -7,7 +7,9 @@ final class PhabricatorBadgesBadge extends PhabricatorBadgesDAO
PhabricatorSubscribableInterface,
PhabricatorTokenReceiverInterface,
PhabricatorFlaggableInterface,
PhabricatorDestructibleInterface {
PhabricatorDestructibleInterface,
PhabricatorConduitResultInterface,
PhabricatorNgramsInterface {
protected $name;
protected $flavor;
@ -49,6 +51,8 @@ final class PhabricatorBadgesBadge extends PhabricatorBadgesDAO
->setQuality(PhabricatorBadgesQuality::DEFAULT_QUALITY)
->setCreatorPHID($actor->getPHID())
->setEditPolicy($edit_policy)
->setFlavor('')
->setDescription('')
->setStatus(self::STATUS_ACTIVE);
}
@ -56,7 +60,7 @@ final class PhabricatorBadgesBadge extends PhabricatorBadgesDAO
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_COLUMN_SCHEMA => array(
'name' => 'text255',
'name' => 'sort255',
'flavor' => 'text255',
'description' => 'text',
'icon' => 'text255',
@ -190,4 +194,46 @@ final class PhabricatorBadgesBadge extends PhabricatorBadgesDAO
$this->saveTransaction();
}
/* -( PhabricatorConduitResultInterface )---------------------------------- */
public function getFieldSpecificationsForConduit() {
return array(
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('name')
->setType('string')
->setDescription(pht('The name of the badge.')),
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('creatorPHID')
->setType('phid')
->setDescription(pht('User PHID of the creator.')),
id(new PhabricatorConduitSearchFieldSpecification())
->setKey('status')
->setType('string')
->setDescription(pht('Active or archived status of the badge.')),
);
}
public function getFieldValuesForConduit() {
return array(
'name' => $this->getName(),
'creatorPHID' => $this->getCreatorPHID(),
'status' => $this->getStatus(),
);
}
public function getConduitSearchAttachments() {
return array();
}
/* -( PhabricatorNgramInterface )------------------------------------------ */
public function newNgrams() {
return array(
id(new PhabricatorBadgesBadgeNameNgrams())
->setValue($this->getName()),
);
}
}

View file

@ -0,0 +1,18 @@
<?php
final class PhabricatorBadgesBadgeNameNgrams
extends PhabricatorSearchNgrams {
public function getNgramKey() {
return 'badgename';
}
public function getColumnName() {
return 'name';
}
public function getApplicationName() {
return 'badges';
}
}

View file

@ -20,6 +20,7 @@ final class PhabricatorBadgesRecipientsListView extends AphrontView {
$badge = $this->badge;
$handles = $this->handles;
$awards = mpull($badge->getAwards(), null, 'getRecipientPHID');
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
@ -34,8 +35,17 @@ final class PhabricatorBadgesRecipientsListView extends AphrontView {
$remove_uri = '/badges/recipients/'.
$badge->getID().'/remove/?phid='.$handle->getPHID();
$award = $awards[$handle->getPHID()];
$awarder_handle = $viewer->renderHandle($award->getAwarderPHID());
$award_date = phabricator_date($award->getDateCreated(), $viewer);
$awarder_info = pht(
'Awarded by %s on %s',
$awarder_handle->render(),
$award_date);
$item = id(new PHUIObjectItemView())
->setHeader($handle->getFullName())
->setSubhead($awarder_info)
->setHref($handle->getURI())
->setImageURI($handle->getImageURI());

View file

@ -94,8 +94,8 @@ final class PhabricatorCalendarEventViewController
$add_comment_form,
))
->setCurtain($curtain)
->addPropertySection(pht('DETAILS'), $details)
->addPropertySection(pht('DESCRIPTION'), $description);
->addPropertySection(pht('Details'), $details)
->addPropertySection(pht('Description'), $description);
return $this->newPage()
->setTitle($page_title)

View file

@ -90,24 +90,11 @@ final class PhabricatorCalendarEventQuery
}
protected function loadPage() {
$table = new PhabricatorCalendarEvent();
$conn_r = $table->establishConnection('r');
$events = $this->loadStandardPage($this->newResultObject());
$viewer = $this->getViewer();
$data = queryfx_all(
$conn_r,
'SELECT event.* FROM %T event %Q %Q %Q %Q %Q',
$table->getTableName(),
$this->buildJoinClause($conn_r),
$this->buildWhereClause($conn_r),
$this->buildGroupClause($conn_r),
$this->buildOrderClause($conn_r),
$this->buildLimitClause($conn_r));
$events = $table->loadAllFromArray($data);
foreach ($events as $event) {
$event->applyViewerTimezone($this->getViewer());
$event->applyViewerTimezone($viewer);
}
if (!$this->generateGhosts) {
@ -115,6 +102,15 @@ final class PhabricatorCalendarEventQuery
}
$enforced_end = null;
$raw_limit = $this->getRawResultLimit();
if (!$raw_limit && !$this->rangeEnd) {
throw new Exception(
pht(
'Event queries which generate ghost events must include either a '.
'result limit or an end date, because they may otherwise generate '.
'an infinite number of results. This query has neither.'));
}
foreach ($events as $key => $event) {
$sequence_start = 0;
@ -176,12 +172,12 @@ final class PhabricatorCalendarEventQuery
$sequence_end++;
$datetime->modify($modify_key);
$date = $datetime->format('U');
if ($sequence_end > $this->getRawResultLimit() + $sequence_start) {
if ($sequence_end > $raw_limit + $sequence_start) {
break;
}
}
} else {
$sequence_end = $this->getRawResultLimit() + $sequence_start;
$sequence_end = $raw_limit + $sequence_start;
}
$sequence_start = max(1, $sequence_start);
@ -190,10 +186,17 @@ final class PhabricatorCalendarEventQuery
$events[] = $event->generateNthGhost($index, $viewer);
}
if (count($events) >= $this->getRawResultLimit()) {
$events = msort($events, 'getDateFrom');
$events = array_slice($events, 0, $this->getRawResultLimit(), true);
$enforced_end = last($events)->getDateFrom();
// NOTE: We're slicing results every time because this makes it cheaper
// to generate future ghosts. If we already have 100 events that occur
// before July 1, we know we never need to generate ghosts after that
// because they couldn't possibly ever appear in the result set.
if ($raw_limit) {
if (count($events) >= $raw_limit) {
$events = msort($events, 'getDateFrom');
$events = array_slice($events, 0, $raw_limit, true);
$enforced_end = last($events)->getDateFrom();
}
}
}
}
@ -251,61 +254,61 @@ final class PhabricatorCalendarEventQuery
return $parts;
}
protected function buildWhereClause(AphrontDatabaseConnection $conn_r) {
$where = array();
protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
$where = parent::buildWhereClauseParts($conn);
if ($this->ids) {
$where[] = qsprintf(
$conn_r,
$conn,
'event.id IN (%Ld)',
$this->ids);
}
if ($this->phids) {
$where[] = qsprintf(
$conn_r,
$conn,
'event.phid IN (%Ls)',
$this->phids);
}
if ($this->rangeBegin) {
$where[] = qsprintf(
$conn_r,
$conn,
'event.dateTo >= %d OR event.isRecurring = 1',
$this->rangeBegin);
}
if ($this->rangeEnd) {
$where[] = qsprintf(
$conn_r,
$conn,
'event.dateFrom <= %d',
$this->rangeEnd);
}
if ($this->inviteePHIDs !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'invitee.inviteePHID IN (%Ls)',
$this->inviteePHIDs);
}
if ($this->creatorPHIDs) {
$where[] = qsprintf(
$conn_r,
$conn,
'event.userPHID IN (%Ls)',
$this->creatorPHIDs);
}
if ($this->isCancelled !== null) {
$where[] = qsprintf(
$conn_r,
$conn,
'event.isCancelled = %d',
(int)$this->isCancelled);
}
if ($this->eventsWithNoParent == true) {
$where[] = qsprintf(
$conn_r,
$conn,
'event.instanceOfEventPHID IS NULL');
}
@ -314,20 +317,19 @@ final class PhabricatorCalendarEventQuery
foreach ($this->instanceSequencePairs as $pair) {
$sql[] = qsprintf(
$conn_r,
$conn,
'(event.instanceOfEventPHID = %s AND event.sequenceIndex = %d)',
$pair[0],
$pair[1]);
}
$where[] = qsprintf(
$conn_r,
$conn,
'%Q',
implode(' OR ', $sql));
}
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
return $where;
}
protected function getPrimaryTableAlias() {

View file

@ -140,6 +140,7 @@ abstract class CelerityResourceController extends PhabricatorController {
private function makeResponseCacheable(AphrontResponse $response) {
$response->setCacheDurationInSeconds(60 * 60 * 24 * 30);
$response->setLastModified(time());
$response->setCanCDN(true);
return $response;
}

View file

@ -32,13 +32,10 @@ final class PhabricatorChatLogChannelListController
->setHeaderText('Channel List')
->setObjectList($list);
return $this->buildApplicationPage(
array(
$crumbs,
$box,
),
array(
'title' => pht('Channel List'),
));
return $this->newPage()
->setTitle(pht('Channel List'))
->setCrumbs($crumbs)
->appendChild($box);
}
}

View file

@ -248,14 +248,11 @@ final class PhabricatorChatLogChannelLogController
$form,
'#');
return $this->buildApplicationPage(
array(
$crumbs,
$box,
),
array(
'title' => pht('Channel Log'),
));
return $this->newPage()
->setTitle(pht('Channel Log'))
->setCrumbs($crumbs)
->appendChild($box);
}
/**

View file

@ -65,10 +65,6 @@ final class ConduitCall extends Phobject {
return $this->handler->shouldAllowUnguardedWrites();
}
public function getRequiredScope() {
return $this->handler->getRequiredScope();
}
public function getErrorDescription($code) {
return $this->handler->getErrorDescription($code);
}

View file

@ -45,7 +45,6 @@ final class PhabricatorConduitAPIController
$auth_error = null;
$conduit_username = '-';
if ($call->shouldRequireAuthentication()) {
$metadata['scope'] = $call->getRequiredScope();
$auth_error = $this->authenticateUser($api_request, $metadata, $method);
// If we've explicitly authenticated the user here and either done
// CSRF validation or are using a non-web authentication mechanism.
@ -185,11 +184,6 @@ final class PhabricatorConduitAPIController
// First, verify the signature.
try {
$protocol_data = $metadata;
// TODO: We should stop writing this into the protocol data when
// processing a request.
unset($protocol_data['scope']);
ConduitClient::verifySignature(
$method,
$api_request->getAllParameters(),
@ -362,11 +356,8 @@ final class PhabricatorConduitAPIController
$user);
}
// handle oauth
$access_token = idx($metadata, 'access_token');
$method_scope = idx($metadata, 'scope');
if ($access_token &&
$method_scope != PhabricatorOAuthServerScope::SCOPE_NOT_ACCESSIBLE) {
if ($access_token) {
$token = id(new PhabricatorOAuthServerAccessToken())
->loadOneWhere('token = %s', $access_token);
if (!$token) {
@ -377,25 +368,35 @@ final class PhabricatorConduitAPIController
}
$oauth_server = new PhabricatorOAuthServer();
$valid = $oauth_server->validateAccessToken($token,
$method_scope);
if (!$valid) {
$authorization = $oauth_server->authorizeToken($token);
if (!$authorization) {
return array(
'ERR-INVALID-AUTH',
pht('Access token is invalid.'),
pht('Access token is invalid or expired.'),
);
}
// valid token, so let's log in the user!
$user_phid = $token->getUserPHID();
$user = id(new PhabricatorUser())
->loadOneWhere('phid = %s', $user_phid);
$user = id(new PhabricatorPeopleQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withPHIDs(array($token->getUserPHID()))
->executeOne();
if (!$user) {
return array(
'ERR-INVALID-AUTH',
pht('Access token is for invalid user.'),
);
}
$ok = $this->authorizeOAuthMethodAccess($authorization, $method);
if (!$ok) {
return array(
'ERR-OAUTH-ACCESS',
pht('You do not have authorization to call this method.'),
);
}
$api_request->setOAuthToken($token);
return $this->validateAuthenticatedUser(
$api_request,
$user);
@ -510,19 +511,22 @@ final class PhabricatorConduitAPIController
'wide',
));
$param_panel = new PHUIObjectBoxView();
$param_panel->setHeaderText(pht('Method Parameters'));
$param_panel->setTable($param_table);
$param_panel = id(new PHUIObjectBoxView())
->setHeaderText(pht('Method Parameters'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($param_table);
$result_panel = new PHUIObjectBoxView();
$result_panel->setHeaderText(pht('Method Result'));
$result_panel->setTable($result_table);
$result_panel = id(new PHUIObjectBoxView())
->setHeaderText(pht('Method Result'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setTable($result_table);
$method_uri = $this->getApplicationURI('method/'.$method.'/');
$crumbs = $this->buildApplicationCrumbs()
->addTextCrumb($method, $method_uri)
->addTextCrumb(pht('Call'));
->addTextCrumb(pht('Call'))
->setBorder(true);
$example_panel = null;
if ($request && $method_implementation) {
@ -532,16 +536,26 @@ final class PhabricatorConduitAPIController
$params);
}
return $this->buildApplicationPage(
array(
$crumbs,
$title = pht('Method Call Result');
$header = id(new PHUIHeaderView())
->setHeader($title)
->setHeaderIcon('fa-exchange');
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter(array(
$param_panel,
$result_panel,
$example_panel,
),
array(
'title' => pht('Method Call Result'),
));
$title = pht('Method Call Result');
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
private function renderAPIValue($value) {
@ -642,4 +656,30 @@ final class PhabricatorConduitAPIController
return array($metadata, $params);
}
private function authorizeOAuthMethodAccess(
PhabricatorOAuthClientAuthorization $authorization,
$method_name) {
$method = ConduitAPIMethod::getConduitMethod($method_name);
if (!$method) {
return false;
}
$required_scope = $method->getRequiredScope();
switch ($required_scope) {
case ConduitAPIMethod::SCOPE_ALWAYS:
return true;
case ConduitAPIMethod::SCOPE_NEVER:
return false;
}
$authorization_scope = $authorization->getScope();
if (!empty($authorization_scope[$required_scope])) {
return true;
}
return false;
}
}

View file

@ -85,37 +85,41 @@ final class PhabricatorConduitConsoleController
$header = id(new PHUIHeaderView())
->setUser($viewer)
->setHeader($method->getAPIMethodName());
->setHeader($method->getAPIMethodName())
->setHeaderIcon('fa-tty');
$form_box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Call Method'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setForm($form);
$content = array();
$properties = $this->buildMethodProperties($method);
$info_box = id(new PHUIObjectBoxView())
->setHeaderText(pht('API Method: %s', $method->getAPIMethodName()))
->setFormErrors($errors)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->appendChild($properties);
$content[] = $info_box;
$content[] = $method->getMethodDocumentation();
$content[] = $form_box;
$content[] = $this->renderExampleBox($method, null);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($method->getAPIMethodName());
$crumbs->setBorder(true);
return $this->buildApplicationPage(
array(
$crumbs,
$content,
),
array(
'title' => $method->getAPIMethodName(),
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter(array(
$info_box,
$method->getMethodDocumentation(),
$form_box,
$this->renderExampleBox($method, null),
));
$title = $method->getAPIMethodName();
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
private function buildMethodProperties(ConduitAPIMethod $method) {
@ -142,6 +146,36 @@ final class PhabricatorConduitConsoleController
pht('Errors'),
$error_description);
$scope = $method->getRequiredScope();
switch ($scope) {
case ConduitAPIMethod::SCOPE_ALWAYS:
$oauth_icon = 'fa-globe green';
$oauth_description = pht(
'OAuth clients may always call this method.');
break;
case ConduitAPIMethod::SCOPE_NEVER:
$oauth_icon = 'fa-ban red';
$oauth_description = pht(
'OAuth clients may never call this method.');
break;
default:
$oauth_icon = 'fa-unlock-alt blue';
$oauth_description = pht(
'OAuth clients may call this method after requesting access to '.
'the "%s" scope.',
$scope);
break;
}
$view->addProperty(
pht('OAuth Scope'),
array(
id(new PHUIIconView())->setIcon($oauth_icon),
' ',
$oauth_description,
));
$view->addSectionHeader(
pht('Description'), PHUIPropertyListView::ICON_SUMMARY);
$view->addTextContent(

View file

@ -56,6 +56,7 @@ abstract class PhabricatorConduitController extends PhabricatorController {
return id(new PHUIObjectBoxView())
->setHeaderText(pht('Examples'))
->setInfoView($info_view)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->addPropertyList($arc_example, pht('arc call-conduit'))
->addPropertyList($curl_example, pht('cURL'))
->addPropertyList($php_example, pht('PHP'));

View file

@ -55,19 +55,26 @@ final class PhabricatorConduitTokenController
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Install Certificate'));
$crumbs->setBorder(true);
$object_box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Certificate Token'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setForm($form);
return $this->buildApplicationPage(
array(
$crumbs,
$object_box,
),
array(
'title' => pht('Certificate Install Token'),
));
$title = pht('Certificate Install Token');
$header = id(new PHUIHeaderView())
->setHeader($title);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter($object_box);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
}

View file

@ -15,6 +15,8 @@ abstract class ConduitAPIMethod
const METHOD_STATUS_UNSTABLE = 'unstable';
const METHOD_STATUS_DEPRECATED = 'deprecated';
const SCOPE_NEVER = 'scope.never';
const SCOPE_ALWAYS = 'scope.always';
/**
* Get a short, human-readable text summary of the method.
@ -108,8 +110,7 @@ abstract class ConduitAPIMethod
}
public function getRequiredScope() {
// by default, conduit methods are not accessible via OAuth
return PhabricatorOAuthServerScope::SCOPE_NOT_ACCESSIBLE;
return self::SCOPE_NEVER;
}
public function executeMethod(ConduitAPIRequest $request) {

View file

@ -24,6 +24,10 @@ final class ConduitGetCapabilitiesConduitAPIMethod extends ConduitAPIMethod {
return 'dict<string, any>';
}
public function getRequiredScope() {
return self::SCOPE_ALWAYS;
}
protected function execute(ConduitAPIRequest $request) {
$authentication = array(
'token',

View file

@ -18,6 +18,10 @@ final class ConduitQueryConduitAPIMethod extends ConduitAPIMethod {
return 'dict<dict>';
}
public function getRequiredScope() {
return self::SCOPE_ALWAYS;
}
protected function execute(ConduitAPIRequest $request) {
$methods = id(new PhabricatorConduitMethodQuery())
->setViewer($request->getUser())

View file

@ -0,0 +1,38 @@
<?php
final class ConduitColumnsParameterType
extends ConduitParameterType {
protected function getParameterValue(array $request, $key) {
// We don't do any meaningful validation here because the transaction
// itself validates everything and the input format is flexible.
return parent::getParameterValue($request, $key);
}
protected function getParameterTypeName() {
return 'columns';
}
protected function getParameterDefault() {
return array();
}
protected function getParameterFormatDescriptions() {
return array(
pht('Single column PHID.'),
pht('List of column PHIDs.'),
pht('List of position dictionaries.'),
pht('List with a mixture of PHIDs and dictionaries.'),
);
}
protected function getParameterExamples() {
return array(
'"PHID-PCOL-1111"',
'["PHID-PCOL-2222", "PHID-PCOL-3333"]',
'[{"columnPHID": "PHID-PCOL-4444", "afterPHID": "PHID-TASK-5555"}]',
'[{"columnPHID": "PHID-PCOL-4444", "beforePHID": "PHID-TASK-6666"}]',
);
}
}

View file

@ -5,6 +5,7 @@ final class ConduitAPIRequest extends Phobject {
protected $params;
private $user;
private $isClusterRequest = false;
private $oauthToken;
public function __construct(array $params) {
$this->params = $params;
@ -48,6 +49,16 @@ final class ConduitAPIRequest extends Phobject {
return $this->user;
}
public function setOAuthToken(
PhabricatorOAuthServerAccessToken $oauth_token) {
$this->oauthToken = $oauth_token;
return $this;
}
public function getOAuthToken() {
return $this->oauthToken;
}
public function setIsClusterRequest($is_cluster_request) {
$this->isClusterRequest = $is_cluster_request;
return $this;

View file

@ -58,18 +58,20 @@ final class PhabricatorConfigAllController
$panel->setHeaderText(pht('Current Settings'));
$panel->setTable($table);
$nav = $this->buildSideNavView();
$nav->selectFilter('all/');
$nav->setCrumbs($crumbs);
$nav->appendChild($panel);
return $this->buildApplicationPage(
$nav,
array(
'title' => $title,
$view = id(new PHUITwoColumnView())
->setNavigation($nav)
->setMainColumn(array(
$panel,
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
}

View file

@ -18,18 +18,17 @@ final class PhabricatorConfigCacheController
$code_box = $this->renderCodeBox();
$data_box = $this->renderDataBox();
$nav->appendChild(
array(
$crumbs,
$view = id(new PHUITwoColumnView())
->setNavigation($nav)
->setMainColumn(array(
$code_box,
$data_box,
));
));
return $this->buildApplicationPage(
$nav,
array(
'title' => $title,
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
private function renderCodeBox() {

View file

@ -153,17 +153,17 @@ final class PhabricatorConfigDatabaseIssueController
$nav = $this->buildSideNavView();
$nav->selectFilter('dbissue/');
$nav->appendChild(
array(
$crumbs,
$table_box,
));
return $this->buildApplicationPage(
$nav,
array(
'title' => $title,
));
$view = id(new PHUITwoColumnView())
->setNavigation($nav)
->setMainColumn(array(
$table_box,
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
}

View file

@ -91,14 +91,16 @@ final class PhabricatorConfigDatabaseStatusController
$crumbs->addTextCrumb(pht('Database Status'));
}
$nav->setCrumbs($crumbs);
$nav->appendChild($body);
$view = id(new PHUITwoColumnView())
->setNavigation($nav)
->setMainColumn(array(
$body,
));
return $this->buildApplicationPage(
$nav,
array(
'title' => $title,
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}

View file

@ -227,11 +227,13 @@ final class PhabricatorConfigEditController
->setValue($examples));
}
$title = pht('Edit %s', $key);
$title = pht('Edit Option: %s', $key);
$header_icon = 'fa-pencil';
$short = pht('Edit');
$form_box = id(new PHUIObjectBoxView())
->setHeaderText($title)
->setHeaderText(pht('Config Option'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setForm($form);
if ($error_view) {
@ -246,21 +248,25 @@ final class PhabricatorConfigEditController
}
$crumbs->addTextCrumb($key, '/config/edit/'.$key);
$crumbs->setBorder(true);
$timeline = $this->buildTransactionTimeline(
$config_entry,
new PhabricatorConfigTransactionQuery());
$timeline->setShouldTerminate(true);
return $this->buildApplicationPage(
array(
$crumbs,
$form_box,
$timeline,
),
array(
'title' => $title,
));
$header = id(new PHUIHeaderView())
->setHeader($title)
->setHeaderIcon($header_icon);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter($form_box);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
private function readRequest(

View file

@ -17,22 +17,26 @@ final class PhabricatorConfigGroupController
$list = $this->buildOptionList($options->getOptions());
$box = id(new PHUIObjectBoxView())
->setHeaderText($title)
->setObjectList($list);
$crumbs = $this
->buildApplicationCrumbs()
->addTextCrumb(pht('Config'), $this->getApplicationURI())
->addTextCrumb($options->getName(), $this->getApplicationURI());
->addTextCrumb($options->getName(), $this->getApplicationURI())
->setBorder(true);
return $this->buildApplicationPage(
array(
$crumbs,
$box,
),
array(
'title' => $title,
));
$header = id(new PHUIHeaderView())
->setHeader($title)
->setHeaderIcon('fa-sliders');
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter($box);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
private function buildOptionList(array $options) {

View file

@ -31,22 +31,22 @@ final class PhabricatorConfigHistoryController
$title = pht('Settings History');
$crumbs = $this->buildApplicationCrumbs();
$crumbs->setBorder(true);
$crumbs->addTextCrumb('Config', $this->getApplicationURI());
$crumbs->addTextCrumb($title, '/config/history/');
$nav = $this->buildSideNavView();
$nav->selectFilter('history/');
$nav->setCrumbs($crumbs);
$nav->appendChild($timeline);
return $this->buildApplicationPage(
array(
$nav,
),
array(
'title' => $title,
));
$view = id(new PHUITwoColumnView())
->setNavigation($nav)
->setMainColumn(array(
$timeline,
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
}

View file

@ -32,14 +32,12 @@ final class PhabricatorConfigIgnoreController
throw new Exception(pht('Unrecognized verb: %s', $verb));
}
$dialog = id(new AphrontDialogView())
->setUser($request->getUser())
return $this->newDialog()
->setTitle($title)
->appendChild($body)
->addSubmitButton($submit_title)
->addCancelButton($issue_uri);
return id(new AphrontDialogResponse())->setDialog($dialog);
}
public function manageApplication($issue) {

View file

@ -56,21 +56,22 @@ final class PhabricatorConfigIssueListController
->setSeverity(PHUIInfoView::SEVERITY_NOTICE);
}
$nav->appendChild($setup_issues);
$title = pht('Setup Issues');
$crumbs = $this
->buildApplicationCrumbs($nav)
->addTextCrumb(pht('Setup'), $this->getApplicationURI('issue/'));
$nav->setCrumbs($crumbs);
$view = id(new PHUITwoColumnView())
->setNavigation($nav)
->setMainColumn(array(
$setup_issues,
));
return $this->buildApplicationPage(
$nav,
array(
'title' => $title,
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
private function buildIssueList(array $issues, $group) {

View file

@ -36,14 +36,10 @@ final class PhabricatorConfigIssueViewController
->addTextCrumb(pht('Setup Issues'), $this->getApplicationURI('issue/'))
->addTextCrumb($title, $request->getRequestURI());
return $this->buildApplicationPage(
array(
$crumbs,
$content,
),
array(
'title' => $title,
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($content);
}
private function renderIssue(PhabricatorSetupIssue $issue) {

View file

@ -23,23 +23,21 @@ final class PhabricatorConfigListController
->setHeaderText(pht('Applications Configuration'))
->setObjectList($apps_list);
$nav->appendChild(
array(
$core,
$apps,
));
$crumbs = $this
->buildApplicationCrumbs()
->addTextCrumb(pht('Config'), $this->getApplicationURI());
$nav->setCrumbs($crumbs);
return $this->buildApplicationPage(
$nav,
array(
'title' => $title,
$view = id(new PHUITwoColumnView())
->setNavigation($nav)
->setMainColumn(array(
$core,
$apps,
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
private function buildConfigOptionsList(array $groups, $type) {

View file

@ -14,24 +14,24 @@ final class PhabricatorConfigModuleController
$module = $all_modules[$key];
$content = $module->renderModuleStatus($request);
$name = $module->getModuleName();
$title = $module->getModuleName();
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($name);
$crumbs->addTextCrumb($title);
$nav = $this->buildSideNavView();
$nav->selectFilter('module/'.$key.'/');
$nav->appendChild(
array(
$crumbs,
$view = id(new PHUITwoColumnView())
->setNavigation($nav)
->setMainColumn(array(
$content,
));
return $this->buildApplicationPage(
$nav,
array(
'title' => $name,
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
}

View file

@ -15,14 +15,16 @@ final class PhabricatorConfigWelcomeController
->buildApplicationCrumbs()
->addTextCrumb(pht('Welcome'));
$nav->setCrumbs($crumbs);
$nav->appendChild($this->buildWelcomeScreen($request));
return $this->buildApplicationPage(
$nav,
array(
'title' => $title,
$view = id(new PHUITwoColumnView())
->setNavigation($nav)
->setMainColumn(array(
$this->buildWelcomeScreen($request),
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
public function buildWelcomeScreen(AphrontRequest $request) {

View file

@ -127,11 +127,9 @@ final class ConpherenceListController extends ConpherenceController {
$layout->setHeader($this->buildHeaderPaneContent(
$conpherence,
$policy_objects));
$response = $this->buildApplicationPage(
$layout,
array(
'title' => $title,
));
$response = $this->newPage()
->setTitle($title)
->appendChild($layout);
break;
}

View file

@ -131,12 +131,10 @@ final class ConpherenceViewController extends
->setLatestTransactionID($data['latest_transaction_id'])
->setRole('thread');
return $this->buildApplicationPage(
$layout,
array(
'title' => $title,
'pageObjects' => array($conpherence->getPHID()),
));
return $this->newPage()
->setTitle($title)
->setPageObjectPHIDs(array($conpherence->getPHID()))
->appendChild($layout);
}
private function renderFormContent() {

View file

@ -46,9 +46,7 @@ final class PhabricatorCountdownApplication extends PhabricatorApplication {
=> 'PhabricatorCountdownViewController',
'comment/(?P<id>[1-9]\d*)/'
=> 'PhabricatorCountdownCommentController',
'edit/(?:(?P<id>[1-9]\d*)/)?'
=> 'PhabricatorCountdownEditController',
'create/'
$this->getEditRoutePattern('edit/')
=> 'PhabricatorCountdownEditController',
'delete/(?P<id>[1-9]\d*)/'
=> 'PhabricatorCountdownDeleteController',

View file

@ -1,63 +0,0 @@
<?php
final class PhabricatorCountdownCommentController
extends PhabricatorCountdownController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
if (!$request->isFormPost()) {
return new Aphront400Response();
}
$countdown = id(new PhabricatorCountdownQuery())
->setViewer($viewer)
->withIDs(array($id))
->executeOne();
if (!$countdown) {
return new Aphront404Response();
}
$is_preview = $request->isPreviewRequest();
$draft = PhabricatorDraft::buildFromRequest($request);
$view_uri = '/'.$countdown->getMonogram();
$xactions = array();
$xactions[] = id(new PhabricatorCountdownTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
->attachComment(
id(new PhabricatorCountdownTransactionComment())
->setContent($request->getStr('comment')));
$editor = id(new PhabricatorCountdownEditor())
->setActor($viewer)
->setContinueOnNoEffect($request->isContinueRequest())
->setContentSourceFromRequest($request)
->setIsPreview($is_preview);
try {
$xactions = $editor->applyTransactions($countdown, $xactions);
} catch (PhabricatorApplicationTransactionNoEffectException $ex) {
return id(new PhabricatorApplicationTransactionNoEffectResponse())
->setCancelURI($view_uri)
->setException($ex);
}
if ($draft) {
$draft->replaceOrDelete();
}
if ($request->isAjax() && $is_preview) {
return id(new PhabricatorApplicationTransactionResponse())
->setViewer($viewer)
->setTransactions($xactions)
->setIsPreview($is_preview);
} else {
return id(new AphrontRedirectResponse())
->setURI($view_uri);
}
}
}

View file

@ -7,16 +7,5 @@ abstract class PhabricatorCountdownController extends PhabricatorController {
->setSearchEngine(new PhabricatorCountdownSearchEngine());
}
protected function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
$crumbs->addAction(
id(new PHUIListItemView())
->setName(pht('Create Countdown'))
->setHref($this->getApplicationURI('create/'))
->setIcon('fa-plus-square'));
return $crumbs;
}
}

View file

@ -4,205 +4,9 @@ final class PhabricatorCountdownEditController
extends PhabricatorCountdownController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
if ($id) {
$countdown = id(new PhabricatorCountdownQuery())
->setViewer($viewer)
->withIDs(array($id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$countdown) {
return new Aphront404Response();
}
$date_value = AphrontFormDateControlValue::newFromEpoch(
$viewer,
$countdown->getEpoch());
$v_projects = PhabricatorEdgeQuery::loadDestinationPHIDs(
$countdown->getPHID(),
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
$v_projects = array_reverse($v_projects);
$title = pht('Edit Countdown: %s', $countdown->getTitle());
} else {
$title = pht('Create Countdown');
$countdown = PhabricatorCountdown::initializeNewCountdown($viewer);
$date_value = AphrontFormDateControlValue::newFromEpoch(
$viewer, PhabricatorTime::getNow());
$v_projects = array();
}
$errors = array();
$e_text = true;
$e_epoch = null;
$v_text = $countdown->getTitle();
$v_desc = $countdown->getDescription();
$v_space = $countdown->getSpacePHID();
$v_view = $countdown->getViewPolicy();
$v_edit = $countdown->getEditPolicy();
if ($request->isFormPost()) {
$v_text = $request->getStr('title');
$v_desc = $request->getStr('description');
$v_space = $request->getStr('spacePHID');
$date_value = AphrontFormDateControlValue::newFromRequest(
$request,
'epoch');
$v_view = $request->getStr('viewPolicy');
$v_edit = $request->getStr('editPolicy');
$v_projects = $request->getArr('projects');
$type_title = PhabricatorCountdownTransaction::TYPE_TITLE;
$type_epoch = PhabricatorCountdownTransaction::TYPE_EPOCH;
$type_description = PhabricatorCountdownTransaction::TYPE_DESCRIPTION;
$type_space = PhabricatorTransactions::TYPE_SPACE;
$type_view = PhabricatorTransactions::TYPE_VIEW_POLICY;
$type_edit = PhabricatorTransactions::TYPE_EDIT_POLICY;
$xactions = array();
$xactions[] = id(new PhabricatorCountdownTransaction())
->setTransactionType($type_title)
->setNewValue($v_text);
$xactions[] = id(new PhabricatorCountdownTransaction())
->setTransactionType($type_epoch)
->setNewValue($date_value);
$xactions[] = id(new PhabricatorCountdownTransaction())
->setTransactionType($type_description)
->setNewValue($v_desc);
$xactions[] = id(new PhabricatorCountdownTransaction())
->setTransactionType($type_space)
->setNewValue($v_space);
$xactions[] = id(new PhabricatorCountdownTransaction())
->setTransactionType($type_view)
->setNewValue($v_view);
$xactions[] = id(new PhabricatorCountdownTransaction())
->setTransactionType($type_edit)
->setNewValue($v_edit);
$proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
$xactions[] = id(new PhabricatorCountdownTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
->setMetadataValue('edge:type', $proj_edge_type)
->setNewValue(array('=' => array_fuse($v_projects)));
$editor = id(new PhabricatorCountdownEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true);
try {
$editor->applyTransactions($countdown, $xactions);
return id(new AphrontRedirectResponse())
->setURI('/'.$countdown->getMonogram());
} catch (PhabricatorApplicationTransactionValidationException $ex) {
$validation_exception = $ex;
$e_title = $ex->getShortMessage($type_title);
$e_epoch = $ex->getShortMessage($type_epoch);
}
}
$crumbs = $this->buildApplicationCrumbs();
$crumbs->setBorder(true);
$cancel_uri = '/countdown/';
if ($countdown->getID()) {
$cancel_uri = '/countdown/'.$countdown->getID().'/';
$crumbs->addTextCrumb('C'.$countdown->getID(), $cancel_uri);
$crumbs->addTextCrumb(pht('Edit'));
$submit_label = pht('Save Changes');
$header_icon = 'fa-pencil';
} else {
$crumbs->addTextCrumb(pht('Create Countdown'));
$submit_label = pht('Create Countdown');
$header_icon = 'fa-plus-square';
}
$policies = id(new PhabricatorPolicyQuery())
->setViewer($viewer)
->setObject($countdown)
->execute();
$form = id(new AphrontFormView())
->setUser($viewer)
->setAction($request->getRequestURI()->getPath())
->appendChild(
id(new AphrontFormTextControl())
->setLabel(pht('Title'))
->setValue($v_text)
->setName('title')
->setError($e_text))
->appendControl(
id(new AphrontFormDateControl())
->setName('epoch')
->setLabel(pht('End Date'))
->setError($e_epoch)
->setValue($date_value))
->appendControl(
id(new PhabricatorRemarkupControl())
->setName('description')
->setLabel(pht('Description'))
->setValue($v_desc))
->appendControl(
id(new AphrontFormPolicyControl())
->setName('viewPolicy')
->setPolicyObject($countdown)
->setPolicies($policies)
->setSpacePHID($v_space)
->setValue($v_view)
->setCapability(PhabricatorPolicyCapability::CAN_VIEW))
->appendControl(
id(new AphrontFormPolicyControl())
->setName('editPolicy')
->setPolicyObject($countdown)
->setPolicies($policies)
->setValue($v_edit)
->setCapability(PhabricatorPolicyCapability::CAN_EDIT))
->appendControl(
id(new AphrontFormTokenizerControl())
->setLabel(pht('Projects'))
->setName('projects')
->setValue($v_projects)
->setDatasource(new PhabricatorProjectDatasource()))
->appendChild(
id(new AphrontFormSubmitControl())
->addCancelButton($cancel_uri)
->setValue($submit_label));
$form_box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Countdown'))
->setFormErrors($errors)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setForm($form);
$header = id(new PHUIHeaderView())
->setHeader($title)
->setHeaderIcon($header_icon);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter($form_box);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild(
array(
$view,
));
return id(new PhabricatorCountdownEditEngine())
->setController($this)
->buildResponse();
}
}

View file

@ -13,4 +13,14 @@ final class PhabricatorCountdownListController
->buildResponse();
}
protected function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
id(new PhabricatorCountdownEditEngine())
->setViewer($this->getViewer())
->addActionToCrumbs($crumbs);
return $crumbs;
}
}

View file

@ -55,12 +55,15 @@ final class PhabricatorCountdownViewController
$timeline = $this->buildTransactionTimeline(
$countdown,
new PhabricatorCountdownTransactionQuery());
$add_comment = $this->buildCommentForm($countdown);
$comment_view = id(new PhabricatorCountdownEditEngine())
->setViewer($viewer)
->buildEditEngineCommentView($countdown);
$content = array(
$countdown_view,
$timeline,
$add_comment,
$comment_view,
);
$view = id(new PHUITwoColumnView())
@ -135,25 +138,4 @@ final class PhabricatorCountdownViewController
->setContent($content);
}
private function buildCommentForm(PhabricatorCountdown $countdown) {
$viewer = $this->getViewer();
$is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
$add_comment_header = $is_serious
? pht('Add Comment')
: pht('Last Words');
$draft = PhabricatorDraft::newFromUserAndKey(
$viewer, $countdown->getPHID());
return id(new PhabricatorApplicationTransactionCommentView())
->setUser($viewer)
->setObjectPHID($countdown->getPHID())
->setDraft($draft)
->setHeaderText($add_comment_header)
->setAction($this->getApplicationURI('/comment/'.$countdown->getID().'/'))
->setSubmitButtonName(pht('Add Comment'));
}
}

View file

@ -0,0 +1,108 @@
<?php
final class PhabricatorCountdownEditEngine
extends PhabricatorEditEngine {
const ENGINECONST = 'countdown.countdown';
public function isEngineConfigurable() {
return false;
}
public function getEngineName() {
return pht('Countdowns');
}
public function getSummaryHeader() {
return pht('Edit Countdowns');
}
public function getSummaryText() {
return pht('Creates and edits countdowns.');
}
public function getEngineApplicationClass() {
return 'PhabricatorCountdownApplication';
}
protected function newEditableObject() {
return PhabricatorCountdown::initializeNewCountdown(
$this->getViewer());
}
protected function newObjectQuery() {
return id(new PhabricatorCountdownQuery());
}
protected function getObjectCreateTitleText($object) {
return pht('Create Countdown');
}
protected function getObjectCreateButtonText($object) {
return pht('Create Countdown');
}
protected function getObjectEditTitleText($object) {
return pht('Edit Countdown: %s', $object->getTitle());
}
protected function getObjectEditShortText($object) {
return pht('Edit Countdown');
}
protected function getObjectCreateShortText() {
return pht('Create Countdown');
}
protected function getObjectName() {
return pht('Countdown');
}
protected function getCommentViewHeaderText($object) {
return pht('Last Words');
}
protected function getCommentViewButtonText($object) {
return pht('Contemplate Infinity');
}
protected function getObjectViewURI($object) {
return $object->getURI();
}
protected function buildCustomEditFields($object) {
$epoch_value = $object->getEpoch();
if ($epoch_value === null) {
$epoch_value = PhabricatorTime::getNow();
}
return array(
id(new PhabricatorTextEditField())
->setKey('name')
->setLabel(pht('Name'))
->setIsRequired(true)
->setTransactionType(PhabricatorCountdownTransaction::TYPE_TITLE)
->setDescription(pht('The countdown name.'))
->setConduitDescription(pht('Rename the countdown.'))
->setConduitTypeDescription(pht('New countdown name.'))
->setValue($object->getTitle()),
id(new PhabricatorEpochEditField())
->setKey('epoch')
->setLabel(pht('End Date'))
->setTransactionType(PhabricatorCountdownTransaction::TYPE_EPOCH)
->setDescription(pht('Date when the countdown ends.'))
->setConduitDescription(pht('Change the end date of the countdown.'))
->setConduitTypeDescription(pht('New countdown end date.'))
->setValue($epoch_value),
id(new PhabricatorRemarkupEditField())
->setKey('description')
->setLabel(pht('Description'))
->setTransactionType(PhabricatorCountdownTransaction::TYPE_DESCRIPTION)
->setDescription(pht('Description of the countdown.'))
->setConduitDescription(pht('Change the countdown description.'))
->setConduitTypeDescription(pht('New description.'))
->setValue($object->getDescription()),
);
}
}

View file

@ -120,19 +120,27 @@ final class PhabricatorCountdownEditor
}
break;
case PhabricatorCountdownTransaction::TYPE_EPOCH:
$date_value = AphrontFormDateControlValue::newFromEpoch(
$this->requireActor(),
$object->getEpoch());
if (!$date_value->isValid()) {
if (!$object->getEpoch() && !$xactions) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht('You must give the countdown a valid end date.'),
nonempty(last($xactions), null));
pht('Required'),
pht('You must give the countdown an end date.'),
null);
$error->setIsMissingFieldError(true);
$errors[] = $error;
}
foreach ($xactions as $xaction) {
$value = $xaction->getNewValue();
if (!$value->isValid()) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht('You must give the countdown a valid end date.'),
$xaction);
$errors[] = $error;
}
}
break;
}

View file

@ -74,4 +74,35 @@ final class PhabricatorCountdownQuery
return 'PhabricatorCountdownApplication';
}
public function getBuiltinOrders() {
return array(
'ending' => array(
'vector' => array('-epoch', '-id'),
'name' => pht('End Date (Past to Future)'),
),
'unending' => array(
'vector' => array('epoch', 'id'),
'name' => pht('End Date (Future to Past)'),
),
) + parent::getBuiltinOrders();
}
public function getOrderableColumns() {
return array(
'epoch' => array(
'table' => $this->getPrimaryTableAlias(),
'column' => 'epoch',
'type' => 'int',
),
) + parent::getOrderableColumns();
}
protected function getPagingValueMap($cursor, array $keys) {
$countdown = $this->loadCursorObject($cursor);
return array(
'epoch' => $countdown->getEpoch(),
'id' => $countdown->getID(),
);
}
}

View file

@ -30,20 +30,18 @@ final class PhabricatorCountdownSearchEngine
}
protected function buildCustomSearchFields() {
return array(
id(new PhabricatorUsersSearchField())
->setLabel(pht('Authors'))
->setKey('authorPHIDs')
->setAliases(array('author', 'authors')),
id(new PhabricatorSearchCheckboxesField())
->setKey('upcoming')
->setOptions(array(
id(new PhabricatorUsersSearchField())
->setLabel(pht('Authors'))
->setKey('authorPHIDs')
->setAliases(array('author', 'authors')),
id(new PhabricatorSearchCheckboxesField())
->setKey('upcoming')
->setOptions(
array(
'upcoming' => pht('Show only upcoming countdowns.'),
)),
);
);
}
protected function getURI($path) {

View file

@ -28,10 +28,13 @@ final class PhabricatorCountdown extends PhabricatorCountdownDAO
$view_policy = $app->getPolicy(
PhabricatorCountdownDefaultViewCapability::CAPABILITY);
$edit_policy = $app->getPolicy(
PhabricatorCountdownDefaultEditCapability::CAPABILITY);
return id(new PhabricatorCountdown())
->setAuthorPHID($actor->getPHID())
->setViewPolicy($view_policy)
->setEpoch(PhabricatorTime::getNow())
->setEditPolicy($edit_policy)
->setSpacePHID($actor->getDefaultSpacePHID());
}
@ -43,6 +46,14 @@ final class PhabricatorCountdown extends PhabricatorCountdownDAO
'description' => 'text',
'mailKey' => 'bytes20',
),
self::CONFIG_KEY_SCHEMA => array(
'key_epoch' => array(
'columns' => array('epoch'),
),
'key_author' => array(
'columns' => array('authorPHID', 'epoch'),
),
),
) + parent::getConfiguration();
}
@ -55,6 +66,10 @@ final class PhabricatorCountdown extends PhabricatorCountdownDAO
return 'C'.$this->getID();
}
public function getURI() {
return '/'.$this->getMonogram();
}
public function save() {
if (!$this->getMailKey()) {
$this->setMailKey(Filesystem::readRandomCharacters(20));

View file

@ -33,42 +33,20 @@ final class PhabricatorCountdownTransaction
$type = $this->getTransactionType();
switch ($type) {
case self::TYPE_TITLE:
if ($old === null) {
return pht(
'%s created this countdown.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s renamed this countdown from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
}
break;
return pht(
'%s renamed this countdown from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
case self::TYPE_DESCRIPTION:
if ($old === null) {
return pht(
'%s set the description of this countdown.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s edited the description of this countdown.',
$this->renderHandleLink($author_phid));
}
break;
return pht(
'%s edited the description of this countdown.',
$this->renderHandleLink($author_phid));
case self::TYPE_EPOCH:
if ($old === null) {
return pht(
'%s set this countdown to end on %s.',
$this->renderHandleLink($author_phid),
phabricator_datetime($new, $this->getViewer()));
} else if ($old != $new) {
return pht(
'%s updated this countdown to end on %s.',
$this->renderHandleLink($author_phid),
phabricator_datetime($new, $this->getViewer()));
}
break;
return pht(
'%s updated this countdown to end on %s.',
$this->renderHandleLink($author_phid),
phabricator_datetime($new, $this->getViewer()));
}
return parent::getTitle();
@ -84,47 +62,20 @@ final class PhabricatorCountdownTransaction
$type = $this->getTransactionType();
switch ($type) {
case self::TYPE_TITLE:
if ($old === null) {
return pht(
'%s created %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
} else {
return pht(
'%s renamed %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
}
break;
return pht(
'%s renamed %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
case self::TYPE_DESCRIPTION:
if ($old === null) {
return pht(
'%s set the description of %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
} else {
return pht(
'%s edited the description of %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
}
break;
return pht(
'%s edited the description of %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
case self::TYPE_EPOCH:
if ($old === null) {
return pht(
'%s set the end date of %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
} else {
return pht(
'%s edited the end date of %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
}
break;
return pht(
'%s edited the end date of %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($object_phid));
}
return parent::getTitleForFeed();
@ -150,15 +101,6 @@ final class PhabricatorCountdownTransaction
return $tags;
}
public function shouldHide() {
$old = $this->getOldValue();
switch ($this->getTransactionType()) {
case self::TYPE_DESCRIPTION:
return ($old === null);
}
return parent::shouldHide();
}
public function hasChangeDetails() {
switch ($this->getTransactionType()) {
case self::TYPE_DESCRIPTION:

View file

@ -23,13 +23,14 @@ final class PhabricatorDaemonBulkJobViewController
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Bulk Jobs'), '/daemon/bulk/');
$crumbs->addTextCrumb($title);
$crumbs->setBorder(true);
$properties = $this->renderProperties($job);
$actions = $this->renderActions($job);
$properties->setActionList($actions);
$curtain = $this->buildCurtainView($job);
$box = id(new PHUIObjectBoxView())
->setHeaderText($title)
->setHeaderText(pht('Details'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->addPropertyList($properties);
$timeline = $this->buildTransactionTimeline(
@ -37,15 +38,22 @@ final class PhabricatorDaemonBulkJobViewController
new PhabricatorWorkerBulkJobTransactionQuery());
$timeline->setShouldTerminate(true);
return $this->buildApplicationPage(
array(
$crumbs,
$header = id(new PHUIHeaderView())
->setHeader($title)
->setHeaderIcon('fa-hourglass');
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->setMainColumn(array(
$box,
$timeline,
),
array(
'title' => $title,
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
private function renderProperties(PhabricatorWorkerBulkJob $job) {
@ -64,12 +72,9 @@ final class PhabricatorDaemonBulkJobViewController
return $view;
}
private function renderActions(PhabricatorWorkerBulkJob $job) {
private function buildCurtainView(PhabricatorWorkerBulkJob $job) {
$viewer = $this->getViewer();
$actions = id(new PhabricatorActionListView())
->setUser($viewer)
->setObject($job);
$curtain = $this->newCurtainView($job);
if ($job->isConfirming()) {
$continue_uri = $job->getMonitorURI();
@ -77,13 +82,13 @@ final class PhabricatorDaemonBulkJobViewController
$continue_uri = $job->getDoneURI();
}
$actions->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setHref($continue_uri)
->setIcon('fa-arrow-circle-o-right')
->setName(pht('Continue')));
return $actions;
return $curtain;
}
}

View file

@ -117,16 +117,15 @@ final class PhabricatorDaemonConsoleController
'n',
));
$completed_panel = new PHUIObjectBoxView();
$completed_panel->setHeaderText(
pht('Recently Completed Tasks (Last 15m)'));
$completed_panel->setTable($completed_table);
$completed_panel = id(new PHUIObjectBoxView())
->setHeaderText(pht('Recently Completed Tasks (Last 15m)'))
->setTable($completed_table);
$daemon_table = new PhabricatorDaemonLogListView();
$daemon_table->setUser($viewer);
$daemon_table->setDaemonLogs($logs);
$daemon_panel = new PHUIObjectBoxView();
$daemon_panel = id(new PHUIObjectBoxView());
$daemon_panel->setHeaderText(pht('Active Daemons'));
$daemon_panel->setObjectList($daemon_table);
@ -218,11 +217,10 @@ final class PhabricatorDaemonConsoleController
$triggers_panel,
));
return $this->buildApplicationPage(
$nav,
array(
'title' => pht('Console'),
));
return $this->newPage()
->setTitle(pht('Console'))
->appendChild($nav);
}
private function buildTriggersTable(array $triggers) {

View file

@ -17,9 +17,9 @@ final class PhabricatorDaemonLogEventViewController
->setCombinedLog(true)
->setShowFullMessage(true);
$log_panel = new PHUIObjectBoxView();
$log_panel->setHeaderText(pht('Combined Log'));
$log_panel->appendChild($event_view);
$log_panel = id(new PHUIObjectBoxView())
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->appendChild($event_view);
$daemon_id = $event->getLogID();
@ -27,17 +27,21 @@ final class PhabricatorDaemonLogEventViewController
->addTextCrumb(
pht('Daemon %s', $daemon_id),
$this->getApplicationURI("log/{$daemon_id}/"))
->addTextCrumb(pht('Event %s', $event->getID()));
->addTextCrumb(pht('Event %s', $event->getID()))
->setBorder(true);
$header = id(new PHUIHeaderView())
->setHeader(pht('Combined Log'))
->setHeaderIcon('fa-file-text');
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter($log_panel);
return $this->newPage()
->setTitle(pht('Combined Daemon Log'))
->appendChild($view);
return $this->buildApplicationPage(
array(
$crumbs,
$log_panel,
),
array(
'title' => pht('Combined Daemon Log'),
));
}
}

View file

@ -31,11 +31,10 @@ final class PhabricatorDaemonLogListController
$nav->appendChild($box);
$nav->appendChild($pager);
return $this->buildApplicationPage(
$nav,
array(
'title' => pht('All Daemons'),
));
return $this->newPage()
->setTitle(pht('All Daemons'))
->appendChild($nav);
}
}

View file

@ -22,9 +22,11 @@ final class PhabricatorDaemonLogViewController
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Daemon %s', $log->getID()));
$crumbs->setBorder(true);
$header = id(new PHUIHeaderView())
->setHeader($log->getDaemon());
->setHeader($log->getDaemon())
->setHeaderIcon('fa-pied-piper-alt');
$tag = id(new PHUITagView())
->setType(PHUITagView::TYPE_STATE);
@ -32,32 +34,38 @@ final class PhabricatorDaemonLogViewController
$status = $log->getStatus();
switch ($status) {
case PhabricatorDaemonLog::STATUS_UNKNOWN:
$tag->setBackgroundColor(PHUITagView::COLOR_ORANGE);
$tag->setName(pht('Unknown'));
$color = 'orange';
$name = pht('Unknown');
$icon = 'fa-warning';
break;
case PhabricatorDaemonLog::STATUS_RUNNING:
$tag->setBackgroundColor(PHUITagView::COLOR_GREEN);
$tag->setName(pht('Running'));
$color = 'green';
$name = pht('Running');
$icon = 'fa-rocket';
break;
case PhabricatorDaemonLog::STATUS_DEAD:
$tag->setBackgroundColor(PHUITagView::COLOR_RED);
$tag->setName(pht('Dead'));
$color = 'red';
$name = pht('Dead');
$icon = 'fa-times';
break;
case PhabricatorDaemonLog::STATUS_WAIT:
$tag->setBackgroundColor(PHUITagView::COLOR_BLUE);
$tag->setName(pht('Waiting'));
$color = 'blue';
$name = pht('Waiting');
$icon = 'fa-clock-o';
break;
case PhabricatorDaemonLog::STATUS_EXITING:
$tag->setBackgroundColor(PHUITagView::COLOR_YELLOW);
$tag->setName(pht('Exiting'));
$color = 'yellow';
$name = pht('Exiting');
$icon = 'fa-check';
break;
case PhabricatorDaemonLog::STATUS_EXITED:
$tag->setBackgroundColor(PHUITagView::COLOR_GREY);
$tag->setName(pht('Exited'));
$color = 'bluegrey';
$name = pht('Exited');
$icon = 'fa-check';
break;
}
$header->addTag($tag);
$header->setStatus($icon, $color, $name);
$properties = $this->buildPropertyListView($log);
@ -65,23 +73,26 @@ final class PhabricatorDaemonLogViewController
->setUser($viewer)
->setEvents($events);
$event_panel = new PHUIObjectBoxView();
$event_panel->setHeaderText(pht('Events'));
$event_panel->appendChild($event_view);
$event_panel = id(new PHUIObjectBoxView())
->setHeaderText(pht('Events'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->appendChild($event_view);
$object_box = id(new PHUIObjectBoxView())
->setHeader($header)
->addPropertyList($properties);
return $this->buildApplicationPage(
array(
$crumbs,
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter(array(
$object_box,
$event_panel,
),
array(
'title' => pht('Daemon Log'),
));
return $this->newPage()
->setTitle(pht('Daemon Log'))
->setCrumbs($crumbs)
->appendChild($view);
}
private function buildPropertyListView(PhabricatorDaemonLog $daemon) {

View file

@ -31,17 +31,18 @@ final class PhabricatorWorkerTaskDetailController
$title = pht('Task %d', $task->getID());
$header = id(new PHUIHeaderView())
->setHeader(pht('Task %d (%s)',
->setHeader(pht('Task %d: %s',
$task->getID(),
$task->getTaskClass()));
$task->getTaskClass()))
->setHeaderIcon('fa-sort');
$properties = $this->buildPropertyListView($task);
$object_box = id(new PHUIObjectBoxView())
->setHeader($header)
->setHeaderText($title)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->addPropertyList($properties);
$retry_head = id(new PHUIHeaderView())
->setHeader(pht('Retries'));
@ -49,6 +50,7 @@ final class PhabricatorWorkerTaskDetailController
$retry_box = id(new PHUIObjectBoxView())
->setHeader($retry_head)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->addPropertyList($retry_info);
$content = array(
@ -59,15 +61,16 @@ final class PhabricatorWorkerTaskDetailController
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($title);
$crumbs->setBorder(true);
return $this->buildApplicationPage(
array(
$crumbs,
$content,
),
array(
'title' => $title,
));
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter($content);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
private function buildPropertyListView(

View file

@ -27,7 +27,6 @@ final class PhabricatorDashboardApplication extends PhabricatorApplication {
'view/(?P<id>\d+)/' => 'PhabricatorDashboardViewController',
'archive/(?P<id>\d+)/' => 'PhabricatorDashboardArchiveController',
'manage/(?P<id>\d+)/' => 'PhabricatorDashboardManageController',
'history/(?P<id>\d+)/' => 'PhabricatorDashboardHistoryController',
'create/' => 'PhabricatorDashboardEditController',
'copy/(?:(?P<id>\d+)/)?' => 'PhabricatorDashboardCopyController',
'edit/(?:(?P<id>\d+)/)?' => 'PhabricatorDashboardEditController',

View file

@ -49,7 +49,7 @@ final class PhabricatorDashboardEditController
if ($is_new) {
$title = pht('Create Dashboard');
$header = pht('Create Dashboard');
$header_icon = 'fa-plus-square';
$button = pht('Create Dashboard');
$cancel_uri = $this->getApplicationURI();
@ -58,11 +58,11 @@ final class PhabricatorDashboardEditController
$id = $dashboard->getID();
$cancel_uri = $this->getApplicationURI('manage/'.$id.'/');
$title = pht('Edit Dashboard %d', $dashboard->getID());
$header = pht('Edit Dashboard "%s"', $dashboard->getName());
$title = pht('Edit Dashboard: %s', $dashboard->getName());
$header_icon = 'fa-pencil';
$button = pht('Save Changes');
$crumbs->addTextCrumb(pht('Dashboard %d', $id), $cancel_uri);
$crumbs->addTextCrumb($dashboard->getName(), $cancel_uri);
$crumbs->addTextCrumb(pht('Edit'));
}
@ -140,6 +140,12 @@ final class PhabricatorDashboardEditController
->setName('name')
->setValue($v_name)
->setError($e_name))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel(pht('Layout Mode'))
->setName('layout_mode')
->setValue($v_layout_mode)
->setOptions($layout_mode_options))
->appendChild(
id(new AphrontFormPolicyControl())
->setName('viewPolicy')
@ -151,13 +157,7 @@ final class PhabricatorDashboardEditController
->setName('editPolicy')
->setPolicyObject($dashboard)
->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
->setPolicies($policies))
->appendChild(
id(new AphrontFormSelectControl())
->setLabel(pht('Layout Mode'))
->setName('layout_mode')
->setValue($v_layout_mode)
->setOptions($layout_mode_options));
->setPolicies($policies));
$form->appendControl(
id(new AphrontFormTokenizerControl())
@ -172,18 +172,25 @@ final class PhabricatorDashboardEditController
->addCancelButton($cancel_uri));
$box = id(new PHUIObjectBoxView())
->setHeaderText($header)
->setHeaderText(pht('Dashboard'))
->setForm($form)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setValidationException($validation_exception);
return $this->buildApplicationPage(
array(
$crumbs,
$box,
),
array(
'title' => $title,
));
$crumbs->setBorder(true);
$header = id(new PHUIHeaderView())
->setHeader($title)
->setHeaderIcon($header_icon);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter($box);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
private function processTemplateRequest(AphrontRequest $request) {

View file

@ -1,48 +0,0 @@
<?php
final class PhabricatorDashboardHistoryController
extends PhabricatorDashboardController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
$dashboard_view_uri = $this->getApplicationURI('view/'.$id.'/');
$dashboard_manage_uri = $this->getApplicationURI('manage/'.$id.'/');
$dashboard = id(new PhabricatorDashboardQuery())
->setViewer($viewer)
->withIDs(array($id))
->executeOne();
if (!$dashboard) {
return new Aphront404Response();
}
$title = $dashboard->getName();
$crumbs = $this->buildApplicationCrumbs();
$crumbs->setBorder(true);
$crumbs->addTextCrumb(
pht('Dashboard %d', $dashboard->getID()),
$dashboard_view_uri);
$crumbs->addTextCrumb(
pht('Manage'),
$dashboard_manage_uri);
$crumbs->addTextCrumb(pht('History'));
$timeline = $this->buildTransactionTimeline(
$dashboard,
new PhabricatorDashboardTransactionQuery());
$timeline->setShouldTerminate(true);
return $this->buildApplicationPage(
array(
$crumbs,
$timeline,
),
array(
'title' => $title,
));
}
}

View file

@ -34,25 +34,25 @@ final class PhabricatorDashboardManageController
pht('Dashboard %d', $dashboard->getID()),
$dashboard_uri);
$crumbs->addTextCrumb(pht('Manage'));
$crumbs->setBorder(true);
$header = $this->buildHeaderView($dashboard);
$actions = $this->buildActionView($dashboard);
$curtain = $this->buildCurtainview($dashboard);
$properties = $this->buildPropertyView($dashboard);
$properties->setActionList($actions);
$box = id(new PHUIObjectBoxView())
->setHeader($header)
->addPropertyList($properties);
$timeline = $this->buildTransactionTimeline(
$dashboard,
new PhabricatorDashboardTransactionQuery());
$info_view = null;
if (!$can_edit) {
$no_edit = pht(
'You do not have permission to edit this dashboard. If you want to '.
'make changes, make a copy first.');
$box->setInfoView(
id(new PHUIInfoView())
->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
->setErrors(array($no_edit)));
$info_view = id(new PHUIInfoView())
->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
->setErrors(array($no_edit));
}
$rendered_dashboard = id(new PhabricatorDashboardRenderingEngine())
@ -61,19 +61,30 @@ final class PhabricatorDashboardManageController
->setArrangeMode($can_edit)
->renderDashboard();
return $this->buildApplicationPage(
array(
$crumbs,
$box,
$rendered_dashboard,
),
array(
'title' => $title,
));
$dashboard_box = id(new PHUIBoxView())
->addClass('dashboard-preview-box')
->appendChild($rendered_dashboard);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->setMainColumn(array(
$info_view,
$properties,
$timeline,
))
->setFooter($dashboard_box);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
private function buildHeaderView(PhabricatorDashboard $dashboard) {
$viewer = $this->getRequest()->getUser();
$viewer = $this->getViewer();
$id = $dashboard->getID();
if ($dashboard->isArchived()) {
$status_icon = 'fa-ban';
@ -87,33 +98,33 @@ final class PhabricatorDashboardManageController
PhabricatorDashboard::getStatusNameMap(),
$dashboard->getStatus());
$button = id(new PHUIButtonView())
->setTag('a')
->setText(pht('View Dashboard'))
->setIcon('fa-columns')
->setHref($this->getApplicationURI("view/{$id}/"));
return id(new PHUIHeaderView())
->setUser($viewer)
->setHeader($dashboard->getName())
->setPolicyObject($dashboard)
->setStatus($status_icon, $status_color, $status_name);
->setStatus($status_icon, $status_color, $status_name)
->setHeaderIcon('fa-dashboard')
->addActionLink($button);
}
private function buildActionView(PhabricatorDashboard $dashboard) {
$viewer = $this->getRequest()->getUser();
private function buildCurtainView(PhabricatorDashboard $dashboard) {
$viewer = $this->getViewer();
$id = $dashboard->getID();
$actions = id(new PhabricatorActionListView())
->setObject($dashboard)
->setUser($viewer);
$curtain = $this->newCurtainView($dashboard);
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$dashboard,
PhabricatorPolicyCapability::CAN_EDIT);
$actions->addAction(
id(new PhabricatorActionView())
->setName(pht('View Dashboard'))
->setIcon('fa-columns')
->setHref($this->getApplicationURI("view/{$id}/")));
$actions->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Edit Dashboard'))
->setIcon('fa-pencil')
@ -121,7 +132,7 @@ final class PhabricatorDashboardManageController
->setDisabled(!$can_edit));
if ($dashboard->isArchived()) {
$actions->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Activate Dashboard'))
->setIcon('fa-check')
@ -129,7 +140,7 @@ final class PhabricatorDashboardManageController
->setDisabled(!$can_edit)
->setWorkflow($can_edit));
} else {
$actions->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Archive Dashboard'))
->setIcon('fa-ban')
@ -138,7 +149,7 @@ final class PhabricatorDashboardManageController
->setWorkflow($can_edit));
}
$actions->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Copy Dashboard'))
->setIcon('fa-files-o')
@ -158,28 +169,21 @@ final class PhabricatorDashboardManageController
$title_install = pht('Install Dashboard');
$href_install = "install/{$id}/";
}
$actions->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName($title_install)
->setIcon('fa-wrench')
->setHref($this->getApplicationURI($href_install))
->setWorkflow(true));
$actions->addAction(
id(new PhabricatorActionView())
->setName(pht('View History'))
->setIcon('fa-history')
->setHref($this->getApplicationURI("history/{$id}/")));
return $actions;
return $curtain;
}
private function buildPropertyView(PhabricatorDashboard $dashboard) {
$viewer = $this->getRequest()->getUser();
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($dashboard);
->setUser($viewer);
$descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions(
$viewer,
@ -193,9 +197,10 @@ final class PhabricatorDashboardManageController
pht('Panels'),
$viewer->renderHandleList($dashboard->getPanelPHIDs()));
$properties->invokeWillRenderEvent();
return $properties;
return id(new PHUIObjectBoxView())
->setHeaderText(pht('Details'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->addPropertyList($properties);
}
}

View file

@ -90,18 +90,18 @@ final class PhabricatorDashboardPanelEditController
}
if ($is_create) {
$title = pht('New Panel');
$header = pht('Create New Panel');
$title = pht('Create New Panel');
$button = pht('Create Panel');
$header_icon = 'fa-plus-square';
if ($dashboard) {
$cancel_uri = $manage_uri;
} else {
$cancel_uri = $this->getApplicationURI('panel/');
}
} else {
$title = pht('Edit %s', $panel->getMonogram());
$header = pht('Edit %s %s', $panel->getMonogram(), $panel->getName());
$title = pht('Edit Panel: %s', $panel->getName());
$button = pht('Save Panel');
$header_icon = 'fa-pencil';
if ($dashboard) {
$cancel_uri = $manage_uri;
} else {
@ -260,10 +260,11 @@ final class PhabricatorDashboardPanelEditController
'/'.$panel->getMonogram());
$crumbs->addTextCrumb(pht('Edit'));
}
$crumbs->setBorder(true);
if ($request->isAjax()) {
return $this->newDialog()
->setTitle($header)
->setTitle($title)
->setSubmitURI($submit_uri)
->setWidth(AphrontDialogView::WIDTH_FORM)
->setValidationException($validation_exception)
@ -279,18 +280,23 @@ final class PhabricatorDashboardPanelEditController
}
$box = id(new PHUIObjectBoxView())
->setHeaderText($header)
->setHeaderText(pht('Panel'))
->setValidationException($validation_exception)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setForm($form);
return $this->buildApplicationPage(
array(
$crumbs,
$box,
),
array(
'title' => $title,
));
$header = id(new PHUIHeaderView())
->setHeader($title)
->setHeaderIcon($header_icon);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter($box);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
private function processPanelTypeRequest(AphrontRequest $request) {
@ -349,26 +355,33 @@ final class PhabricatorDashboardPanelEditController
}
$title = pht('Create Dashboard Panel');
$header_icon = 'fa-plus-square';
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(
pht('Panels'),
$this->getApplicationURI('panel/'));
$crumbs->addTextCrumb(pht('New Panel'));
$crumbs->setBorder(true);
$box = id(new PHUIObjectBoxView())
->setHeaderText($title)
->setHeaderText(pht('Panel'))
->setFormErrors($errors)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setForm($form);
return $this->buildApplicationPage(
array(
$crumbs,
$box,
),
array(
'title' => $title,
));
$header = id(new PHUIHeaderView())
->setHeader($title)
->setHeaderIcon($header_icon);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter($box);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
private function processPanelCloneRequest(

View file

@ -50,20 +50,18 @@ final class PhabricatorDashboardPanelRenderController
$crumbs = $this->buildApplicationCrumbs()
->addTextCrumb(pht('Panels'), $this->getApplicationURI('panel/'))
->addTextCrumb($panel->getMonogram(), '/'.$panel->getMonogram())
->addTextCrumb(pht('Standalone View'));
->addTextCrumb(pht('Standalone View'))
->setBorder(true);
$view = id(new PHUIBoxView())
->addClass('dashboard-view')
->appendChild($rendered_panel);
return $this->buildApplicationPage(
array(
$crumbs,
$view,
),
array(
'title' => array(pht('Panel'), $panel->getName()),
));
return $this->newPage()
->setTitle(array(pht('Panel'), $panel->getName()))
->setCrumbs($crumbs)
->appendChild($view);
}
}

View file

@ -25,19 +25,15 @@ final class PhabricatorDashboardPanelViewController
pht('Panels'),
$this->getApplicationURI('panel/'));
$crumbs->addTextCrumb($panel->getMonogram());
$crumbs->setBorder(true);
$header = $this->buildHeaderView($panel);
$actions = $this->buildActionView($panel);
$curtain = $this->buildCurtainView($panel);
$properties = $this->buildPropertyView($panel);
$timeline = $this->buildTransactionTimeline(
$panel,
new PhabricatorDashboardPanelTransactionQuery());
$timeline->setShouldTerminate(true);
$properties->setActionList($actions);
$box = id(new PHUIObjectBoxView())
->setHeader($header)
->addPropertyList($properties);
$rendered_panel = id(new PhabricatorDashboardPanelRenderingEngine())
->setViewer($viewer)
@ -45,31 +41,41 @@ final class PhabricatorDashboardPanelViewController
->setParentPanelPHIDs(array())
->renderPanel();
$view = id(new PHUIBoxView())
->addMargin(PHUI::MARGIN_LARGE_LEFT)
->addMargin(PHUI::MARGIN_LARGE_RIGHT)
->addMargin(PHUI::MARGIN_LARGE_TOP)
$preview = id(new PHUIBoxView())
->addClass('dashboard-preview-box')
->appendChild($rendered_panel);
return $this->buildApplicationPage(
array(
$crumbs,
$box,
$view,
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->setMainColumn(array(
$properties,
$timeline,
),
array(
'title' => $title,
));
))
->setFooter($rendered_panel);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
private function buildHeaderView(PhabricatorDashboardPanel $panel) {
$viewer = $this->getRequest()->getUser();
$viewer = $this->getViewer();
$id = $panel->getID();
$button = id(new PHUIButtonView())
->setTag('a')
->setText(pht('View Panel'))
->setIcon('fa-columns')
->setHref($this->getApplicationURI("panel/render/{$id}/"));
$header = id(new PHUIHeaderView())
->setUser($viewer)
->setHeader($panel->getName())
->setPolicyObject($panel);
->setPolicyObject($panel)
->setHeaderIcon('fa-columns')
->addActionLink($button);
if (!$panel->getIsArchived()) {
$header->setStatus('fa-check', 'bluegrey', pht('Active'));
@ -79,20 +85,18 @@ final class PhabricatorDashboardPanelViewController
return $header;
}
private function buildActionView(PhabricatorDashboardPanel $panel) {
$viewer = $this->getRequest()->getUser();
private function buildCurtainView(PhabricatorDashboardPanel $panel) {
$viewer = $this->getViewer();
$id = $panel->getID();
$actions = id(new PhabricatorActionListView())
->setObject($panel)
->setUser($viewer);
$curtain = $this->newCurtainView($panel);
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$panel,
PhabricatorPolicyCapability::CAN_EDIT);
$actions->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Edit Panel'))
->setIcon('fa-pencil')
@ -108,7 +112,7 @@ final class PhabricatorDashboardPanelViewController
$archive_icon = 'fa-check';
}
$actions->addAction(
$curtain->addAction(
id(new PhabricatorActionView())
->setName($archive_text)
->setIcon($archive_icon)
@ -116,21 +120,14 @@ final class PhabricatorDashboardPanelViewController
->setDisabled(!$can_edit)
->setWorkflow(true));
$actions->addAction(
id(new PhabricatorActionView())
->setName(pht('View Standalone'))
->setIcon('fa-eye')
->setHref($this->getApplicationURI("panel/render/{$id}/")));
return $actions;
return $curtain;
}
private function buildPropertyView(PhabricatorDashboardPanel $panel) {
$viewer = $this->getRequest()->getUser();
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($panel);
->setUser($viewer);
$descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions(
$viewer,
@ -167,7 +164,10 @@ final class PhabricatorDashboardPanelViewController
? $viewer->renderHandleList($dashboard_phids)
: phutil_tag('em', array(), $does_not_appear));
return $properties;
return id(new PHUIObjectBoxView())
->setHeaderText(pht('Details'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->addPropertyList($properties);
}
}

View file

@ -36,14 +36,10 @@ final class PhabricatorDashboardViewController
$rendered_dashboard = $this->buildEmptyView();
}
return $this->buildApplicationPage(
array(
$crumbs,
$rendered_dashboard,
),
array(
'title' => $title,
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($rendered_dashboard);
}
protected function buildApplicationCrumbs() {

View file

@ -172,13 +172,13 @@ final class DifferentialRevisionEditController
if ($revision->getID()) {
if ($diff) {
$header_icon = 'fa-upload';
$title = pht('Update Differential Revision');
$title = pht('Update Revision');
$crumbs->addTextCrumb(
'D'.$revision->getID(),
'/differential/diff/'.$diff->getID().'/');
} else {
$header_icon = 'fa-pencil';
$title = pht('Edit Differential Revision');
$title = pht('Edit Revision: %s', $revision->getTitle());
$crumbs->addTextCrumb(
'D'.$revision->getID(),
'/D'.$revision->getID());

View file

@ -480,7 +480,7 @@ final class DifferentialRevisionViewController extends DifferentialController {
}
$header = id(new PHUIHeaderView())
->setHeader(pht('DETAILS'));
->setHeader(pht('Details'));
return id(new PHUIObjectBoxView())
->setHeader($header)
@ -1033,7 +1033,7 @@ final class DifferentialRevisionViewController extends DifferentialController {
}
$box = id(new PHUIObjectBoxView())
->setHeaderText(pht('DIFF DETAIL'))
->setHeaderText(pht('Diff Detail'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setUser($viewer);
@ -1117,7 +1117,7 @@ final class DifferentialRevisionViewController extends DifferentialController {
}
$box_view = id(new PHUIObjectBoxView())
->setHeaderText(pht('ACTIVE OPERATIONS'))
->setHeaderText(pht('Active Operations'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY);
return id(new DrydockRepositoryOperationStatusView())

View file

@ -310,7 +310,7 @@ final class DiffusionBrowseController extends DiffusionController {
));
if ($properties) {
$view->addPropertySection(pht('DETAILS'), $properties);
$view->addPropertySection(pht('Details'), $properties);
}
$title = array($basename, $repository->getDisplayName());
@ -413,7 +413,7 @@ final class DiffusionBrowseController extends DiffusionController {
));
if ($details) {
$view->addPropertySection(pht('DETAILS'), $details);
$view->addPropertySection(pht('Details'), $details);
}
return $this->newPage()
@ -1409,7 +1409,7 @@ final class DiffusionBrowseController extends DiffusionController {
$file = $this->renderFileButton($file_uri);
$header = id(new PHUIHeaderView())
->setHeader(pht('DETAILS'))
->setHeader(pht('Details'))
->addActionLink($file);
$box = id(new PHUIObjectBoxView())
@ -1426,7 +1426,7 @@ final class DiffusionBrowseController extends DiffusionController {
->appendChild($message);
$header = id(new PHUIHeaderView())
->setHeader(pht('DETAILS'));
->setHeader(pht('Details'));
$box = id(new PHUIObjectBoxView())
->setHeader($header)

View file

@ -57,14 +57,13 @@ final class DiffusionCommitController extends DiffusionController {
'Failed to load the commit because the commit has not been '.
'parsed yet.'));
return $this->buildApplicationPage(
array(
$crumbs,
$error,
),
array(
'title' => pht('Commit Still Parsing'),
));
$title = pht('Commit Still Parsing');
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($error);
}
$audit_requests = $commit->getAudits();
@ -356,8 +355,8 @@ final class DiffusionCommitController extends DiffusionController {
$change_list,
$add_comment,
))
->addPropertySection(pht('DESCRIPTION'), $detail_list)
->addPropertySection(pht('DETAILS'), $details)
->addPropertySection(pht('Description'), $detail_list)
->addPropertySection(pht('Details'), $details)
->setCurtain($curtain);
$page = $this->newPage()

View file

@ -288,7 +288,7 @@ final class DiffusionRepositoryController extends DiffusionController {
$description = new PHUIRemarkupView($viewer, $description);
$view->addTextContent($description);
return id(new PHUIObjectBoxView())
->setHeaderText(pht('DESCRIPTION'))
->setHeaderText(pht('Description'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->appendChild($view);
}
@ -354,7 +354,7 @@ final class DiffusionRepositoryController extends DiffusionController {
}
$box = id(new PHUIObjectBoxView())
->setHeaderText(pht('DETAILS'))
->setHeaderText(pht('Details'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->appendChild($view);

View file

@ -991,11 +991,12 @@ final class DiffusionServeController extends DiffusionController {
// <https://github.com/github/git-lfs/issues/1088>
$no_authorization = 'Basic '.base64_encode('none');
$get_uri = $file->getCDNURIWithToken();
$get_uri = $file->getCDNURI();
$actions['download'] = array(
'href' => $get_uri,
'header' => array(
'Authorization' => $no_authorization,
'X-Phabricator-Request-Type' => 'git-lfs',
),
);
} else {

View file

@ -364,7 +364,7 @@ final class DiffusionCommitQuery
if ($repo === null) {
if ($this->defaultRepository) {
$repo = $this->defaultRepository->getCallsign();
$repo = $this->defaultRepository->getPHID();
}
}
@ -375,7 +375,7 @@ final class DiffusionCommitQuery
$bare[] = $commit_identifier;
} else {
$refs[] = array(
'callsign' => $repo,
'repository' => $repo,
'identifier' => $commit_identifier,
);
}
@ -392,17 +392,16 @@ final class DiffusionCommitQuery
}
if ($refs) {
$callsigns = ipull($refs, 'callsign');
$repositories = ipull($refs, 'repository');
$repos = id(new PhabricatorRepositoryQuery())
->setViewer($this->getViewer())
->withIdentifiers($callsigns);
->withIdentifiers($repositories);
$repos->execute();
$repos = $repos->getIdentifierMap();
foreach ($refs as $key => $ref) {
$repo = idx($repos, $ref['callsign']);
$repo = idx($repos, $ref['repository']);
if (!$repo) {
continue;
}

View file

@ -240,14 +240,12 @@ final class DivinerAtomController extends DivinerController {
$prop_list = phutil_tag_div('phui-document-view-pro-box', $prop_list);
return $this->buildApplicationPage(
array(
$crumbs,
return $this->newPage()
->setTitle($symbol->getTitle())
->setCrumbs($crumbs)
->appendChild(array(
$document,
$prop_list,
),
array(
'title' => $symbol->getTitle(),
));
}

View file

@ -92,13 +92,11 @@ final class DivinerBookController extends DivinerController {
$document->appendChild($preface_view);
$document->appendChild($out);
return $this->buildApplicationPage(
array(
$crumbs,
return $this->newPage()
->setTitle($book->getTitle())
->setCrumbs($crumbs)
->appendChild(array(
$document,
),
array(
'title' => $book->getTitle(),
));
}

View file

@ -57,8 +57,10 @@ final class DivinerBookEditController extends DivinerController {
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Edit Basics'));
$crumbs->setBorder(true);
$title = pht('Edit %s', $book->getTitle());
$title = pht('Edit Book: %s', $book->getTitle());
$header_icon = 'fa-pencil';
$policies = id(new PhabricatorPolicyQuery())
->setViewer($viewer)
@ -104,8 +106,9 @@ final class DivinerBookEditController extends DivinerController {
->setValue(pht('Save'))
->addCancelButton($view_uri));
$object_box = id(new PHUIObjectBoxView())
->setHeaderText($title)
$box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Book'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setForm($form);
$timeline = $this->buildTransactionTimeline(
@ -113,15 +116,21 @@ final class DivinerBookEditController extends DivinerController {
new DivinerLiveBookTransactionQuery());
$timeline->setShouldTerminate(true);
return $this->buildApplicationPage(
array(
$crumbs,
$object_box,
$header = id(new PHUIHeaderView())
->setHeader($title)
->setHeaderIcon($header_icon);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter(array(
$box,
$timeline,
),
array(
'title' => $title,
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
}

Some files were not shown because too many files have changed in this diff Show more