1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-01-25 05:58:21 +01:00

(stable) Promote 2018 Week 33

This commit is contained in:
epriestley 2018-08-18 13:15:12 -07:00
commit 5bcaa0f557
61 changed files with 695 additions and 489 deletions

View file

@ -12,7 +12,7 @@ return array(
'core.pkg.css' => 'f515619b',
'core.pkg.js' => '2058ec09',
'differential.pkg.css' => '06dc617c',
'differential.pkg.js' => 'ef19e026',
'differential.pkg.js' => 'c1cfa143',
'diffusion.pkg.css' => 'a2d17c7d',
'diffusion.pkg.js' => '6134c5a1',
'maniphest.pkg.css' => '4845691a',
@ -373,12 +373,12 @@ return array(
'rsrc/js/application/dashboard/behavior-dashboard-query-panel-select.js' => '453c5375',
'rsrc/js/application/dashboard/behavior-dashboard-tab-panel.js' => 'd4eecc63',
'rsrc/js/application/diff/DiffChangeset.js' => 'b49b59d6',
'rsrc/js/application/diff/DiffChangesetList.js' => 'f0ffe8c3',
'rsrc/js/application/diff/DiffChangesetList.js' => 'e0b984b5',
'rsrc/js/application/diff/DiffInline.js' => 'e83d28f3',
'rsrc/js/application/diff/behavior-preview-link.js' => '051c7832',
'rsrc/js/application/differential/behavior-comment-preview.js' => '51c5ad07',
'rsrc/js/application/differential/behavior-diff-radios.js' => 'e1ff79b1',
'rsrc/js/application/differential/behavior-populate.js' => '419998ab',
'rsrc/js/application/differential/behavior-populate.js' => 'f0eb6708',
'rsrc/js/application/differential/behavior-user-select.js' => 'a8d8459d',
'rsrc/js/application/diffusion/DiffusionLocateFileSource.js' => '00676f00',
'rsrc/js/application/diffusion/behavior-audit-preview.js' => 'd835b03a',
@ -393,7 +393,7 @@ return array(
'rsrc/js/application/files/behavior-launch-icon-composer.js' => '48086888',
'rsrc/js/application/harbormaster/behavior-harbormaster-log.js' => '549459b8',
'rsrc/js/application/herald/HeraldRuleEditor.js' => 'dca75c0e',
'rsrc/js/application/herald/PathTypeahead.js' => '662e9cea',
'rsrc/js/application/herald/PathTypeahead.js' => '6d8c7912',
'rsrc/js/application/herald/herald-rule-editor.js' => '7ebaeed3',
'rsrc/js/application/maniphest/behavior-batch-selector.js' => 'ad54037e',
'rsrc/js/application/maniphest/behavior-line-chart.js' => 'e4232876',
@ -423,7 +423,7 @@ return array(
'rsrc/js/application/search/behavior-reorder-profile-menu-items.js' => 'e2e0a072',
'rsrc/js/application/search/behavior-reorder-queries.js' => 'e9581f08',
'rsrc/js/application/slowvote/behavior-slowvote-embed.js' => '887ad43f',
'rsrc/js/application/transactions/behavior-comment-actions.js' => '9a6dd75c',
'rsrc/js/application/transactions/behavior-comment-actions.js' => '54110499',
'rsrc/js/application/transactions/behavior-reorder-configs.js' => 'd7a74243',
'rsrc/js/application/transactions/behavior-reorder-fields.js' => 'b59e1e96',
'rsrc/js/application/transactions/behavior-show-older-transactions.js' => '8f29b364',
@ -506,7 +506,7 @@ return array(
'rsrc/js/phuix/PHUIXActionListView.js' => 'b5c256b8',
'rsrc/js/phuix/PHUIXActionView.js' => '8d4a8c72',
'rsrc/js/phuix/PHUIXAutocomplete.js' => 'df1bbd34',
'rsrc/js/phuix/PHUIXButtonView.js' => '8a91e1ac',
'rsrc/js/phuix/PHUIXButtonView.js' => '85ac9772',
'rsrc/js/phuix/PHUIXDropdownMenu.js' => '04b2ae03',
'rsrc/js/phuix/PHUIXExample.js' => '68af71ca',
'rsrc/js/phuix/PHUIXFormControl.js' => '210a16c1',
@ -575,7 +575,7 @@ return array(
'javelin-behavior-bulk-job-reload' => 'edf8a145',
'javelin-behavior-calendar-month-view' => 'fe33e256',
'javelin-behavior-choose-control' => '327a00d1',
'javelin-behavior-comment-actions' => '9a6dd75c',
'javelin-behavior-comment-actions' => '54110499',
'javelin-behavior-config-reorder-fields' => 'b6993408',
'javelin-behavior-conpherence-menu' => '4047cd35',
'javelin-behavior-conpherence-participant-pane' => 'd057e45a',
@ -594,7 +594,7 @@ return array(
'javelin-behavior-diff-preview-link' => '051c7832',
'javelin-behavior-differential-diff-radios' => 'e1ff79b1',
'javelin-behavior-differential-feedback-preview' => '51c5ad07',
'javelin-behavior-differential-populate' => '419998ab',
'javelin-behavior-differential-populate' => 'f0eb6708',
'javelin-behavior-differential-user-select' => 'a8d8459d',
'javelin-behavior-diffusion-commit-branches' => 'bdaf4d04',
'javelin-behavior-diffusion-commit-graph' => '75b83cbb',
@ -739,7 +739,7 @@ return array(
'owners-path-editor' => 'c96502cf',
'owners-path-editor-css' => '9c136c29',
'paste-css' => '9fcc9773',
'path-typeahead' => '662e9cea',
'path-typeahead' => '6d8c7912',
'people-picture-menu-item-css' => 'a06f7f34',
'people-profile-css' => '4df76faf',
'phabricator-action-list-view-css' => '0bcd9a45',
@ -752,7 +752,7 @@ return array(
'phabricator-darkmessage' => 'c48cccdd',
'phabricator-dashboard-css' => 'fe5b1869',
'phabricator-diff-changeset' => 'b49b59d6',
'phabricator-diff-changeset-list' => 'f0ffe8c3',
'phabricator-diff-changeset-list' => 'e0b984b5',
'phabricator-diff-inline' => 'e83d28f3',
'phabricator-drag-and-drop-file-upload' => '58dea2fa',
'phabricator-draggable-list' => 'bea6e7f4',
@ -858,7 +858,7 @@ return array(
'phuix-action-list-view' => 'b5c256b8',
'phuix-action-view' => '8d4a8c72',
'phuix-autocomplete' => 'df1bbd34',
'phuix-button-view' => '8a91e1ac',
'phuix-button-view' => '85ac9772',
'phuix-dropdown-menu' => '04b2ae03',
'phuix-form-control-view' => '210a16c1',
'phuix-icon-view' => 'bff6884b',
@ -1133,14 +1133,6 @@ return array(
'javelin-workflow',
'phabricator-draggable-list',
),
'419998ab' => array(
'javelin-behavior',
'javelin-dom',
'javelin-stratcom',
'phabricator-tooltip',
'phabricator-diff-changeset-list',
'phabricator-diff-changeset',
),
'4250a34e' => array(
'javelin-behavior',
'javelin-dom',
@ -1259,6 +1251,15 @@ return array(
'javelin-vector',
'javelin-typeahead-static-source',
),
54110499 => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-workflow',
'javelin-dom',
'phuix-form-control-view',
'phuix-icon-view',
'javelin-behavior-phabricator-gesture',
),
'549459b8' => array(
'javelin-behavior',
),
@ -1361,14 +1362,6 @@ return array(
'javelin-workflow',
'javelin-dom',
),
'662e9cea' => array(
'javelin-install',
'javelin-typeahead',
'javelin-dom',
'javelin-request',
'javelin-typeahead-ondemand-source',
'javelin-util',
),
66888767 => array(
'javelin-behavior',
'javelin-stratcom',
@ -1444,6 +1437,14 @@ return array(
'javelin-typeahead',
'javelin-uri',
),
'6d8c7912' => array(
'javelin-install',
'javelin-typeahead',
'javelin-dom',
'javelin-request',
'javelin-typeahead-ondemand-source',
'javelin-util',
),
'70baed2f' => array(
'javelin-install',
'javelin-dom',
@ -1537,6 +1538,10 @@ return array(
'javelin-dom',
'javelin-stratcom',
),
'85ac9772' => array(
'javelin-install',
'javelin-dom',
),
'85ee8ce6' => array(
'aphront-dialog-view-css',
),
@ -1564,10 +1569,6 @@ return array(
'javelin-install',
'javelin-dom',
),
'8a91e1ac' => array(
'javelin-install',
'javelin-dom',
),
'8ce821c5' => array(
'phabricator-notification',
'javelin-stratcom',
@ -1644,15 +1645,6 @@ return array(
'javelin-mask',
'phabricator-drag-and-drop-file-upload',
),
'9a6dd75c' => array(
'javelin-behavior',
'javelin-stratcom',
'javelin-workflow',
'javelin-dom',
'phuix-form-control-view',
'phuix-icon-view',
'javelin-behavior-phabricator-gesture',
),
'9a860428' => array(
'javelin-behavior',
'javelin-dom',
@ -2025,6 +2017,10 @@ return array(
'phuix-icon-view',
'phabricator-prefab',
),
'e0b984b5' => array(
'javelin-install',
'phuix-button-view',
),
'e1d25dfb' => array(
'javelin-behavior',
'javelin-stratcom',
@ -2117,9 +2113,13 @@ return array(
'javelin-workflow',
'javelin-json',
),
'f0ffe8c3' => array(
'javelin-install',
'phuix-button-view',
'f0eb6708' => array(
'javelin-behavior',
'javelin-dom',
'javelin-stratcom',
'phabricator-tooltip',
'phabricator-diff-changeset-list',
'phabricator-diff-changeset',
),
'f1ff5494' => array(
'phui-button-css',

View file

@ -39,6 +39,10 @@ $data = array();
$futures = array();
foreach (explode("\n", trim($input)) as $file) {
if (!strlen($file)) {
continue;
}
$file = Filesystem::readablePath($file);
$futures[$file] = ctags_get_parser_future($file);
}

View file

@ -27,6 +27,10 @@ $data = array();
$futures = array();
foreach (explode("\n", trim($input)) as $file) {
if (!strlen($file)) {
continue;
}
$file = Filesystem::readablePath($file);
$data[$file] = Filesystem::readFile($file);
$futures[$file] = PhutilXHPASTBinary::getParserFuture($data[$file]);

View file

@ -1646,13 +1646,8 @@ phutil_register_library_map(array(
'ManiphestDAO' => 'applications/maniphest/storage/ManiphestDAO.php',
'ManiphestDefaultEditCapability' => 'applications/maniphest/capability/ManiphestDefaultEditCapability.php',
'ManiphestDefaultViewCapability' => 'applications/maniphest/capability/ManiphestDefaultViewCapability.php',
'ManiphestEditAssignCapability' => 'applications/maniphest/capability/ManiphestEditAssignCapability.php',
'ManiphestEditConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestEditConduitAPIMethod.php',
'ManiphestEditEngine' => 'applications/maniphest/editor/ManiphestEditEngine.php',
'ManiphestEditPoliciesCapability' => 'applications/maniphest/capability/ManiphestEditPoliciesCapability.php',
'ManiphestEditPriorityCapability' => 'applications/maniphest/capability/ManiphestEditPriorityCapability.php',
'ManiphestEditProjectsCapability' => 'applications/maniphest/capability/ManiphestEditProjectsCapability.php',
'ManiphestEditStatusCapability' => 'applications/maniphest/capability/ManiphestEditStatusCapability.php',
'ManiphestEmailCommand' => 'applications/maniphest/command/ManiphestEmailCommand.php',
'ManiphestGetTaskTransactionsConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestGetTaskTransactionsConduitAPIMethod.php',
'ManiphestHovercardEngineExtension' => 'applications/maniphest/engineextension/ManiphestHovercardEngineExtension.php',
@ -4562,6 +4557,8 @@ phutil_register_library_map(array(
'PhabricatorUserCustomFieldNumericIndex' => 'applications/people/storage/PhabricatorUserCustomFieldNumericIndex.php',
'PhabricatorUserCustomFieldStringIndex' => 'applications/people/storage/PhabricatorUserCustomFieldStringIndex.php',
'PhabricatorUserDAO' => 'applications/people/storage/PhabricatorUserDAO.php',
'PhabricatorUserDisableTransaction' => 'applications/people/xaction/PhabricatorUserDisableTransaction.php',
'PhabricatorUserEditEngine' => 'applications/people/editor/PhabricatorUserEditEngine.php',
'PhabricatorUserEditor' => 'applications/people/editor/PhabricatorUserEditor.php',
'PhabricatorUserEditorTestCase' => 'applications/people/editor/__tests__/PhabricatorUserEditorTestCase.php',
'PhabricatorUserEmail' => 'applications/people/storage/PhabricatorUserEmail.php',
@ -4583,7 +4580,6 @@ phutil_register_library_map(array(
'PhabricatorUserPreferencesTransaction' => 'applications/settings/storage/PhabricatorUserPreferencesTransaction.php',
'PhabricatorUserPreferencesTransactionQuery' => 'applications/settings/query/PhabricatorUserPreferencesTransactionQuery.php',
'PhabricatorUserProfile' => 'applications/people/storage/PhabricatorUserProfile.php',
'PhabricatorUserProfileEditor' => 'applications/people/editor/PhabricatorUserProfileEditor.php',
'PhabricatorUserProfileImageCacheType' => 'applications/people/cache/PhabricatorUserProfileImageCacheType.php',
'PhabricatorUserRealNameField' => 'applications/people/customfield/PhabricatorUserRealNameField.php',
'PhabricatorUserRolesField' => 'applications/people/customfield/PhabricatorUserRolesField.php',
@ -4593,6 +4589,8 @@ phutil_register_library_map(array(
'PhabricatorUserTestCase' => 'applications/people/storage/__tests__/PhabricatorUserTestCase.php',
'PhabricatorUserTitleField' => 'applications/people/customfield/PhabricatorUserTitleField.php',
'PhabricatorUserTransaction' => 'applications/people/storage/PhabricatorUserTransaction.php',
'PhabricatorUserTransactionEditor' => 'applications/people/editor/PhabricatorUserTransactionEditor.php',
'PhabricatorUserTransactionType' => 'applications/people/xaction/PhabricatorUserTransactionType.php',
'PhabricatorUsersEditField' => 'applications/transactions/editfield/PhabricatorUsersEditField.php',
'PhabricatorUsersPolicyRule' => 'applications/people/policyrule/PhabricatorUsersPolicyRule.php',
'PhabricatorUsersSearchField' => 'applications/people/searchfield/PhabricatorUsersSearchField.php',
@ -5232,6 +5230,7 @@ phutil_register_library_map(array(
'TransactionSearchConduitAPIMethod' => 'applications/transactions/conduit/TransactionSearchConduitAPIMethod.php',
'UserConduitAPIMethod' => 'applications/people/conduit/UserConduitAPIMethod.php',
'UserDisableConduitAPIMethod' => 'applications/people/conduit/UserDisableConduitAPIMethod.php',
'UserEditConduitAPIMethod' => 'applications/people/conduit/UserEditConduitAPIMethod.php',
'UserEnableConduitAPIMethod' => 'applications/people/conduit/UserEnableConduitAPIMethod.php',
'UserFindConduitAPIMethod' => 'applications/people/conduit/UserFindConduitAPIMethod.php',
'UserQueryConduitAPIMethod' => 'applications/people/conduit/UserQueryConduitAPIMethod.php',
@ -7148,13 +7147,8 @@ phutil_register_library_map(array(
'ManiphestDAO' => 'PhabricatorLiskDAO',
'ManiphestDefaultEditCapability' => 'PhabricatorPolicyCapability',
'ManiphestDefaultViewCapability' => 'PhabricatorPolicyCapability',
'ManiphestEditAssignCapability' => 'PhabricatorPolicyCapability',
'ManiphestEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod',
'ManiphestEditEngine' => 'PhabricatorEditEngine',
'ManiphestEditPoliciesCapability' => 'PhabricatorPolicyCapability',
'ManiphestEditPriorityCapability' => 'PhabricatorPolicyCapability',
'ManiphestEditProjectsCapability' => 'PhabricatorPolicyCapability',
'ManiphestEditStatusCapability' => 'PhabricatorPolicyCapability',
'ManiphestEmailCommand' => 'MetaMTAEmailTransactionCommand',
'ManiphestGetTaskTransactionsConduitAPIMethod' => 'ManiphestConduitAPIMethod',
'ManiphestHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension',
@ -10546,6 +10540,8 @@ phutil_register_library_map(array(
'PhabricatorUserCustomFieldNumericIndex' => 'PhabricatorCustomFieldNumericIndexStorage',
'PhabricatorUserCustomFieldStringIndex' => 'PhabricatorCustomFieldStringIndexStorage',
'PhabricatorUserDAO' => 'PhabricatorLiskDAO',
'PhabricatorUserDisableTransaction' => 'PhabricatorUserTransactionType',
'PhabricatorUserEditEngine' => 'PhabricatorEditEngine',
'PhabricatorUserEditor' => 'PhabricatorEditor',
'PhabricatorUserEditorTestCase' => 'PhabricatorTestCase',
'PhabricatorUserEmail' => 'PhabricatorUserDAO',
@ -10575,7 +10571,6 @@ phutil_register_library_map(array(
'PhabricatorUserPreferencesTransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorUserPreferencesTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorUserProfile' => 'PhabricatorUserDAO',
'PhabricatorUserProfileEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorUserProfileImageCacheType' => 'PhabricatorUserCacheType',
'PhabricatorUserRealNameField' => 'PhabricatorUserCustomField',
'PhabricatorUserRolesField' => 'PhabricatorUserCustomField',
@ -10584,7 +10579,9 @@ phutil_register_library_map(array(
'PhabricatorUserStatusField' => 'PhabricatorUserCustomField',
'PhabricatorUserTestCase' => 'PhabricatorTestCase',
'PhabricatorUserTitleField' => 'PhabricatorUserCustomField',
'PhabricatorUserTransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorUserTransaction' => 'PhabricatorModularTransaction',
'PhabricatorUserTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorUserTransactionType' => 'PhabricatorModularTransactionType',
'PhabricatorUsersEditField' => 'PhabricatorTokenizerEditField',
'PhabricatorUsersPolicyRule' => 'PhabricatorPolicyRule',
'PhabricatorUsersSearchField' => 'PhabricatorSearchTokenizerField',
@ -11386,6 +11383,7 @@ phutil_register_library_map(array(
'TransactionSearchConduitAPIMethod' => 'ConduitAPIMethod',
'UserConduitAPIMethod' => 'ConduitAPIMethod',
'UserDisableConduitAPIMethod' => 'UserConduitAPIMethod',
'UserEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod',
'UserEnableConduitAPIMethod' => 'UserConduitAPIMethod',
'UserFindConduitAPIMethod' => 'UserConduitAPIMethod',
'UserQueryConduitAPIMethod' => 'UserConduitAPIMethod',

View file

@ -127,6 +127,9 @@ final class AlmanacInterfaceEditEngine
}
protected function getObjectCreateCancelURI($object) {
if ($this->getDevice()) {
return $this->getDevice()->getURI();
}
return '/almanac/interface/';
}

View file

@ -178,6 +178,7 @@ final class PhabricatorAuthPassword
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
);
}
@ -195,7 +196,7 @@ final class PhabricatorAuthPassword
public function getExtendedPolicy($capability, PhabricatorUser $viewer) {
return array(
array($this->getObject(), PhabricatorPolicyCapability::CAN_VIEW),
array($this->getObject(), $capability),
);
}

View file

@ -84,8 +84,6 @@ final class PhabricatorExtraConfigSetupCheck extends PhabricatorSetupCheck {
$issue->addPhabricatorConfig($key);
}
}
$this->executeManiphestFieldChecks();
}
/**
@ -361,69 +359,4 @@ final class PhabricatorExtraConfigSetupCheck extends PhabricatorSetupCheck {
return $ancient_config;
}
private function executeManiphestFieldChecks() {
$maniphest_appclass = 'PhabricatorManiphestApplication';
if (!PhabricatorApplication::isClassInstalled($maniphest_appclass)) {
return;
}
$capabilities = array(
ManiphestEditAssignCapability::CAPABILITY,
ManiphestEditPoliciesCapability::CAPABILITY,
ManiphestEditPriorityCapability::CAPABILITY,
ManiphestEditProjectsCapability::CAPABILITY,
ManiphestEditStatusCapability::CAPABILITY,
);
// Check for any of these capabilities set to anything other than
// "All Users".
$any_set = false;
$app = new PhabricatorManiphestApplication();
foreach ($capabilities as $capability) {
$setting = $app->getPolicy($capability);
if ($setting != PhabricatorPolicies::POLICY_USER) {
$any_set = true;
break;
}
}
if (!$any_set) {
return;
}
$issue_summary = pht(
'Maniphest is currently configured with deprecated policy settings '.
'which will be removed in a future version of Phabricator.');
$message = pht(
'Some policy settings in Maniphest are now deprecated and will be '.
'removed in a future version of Phabricator. You are currently using '.
'at least one of these settings.'.
"\n\n".
'The deprecated settings are "Can Assign Tasks", '.
'"Can Edit Task Policies", "Can Prioritize Tasks", '.
'"Can Edit Task Projects", and "Can Edit Task Status". You can '.
'find these settings in Applications, or follow the link below.'.
"\n\n".
'You can find discussion of this change (including rationale and '.
'recommendations on how to configure similar features) in the upstream, '.
'at the link below.'.
"\n\n".
'To resolve this issue, set all of these policies to "All Users" after '.
'making any necessary form customization changes.');
$more_href = 'https://secure.phabricator.com/T10003';
$edit_href = '/applications/view/PhabricatorManiphestApplication/';
$issue = $this->newIssue('maniphest.T10003-per-field-policies')
->setShortName(pht('Deprecated Policies'))
->setName(pht('Deprecated Maniphest Field Policies'))
->setSummary($issue_summary)
->setMessage($message)
->addLink($more_href, pht('Learn More: Upstream Discussion'))
->addLink($edit_href, pht('Edit These Settings'));
}
}

View file

@ -276,6 +276,7 @@ final class DifferentialChangesetViewController extends DifferentialController {
->setDiff($diff)
->setTitle(pht('Standalone View'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setIsStandalone(true)
->setParser($parser);
if ($revision_id) {

View file

@ -10,6 +10,7 @@ final class DifferentialChangesetListView extends AphrontView {
private $whitespace;
private $background;
private $header;
private $isStandalone;
private $standaloneURI;
private $leftRawFileURI;
@ -124,6 +125,15 @@ final class DifferentialChangesetListView extends AphrontView {
return $this;
}
public function setIsStandalone($is_standalone) {
$this->isStandalone = $is_standalone;
return $this;
}
public function getIsStandalone() {
return $this->isStandalone;
}
public function setBackground($background) {
$this->background = $background;
return $this;
@ -219,6 +229,7 @@ final class DifferentialChangesetListView extends AphrontView {
'changesetViewIDs' => $ids,
'inlineURI' => $this->inlineURI,
'inlineListURI' => $this->inlineListURI,
'isStandalone' => $this->getIsStandalone(),
'pht' => array(
'Open in Editor' => pht('Open in Editor'),
'Show All Context' => pht('Show All Context'),
@ -298,6 +309,7 @@ final class DifferentialChangesetListView extends AphrontView {
'Show All Inlines' => pht('Show All Inlines'),
'List Inline Comments' => pht('List Inline Comments'),
'Display Options' => pht('Display Options'),
'Hide or show all inline comments.' =>
pht('Hide or show all inline comments.'),

View file

@ -24,6 +24,7 @@ final class DiffusionBlameController extends DiffusionController {
->setViewer($viewer)
->withRepository($repository)
->withIdentifiers($identifiers)
->needIdentities(true)
->execute();
$commits = mpull($commits, null, 'getCommitIdentifier');
} else {
@ -68,10 +69,7 @@ final class DiffusionBlameController extends DiffusionController {
$handle_phids = array();
foreach ($commits as $commit) {
$author_phid = $commit->getAuthorPHID();
if ($author_phid) {
$handle_phids[] = $author_phid;
}
$handle_phids[] = $commit->getAuthorDisplayPHID();
}
foreach ($revisions as $revision) {
@ -117,7 +115,7 @@ final class DiffusionBlameController extends DiffusionController {
$author_phid = null;
if ($commit) {
$author_phid = $commit->getAuthorPHID();
$author_phid = $commit->getAuthorDisplayPHID();
}
if (!$author_phid && $revision) {

View file

@ -46,6 +46,7 @@ final class DiffusionCommitController extends DiffusionController {
->needCommitData(true)
->needAuditRequests(true)
->setLimit(100)
->needIdentities(true)
->execute();
$multiple_results = count($commits) > 1;
@ -504,15 +505,13 @@ final class DiffusionCommitController extends DiffusionController {
$phids = $edge_query->getDestinationPHIDs(array($commit_phid));
if ($data->getCommitDetail('authorPHID')) {
$phids[] = $data->getCommitDetail('authorPHID');
}
if ($data->getCommitDetail('reviewerPHID')) {
$phids[] = $data->getCommitDetail('reviewerPHID');
}
if ($data->getCommitDetail('committerPHID')) {
$phids[] = $data->getCommitDetail('committerPHID');
}
$phids[] = $commit->getCommitterDisplayPHID();
$phids[] = $commit->getAuthorDisplayPHID();
// NOTE: We should never normally have more than a single push log, but
// it can occur naturally if a commit is pushed, then the branch it was
@ -573,24 +572,11 @@ final class DiffusionCommitController extends DiffusionController {
}
}
$author_phid = $data->getCommitDetail('authorPHID');
$author_name = $data->getAuthorName();
$author_epoch = $data->getCommitDetail('authorEpoch');
$committed_info = id(new PHUIStatusItemView())
->setNote(phabricator_datetime($commit->getEpoch(), $viewer));
$committer_phid = $data->getCommitDetail('committerPHID');
$committer_name = $data->getCommitDetail('committer');
if ($committer_phid) {
$committed_info->setTarget($handles[$committer_phid]->renderLink());
} else if (strlen($committer_name)) {
$committed_info->setTarget($committer_name);
} else if ($author_phid) {
$committed_info->setTarget($handles[$author_phid]->renderLink());
} else if (strlen($author_name)) {
$committed_info->setTarget($author_name);
}
->setNote(phabricator_datetime($commit->getEpoch(), $viewer))
->setTarget($commit->renderAnyCommitter($viewer, $handles));
$committed_list = new PHUIStatusListView();
$committed_list->addItem($committed_info);
@ -716,7 +702,7 @@ final class DiffusionCommitController extends DiffusionController {
return null;
}
$author_phid = $data->getCommitDetail('authorPHID');
$author_phid = $commit->getAuthorDisplayPHID();
$author_name = $data->getAuthorName();
$author_epoch = $data->getCommitDetail('authorEpoch');
$date = null;
@ -748,10 +734,8 @@ final class DiffusionCommitController extends DiffusionController {
->setImage($image_uri)
->setImageHref($image_href)
->setContent($content);
}
private function buildComments(PhabricatorRepositoryCommit $commit) {
$timeline = $this->buildTransactionTimeline(
$commit,

View file

@ -35,6 +35,7 @@ final class DiffusionLastModifiedController extends DiffusionController {
->withRepository($drequest->getRepository())
->withIdentifiers(array_values($modified_map))
->needCommitData(true)
->needIdentities(true)
->execute();
$commit_map = mpull($commit_map, null, 'getCommitIdentifier');
} else {
@ -54,9 +55,8 @@ final class DiffusionLastModifiedController extends DiffusionController {
$phids = array();
foreach ($commits as $commit) {
$data = $commit->getCommitData();
$phids[] = $data->getCommitDetail('authorPHID');
$phids[] = $data->getCommitDetail('committerPHID');
$phids[] = $commit->getCommitterDisplayPHID();
$phids[] = $commit->getAuthorDisplayPHID();
}
$phids = array_filter($phids);
$handles = $this->loadViewerHandles($phids);
@ -110,38 +110,21 @@ final class DiffusionLastModifiedController extends DiffusionController {
$date = '';
}
$data = $commit->getCommitData();
if ($data) {
$author_phid = $data->getCommitDetail('authorPHID');
if ($author_phid && isset($handles[$author_phid])) {
$author = $handles[$author_phid]->renderLink();
} else {
$author = DiffusionView::renderName($data->getAuthorName());
}
$author = $commit->renderAuthor($viewer, $handles);
$committer = $commit->renderCommitter($viewer, $handles);
$committer = $data->getCommitDetail('committer');
if ($committer) {
$committer_phid = $data->getCommitDetail('committerPHID');
if ($committer_phid && isset($handles[$committer_phid])) {
$committer = $handles[$committer_phid]->renderLink();
} else {
$committer = DiffusionView::renderName($committer);
}
if ($author != $committer) {
$author = hsprintf('%s/%s', $author, $committer);
}
}
$details = DiffusionView::linkDetail(
$drequest->getRepository(),
$commit->getCommitIdentifier(),
$data->getSummary());
$details = AphrontTableView::renderSingleDisplayLine($details);
} else {
$author = '';
$details = '';
if ($author != $committer) {
$author = hsprintf('%s/%s', $author, $committer);
}
$data = $commit->getCommitData();
$details = DiffusionView::linkDetail(
$drequest->getRepository(),
$commit->getCommitIdentifier(),
$data->getSummary());
$details = AphrontTableView::renderSingleDisplayLine($details);
$return = array(
'commit' => $modified,
'date' => $date,

View file

@ -9,6 +9,7 @@ final class DrydockRepositoryOperationQuery extends DrydockQuery {
private $operationStates;
private $operationTypes;
private $isDismissed;
private $authorPHIDs;
public function withIDs(array $ids) {
$this->ids = $ids;
@ -45,6 +46,11 @@ final class DrydockRepositoryOperationQuery extends DrydockQuery {
return $this;
}
public function withAuthorPHIDs(array $phids) {
$this->authorPHIDs = $phids;
return $this;
}
public function newResultObject() {
return new DrydockRepositoryOperation();
}
@ -165,6 +171,13 @@ final class DrydockRepositoryOperationQuery extends DrydockQuery {
(int)$this->isDismissed);
}
if ($this->authorPHIDs !== null) {
$where[] = qsprintf(
$conn,
'authorPHID IN (%Ls)',
$this->authorPHIDs);
}
return $where;
}

View file

@ -18,11 +18,41 @@ final class DrydockRepositoryOperationSearchEngine
protected function buildQueryFromParameters(array $map) {
$query = $this->newQuery();
if ($map['repositoryPHIDs']) {
$query->withRepositoryPHIDs($map['repositoryPHIDs']);
}
if ($map['authorPHIDs']) {
$query->withAuthorPHIDs($map['authorPHIDs']);
}
if ($map['states']) {
$query->withOperationStates($map['states']);
}
return $query;
}
protected function buildCustomSearchFields() {
return array(
id(new PhabricatorSearchDatasourceField())
->setLabel(pht('Repositories'))
->setKey('repositoryPHIDs')
->setAliases(array('repository', 'repositories', 'repositoryPHID'))
->setDatasource(new DiffusionRepositoryFunctionDatasource()),
// NOTE: Repository operations aren't necessarily created by a real
// user, but for now they normally are. Just use a user typeahead until
// more use cases arise.
id(new PhabricatorUsersSearchField())
->setLabel(pht('Authors'))
->setKey('authorPHIDs')
->setAliases(array('author', 'authors', 'authorPHID')),
id(new PhabricatorSearchCheckboxesField())
->setLabel(pht('States'))
->setKey('states')
->setAliases(array('state'))
->setOptions(DrydockRepositoryOperation::getOperationStateNameMap()),
);
}
@ -72,6 +102,10 @@ final class DrydockRepositoryOperationSearchEngine
$item->setStatusIcon($icon, $name);
$created = phabricator_datetime($operation->getDateCreated(), $viewer);
$item->addIcon(null, $created);
$item->addByline(
array(
pht('Via:'),

View file

@ -99,6 +99,15 @@ final class DrydockRepositoryOperation extends DrydockDAO
return $this;
}
public static function getOperationStateNameMap() {
return array(
self::STATE_WAIT => pht('Waiting'),
self::STATE_WORK => pht('Working'),
self::STATE_DONE => pht('Done'),
self::STATE_FAIL => pht('Failed'),
);
}
public static function getOperationStateIcon($state) {
$map = array(
self::STATE_WAIT => 'fa-clock-o',
@ -111,13 +120,7 @@ final class DrydockRepositoryOperation extends DrydockDAO
}
public static function getOperationStateName($state) {
$map = array(
self::STATE_WAIT => pht('Waiting'),
self::STATE_WORK => pht('Working'),
self::STATE_DONE => pht('Done'),
self::STATE_FAIL => pht('Failed'),
);
$map = self::getOperationStateNameMap();
return idx($map, $state, pht('<Unknown: %s>', $state));
}

View file

@ -30,7 +30,8 @@ final class PhabricatorFavoritesMainMenuBarExtension
->addClass('phabricator-core-user-menu')
->setNoCSS(true)
->setDropdown(true)
->setDropdownMenu($dropdown);
->setDropdownMenu($dropdown)
->setAuralLabel(pht('Favorites Menu'));
return array(
$favorites_menu,

View file

@ -85,11 +85,6 @@ final class PhabricatorManiphestApplication extends PhabricatorApplication {
'template' => ManiphestTaskPHIDType::TYPECONST,
'capability' => PhabricatorPolicyCapability::CAN_EDIT,
),
ManiphestEditStatusCapability::CAPABILITY => array(),
ManiphestEditAssignCapability::CAPABILITY => array(),
ManiphestEditPoliciesCapability::CAPABILITY => array(),
ManiphestEditPriorityCapability::CAPABILITY => array(),
ManiphestEditProjectsCapability::CAPABILITY => array(),
ManiphestBulkEditCapability::CAPABILITY => array(),
);
}

View file

@ -1,15 +0,0 @@
<?php
final class ManiphestEditAssignCapability extends PhabricatorPolicyCapability {
const CAPABILITY = 'maniphest.edit.assign';
public function getCapabilityName() {
return pht('Can Assign Tasks');
}
public function describeCapabilityRejection() {
return pht('You do not have permission to assign tasks.');
}
}

View file

@ -1,16 +0,0 @@
<?php
final class ManiphestEditPoliciesCapability
extends PhabricatorPolicyCapability {
const CAPABILITY = 'maniphest.edit.policies';
public function getCapabilityName() {
return pht('Can Edit Task Policies');
}
public function describeCapabilityRejection() {
return pht('You do not have permission to edit task policies.');
}
}

View file

@ -1,16 +0,0 @@
<?php
final class ManiphestEditPriorityCapability
extends PhabricatorPolicyCapability {
const CAPABILITY = 'maniphest.edit.priority';
public function getCapabilityName() {
return pht('Can Prioritize Tasks');
}
public function describeCapabilityRejection() {
return pht('You do not have permission to prioritize tasks.');
}
}

View file

@ -1,16 +0,0 @@
<?php
final class ManiphestEditProjectsCapability
extends PhabricatorPolicyCapability {
const CAPABILITY = 'maniphest.edit.projects';
public function getCapabilityName() {
return pht('Can Edit Task Projects');
}
public function describeCapabilityRejection() {
return pht('You do not have permission to edit task projects.');
}
}

View file

@ -1,15 +0,0 @@
<?php
final class ManiphestEditStatusCapability extends PhabricatorPolicyCapability {
const CAPABILITY = 'maniphest.edit.status';
public function getCapabilityName() {
return pht('Can Edit Task Status');
}
public function describeCapabilityRejection() {
return pht('You do not have permission to edit task status.');
}
}

View file

@ -279,51 +279,6 @@ final class ManiphestTransactionEditor
->setTask($object);
}
protected function requireCapabilities(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
parent::requireCapabilities($object, $xaction);
$app_capability_map = array(
ManiphestTaskPriorityTransaction::TRANSACTIONTYPE =>
ManiphestEditPriorityCapability::CAPABILITY,
ManiphestTaskStatusTransaction::TRANSACTIONTYPE =>
ManiphestEditStatusCapability::CAPABILITY,
ManiphestTaskOwnerTransaction::TRANSACTIONTYPE =>
ManiphestEditAssignCapability::CAPABILITY,
PhabricatorTransactions::TYPE_EDIT_POLICY =>
ManiphestEditPoliciesCapability::CAPABILITY,
PhabricatorTransactions::TYPE_VIEW_POLICY =>
ManiphestEditPoliciesCapability::CAPABILITY,
);
$transaction_type = $xaction->getTransactionType();
$app_capability = null;
if ($transaction_type == PhabricatorTransactions::TYPE_EDGE) {
switch ($xaction->getMetadataValue('edge:type')) {
case PhabricatorProjectObjectHasProjectEdgeType::EDGECONST:
$app_capability = ManiphestEditProjectsCapability::CAPABILITY;
break;
}
} else {
$app_capability = idx($app_capability_map, $transaction_type);
}
if ($app_capability) {
$app = id(new PhabricatorApplicationQuery())
->setViewer($this->getActor())
->withClasses(array('PhabricatorManiphestApplication'))
->executeOne();
PhabricatorPolicyFilter::requireCapability(
$this->getActor(),
$app,
$app_capability);
}
}
protected function adjustObjectForPolicyChecks(
PhabricatorLiskDAO $object,
array $xactions) {

View file

@ -369,11 +369,7 @@ final class ManiphestTaskSearchEngine
$can_edit_priority = false;
$can_bulk_edit = false;
} else {
$can_edit_priority = PhabricatorPolicyFilter::hasCapability(
$viewer,
$this->getApplication(),
ManiphestEditPriorityCapability::CAPABILITY);
$can_edit_priority = true;
$can_bulk_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$this->getApplication(),

View file

@ -621,7 +621,7 @@ final class PhabricatorMetaMTAMail
public function sendWithMailers(array $mailers) {
if (!$mailers) {
$any_mailers = self::newMailers();
$any_mailers = self::newMailers(array());
// NOTE: We can end up here with some custom list of "$mailers", like
// from a unit test. In that case, this message could be misleading. We

View file

@ -0,0 +1,20 @@
<?php
final class UserEditConduitAPIMethod
extends PhabricatorEditEngineAPIMethod {
public function getAPIMethodName() {
return 'user.edit';
}
public function newEditEngine() {
return new PhabricatorUserEditEngine();
}
public function getMethodSummary() {
return pht(
'Apply transactions to edit a user. (Users can not be created via '.
'the API.)');
}
}

View file

@ -38,10 +38,9 @@ final class PhabricatorPeopleProfileEditController
new PhabricatorUserTransaction(),
$request);
$editor = id(new PhabricatorUserProfileEditor())
$editor = id(new PhabricatorUserTransactionEditor())
->setActor($viewer)
->setContentSource(
PhabricatorContentSource::newFromRequest($request))
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true);
try {

View file

@ -9,6 +9,14 @@ final class PhabricatorUserBlurbField
return 'user:blurb';
}
public function getModernFieldKey() {
return 'blurb';
}
public function getFieldKeyForConduit() {
return $this->getModernFieldKey();
}
public function getFieldName() {
return pht('Blurb');
}
@ -50,6 +58,11 @@ final class PhabricatorUserBlurbField
$this->value = $request->getStr($this->getFieldKey());
}
public function setValueFromStorage($value) {
$this->value = $value;
return $this;
}
public function renderEditControl(array $handles) {
return id(new PhabricatorRemarkupControl())
->setUser($this->getViewer())
@ -85,4 +98,12 @@ final class PhabricatorUserBlurbField
return 'block';
}
public function shouldAppearInConduitTransactions() {
return true;
}
protected function newConduitEditParameterType() {
return new ConduitStringParameterType();
}
}

View file

@ -9,6 +9,14 @@ final class PhabricatorUserIconField
return 'user:icon';
}
public function getModernFieldKey() {
return 'icon';
}
public function getFieldKeyForConduit() {
return $this->getModernFieldKey();
}
public function getFieldName() {
return pht('Icon');
}
@ -50,6 +58,11 @@ final class PhabricatorUserIconField
$this->value = $request->getStr($this->getFieldKey());
}
public function setValueFromStorage($value) {
$this->value = $value;
return $this;
}
public function renderEditControl(array $handles) {
return id(new PHUIFormIconSetControl())
->setName($this->getFieldKey())
@ -58,4 +71,12 @@ final class PhabricatorUserIconField
->setIconSet(new PhabricatorPeopleIconSet());
}
public function shouldAppearInConduitTransactions() {
return true;
}
protected function newConduitEditParameterType() {
return new ConduitStringParameterType();
}
}

View file

@ -9,6 +9,14 @@ final class PhabricatorUserRealNameField
return 'user:realname';
}
public function getModernFieldKey() {
return 'realName';
}
public function getFieldKeyForConduit() {
return $this->getModernFieldKey();
}
public function getFieldName() {
return pht('Real Name');
}
@ -53,6 +61,11 @@ final class PhabricatorUserRealNameField
$this->value = $request->getStr($this->getFieldKey());
}
public function setValueFromStorage($value) {
$this->value = $value;
return $this;
}
public function renderEditControl(array $handles) {
return id(new AphrontFormTextControl())
->setName($this->getFieldKey())
@ -65,4 +78,12 @@ final class PhabricatorUserRealNameField
return PhabricatorEnv::getEnvConfig('account.editable');
}
public function shouldAppearInConduitTransactions() {
return true;
}
protected function newConduitEditParameterType() {
return new ConduitStringParameterType();
}
}

View file

@ -9,6 +9,14 @@ final class PhabricatorUserTitleField
return 'user:title';
}
public function getModernFieldKey() {
return 'title';
}
public function getFieldKeyForConduit() {
return $this->getModernFieldKey();
}
public function getFieldName() {
return pht('Title');
}
@ -50,6 +58,11 @@ final class PhabricatorUserTitleField
$this->value = $request->getStr($this->getFieldKey());
}
public function setValueFromStorage($value) {
$this->value = $value;
return $this;
}
public function renderEditControl(array $handles) {
return id(new AphrontFormTextControl())
->setName($this->getFieldKey())
@ -57,4 +70,12 @@ final class PhabricatorUserTitleField
->setLabel($this->getFieldName());
}
public function shouldAppearInConduitTransactions() {
return true;
}
protected function newConduitEditParameterType() {
return new ConduitStringParameterType();
}
}

View file

@ -0,0 +1,81 @@
<?php
final class PhabricatorUserEditEngine
extends PhabricatorEditEngine {
const ENGINECONST = 'people.user';
public function isEngineConfigurable() {
return false;
}
public function getEngineName() {
return pht('Users');
}
public function getSummaryHeader() {
return pht('Configure User Forms');
}
public function getSummaryText() {
return pht('Configure creation and editing forms for users.');
}
public function getEngineApplicationClass() {
return 'PhabricatorPeopleApplication';
}
protected function newEditableObject() {
return new PhabricatorUser();
}
protected function newObjectQuery() {
return id(new PhabricatorPeopleQuery());
}
protected function getObjectCreateTitleText($object) {
return pht('Create New User');
}
protected function getObjectEditTitleText($object) {
return pht('Edit User: %s', $object->getUsername());
}
protected function getObjectEditShortText($object) {
return $object->getMonogram();
}
protected function getObjectCreateShortText() {
return pht('Create User');
}
protected function getObjectName() {
return pht('User');
}
protected function getObjectViewURI($object) {
return $object->getURI();
}
protected function getCreateNewObjectPolicy() {
// At least for now, forbid creating new users via EditEngine. This is
// primarily enforcing that "user.edit" can not create users via the API.
return PhabricatorPolicies::POLICY_NOONE;
}
protected function buildCustomEditFields($object) {
return array(
id(new PhabricatorBoolEditField())
->setKey('disabled')
->setOptions(pht('Active'), pht('Disabled'))
->setLabel(pht('Disabled'))
->setDescription(pht('Disable the user.'))
->setTransactionType(PhabricatorUserDisableTransaction::TRANSACTIONTYPE)
->setIsConduitOnly(true)
->setConduitDescription(pht('Disable or enable the user.'))
->setConduitTypeDescription(pht('True to disable the user.'))
->setValue($object->getIsDisabled()),
);
}
}

View file

@ -1,6 +1,6 @@
<?php
final class PhabricatorUserProfileEditor
final class PhabricatorUserTransactionEditor
extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
@ -8,8 +8,7 @@ final class PhabricatorUserProfileEditor
}
public function getEditorObjectsDescription() {
return pht('User Profiles');
return pht('Users');
}
}

View file

@ -43,7 +43,8 @@ final class PeopleMainMenuBarExtension
->setIcon($profile_image)
->addClass('phabricator-core-user-menu')
->setHasCaret(true)
->setNoCSS(true);
->setNoCSS(true)
->setAuralLabel(pht('Account Menu'));
return array(
$user_menu,

View file

@ -1362,7 +1362,7 @@ final class PhabricatorUser
public function getApplicationTransactionEditor() {
return new PhabricatorUserProfileEditor();
return new PhabricatorUserTransactionEditor();
}
public function getApplicationTransactionObject() {

View file

@ -1,7 +1,7 @@
<?php
final class PhabricatorUserTransaction
extends PhabricatorApplicationTransaction {
extends PhabricatorModularTransaction {
public function getApplicationName() {
return 'user';
@ -15,4 +15,8 @@ final class PhabricatorUserTransaction
return null;
}
public function getBaseTransactionClass() {
return 'PhabricatorUserTransactionType';
}
}

View file

@ -0,0 +1,72 @@
<?php
final class PhabricatorUserDisableTransaction
extends PhabricatorUserTransactionType {
const TRANSACTIONTYPE = 'user.disable';
public function generateOldValue($object) {
return (bool)$object->getIsDisabled();
}
public function generateNewValue($object, $value) {
return (bool)$value;
}
public function applyInternalEffects($object, $value) {
$object->setIsDisabled((int)$value);
$this->newUserLog(PhabricatorUserLog::ACTION_DISABLE)
->setOldValue((bool)$object->getIsDisabled())
->setNewValue((bool)$value)
->save();
}
public function getTitle() {
$new = $this->getNewValue();
if ($new) {
return pht(
'%s disabled this user.',
$this->renderAuthor());
} else {
return pht(
'%s enabled this user.',
$this->renderAuthor());
}
}
public function getTitleForFeed() {
$new = $this->getNewValue();
if ($new) {
return pht(
'%s disabled %s.',
$this->renderAuthor(),
$this->renderObject());
} else {
return pht(
'%s enabled %s.',
$this->renderAuthor(),
$this->renderObject());
}
}
public function validateTransactions($object, array $xactions) {
$errors = array();
foreach ($xactions as $xaction) {
$is_disabled = (bool)$object->getIsDisabled();
if ((bool)$xaction->getNewValue() === $is_disabled) {
continue;
}
if ($this->getActingAsPHID() === $object->getPHID()) {
$errors[] = $this->newInvalidError(
pht('You can not enable or disable your own account.'));
}
}
return $errors;
}
}

View file

@ -0,0 +1,13 @@
<?php
abstract class PhabricatorUserTransactionType
extends PhabricatorModularTransactionType {
protected function newUserLog($action) {
return PhabricatorUserLog::initializeNewLog(
$this->getActor(),
$this->getObject()->getPHID(),
$action);
}
}

View file

@ -516,58 +516,6 @@ final class PhrictionTransactionEditor
}
return $error;
}
protected function requireCapabilities(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
/*
* New objects have a special case. If a user can't see
* x/y
* then definitely don't let them make some
* x/y/z
* We need to load the direct parent to handle this case.
*/
if ($this->getIsNewObject()) {
$actor = $this->requireActor();
$parent_doc = null;
$ancestral_slugs = PhabricatorSlug::getAncestry($object->getSlug());
// No ancestral slugs is "/"; the first person gets to play with "/".
if ($ancestral_slugs) {
$parent = end($ancestral_slugs);
$parent_doc = id(new PhrictionDocumentQuery())
->setViewer($actor)
->withSlugs(array($parent))
->executeOne();
// If the $actor can't see the $parent_doc then they can't create
// the child $object; throw a policy exception.
if (!$parent_doc) {
id(new PhabricatorPolicyFilter())
->setViewer($actor)
->raisePolicyExceptions(true)
->rejectObject(
$object,
$object->getEditPolicy(),
PhabricatorPolicyCapability::CAN_EDIT);
}
// If the $actor can't edit the $parent_doc then they can't create
// the child $object; throw a policy exception.
if (!PhabricatorPolicyFilter::hasCapability(
$actor,
$parent_doc,
PhabricatorPolicyCapability::CAN_EDIT)) {
id(new PhabricatorPolicyFilter())
->setViewer($actor)
->raisePolicyExceptions(true)
->rejectObject(
$object,
$object->getEditPolicy(),
PhabricatorPolicyCapability::CAN_EDIT);
}
}
}
return parent::requireCapabilities($object, $xaction);
}
protected function supportsSearch() {
return true;

View file

@ -91,6 +91,29 @@ final class PhrictionDocumentTitleTransaction
pht('Documents must have a title.'));
}
if ($this->isNewObject()) {
// No ancestral slugs is "/". No ancestry checks apply when creating the
// root document.
$ancestral_slugs = PhabricatorSlug::getAncestry($object->getSlug());
if ($ancestral_slugs) {
// You must be able to view and edit the parent document to create a new
// child.
$parent_document = id(new PhrictionDocumentQuery())
->setViewer($this->getActor())
->withSlugs(array(last($ancestral_slugs)))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$parent_document) {
$errors[] = $this->newInvalidError(
pht('You can not create a document which does not have a parent.'));
}
}
}
return $errors;
}

View file

@ -137,22 +137,4 @@ final class PhabricatorProjectColumnTransactionEditor
return $errors;
}
protected function requireCapabilities(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorProjectColumnTransaction::TYPE_NAME:
case PhabricatorProjectColumnTransaction::TYPE_STATUS:
PhabricatorPolicyFilter::requireCapability(
$this->requireActor(),
$object,
PhabricatorPolicyCapability::CAN_EDIT);
return;
}
return parent::requireCapabilities($object, $xaction);
}
}

View file

@ -120,12 +120,6 @@ final class PhabricatorProjectTransactionEditor
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorProjectLockTransaction::TRANSACTIONTYPE:
PhabricatorPolicyFilter::requireCapability(
$this->requireActor(),
newv($this->getEditorApplicationClass(), array()),
ProjectCanLockProjectsCapability::CAPABILITY);
return;
case PhabricatorTransactions::TYPE_EDGE:
switch ($xaction->getMetadataValue('edge:type')) {
case PhabricatorProjectProjectHasMemberEdgeType::EDGECONST:

View file

@ -53,4 +53,12 @@ final class PhabricatorProjectLockTransaction
}
}
public function validateTransactions($object, array $xactions) {
if ($xactions) {
$this->requireApplicationCapability(
ProjectCanLockProjectsCapability::CAPABILITY);
}
return array();
}
}

View file

@ -236,40 +236,6 @@ final class PhabricatorRepositoryEditor
}
protected function requireCapabilities(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorRepositoryTransaction::TYPE_ACTIVATE:
case PhabricatorRepositoryTransaction::TYPE_NAME:
case PhabricatorRepositoryTransaction::TYPE_DESCRIPTION:
case PhabricatorRepositoryTransaction::TYPE_ENCODING:
case PhabricatorRepositoryTransaction::TYPE_DEFAULT_BRANCH:
case PhabricatorRepositoryTransaction::TYPE_TRACK_ONLY:
case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE_ONLY:
case PhabricatorRepositoryTransaction::TYPE_UUID:
case PhabricatorRepositoryTransaction::TYPE_SVN_SUBPATH:
case PhabricatorRepositoryTransaction::TYPE_VCS:
case PhabricatorRepositoryTransaction::TYPE_NOTIFY:
case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE:
case PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY:
case PhabricatorRepositoryTransaction::TYPE_DANGEROUS:
case PhabricatorRepositoryTransaction::TYPE_ENORMOUS:
case PhabricatorRepositoryTransaction::TYPE_SLUG:
case PhabricatorRepositoryTransaction::TYPE_SERVICE:
case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_SOURCES:
case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_LANGUAGE:
case PhabricatorRepositoryTransaction::TYPE_STAGING_URI:
case PhabricatorRepositoryTransaction::TYPE_AUTOMATION_BLUEPRINTS:
PhabricatorPolicyFilter::requireCapability(
$this->requireActor(),
$object,
PhabricatorPolicyCapability::CAN_EDIT);
break;
}
}
protected function validateTransaction(
PhabricatorLiskDAO $object,
$type,

View file

@ -39,6 +39,7 @@ final class PhabricatorRepositoryIdentityPHIDType
$handle->setObjectName(pht('Identity %d', $id));
$handle->setName($name);
$handle->setURI($identity->getURI());
$handle->setIcon('fa-user');
}
}

View file

@ -439,6 +439,77 @@ final class PhabricatorRepositoryCommit
return $repository->formatCommitName($identifier, $local = true);
}
/**
* Make a strong effort to find a way to render this commit's committer.
* This currently attempts to use @{PhabricatorRepositoryIdentity}, and
* falls back to examining the commit detail information. After we force
* the migration to using identities, update this method to remove the
* fallback. See T12164 for details.
*/
public function renderAnyCommitter(PhabricatorUser $viewer, $handles) {
$committer = $this->renderCommitter($viewer, $handles);
if ($committer) {
return $committer;
}
return $this->renderAuthor($viewer, $handles);
}
public function renderCommitter(PhabricatorUser $viewer, $handles) {
$committer_phid = $this->getCommitterDisplayPHID();
if ($committer_phid) {
return $handles[$committer_phid]->renderLink();
}
$data = $this->getCommitData();
$committer_name = $data->getCommitDetail('committer');
if (strlen($committer_name)) {
return DiffusionView::renderName($committer_name);
}
return null;
}
public function renderAuthor(PhabricatorUser $viewer, $handles) {
$author_phid = $this->getAuthorDisplayPHID();
if ($author_phid) {
return $handles[$author_phid]->renderLink();
}
$data = $this->getCommitData();
$author_name = $data->getAuthorName();
if (strlen($author_name)) {
return DiffusionView::renderName($author_name);
}
return null;
}
public function hasCommitterIdentity() {
return ($this->getCommitterIdentity() !== null);
}
public function hasAuthorIdentity() {
return ($this->getAuthorIdentity() !== null);
}
public function getCommitterDisplayPHID() {
if ($this->hasCommitterIdentity()) {
return $this->getCommitterIdentity()->getIdentityDisplayPHID();
}
$data = $this->getCommitData();
return $data->getCommitDetail('committerPHID');
}
public function getAuthorDisplayPHID() {
if ($this->hasAuthorIdentity()) {
return $this->getAuthorIdentity()->getIdentityDisplayPHID();
}
$data = $this->getCommitData();
return $data->getCommitDetail('authorPHID');
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */

View file

@ -78,6 +78,14 @@ final class PhabricatorRepositoryIdentity
return ($this->currentEffectiveUserPHID != null);
}
public function getIdentityDisplayPHID() {
if ($this->hasEffectiveUser()) {
return $this->getCurrentEffectiveUserPHID();
} else {
return $this->getPHID();
}
}
public function save() {
if ($this->manuallySetUserPHID) {
$this->currentEffectiveUserPHID = $this->manuallySetUserPHID;

View file

@ -58,7 +58,7 @@ final class SubscriptionListDialogBuilder extends Phobject {
->addCancelButton($object_handle->getURI(), pht('Close'));
}
private function buildBody(PhabricatorUser $viewer, array $handles) {
private function buildBody(PhabricatorUser $viewer, $handles) {
$list = id(new PHUIObjectItemListView())
->setUser($viewer);

View file

@ -356,4 +356,14 @@ abstract class PhabricatorModularTransactionType
return array();
}
protected function requireApplicationCapability($capability) {
$application_class = $this->getEditor()->getEditorApplicationClass();
$application = newv($application_class, array());
PhabricatorPolicyFilter::requireCapability(
$this->getActor(),
$application,
$capability);
}
}

View file

@ -230,7 +230,7 @@ class PhabricatorApplicationTransactionCommentView extends AphrontView {
'div',
array(
'style' => 'background-image: url('.$image_uri.')',
'class' => 'phui-comment-image',
'class' => 'phui-comment-image visual-only',
));
$wedge = phutil_tag(
'div',
@ -319,14 +319,18 @@ class PhabricatorApplicationTransactionCommentView extends AphrontView {
foreach ($comment_actions as $key => $comment_action) {
$key = $comment_action->getKey();
$label = $comment_action->getLabel();
$action_map[$key] = array(
'key' => $key,
'label' => $comment_action->getLabel(),
'label' => $label,
'type' => $comment_action->getPHUIXControlType(),
'spec' => $comment_action->getPHUIXControlSpecification(),
'initialValue' => $comment_action->getInitialValue(),
'groupKey' => $comment_action->getGroupKey(),
'conflictKey' => $comment_action->getConflictKey(),
'auralLabel' => pht('Remove Action: %s', $label),
);
$type_map[$key] = $comment_action;

View file

@ -233,7 +233,8 @@ final class PHUIDiffInlineCommentDetailView
->setIcon('fa-reply')
->setTooltip(pht('Reply'))
->addSigil('differential-inline-reply')
->setMustCapture(true);
->setMustCapture(true)
->setAuralLabel(pht('Reply'));
}
if ($this->editable && !$this->preview) {
@ -242,14 +243,16 @@ final class PHUIDiffInlineCommentDetailView
->setIcon('fa-pencil')
->setTooltip(pht('Edit'))
->addSigil('differential-inline-edit')
->setMustCapture(true);
->setMustCapture(true)
->setAuralLabel(pht('Edit'));
$action_buttons[] = id(new PHUIButtonView())
->setTag('a')
->setIcon('fa-trash-o')
->setTooltip(pht('Delete'))
->addSigil('differential-inline-delete')
->setMustCapture(true);
->setMustCapture(true)
->setAuralLabel(pht('Delete'));
} else if ($this->preview) {
$links[] = javelin_tag(
@ -268,7 +271,8 @@ final class PHUIDiffInlineCommentDetailView
->setTooltip(pht('Delete'))
->setIcon('fa-trash-o')
->addSigil('differential-inline-delete')
->setMustCapture(true);
->setMustCapture(true)
->setAuralLabel(pht('Delete'));
}
if (!$this->preview && $this->canHide()) {
@ -277,7 +281,8 @@ final class PHUIDiffInlineCommentDetailView
->setTooltip(pht('Collapse'))
->setIcon('fa-times')
->addSigil('hide-inline')
->setMustCapture(true);
->setMustCapture(true)
->setAuralLabel(pht('Collapse'));
}
$done_button = null;

View file

@ -94,21 +94,24 @@ final class PhabricatorMainMenuSearchView extends AphrontView {
'action' => '/search/',
'method' => 'POST',
),
phutil_tag_div('phabricator-main-menu-search-container', array(
$input,
phutil_tag(
'button',
array(
'id' => $button_id,
'class' => 'phui-icon-view phui-font-fa fa-search',
phutil_tag(
'div',
array(
'class' => 'phabricator-main-menu-search-container',
),
array(
$input,
phutil_tag(
'button',
array(
'id' => $button_id,
'class' => 'phui-icon-view phui-font-fa fa-search',
),
array(
$selector,
$search_text,
)),
$primary_input,
$target,
)));
$search_text),
$selector,
$primary_input,
$target,
)));
return $form;
}
@ -207,6 +210,7 @@ final class PhabricatorMainMenuSearchView extends AphrontView {
id(new PHUIIconView())
->addSigil('global-search-dropdown-icon')
->setIcon($current_icon))
->setAuralLabel(pht('Configure Global Search'))
->setDropdown(true);
$input = javelin_tag(

View file

@ -232,7 +232,8 @@ final class PhabricatorMainMenuView extends AphrontView {
->addClass('phabricator-core-user-menu')
->addClass('phabricator-core-user-mobile-menu')
->setNoCSS(true)
->setDropdownMenu($dropdown);
->setDropdownMenu($dropdown)
->setAuralLabel(pht('Page Menu'));
}
private function renderApplicationMenu() {

View file

@ -31,6 +31,7 @@ final class PHUIButtonView extends AphrontTagView {
private $noCSS;
private $hasCaret;
private $buttonType = self::BUTTONTYPE_DEFAULT;
private $auralLabel;
public function setName($name) {
$this->name = $name;
@ -123,6 +124,15 @@ final class PHUIButtonView extends AphrontTagView {
return $this->buttonType;
}
public function setAuralLabel($aural_label) {
$this->auralLabel = $aural_label;
return $this;
}
public function getAuralLabel() {
return $this->auralLabel;
}
public function setIcon($icon, $first = true) {
if (!($icon instanceof PHUIIconView)) {
$icon = id(new PHUIIconView())
@ -223,6 +233,13 @@ final class PHUIButtonView extends AphrontTagView {
$classes = array();
}
// See PHI823. If we aren't rendering a "<button>" tag, give the tag we
// are rendering a "button" role as a hint to screen readers.
$role = null;
if ($this->tag !== 'button') {
$role = 'button';
}
return array(
'class' => $classes,
'href' => $this->href,
@ -230,6 +247,7 @@ final class PHUIButtonView extends AphrontTagView {
'title' => $this->title,
'sigil' => $sigil,
'meta' => $meta,
'role' => $role,
);
}
@ -265,10 +283,21 @@ final class PHUIButtonView extends AphrontTagView {
$caret = phutil_tag('span', array('class' => 'caret'), '');
}
$aural = null;
if ($this->auralLabel !== null) {
$aural = phutil_tag(
'span',
array(
'class' => 'aural-only',
),
$this->auralLabel);
}
if ($this->iconFirst == true) {
return array($icon, $text, $caret);
return array($aural, $icon, $text, $caret);
} else {
return array($text, $icon, $caret);
return array($aural, $text, $icon, $caret);
}
}
}

View file

@ -55,7 +55,7 @@ final class PHUIHeadThingView extends AphrontTagView {
$image = phutil_tag(
'a',
array(
'class' => 'phui-head-thing-image',
'class' => 'phui-head-thing-image visual-only',
'style' => 'background-image: url('.$this->image.');',
'href' => $this->imageHref,
));

View file

@ -404,7 +404,7 @@ final class PHUITimelineEventView extends AphrontView {
($this->userHandle->getURI()) ? 'a' : 'div',
array(
'style' => 'background-image: url('.$image_uri.')',
'class' => 'phui-timeline-image',
'class' => 'phui-timeline-image visual-only',
'href' => $this->userHandle->getURI(),
),
'');

View file

@ -89,7 +89,8 @@ JX.install('DiffChangesetList', {
properties: {
translations: null,
inlineURI: null,
inlineListURI: null
inlineListURI: null,
isStandalone: false
},
members: {
@ -149,6 +150,12 @@ JX.install('DiffChangesetList', {
this._initialized = true;
var pht = this.getTranslations();
// We may be viewing the normal "/D123" view (with all the changesets)
// or the standalone view (with just one changeset). In the standalone
// view, some options (like jumping to next or previous file) do not
// make sense and do not function.
var standalone = this.getIsStandalone();
var label;
label = pht('Jump to next change.');
@ -157,11 +164,13 @@ JX.install('DiffChangesetList', {
label = pht('Jump to previous change.');
this._installJumpKey('k', label, -1);
label = pht('Jump to next file.');
this._installJumpKey('J', label, 1, 'file');
if (!standalone) {
label = pht('Jump to next file.');
this._installJumpKey('J', label, 1, 'file');
label = pht('Jump to previous file.');
this._installJumpKey('K', label, -1, 'file');
label = pht('Jump to previous file.');
this._installJumpKey('K', label, -1, 'file');
}
label = pht('Jump to next inline comment.');
this._installJumpKey('n', label, 1, 'comment');
@ -176,11 +185,13 @@ JX.install('DiffChangesetList', {
'Jump to previous inline comment, including collapsed comments.');
this._installJumpKey('P', label, -1, 'comment', true);
label = pht('Hide or show the current file.');
this._installKey('h', label, this._onkeytogglefile);
if (!standalone) {
label = pht('Hide or show the current file.');
this._installKey('h', label, this._onkeytogglefile);
label = pht('Jump to the table of contents.');
this._installKey('t', label, this._ontoc);
label = pht('Jump to the table of contents.');
this._installKey('t', label, this._ontoc);
}
label = pht('Reply to selected inline comment or change.');
this._installKey('r', label, JX.bind(this, this._onkeyreply, false));
@ -1651,9 +1662,12 @@ JX.install('DiffChangesetList', {
_getMenuButton: function() {
if (!this._menuButton) {
var pht = this.getTranslations();
var button = new JX.PHUIXButtonView()
.setIcon('fa-bars')
.setButtonType(JX.PHUIXButtonView.BUTTONTYPE_SIMPLE);
.setButtonType(JX.PHUIXButtonView.BUTTONTYPE_SIMPLE)
.setAuralLabel(pht('Display Options'));
var dropdown = new JX.PHUIXDropdownMenu(button.getNode());
this._menuItems = {};
@ -1692,8 +1706,6 @@ JX.install('DiffChangesetList', {
dropdown.listen('open', JX.bind(this, this._ondropdown));
var pht = this.getTranslations();
if (this.getInlineListURI()) {
list.addItem(
new JX.PHUIXActionView()

View file

@ -61,7 +61,8 @@ JX.behavior('differential-populate', function(config, statics) {
var changeset_list = new JX.DiffChangesetList()
.setTranslations(JX.phtize(config.pht))
.setInlineURI(config.inlineURI)
.setInlineListURI(config.inlineListURI);
.setInlineListURI(config.inlineListURI)
.setIsStandalone(config.isStandalone);
// Install and activate the current page.
var page_id = JX.Quicksand.getCurrentPageID();

View file

@ -208,8 +208,6 @@ JX.install('PathTypeahead', {
this._validationInflight = validation_request;
JX.DOM.setContent(error_display, JX.$H(this._icons.test));
validation_request.setTimeout(750);
validation_request.send();
}
}

View file

@ -163,9 +163,12 @@ JX.behavior('comment-actions', function(config) {
option.disabled = true;
var aural = JX.$N('span', {className: 'aural-only'}, action.auralLabel);
var icon = new JX.PHUIXIconView()
.setIcon('fa-times-circle');
var remove = JX.$N('a', {href: '#'}, icon.getNode());
var remove = JX.$N('a', {href: '#'}, [aural, icon.getNode()]);
var control = new JX.PHUIXFormControl()
.setLabel(action.label)

View file

@ -13,6 +13,7 @@ JX.install('PHUIXButtonView', {
members: {
_node: null,
_textNode: null,
_auralNode: null,
_iconView: null,
_color: null,
@ -69,6 +70,12 @@ JX.install('PHUIXButtonView', {
return this;
},
setAuralLabel: function(label) {
JX.DOM.setContent(this._getAuralNode(), label);
this._redraw();
return this;
},
getNode: function() {
if (!this._node) {
var attrs = {
@ -95,13 +102,31 @@ JX.install('PHUIXButtonView', {
return this._textNode;
},
_getAuralNode: function() {
if (!this._auralNode) {
var attrs = {
className: 'aural-only'
};
this._auralNode = JX.$N('span', attrs);
}
return this._auralNode;
},
_redraw: function() {
var node = this.getNode();
var aural = this._auralNode;
var icon = this._iconView;
var text = this._textNode;
var content = [];
if (aural) {
content.push(aural);
}
if (icon) {
content.push(icon.getNode());
}