mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-15 10:00:55 +01:00
(stable) Promote 2017 Week 7
This commit is contained in:
commit
d963227c83
170 changed files with 1552 additions and 894 deletions
|
@ -2027,8 +2027,10 @@ phutil_register_library_map(array(
|
|||
'PhabricatorBadgesListController' => 'applications/badges/controller/PhabricatorBadgesListController.php',
|
||||
'PhabricatorBadgesMailReceiver' => 'applications/badges/mail/PhabricatorBadgesMailReceiver.php',
|
||||
'PhabricatorBadgesPHIDType' => 'applications/badges/phid/PhabricatorBadgesPHIDType.php',
|
||||
'PhabricatorBadgesProfileController' => 'applications/badges/controller/PhabricatorBadgesProfileController.php',
|
||||
'PhabricatorBadgesQuality' => 'applications/badges/constants/PhabricatorBadgesQuality.php',
|
||||
'PhabricatorBadgesQuery' => 'applications/badges/query/PhabricatorBadgesQuery.php',
|
||||
'PhabricatorBadgesRecipientsController' => 'applications/badges/controller/PhabricatorBadgesRecipientsController.php',
|
||||
'PhabricatorBadgesRecipientsListView' => 'applications/badges/view/PhabricatorBadgesRecipientsListView.php',
|
||||
'PhabricatorBadgesRemoveRecipientsController' => 'applications/badges/controller/PhabricatorBadgesRemoveRecipientsController.php',
|
||||
'PhabricatorBadgesReplyHandler' => 'applications/badges/mail/PhabricatorBadgesReplyHandler.php',
|
||||
|
@ -2464,8 +2466,8 @@ phutil_register_library_map(array(
|
|||
'PhabricatorDashboardAddPanelController' => 'applications/dashboard/controller/PhabricatorDashboardAddPanelController.php',
|
||||
'PhabricatorDashboardApplication' => 'applications/dashboard/application/PhabricatorDashboardApplication.php',
|
||||
'PhabricatorDashboardArchiveController' => 'applications/dashboard/controller/PhabricatorDashboardArchiveController.php',
|
||||
'PhabricatorDashboardArrangeController' => 'applications/dashboard/controller/PhabricatorDashboardArrangeController.php',
|
||||
'PhabricatorDashboardController' => 'applications/dashboard/controller/PhabricatorDashboardController.php',
|
||||
'PhabricatorDashboardCopyController' => 'applications/dashboard/controller/PhabricatorDashboardCopyController.php',
|
||||
'PhabricatorDashboardDAO' => 'applications/dashboard/storage/PhabricatorDashboardDAO.php',
|
||||
'PhabricatorDashboardDashboardHasPanelEdgeType' => 'applications/dashboard/edge/PhabricatorDashboardDashboardHasPanelEdgeType.php',
|
||||
'PhabricatorDashboardDashboardPHIDType' => 'applications/dashboard/phid/PhabricatorDashboardDashboardPHIDType.php',
|
||||
|
@ -2503,6 +2505,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorDashboardPanelTransactionQuery' => 'applications/dashboard/query/PhabricatorDashboardPanelTransactionQuery.php',
|
||||
'PhabricatorDashboardPanelType' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelType.php',
|
||||
'PhabricatorDashboardPanelViewController' => 'applications/dashboard/controller/PhabricatorDashboardPanelViewController.php',
|
||||
'PhabricatorDashboardProfileController' => 'applications/dashboard/controller/PhabricatorDashboardProfileController.php',
|
||||
'PhabricatorDashboardProfileMenuItem' => 'applications/search/menuitem/PhabricatorDashboardProfileMenuItem.php',
|
||||
'PhabricatorDashboardQuery' => 'applications/dashboard/query/PhabricatorDashboardQuery.php',
|
||||
'PhabricatorDashboardQueryPanelType' => 'applications/dashboard/paneltype/PhabricatorDashboardQueryPanelType.php',
|
||||
|
@ -2516,7 +2519,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorDashboardTransaction' => 'applications/dashboard/storage/PhabricatorDashboardTransaction.php',
|
||||
'PhabricatorDashboardTransactionEditor' => 'applications/dashboard/editor/PhabricatorDashboardTransactionEditor.php',
|
||||
'PhabricatorDashboardTransactionQuery' => 'applications/dashboard/query/PhabricatorDashboardTransactionQuery.php',
|
||||
'PhabricatorDashboardUninstallController' => 'applications/dashboard/controller/PhabricatorDashboardUninstallController.php',
|
||||
'PhabricatorDashboardViewController' => 'applications/dashboard/controller/PhabricatorDashboardViewController.php',
|
||||
'PhabricatorDataCacheSpec' => 'applications/cache/spec/PhabricatorDataCacheSpec.php',
|
||||
'PhabricatorDataNotAttachedException' => 'infrastructure/storage/lisk/PhabricatorDataNotAttachedException.php',
|
||||
|
@ -2947,6 +2949,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorMailManagementSendTestWorkflow' => 'applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php',
|
||||
'PhabricatorMailManagementShowInboundWorkflow' => 'applications/metamta/management/PhabricatorMailManagementShowInboundWorkflow.php',
|
||||
'PhabricatorMailManagementShowOutboundWorkflow' => 'applications/metamta/management/PhabricatorMailManagementShowOutboundWorkflow.php',
|
||||
'PhabricatorMailManagementUnverifyWorkflow' => 'applications/metamta/management/PhabricatorMailManagementUnverifyWorkflow.php',
|
||||
'PhabricatorMailManagementVolumeWorkflow' => 'applications/metamta/management/PhabricatorMailManagementVolumeWorkflow.php',
|
||||
'PhabricatorMailManagementWorkflow' => 'applications/metamta/management/PhabricatorMailManagementWorkflow.php',
|
||||
'PhabricatorMailOutboundMailHeraldAdapter' => 'applications/metamta/herald/PhabricatorMailOutboundMailHeraldAdapter.php',
|
||||
|
@ -3029,6 +3032,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorModularTransactionType' => 'applications/transactions/storage/PhabricatorModularTransactionType.php',
|
||||
'PhabricatorMonospacedFontSetting' => 'applications/settings/setting/PhabricatorMonospacedFontSetting.php',
|
||||
'PhabricatorMonospacedTextareasSetting' => 'applications/settings/setting/PhabricatorMonospacedTextareasSetting.php',
|
||||
'PhabricatorMotivatorProfileMenuItem' => 'applications/search/menuitem/PhabricatorMotivatorProfileMenuItem.php',
|
||||
'PhabricatorMultiColumnUIExample' => 'applications/uiexample/examples/PhabricatorMultiColumnUIExample.php',
|
||||
'PhabricatorMultiFactorSettingsPanel' => 'applications/settings/panel/PhabricatorMultiFactorSettingsPanel.php',
|
||||
'PhabricatorMultimeterApplication' => 'applications/multimeter/application/PhabricatorMultimeterApplication.php',
|
||||
|
@ -3368,6 +3372,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPhurlURLAccessController' => 'applications/phurl/controller/PhabricatorPhurlURLAccessController.php',
|
||||
'PhabricatorPhurlURLCommentController' => 'applications/phurl/controller/PhabricatorPhurlURLCommentController.php',
|
||||
'PhabricatorPhurlURLCreateCapability' => 'applications/phurl/capability/PhabricatorPhurlURLCreateCapability.php',
|
||||
'PhabricatorPhurlURLDatasource' => 'applications/phurl/typeahead/PhabricatorPhurlURLDatasource.php',
|
||||
'PhabricatorPhurlURLEditConduitAPIMethod' => 'applications/phurl/conduit/PhabricatorPhurlURLEditConduitAPIMethod.php',
|
||||
'PhabricatorPhurlURLEditController' => 'applications/phurl/controller/PhabricatorPhurlURLEditController.php',
|
||||
'PhabricatorPhurlURLEditEngine' => 'applications/phurl/editor/PhabricatorPhurlURLEditEngine.php',
|
||||
|
@ -3770,6 +3775,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSettingsDeveloperPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsDeveloperPanelGroup.php',
|
||||
'PhabricatorSettingsEditEngine' => 'applications/settings/editor/PhabricatorSettingsEditEngine.php',
|
||||
'PhabricatorSettingsEmailPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsEmailPanelGroup.php',
|
||||
'PhabricatorSettingsIssueController' => 'applications/settings/controller/PhabricatorSettingsIssueController.php',
|
||||
'PhabricatorSettingsListController' => 'applications/settings/controller/PhabricatorSettingsListController.php',
|
||||
'PhabricatorSettingsLogsPanelGroup' => 'applications/settings/panelgroup/PhabricatorSettingsLogsPanelGroup.php',
|
||||
'PhabricatorSettingsMainController' => 'applications/settings/controller/PhabricatorSettingsMainController.php',
|
||||
|
@ -6938,7 +6944,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPolicyInterface',
|
||||
'PhabricatorApplicationTransactionInterface',
|
||||
'PhabricatorSubscribableInterface',
|
||||
'PhabricatorTokenReceiverInterface',
|
||||
'PhabricatorFlaggableInterface',
|
||||
'PhabricatorDestructibleInterface',
|
||||
'PhabricatorConduitResultInterface',
|
||||
|
@ -6960,8 +6965,10 @@ phutil_register_library_map(array(
|
|||
'PhabricatorBadgesListController' => 'PhabricatorBadgesController',
|
||||
'PhabricatorBadgesMailReceiver' => 'PhabricatorObjectMailReceiver',
|
||||
'PhabricatorBadgesPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhabricatorBadgesProfileController' => 'PhabricatorController',
|
||||
'PhabricatorBadgesQuality' => 'Phobject',
|
||||
'PhabricatorBadgesQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorBadgesRecipientsController' => 'PhabricatorBadgesProfileController',
|
||||
'PhabricatorBadgesRecipientsListView' => 'AphrontView',
|
||||
'PhabricatorBadgesRemoveRecipientsController' => 'PhabricatorBadgesController',
|
||||
'PhabricatorBadgesReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
|
||||
|
@ -6971,7 +6978,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorBadgesTransaction' => 'PhabricatorApplicationTransaction',
|
||||
'PhabricatorBadgesTransactionComment' => 'PhabricatorApplicationTransactionComment',
|
||||
'PhabricatorBadgesTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhabricatorBadgesViewController' => 'PhabricatorBadgesController',
|
||||
'PhabricatorBadgesViewController' => 'PhabricatorBadgesProfileController',
|
||||
'PhabricatorBarePageUIExample' => 'PhabricatorUIExample',
|
||||
'PhabricatorBarePageView' => 'AphrontPageView',
|
||||
'PhabricatorBaseURISetupCheck' => 'PhabricatorSetupCheck',
|
||||
|
@ -7470,8 +7477,8 @@ phutil_register_library_map(array(
|
|||
'PhabricatorDashboardAddPanelController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardApplication' => 'PhabricatorApplication',
|
||||
'PhabricatorDashboardArchiveController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardArrangeController' => 'PhabricatorDashboardProfileController',
|
||||
'PhabricatorDashboardController' => 'PhabricatorController',
|
||||
'PhabricatorDashboardCopyController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardDAO' => 'PhabricatorLiskDAO',
|
||||
'PhabricatorDashboardDashboardHasPanelEdgeType' => 'PhabricatorEdgeType',
|
||||
'PhabricatorDashboardDashboardPHIDType' => 'PhabricatorPHIDType',
|
||||
|
@ -7481,7 +7488,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorDashboardInstall' => 'PhabricatorDashboardDAO',
|
||||
'PhabricatorDashboardLayoutConfig' => 'Phobject',
|
||||
'PhabricatorDashboardListController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardManageController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardManageController' => 'PhabricatorDashboardProfileController',
|
||||
'PhabricatorDashboardMovePanelController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardNgrams' => 'PhabricatorSearchNgrams',
|
||||
'PhabricatorDashboardPanel' => array(
|
||||
|
@ -7520,6 +7527,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorDashboardPanelTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhabricatorDashboardPanelType' => 'Phobject',
|
||||
'PhabricatorDashboardPanelViewController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardProfileController' => 'PhabricatorController',
|
||||
'PhabricatorDashboardProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
||||
'PhabricatorDashboardQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorDashboardQueryPanelType' => 'PhabricatorDashboardPanelType',
|
||||
|
@ -7533,8 +7541,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorDashboardTransaction' => 'PhabricatorApplicationTransaction',
|
||||
'PhabricatorDashboardTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||
'PhabricatorDashboardTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhabricatorDashboardUninstallController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardViewController' => 'PhabricatorDashboardController',
|
||||
'PhabricatorDashboardViewController' => 'PhabricatorDashboardProfileController',
|
||||
'PhabricatorDataCacheSpec' => 'PhabricatorCacheSpec',
|
||||
'PhabricatorDataNotAttachedException' => 'Exception',
|
||||
'PhabricatorDatabaseHealthRecord' => 'Phobject',
|
||||
|
@ -8007,6 +8014,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorMailManagementSendTestWorkflow' => 'PhabricatorMailManagementWorkflow',
|
||||
'PhabricatorMailManagementShowInboundWorkflow' => 'PhabricatorMailManagementWorkflow',
|
||||
'PhabricatorMailManagementShowOutboundWorkflow' => 'PhabricatorMailManagementWorkflow',
|
||||
'PhabricatorMailManagementUnverifyWorkflow' => 'PhabricatorMailManagementWorkflow',
|
||||
'PhabricatorMailManagementVolumeWorkflow' => 'PhabricatorMailManagementWorkflow',
|
||||
'PhabricatorMailManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
||||
'PhabricatorMailOutboundMailHeraldAdapter' => 'HeraldAdapter',
|
||||
|
@ -8099,6 +8107,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorModularTransactionType' => 'Phobject',
|
||||
'PhabricatorMonospacedFontSetting' => 'PhabricatorStringSetting',
|
||||
'PhabricatorMonospacedTextareasSetting' => 'PhabricatorSelectSetting',
|
||||
'PhabricatorMotivatorProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
||||
'PhabricatorMultiColumnUIExample' => 'PhabricatorUIExample',
|
||||
'PhabricatorMultiFactorSettingsPanel' => 'PhabricatorSettingsPanel',
|
||||
'PhabricatorMultimeterApplication' => 'PhabricatorApplication',
|
||||
|
@ -8515,6 +8524,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorPhurlURLAccessController' => 'PhabricatorPhurlController',
|
||||
'PhabricatorPhurlURLCommentController' => 'PhabricatorPhurlController',
|
||||
'PhabricatorPhurlURLCreateCapability' => 'PhabricatorPolicyCapability',
|
||||
'PhabricatorPhurlURLDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||
'PhabricatorPhurlURLEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod',
|
||||
'PhabricatorPhurlURLEditController' => 'PhabricatorPhurlController',
|
||||
'PhabricatorPhurlURLEditEngine' => 'PhabricatorEditEngine',
|
||||
|
@ -9017,6 +9027,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorSettingsDeveloperPanelGroup' => 'PhabricatorSettingsPanelGroup',
|
||||
'PhabricatorSettingsEditEngine' => 'PhabricatorEditEngine',
|
||||
'PhabricatorSettingsEmailPanelGroup' => 'PhabricatorSettingsPanelGroup',
|
||||
'PhabricatorSettingsIssueController' => 'PhabricatorController',
|
||||
'PhabricatorSettingsListController' => 'PhabricatorController',
|
||||
'PhabricatorSettingsLogsPanelGroup' => 'PhabricatorSettingsPanelGroup',
|
||||
'PhabricatorSettingsMainController' => 'PhabricatorController',
|
||||
|
|
|
@ -61,7 +61,7 @@ final class PhabricatorAuthUnlinkController
|
|||
return id(new AphrontRedirectResponse())->setURI($this->getDoneURI());
|
||||
}
|
||||
|
||||
return $this->renderConfirmDialog($account);
|
||||
return $this->renderConfirmDialog();
|
||||
}
|
||||
|
||||
private function getDoneURI() {
|
||||
|
|
|
@ -191,17 +191,19 @@ final class PhabricatorAuthEditController
|
|||
->setHeader(pht('%s: %s', $title, $provider->getProviderName()))
|
||||
->setHeaderIcon($header_icon);
|
||||
|
||||
if (!$is_new) {
|
||||
if ($config->getIsEnabled()) {
|
||||
$status_name = pht('Enabled');
|
||||
$status_color = 'green';
|
||||
$status_icon = 'fa-check';
|
||||
$header->setStatus($status_icon, $status_color, $status_name);
|
||||
} else if (!$is_new) {
|
||||
} else {
|
||||
$status_name = pht('Disabled');
|
||||
$status_color = 'indigo';
|
||||
$status_icon = 'fa-ban';
|
||||
$header->setStatus($status_icon, $status_color, $status_name);
|
||||
}
|
||||
}
|
||||
|
||||
$config_name = 'auth.email-domains';
|
||||
$config_href = '/config/edit/'.$config_name.'/';
|
||||
|
|
|
@ -47,11 +47,14 @@ final class PhabricatorBadgesApplication extends PhabricatorApplication {
|
|||
=> 'PhabricatorBadgesArchiveController',
|
||||
'view/(?:(?P<id>\d+)/)?'
|
||||
=> 'PhabricatorBadgesViewController',
|
||||
'recipients/(?P<id>[1-9]\d*)/'
|
||||
'recipients/' => array(
|
||||
'(?P<id>[1-9]\d*)/'
|
||||
=> 'PhabricatorBadgesRecipientsController',
|
||||
'(?P<id>[1-9]\d*)/add/'
|
||||
=> 'PhabricatorBadgesEditRecipientsController',
|
||||
'recipients/(?P<id>[1-9]\d*)/remove/'
|
||||
'(?P<id>[1-9]\d*)/remove/'
|
||||
=> 'PhabricatorBadgesRemoveRecipientsController',
|
||||
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ final class PhabricatorBadgesAwardController
|
|||
->setTransactionType(PhabricatorBadgesTransaction::TYPE_AWARD)
|
||||
->setNewValue($award_phids);
|
||||
|
||||
$editor = id(new PhabricatorBadgesEditor($badge))
|
||||
$editor = id(new PhabricatorBadgesEditor())
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
|
|
|
@ -22,7 +22,7 @@ final class PhabricatorBadgesEditRecipientsController
|
|||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$view_uri = $this->getApplicationURI('view/'.$badge->getID().'/');
|
||||
$view_uri = $this->getApplicationURI('recipients/'.$badge->getID().'/');
|
||||
$awards = $badge->getAwards();
|
||||
$recipient_phids = mpull($awards, 'getRecipientPHID');
|
||||
|
||||
|
@ -40,7 +40,7 @@ final class PhabricatorBadgesEditRecipientsController
|
|||
->setTransactionType(PhabricatorBadgesTransaction::TYPE_AWARD)
|
||||
->setNewValue($award_phids);
|
||||
|
||||
$editor = id(new PhabricatorBadgesEditor($badge))
|
||||
$editor = id(new PhabricatorBadgesEditor())
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
|
@ -79,13 +79,13 @@ final class PhabricatorBadgesEditRecipientsController
|
|||
->appendControl(
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setName('phids')
|
||||
->setLabel(pht('Add Recipients'))
|
||||
->setLabel(pht('Recipients'))
|
||||
->setDatasource(new PhabricatorPeopleDatasource()));
|
||||
}
|
||||
|
||||
$dialog = id(new AphrontDialogView())
|
||||
->setUser($viewer)
|
||||
->setTitle(pht('Award Badges'))
|
||||
->setTitle(pht('Add Recipients'))
|
||||
->appendForm($form)
|
||||
->addCancelButton($view_uri)
|
||||
->addSubmitButton(pht('Add Recipients'));
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
|
||||
abstract class PhabricatorBadgesProfileController
|
||||
extends PhabricatorController {
|
||||
|
||||
private $badge;
|
||||
|
||||
public function setBadge(PhabricatorBadgesBadge $badge) {
|
||||
$this->badge = $badge;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBadge() {
|
||||
return $this->badge;
|
||||
}
|
||||
|
||||
public function buildApplicationMenu() {
|
||||
return $this->buildSideNavView()->getMenu();
|
||||
}
|
||||
|
||||
protected function buildHeaderView() {
|
||||
$viewer = $this->getViewer();
|
||||
$badge = $this->getBadge();
|
||||
$id = $badge->getID();
|
||||
|
||||
if ($badge->isArchived()) {
|
||||
$status_icon = 'fa-ban';
|
||||
$status_color = 'dark';
|
||||
} else {
|
||||
$status_icon = 'fa-check';
|
||||
$status_color = 'bluegrey';
|
||||
}
|
||||
$status_name = idx(
|
||||
PhabricatorBadgesBadge::getStatusNameMap(),
|
||||
$badge->getStatus());
|
||||
|
||||
return id(new PHUIHeaderView())
|
||||
->setHeader($badge->getName())
|
||||
->setUser($viewer)
|
||||
->setPolicyObject($badge)
|
||||
->setStatus($status_icon, $status_color, $status_name)
|
||||
->setHeaderIcon('fa-trophy');
|
||||
}
|
||||
|
||||
protected function buildApplicationCrumbs() {
|
||||
$badge = $this->getBadge();
|
||||
$id = $badge->getID();
|
||||
$badge_uri = $this->getApplicationURI("/view/{$id}/");
|
||||
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb($badge->getName(), $badge_uri);
|
||||
$crumbs->setBorder(true);
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
protected function buildSideNavView($filter = null) {
|
||||
$viewer = $this->getViewer();
|
||||
$badge = $this->getBadge();
|
||||
$id = $badge->getID();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$badge,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$nav = id(new AphrontSideNavFilterView())
|
||||
->setBaseURI(new PhutilURI($this->getApplicationURI()));
|
||||
|
||||
$nav->addLabel(pht('Badge'));
|
||||
|
||||
$nav->addFilter(
|
||||
'view',
|
||||
pht('View Badge'),
|
||||
$this->getApplicationURI("/view/{$id}/"),
|
||||
'fa-trophy');
|
||||
|
||||
$nav->addFilter(
|
||||
'recipients',
|
||||
pht('View Recipients'),
|
||||
$this->getApplicationURI("/recipients/{$id}/"),
|
||||
'fa-group');
|
||||
|
||||
$nav->selectFilter($filter);
|
||||
|
||||
return $nav;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBadgesRecipientsController
|
||||
extends PhabricatorBadgesProfileController {
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$badge = id(new PhabricatorBadgesQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needRecipients(true)
|
||||
->executeOne();
|
||||
if (!$badge) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$this->setBadge($badge);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(pht('Recipients'));
|
||||
$crumbs->setBorder(true);
|
||||
$title = $badge->getName();
|
||||
|
||||
$header = $this->buildHeaderView();
|
||||
|
||||
$awards = $badge->getAwards();
|
||||
$recipient_phids = mpull($awards, 'getRecipientPHID');
|
||||
$recipient_phids = array_reverse($recipient_phids);
|
||||
$handles = $this->loadViewerHandles($recipient_phids);
|
||||
|
||||
$recipient_list = id(new PhabricatorBadgesRecipientsListView())
|
||||
->setBadge($badge)
|
||||
->setHandles($handles)
|
||||
->setUser($viewer);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(array(
|
||||
$recipient_list,
|
||||
));
|
||||
|
||||
$navigation = $this->buildSideNavView('recipients');
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setPageObjectPHIDs(array($badge->getPHID()))
|
||||
->setNavigation($navigation)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
}
|
|
@ -37,7 +37,7 @@ final class PhabricatorBadgesRemoveRecipientsController
|
|||
->setTransactionType(PhabricatorBadgesTransaction::TYPE_REVOKE)
|
||||
->setNewValue(array($remove_phid));
|
||||
|
||||
$editor = id(new PhabricatorBadgesEditor($badge))
|
||||
$editor = id(new PhabricatorBadgesEditor())
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnNoEffect(true)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBadgesViewController
|
||||
extends PhabricatorBadgesController {
|
||||
extends PhabricatorBadgesProfileController {
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
|
@ -14,35 +14,17 @@ final class PhabricatorBadgesViewController
|
|||
$badge = id(new PhabricatorBadgesQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needRecipients(true)
|
||||
->executeOne();
|
||||
if (!$badge) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$this->setBadge($badge);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb($badge->getName());
|
||||
$crumbs->setBorder(true);
|
||||
$title = $badge->getName();
|
||||
|
||||
if ($badge->isArchived()) {
|
||||
$status_icon = 'fa-ban';
|
||||
$status_color = 'dark';
|
||||
} else {
|
||||
$status_icon = 'fa-check';
|
||||
$status_color = 'bluegrey';
|
||||
}
|
||||
$status_name = idx(
|
||||
PhabricatorBadgesBadge::getStatusNameMap(),
|
||||
$badge->getStatus());
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($badge->getName())
|
||||
->setUser($viewer)
|
||||
->setPolicyObject($badge)
|
||||
->setStatus($status_icon, $status_color, $status_name)
|
||||
->setHeaderIcon('fa-trophy');
|
||||
|
||||
$header = $this->buildHeaderView();
|
||||
$curtain = $this->buildCurtain($badge);
|
||||
$details = $this->buildDetailsView($badge);
|
||||
|
||||
|
@ -50,16 +32,6 @@ final class PhabricatorBadgesViewController
|
|||
$badge,
|
||||
new PhabricatorBadgesTransactionQuery());
|
||||
|
||||
$awards = $badge->getAwards();
|
||||
$recipient_phids = mpull($awards, 'getRecipientPHID');
|
||||
$recipient_phids = array_reverse($recipient_phids);
|
||||
$handles = $this->loadViewerHandles($recipient_phids);
|
||||
|
||||
$recipient_list = id(new PhabricatorBadgesRecipientsListView())
|
||||
->setBadge($badge)
|
||||
->setHandles($handles)
|
||||
->setUser($viewer);
|
||||
|
||||
$comment_view = id(new PhabricatorBadgesEditEngine())
|
||||
->setViewer($viewer)
|
||||
->buildEditEngineCommentView($badge);
|
||||
|
@ -68,16 +40,18 @@ final class PhabricatorBadgesViewController
|
|||
->setHeader($header)
|
||||
->setCurtain($curtain)
|
||||
->setMainColumn(array(
|
||||
$recipient_list,
|
||||
$timeline,
|
||||
$comment_view,
|
||||
))
|
||||
->addPropertySection(pht('Description'), $details);
|
||||
|
||||
$navigation = $this->buildSideNavView('view');
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setPageObjectPHIDs(array($badge->getPHID()))
|
||||
->setNavigation($navigation)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
|
@ -116,7 +90,7 @@ final class PhabricatorBadgesViewController
|
|||
$id = $badge->getID();
|
||||
$edit_uri = $this->getApplicationURI("/edit/{$id}/");
|
||||
$archive_uri = $this->getApplicationURI("/archive/{$id}/");
|
||||
$award_uri = $this->getApplicationURI("/recipients/{$id}/");
|
||||
$award_uri = $this->getApplicationURI("/recipients/{$id}/add/");
|
||||
|
||||
$curtain = $this->newCurtainView($badge);
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ final class PhabricatorBadgesBadge extends PhabricatorBadgesDAO
|
|||
PhabricatorPolicyInterface,
|
||||
PhabricatorApplicationTransactionInterface,
|
||||
PhabricatorSubscribableInterface,
|
||||
PhabricatorTokenReceiverInterface,
|
||||
PhabricatorFlaggableInterface,
|
||||
PhabricatorDestructibleInterface,
|
||||
PhabricatorConduitResultInterface,
|
||||
|
@ -161,14 +160,6 @@ final class PhabricatorBadgesBadge extends PhabricatorBadgesDAO
|
|||
}
|
||||
|
||||
|
||||
/* -( PhabricatorTokenReceiverInterface )---------------------------------- */
|
||||
|
||||
|
||||
public function getUsersToNotifyOfTokenGiven() {
|
||||
return array($this->getCreatorPHID());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
||||
|
||||
|
|
|
@ -38,6 +38,10 @@ final class PhabricatorBadgesTransaction
|
|||
|
||||
$type = $this->getTransactionType();
|
||||
switch ($type) {
|
||||
case PhabricatorTransactions::TYPE_CREATE:
|
||||
return pht(
|
||||
'%s created this badge.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
case self::TYPE_NAME:
|
||||
if ($old === null) {
|
||||
return pht(
|
||||
|
|
|
@ -27,6 +27,18 @@ final class PhabricatorBadgesRecipientsListView extends AphrontView {
|
|||
$badge,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$award_button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-plus')
|
||||
->setText(pht('Add Recipents'))
|
||||
->setWorkflow(true)
|
||||
->setDisabled(!$can_edit)
|
||||
->setHref('/badges/recipients/'.$badge->getID().'/add/');
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Recipients'))
|
||||
->addActionLink($award_button);
|
||||
|
||||
$list = id(new PHUIObjectItemListView())
|
||||
->setNoDataString(pht('This badge does not have any recipients.'))
|
||||
->setFlush(true);
|
||||
|
@ -62,7 +74,7 @@ final class PhabricatorBadgesRecipientsListView extends AphrontView {
|
|||
}
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Recipients'))
|
||||
->setHeader($header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setObjectList($list);
|
||||
|
||||
|
|
|
@ -251,7 +251,7 @@ abstract class PhabricatorApplication
|
|||
}
|
||||
|
||||
final protected function getInboundEmailSupportLink() {
|
||||
return PhabricatorEnv::getDocLink('Configuring Inbound Email');
|
||||
return PhabricatorEnv::getDoclink('Configuring Inbound Email');
|
||||
}
|
||||
|
||||
public function getAppEmailBlurb() {
|
||||
|
|
|
@ -7,9 +7,7 @@ final class CalendarTimeUtilTestCase extends PhabricatorTestCase {
|
|||
$u->overrideTimezoneIdentifier('America/Los_Angeles');
|
||||
$days = $this->getAllDays();
|
||||
foreach ($days as $day) {
|
||||
$data = CalendarTimeUtil::getCalendarWidgetTimestamps(
|
||||
$u,
|
||||
$day);
|
||||
$data = CalendarTimeUtil::getTimestamps($u, $day, 1);
|
||||
|
||||
$this->assertEqual(
|
||||
'000000',
|
||||
|
|
|
@ -70,7 +70,7 @@ final class PhabricatorCalendarExportEditEngine
|
|||
|
||||
$current_mode = $object->getPolicyMode();
|
||||
if (empty($export_modes[$current_mode])) {
|
||||
array_shift($export_modes, $current_mode);
|
||||
array_unshift($export_modes, $current_mode);
|
||||
}
|
||||
|
||||
$mode_options = array();
|
||||
|
|
|
@ -14,7 +14,7 @@ final class PhabricatorCalendarExternalInvitee
|
|||
PhabricatorUser $actor, $event) {
|
||||
return id(new PhabricatorCalendarEventInvitee())
|
||||
->setInviterPHID($actor->getPHID())
|
||||
->setStatus(self::STATUS_INVITED)
|
||||
->setStatus(PhabricatorCalendarEventInvitee::STATUS_INVITED)
|
||||
->setEventPHID($event->getPHID());
|
||||
}
|
||||
|
||||
|
|
|
@ -201,8 +201,8 @@ final class CelerityDefaultPostprocessor
|
|||
'copy-background' => '#f1c40f',
|
||||
|
||||
// Background color for "most" themes.
|
||||
'page.background' => '#f8f8fb',
|
||||
'page.sidenav' => '#f0f0f2',
|
||||
'page.background' => '#f3f5f7',
|
||||
'page.sidenav' => '#eaedf1',
|
||||
|
||||
'menu.profile.text' => 'rgba(255,255,255,.8)',
|
||||
'menu.profile.text.selected' => 'rgba(255,255,255,1)',
|
||||
|
|
|
@ -154,7 +154,7 @@ abstract class PhabricatorConduitController extends PhabricatorController {
|
|||
$parts[] = "\n\n";
|
||||
|
||||
$parts[] = 'require_once ';
|
||||
$parts[] = phutil_var_export($libphutil_path, true);
|
||||
$parts[] = phutil_var_export($libphutil_path);
|
||||
$parts[] = ";\n\n";
|
||||
|
||||
$parts[] = '$api_token = "';
|
||||
|
@ -168,7 +168,7 @@ abstract class PhabricatorConduitController extends PhabricatorController {
|
|||
$parts[] = ');';
|
||||
} else {
|
||||
$params = $this->simplifyParams($params);
|
||||
$params = phutil_var_export($params, true);
|
||||
$params = phutil_var_export($params);
|
||||
$parts[] = phutil_tag('strong', array('class' => 'real'), $params);
|
||||
$parts[] = ';';
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ abstract class PhabricatorConduitController extends PhabricatorController {
|
|||
$parts[] = phutil_tag(
|
||||
'strong',
|
||||
array('class' => 'real'),
|
||||
phutil_var_export(PhabricatorEnv::getURI('/'), true));
|
||||
phutil_var_export(PhabricatorEnv::getURI('/')));
|
||||
$parts[] = ");\n";
|
||||
|
||||
$parts[] = '$client->setConduitToken($api_token);';
|
||||
|
@ -188,7 +188,7 @@ abstract class PhabricatorConduitController extends PhabricatorController {
|
|||
$parts[] = phutil_tag(
|
||||
'strong',
|
||||
array('class' => 'real'),
|
||||
phutil_var_export($method->getAPIMethodName(), true));
|
||||
phutil_var_export($method->getAPIMethodName()));
|
||||
$parts[] = ', ';
|
||||
$parts[] = '$api_parameters';
|
||||
$parts[] = ");\n";
|
||||
|
|
|
@ -162,7 +162,7 @@ final class PhabricatorConduitLogSearchEngine
|
|||
->addSigil('has-tooltip')
|
||||
->setMetadata(
|
||||
array(
|
||||
'tip' => pht('Unknown ("%s")', $status),
|
||||
'tip' => pht('Unknown ("%s")', $method_status),
|
||||
));
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ final class PhabricatorDaemonsSetupCheck extends PhabricatorSetupCheck {
|
|||
->execute();
|
||||
|
||||
if (!$task_daemon) {
|
||||
$doc_href = PhabricatorEnv::getDocLink('Managing Daemons with phd');
|
||||
$doc_href = PhabricatorEnv::getDoclink('Managing Daemons with phd');
|
||||
|
||||
$summary = pht(
|
||||
'You must start the Phabricator daemons to send email, rebuild '.
|
||||
|
|
|
@ -14,7 +14,7 @@ final class PhabricatorPHPConfigSetupCheck extends PhabricatorSetupCheck {
|
|||
protected function executeChecks() {
|
||||
|
||||
if (empty($_SERVER['REMOTE_ADDR'])) {
|
||||
$doc_href = PhabricatorEnv::getDocLink('Configuring a Preamble Script');
|
||||
$doc_href = PhabricatorEnv::getDoclink('Configuring a Preamble Script');
|
||||
|
||||
$summary = pht(
|
||||
'You likely need to fix your preamble script so '.
|
||||
|
|
|
@ -52,7 +52,7 @@ final class PhabricatorSecuritySetupCheck extends PhabricatorSetupCheck {
|
|||
$file_key = 'security.alternate-file-domain';
|
||||
$file_domain = PhabricatorEnv::getEnvConfig($file_key);
|
||||
if (!$file_domain) {
|
||||
$doc_href = PhabricatorEnv::getDocLink('Configuring a File Domain');
|
||||
$doc_href = PhabricatorEnv::getDoclink('Configuring a File Domain');
|
||||
|
||||
$this->newIssue('security.'.$file_key)
|
||||
->setName(pht('Alternate File Domain Not Configured'))
|
||||
|
|
|
@ -16,7 +16,7 @@ final class PhabricatorStorageSetupCheck extends PhabricatorSetupCheck {
|
|||
$this->checkS3();
|
||||
|
||||
if (!$chunk_engine_active) {
|
||||
$doc_href = PhabricatorEnv::getDocLink('Configuring File Storage');
|
||||
$doc_href = PhabricatorEnv::getDoclink('Configuring File Storage');
|
||||
|
||||
$message = pht(
|
||||
'Large file storage has not been configured, which will limit '.
|
||||
|
|
|
@ -21,7 +21,7 @@ final class PhabricatorConfigClusterDatabasesController
|
|||
->setText(pht('Documentation')));
|
||||
|
||||
$crumbs = $this
|
||||
->buildApplicationCrumbs($nav)
|
||||
->buildApplicationCrumbs()
|
||||
->addTextCrumb($title)
|
||||
->setBorder(true);
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ final class PhabricatorConfigClusterNotificationsController
|
|||
->setText(pht('Documentation')));
|
||||
|
||||
$crumbs = $this
|
||||
->buildApplicationCrumbs($nav)
|
||||
->buildApplicationCrumbs()
|
||||
->addTextCrumb($title)
|
||||
->setBorder(true);
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ final class PhabricatorConfigClusterRepositoriesController
|
|||
->setText(pht('Documentation')));
|
||||
|
||||
$crumbs = $this
|
||||
->buildApplicationCrumbs($nav)
|
||||
->buildApplicationCrumbs()
|
||||
->addTextCrumb(pht('Repository Servers'))
|
||||
->setBorder(true);
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ final class PhabricatorConfigIssueListController
|
|||
->setProfileHeader(true);
|
||||
|
||||
$crumbs = $this
|
||||
->buildApplicationCrumbs($nav)
|
||||
->buildApplicationCrumbs()
|
||||
->addTextCrumb(pht('Setup Issues'))
|
||||
->setBorder(true);
|
||||
|
||||
|
|
|
@ -84,11 +84,13 @@ final class PhabricatorAuthenticationConfigOptions
|
|||
'Determines whether or not basic account information is editable.'))
|
||||
->setDescription(
|
||||
pht(
|
||||
'Is basic account information (email, real name, profile '.
|
||||
'picture) editable? If you set up Phabricator to automatically '.
|
||||
'synchronize account information from some other authoritative '.
|
||||
'system, you can disable this to ensure information remains '.
|
||||
'consistent across both systems.')),
|
||||
'This option controls whether users can edit account email '.
|
||||
'addresses and profile real names.'.
|
||||
"\n\n".
|
||||
'If you set up Phabricator to automatically synchronize account '.
|
||||
'information from some other authoritative system, you can '.
|
||||
'prevent users from making these edits to ensure information '.
|
||||
'remains consistent across both systems.')),
|
||||
$this->newOption('account.minimum-password-length', 'int', 8)
|
||||
->setSummary(pht('Minimum password length.'))
|
||||
->setDescription(
|
||||
|
|
|
@ -61,9 +61,10 @@ of each approach are:
|
|||
a normal recipient and also Cc'd on a mailing list.
|
||||
- Getting threading to work properly is harder, and probably requires
|
||||
making mail less useful by turning off options.
|
||||
- Sometimes people will "Reply All" and everyone will get two mails,
|
||||
one from the user and one from Phabricator turning their mail into
|
||||
a comment.
|
||||
- Sometimes people will "Reply All", which can send mail to too many
|
||||
recipients. Phabricator will try not to send mail to users who already
|
||||
received a similar message, but can not prevent all stray email arising
|
||||
from "Reply All".
|
||||
- Not supported with a private reply-to address.
|
||||
- Mails are sent in the server default translation.
|
||||
- One mail to each user:
|
||||
|
@ -73,7 +74,8 @@ of each approach are:
|
|||
mail.
|
||||
- Getting threading to work properly is easier, and threading settings
|
||||
can be customzied by each user.
|
||||
- "Reply All" no longer spams all other users.
|
||||
- "Reply All" will never send extra mail to other users involved in the
|
||||
thread.
|
||||
- Required if private reply-to addresses are configured.
|
||||
- Mails are sent in the language of user preference.
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ final class PhabricatorSyntaxHighlightingConfigOptions
|
|||
}
|
||||
|
||||
public function getOptions() {
|
||||
$caches_href = PhabricatorEnv::getDocLink('Managing Caches');
|
||||
$caches_href = PhabricatorEnv::getDoclink('Managing Caches');
|
||||
|
||||
return array(
|
||||
$this->newOption(
|
||||
|
|
|
@ -9,6 +9,7 @@ final class PhabricatorConfigKeySchema
|
|||
private $unique;
|
||||
private $table;
|
||||
private $indexType;
|
||||
private $property;
|
||||
|
||||
public function setIndexType($index_type) {
|
||||
$this->indexType = $index_type;
|
||||
|
|
|
@ -50,9 +50,6 @@ final class ConpherenceCreateThreadConduitAPIMethod
|
|||
if ($errors) {
|
||||
foreach ($errors as $error_code) {
|
||||
switch ($error_code) {
|
||||
case ConpherenceEditor::ERROR_EMPTY_TITLE:
|
||||
throw new ConduitException('ERR_EMPTY_TITLE');
|
||||
break;
|
||||
case ConpherenceEditor::ERROR_EMPTY_PARTICIPANTS:
|
||||
throw new ConduitException('ERR_EMPTY_PARTICIPANT_PHIDS');
|
||||
break;
|
||||
|
|
|
@ -27,10 +27,9 @@ final class PhabricatorDashboardApplication extends PhabricatorApplication {
|
|||
'view/(?P<id>\d+)/' => 'PhabricatorDashboardViewController',
|
||||
'archive/(?P<id>\d+)/' => 'PhabricatorDashboardArchiveController',
|
||||
'manage/(?P<id>\d+)/' => 'PhabricatorDashboardManageController',
|
||||
'arrange/(?P<id>\d+)/' => 'PhabricatorDashboardArrangeController',
|
||||
'create/' => 'PhabricatorDashboardEditController',
|
||||
'copy/(?:(?P<id>\d+)/)?' => 'PhabricatorDashboardCopyController',
|
||||
'edit/(?:(?P<id>\d+)/)?' => 'PhabricatorDashboardEditController',
|
||||
'uninstall/(?P<id>\d+)/' => 'PhabricatorDashboardUninstallController',
|
||||
'addpanel/(?P<id>\d+)/' => 'PhabricatorDashboardAddPanelController',
|
||||
'movepanel/(?P<id>\d+)/' => 'PhabricatorDashboardMovePanelController',
|
||||
'removepanel/(?P<id>\d+)/'
|
||||
|
|
|
@ -10,6 +10,7 @@ final class PhabricatorDashboardAddPanelController
|
|||
$dashboard = id(new PhabricatorDashboardQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needPanels(true)
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
|
@ -20,9 +21,10 @@ final class PhabricatorDashboardAddPanelController
|
|||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$redirect_uri = $this->getApplicationURI('manage/'.$dashboard->getID().'/');
|
||||
$redirect_uri = $this->getApplicationURI(
|
||||
'arrange/'.$dashboard->getID().'/');
|
||||
|
||||
$v_panel = $request->getStr('panel');
|
||||
$v_panel = head($request->getArr('panel'));
|
||||
$e_panel = true;
|
||||
$errors = array();
|
||||
if ($request->isFormPost()) {
|
||||
|
@ -32,9 +34,18 @@ final class PhabricatorDashboardAddPanelController
|
|||
->withIDs(array($v_panel))
|
||||
->executeOne();
|
||||
if (!$panel) {
|
||||
$errors[] = pht('No such panel!');
|
||||
$errors[] = pht('Not a valid panel.');
|
||||
$e_panel = pht('Invalid');
|
||||
}
|
||||
|
||||
$on_dashboard = $dashboard->getPanels();
|
||||
$on_ids = mpull($on_dashboard, null, 'getID');
|
||||
if (array_key_exists($v_panel, $on_ids)) {
|
||||
$p_name = $panel->getName();
|
||||
$errors[] = pht('Panel "%s" already exists on dashboard.', $p_name);
|
||||
$e_panel = pht('Invalid');
|
||||
}
|
||||
|
||||
} else {
|
||||
$errors[] = pht('Select a panel to add.');
|
||||
$e_panel = pht('Required');
|
||||
|
@ -69,26 +80,18 @@ final class PhabricatorDashboardAddPanelController
|
|||
->addCancelButton($redirect_uri);
|
||||
}
|
||||
|
||||
$panel_options = array();
|
||||
foreach ($panels as $panel) {
|
||||
$panel_options[$panel->getID()] = pht(
|
||||
'%s %s',
|
||||
$panel->getMonogram(),
|
||||
$panel->getName());
|
||||
}
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->addHiddenInput('column', $request->getInt('column'))
|
||||
->appendRemarkupInstructions(
|
||||
pht('Choose a panel to add to this dashboard:'))
|
||||
->appendChild(
|
||||
id(new AphrontFormSelectControl())
|
||||
id(new AphrontFormTokenizerControl())
|
||||
->setUser($this->getViewer())
|
||||
->setDatasource(new PhabricatorDashboardPanelDatasource())
|
||||
->setLimit(1)
|
||||
->setName('panel')
|
||||
->setLabel(pht('Panel'))
|
||||
->setValue($v_panel)
|
||||
->setError($e_panel)
|
||||
->setOptions($panel_options));
|
||||
->setLabel(pht('Panel')));
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Add Panel'))
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardArrangeController
|
||||
extends PhabricatorDashboardProfileController {
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$dashboard = id(new PhabricatorDashboardQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needPanels(true)
|
||||
->executeOne();
|
||||
if (!$dashboard) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$this->setDashboard($dashboard);
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$dashboard,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$title = $dashboard->getName();
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(pht('Arrange'));
|
||||
$header = $this->buildHeaderView();
|
||||
|
||||
$info_view = null;
|
||||
if (!$can_edit) {
|
||||
$no_edit = pht(
|
||||
'You do not have permission to edit this dashboard.');
|
||||
|
||||
$info_view = id(new PHUIInfoView())
|
||||
->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
|
||||
->setErrors(array($no_edit));
|
||||
}
|
||||
|
||||
$rendered_dashboard = id(new PhabricatorDashboardRenderingEngine())
|
||||
->setViewer($viewer)
|
||||
->setDashboard($dashboard)
|
||||
->setArrangeMode($can_edit)
|
||||
->renderDashboard();
|
||||
|
||||
$dashboard_box = id(new PHUIBoxView())
|
||||
->addClass('dashboard-preview-box')
|
||||
->appendChild($rendered_dashboard);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(array(
|
||||
$info_view,
|
||||
$dashboard_box,
|
||||
));
|
||||
|
||||
$navigation = $this->buildSideNavView('arrange');
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setNavigation($navigation)
|
||||
->appendChild($view);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardCopyController
|
||||
extends PhabricatorDashboardController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$dashboard = id(new PhabricatorDashboardQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->needPanels(true)
|
||||
->executeOne();
|
||||
if (!$dashboard) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$manage_uri = $this->getApplicationURI('manage/'.$dashboard->getID().'/');
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
|
||||
$copy = PhabricatorDashboard::initializeNewDashboard($viewer);
|
||||
$copy = PhabricatorDashboard::copyDashboard($copy, $dashboard);
|
||||
|
||||
$copy->setName(pht('Copy of %s', $copy->getName()));
|
||||
|
||||
// Set up all the edges for the new dashboard.
|
||||
|
||||
$xactions = array();
|
||||
$xactions[] = id(new PhabricatorDashboardTransaction())
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
|
||||
->setMetadataValue(
|
||||
'edge:type',
|
||||
PhabricatorDashboardDashboardHasPanelEdgeType::EDGECONST)
|
||||
->setNewValue(
|
||||
array(
|
||||
'=' => array_fuse($dashboard->getPanelPHIDs()),
|
||||
));
|
||||
|
||||
$editor = id(new PhabricatorDashboardTransactionEditor())
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnMissingFields(true)
|
||||
->setContinueOnNoEffect(true)
|
||||
->applyTransactions($copy, $xactions);
|
||||
|
||||
$manage_uri = $this->getApplicationURI('edit/'.$copy->getID().'/');
|
||||
return id(new AphrontRedirectResponse())->setURI($manage_uri);
|
||||
}
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Copy Dashboard'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Create a copy of the dashboard "%s"?',
|
||||
phutil_tag('strong', array(), $dashboard->getName())))
|
||||
->addCancelButton($manage_uri)
|
||||
->addSubmitButton(pht('Create Copy'));
|
||||
}
|
||||
|
||||
}
|
|
@ -117,7 +117,7 @@ final class PhabricatorDashboardEditController
|
|||
->setContentSourceFromRequest($request)
|
||||
->applyTransactions($dashboard, $xactions);
|
||||
|
||||
$uri = $this->getApplicationURI('manage/'.$dashboard->getID().'/');
|
||||
$uri = $this->getApplicationURI('arrange/'.$dashboard->getID().'/');
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($uri);
|
||||
} catch (PhabricatorApplicationTransactionValidationException $ex) {
|
||||
|
@ -351,7 +351,7 @@ final class PhabricatorDashboardEditController
|
|||
->setContentSourceFromRequest($request)
|
||||
->applyTransactions($dashboard, $xactions);
|
||||
|
||||
$manage_uri = $this->getApplicationURI('manage/'.$dashboard->getID().'/');
|
||||
$manage_uri = $this->getApplicationURI('arrange/'.$dashboard->getID().'/');
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($manage_uri);
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardManageController
|
||||
extends PhabricatorDashboardController {
|
||||
extends PhabricatorDashboardProfileController {
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$dashboard_uri = $this->getApplicationURI('view/'.$id.'/');
|
||||
|
||||
// TODO: This UI should drop a lot of capabilities if the user can't
|
||||
// edit the dashboard, but we should still let them in for "Install" and
|
||||
// "View History".
|
||||
|
@ -21,6 +23,7 @@ final class PhabricatorDashboardManageController
|
|||
if (!$dashboard) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$this->setDashboard($dashboard);
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
|
@ -30,41 +33,27 @@ final class PhabricatorDashboardManageController
|
|||
$title = $dashboard->getName();
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(
|
||||
pht('Dashboard %d', $dashboard->getID()),
|
||||
$dashboard_uri);
|
||||
$crumbs->addTextCrumb(pht('Manage'));
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
$header = $this->buildHeaderView($dashboard);
|
||||
$curtain = $this->buildCurtainview($dashboard);
|
||||
$header = $this->buildHeaderView();
|
||||
$curtain = $this->buildCurtainView($dashboard);
|
||||
$properties = $this->buildPropertyView($dashboard);
|
||||
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$dashboard,
|
||||
new PhabricatorDashboardTransactionQuery());
|
||||
$timeline->setShouldTerminate(true);
|
||||
|
||||
$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.');
|
||||
'You do not have permission to edit this dashboard.');
|
||||
|
||||
$info_view = id(new PHUIInfoView())
|
||||
->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
|
||||
->setErrors(array($no_edit));
|
||||
}
|
||||
|
||||
$rendered_dashboard = id(new PhabricatorDashboardRenderingEngine())
|
||||
->setViewer($viewer)
|
||||
->setDashboard($dashboard)
|
||||
->setArrangeMode($can_edit)
|
||||
->renderDashboard();
|
||||
|
||||
$dashboard_box = id(new PHUIBoxView())
|
||||
->addClass('dashboard-preview-box')
|
||||
->appendChild($rendered_dashboard);
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setCurtain($curtain)
|
||||
|
@ -72,47 +61,18 @@ final class PhabricatorDashboardManageController
|
|||
$info_view,
|
||||
$properties,
|
||||
$timeline,
|
||||
))
|
||||
->setFooter($dashboard_box);
|
||||
));
|
||||
|
||||
$navigation = $this->buildSideNavView('manage');
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setNavigation($navigation)
|
||||
->appendChild($view);
|
||||
|
||||
}
|
||||
|
||||
private function buildHeaderView(PhabricatorDashboard $dashboard) {
|
||||
$viewer = $this->getViewer();
|
||||
$id = $dashboard->getID();
|
||||
|
||||
if ($dashboard->isArchived()) {
|
||||
$status_icon = 'fa-ban';
|
||||
$status_color = 'dark';
|
||||
} else {
|
||||
$status_icon = 'fa-check';
|
||||
$status_color = 'bluegrey';
|
||||
}
|
||||
|
||||
$status_name = idx(
|
||||
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)
|
||||
->setHeaderIcon($dashboard->getIcon())
|
||||
->addActionLink($button);
|
||||
}
|
||||
|
||||
private function buildCurtainView(PhabricatorDashboard $dashboard) {
|
||||
$viewer = $this->getViewer();
|
||||
$id = $dashboard->getID();
|
||||
|
@ -149,13 +109,6 @@ final class PhabricatorDashboardManageController
|
|||
->setWorkflow($can_edit));
|
||||
}
|
||||
|
||||
$curtain->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Copy Dashboard'))
|
||||
->setIcon('fa-files-o')
|
||||
->setHref($this->getApplicationURI("copy/{$id}/"))
|
||||
->setWorkflow(true));
|
||||
|
||||
return $curtain;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ final class PhabricatorDashboardPanelEditController
|
|||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$manage_uri = $this->getApplicationURI('manage/'.$dashboard_id.'/');
|
||||
$manage_uri = $this->getApplicationURI('arrange/'.$dashboard_id.'/');
|
||||
}
|
||||
|
||||
if ($id) {
|
||||
|
@ -52,25 +52,6 @@ final class PhabricatorDashboardPanelEditController
|
|||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
if ($dashboard) {
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$panel,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
if (!$can_edit) {
|
||||
if ($request->isFormPost() && $request->getBool('copy')) {
|
||||
$panel = $this->copyPanel(
|
||||
$request,
|
||||
$dashboard,
|
||||
$panel);
|
||||
} else {
|
||||
return $this->processPanelCloneRequest(
|
||||
$request,
|
||||
$dashboard,
|
||||
$panel);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$is_create = true;
|
||||
|
||||
|
@ -162,7 +143,7 @@ final class PhabricatorDashboardPanelEditController
|
|||
->applyTransactions($panel, $xactions);
|
||||
|
||||
// If we're creating a panel directly on a dashboard, add it now.
|
||||
if ($dashboard) {
|
||||
if ($dashboard && $is_create) {
|
||||
PhabricatorDashboardTransactionEditor::addPanelToDashboard(
|
||||
$viewer,
|
||||
PhabricatorContentSource::newFromRequest($request),
|
||||
|
@ -365,79 +346,5 @@ final class PhabricatorDashboardPanelEditController
|
|||
->appendChild($view);
|
||||
}
|
||||
|
||||
private function processPanelCloneRequest(
|
||||
AphrontRequest $request,
|
||||
PhabricatorDashboard $dashboard,
|
||||
PhabricatorDashboardPanel $panel) {
|
||||
|
||||
$viewer = $request->getUser();
|
||||
|
||||
$manage_uri = $this->getApplicationURI('manage/'.$dashboard->getID().'/');
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Copy Panel?'))
|
||||
->addHiddenInput('copy', true)
|
||||
->addHiddenInput('dashboardID', $request->getInt('dashboardID'))
|
||||
->addHiddenInput('column', $request->getInt('column'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'You do not have permission to edit this dashboard panel, but you '.
|
||||
'can make a copy and edit that instead. If you choose to copy the '.
|
||||
'panel, the original will be replaced with the new copy on this '.
|
||||
'dashboard.'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Do you want to make a copy of this panel?'))
|
||||
->addCancelButton($manage_uri)
|
||||
->addSubmitButton(pht('Copy Panel'));
|
||||
}
|
||||
|
||||
private function copyPanel(
|
||||
AphrontRequest $request,
|
||||
PhabricatorDashboard $dashboard,
|
||||
PhabricatorDashboardPanel $panel) {
|
||||
|
||||
$viewer = $request->getUser();
|
||||
|
||||
$copy = PhabricatorDashboardPanel::initializeNewPanel($viewer);
|
||||
$copy = PhabricatorDashboardPanel::copyPanel($copy, $panel, $viewer);
|
||||
|
||||
$copy->openTransaction();
|
||||
$copy->save();
|
||||
|
||||
// TODO: This should record a transaction on the panel copy, too.
|
||||
|
||||
$xactions = array();
|
||||
$xactions[] = id(new PhabricatorDashboardTransaction())
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
|
||||
->setMetadataValue(
|
||||
'edge:type',
|
||||
PhabricatorDashboardDashboardHasPanelEdgeType::EDGECONST)
|
||||
->setNewValue(
|
||||
array(
|
||||
'+' => array(
|
||||
$copy->getPHID() => $copy->getPHID(),
|
||||
),
|
||||
'-' => array(
|
||||
$panel->getPHID() => $panel->getPHID(),
|
||||
),
|
||||
));
|
||||
|
||||
$layout_config = $dashboard->getLayoutConfigObject();
|
||||
$layout_config->replacePanel($panel->getPHID(), $copy->getPHID());
|
||||
$dashboard->setLayoutConfigFromObject($layout_config);
|
||||
$dashboard->save();
|
||||
|
||||
$editor = id(new PhabricatorDashboardTransactionEditor())
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->setContinueOnMissingFields(true)
|
||||
->setContinueOnNoEffect(true)
|
||||
->applyTransactions($dashboard, $xactions);
|
||||
$copy->saveTransaction();
|
||||
|
||||
return $copy;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
abstract class PhabricatorDashboardProfileController
|
||||
extends PhabricatorController {
|
||||
|
||||
private $dashboard;
|
||||
|
||||
public function setDashboard(PhabricatorDashboard $dashboard) {
|
||||
$this->dashboard = $dashboard;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDashboard() {
|
||||
return $this->dashboard;
|
||||
}
|
||||
|
||||
public function buildApplicationMenu() {
|
||||
return $this->buildSideNavView()->getMenu();
|
||||
}
|
||||
|
||||
protected function buildHeaderView() {
|
||||
$viewer = $this->getViewer();
|
||||
$dashboard = $this->getDashboard();
|
||||
$id = $dashboard->getID();
|
||||
|
||||
if ($dashboard->isArchived()) {
|
||||
$status_icon = 'fa-ban';
|
||||
$status_color = 'dark';
|
||||
} else {
|
||||
$status_icon = 'fa-check';
|
||||
$status_color = 'bluegrey';
|
||||
}
|
||||
|
||||
$status_name = idx(
|
||||
PhabricatorDashboard::getStatusNameMap(),
|
||||
$dashboard->getStatus());
|
||||
|
||||
return id(new PHUIHeaderView())
|
||||
->setUser($viewer)
|
||||
->setHeader($dashboard->getName())
|
||||
->setPolicyObject($dashboard)
|
||||
->setStatus($status_icon, $status_color, $status_name)
|
||||
->setHeaderIcon($dashboard->getIcon());
|
||||
}
|
||||
|
||||
protected function buildApplicationCrumbs() {
|
||||
$dashboard = $this->getDashboard();
|
||||
$id = $dashboard->getID();
|
||||
$dashboard_uri = $this->getApplicationURI("/view/{$id}/");
|
||||
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb($dashboard->getName(), $dashboard_uri);
|
||||
$crumbs->setBorder(true);
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
protected function buildSideNavView($filter = null) {
|
||||
$viewer = $this->getViewer();
|
||||
$dashboard = $this->getDashboard();
|
||||
$id = $dashboard->getID();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$dashboard,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$nav = id(new AphrontSideNavFilterView())
|
||||
->setBaseURI(new PhutilURI($this->getApplicationURI()));
|
||||
|
||||
$nav->addLabel(pht('Dashboard'));
|
||||
|
||||
$nav->addFilter(
|
||||
'view',
|
||||
pht('View Dashboard'),
|
||||
$this->getApplicationURI("/view/{$id}/"),
|
||||
'fa-dashboard');
|
||||
|
||||
$nav->addFilter(
|
||||
'arrange',
|
||||
pht('Arrange Panels'),
|
||||
$this->getApplicationURI("/arrange/{$id}/"),
|
||||
'fa-columns');
|
||||
|
||||
$nav->addFilter(
|
||||
'manage',
|
||||
pht('Manage Dashboard'),
|
||||
$this->getApplicationURI("/manage/{$id}/"),
|
||||
'fa-gears');
|
||||
|
||||
$nav->selectFilter($filter);
|
||||
|
||||
return $nav;
|
||||
}
|
||||
|
||||
}
|
|
@ -43,7 +43,7 @@ final class PhabricatorDashboardRemovePanelController
|
|||
}
|
||||
|
||||
$redirect_uri = $this->getApplicationURI(
|
||||
'manage/'.$dashboard->getID().'/');
|
||||
'arrange/'.$dashboard->getID().'/');
|
||||
$layout_config = $dashboard->getLayoutConfigObject();
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
|
|
|
@ -1,131 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardUninstallController
|
||||
extends PhabricatorDashboardController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$dashboard = id(new PhabricatorDashboardQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($id))
|
||||
->executeOne();
|
||||
if (!$dashboard) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$dashboard_phid = $dashboard->getPHID();
|
||||
|
||||
$object_phid = $request->getStr('objectPHID', $viewer->getPHID());
|
||||
$object = id(new PhabricatorObjectQuery())
|
||||
->setViewer($viewer)
|
||||
->requireCapabilities(
|
||||
array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
PhabricatorPolicyCapability::CAN_EDIT,
|
||||
))
|
||||
->withPHIDs(array($object_phid))
|
||||
->executeOne();
|
||||
if (!$object) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$application_class = $request->getStr(
|
||||
'applicationClass',
|
||||
'PhabricatorHomeApplication');
|
||||
|
||||
$dashboard_install = id(new PhabricatorDashboardInstall())
|
||||
->loadOneWhere(
|
||||
'objectPHID = %s AND applicationClass = %s',
|
||||
$object_phid,
|
||||
$application_class);
|
||||
if (!$dashboard_install) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
if ($dashboard_install->getDashboardPHID() != $dashboard_phid) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$installer_phid = $viewer->getPHID();
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$dashboard_install->delete();
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($this->getRedirectURI($application_class, $object_phid));
|
||||
}
|
||||
|
||||
$body = $this->getBodyContent(
|
||||
$application_class,
|
||||
$object_phid,
|
||||
$installer_phid);
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($viewer)
|
||||
->appendChild($body);
|
||||
|
||||
return $this->newDialog()
|
||||
->setTitle(pht('Uninstall Dashboard'))
|
||||
->appendChild($form->buildLayoutView())
|
||||
->addCancelButton($this->getCancelURI(
|
||||
$application_class, $object_phid, $id))
|
||||
->addSubmitButton(pht('Uninstall Dashboard'));
|
||||
}
|
||||
|
||||
private function getBodyContent(
|
||||
$application_class,
|
||||
$object_phid,
|
||||
$installer_phid) {
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$body = array();
|
||||
switch ($application_class) {
|
||||
case 'PhabricatorHomeApplication':
|
||||
if ($installer_phid == $object_phid) {
|
||||
$body[] = phutil_tag(
|
||||
'p',
|
||||
array(),
|
||||
pht(
|
||||
'Are you sure you want to uninstall this dashboard as your '.
|
||||
'home page?'));
|
||||
$body[] = phutil_tag(
|
||||
'p',
|
||||
array(),
|
||||
pht(
|
||||
'You will be re-directed to your bland, default home page if '.
|
||||
'you choose to uninstall this dashboard.'));
|
||||
} else {
|
||||
$body[] = phutil_tag(
|
||||
'p',
|
||||
array(),
|
||||
pht(
|
||||
'Are you sure you want to uninstall this dashboard as the home '.
|
||||
'page for %s?',
|
||||
$viewer->renderHandle($object_phid)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
return $body;
|
||||
}
|
||||
|
||||
private function getCancelURI($application_class, $object_phid, $id) {
|
||||
$uri = null;
|
||||
switch ($application_class) {
|
||||
case 'PhabricatorHomeApplication':
|
||||
$uri = '/dashboard/view/'.$id.'/';
|
||||
break;
|
||||
}
|
||||
return $uri;
|
||||
}
|
||||
|
||||
private function getRedirectURI($application_class, $object_phid) {
|
||||
$uri = null;
|
||||
switch ($application_class) {
|
||||
case 'PhabricatorHomeApplication':
|
||||
$uri = '/';
|
||||
break;
|
||||
}
|
||||
return $uri;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +1,7 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorDashboardViewController
|
||||
extends PhabricatorDashboardController {
|
||||
|
||||
private $id;
|
||||
extends PhabricatorDashboardProfileController {
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
|
@ -11,63 +9,51 @@ final class PhabricatorDashboardViewController
|
|||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$this->id = $request->getURIData('id');
|
||||
$id = $request->getURIData('id');
|
||||
|
||||
$dashboard = id(new PhabricatorDashboardQuery())
|
||||
->setViewer($viewer)
|
||||
->withIDs(array($this->id))
|
||||
->withIDs(array($id))
|
||||
->needPanels(true)
|
||||
->executeOne();
|
||||
if (!$dashboard) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$this->setDashboard($dashboard);
|
||||
|
||||
$dashboard_uri = $this->getApplicationURI("view/{$id}/");
|
||||
$title = $dashboard->getName();
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->setBorder(true);
|
||||
$crumbs->addTextCrumb(pht('Dashboard %d', $dashboard->getID()));
|
||||
$crumbs->addTextCrumb(pht('View'));
|
||||
|
||||
if ($dashboard->getPanelPHIDs()) {
|
||||
$rendered_dashboard = id(new PhabricatorDashboardRenderingEngine())
|
||||
->setViewer($viewer)
|
||||
->setDashboard($dashboard)
|
||||
->renderDashboard();
|
||||
$content = id(new PHUIBoxView())
|
||||
->addClass('dashboard-preview-box')
|
||||
->appendChild($rendered_dashboard);
|
||||
} else {
|
||||
$rendered_dashboard = $this->buildEmptyView();
|
||||
$content = id(new PHUIInfoView())
|
||||
->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
|
||||
->appendChild(pht('This dashboard has no panels yet.'));
|
||||
}
|
||||
|
||||
$navigation = $this->buildSideNavView('view');
|
||||
$header = $this->buildHeaderView();
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setFooter(array(
|
||||
$content,
|
||||
));
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->appendChild($rendered_dashboard);
|
||||
}
|
||||
|
||||
protected function buildApplicationCrumbs() {
|
||||
$crumbs = parent::buildApplicationCrumbs();
|
||||
$id = $this->id;
|
||||
|
||||
$crumbs->addAction(
|
||||
id(new PHUIListItemView())
|
||||
->setIcon('fa-th')
|
||||
->setName(pht('Manage Dashboard'))
|
||||
->setHref($this->getApplicationURI("manage/{$id}/")));
|
||||
|
||||
return $crumbs;
|
||||
}
|
||||
|
||||
public function buildEmptyView() {
|
||||
$id = $this->id;
|
||||
$manage_uri = $this->getApplicationURI("manage/{$id}/");
|
||||
|
||||
return id(new PHUIInfoView())
|
||||
->setSeverity(PHUIInfoView::SEVERITY_NODATA)
|
||||
->appendChild(
|
||||
pht('This dashboard has no panels '.
|
||||
'yet. Use %s to add panels.',
|
||||
phutil_tag(
|
||||
'a',
|
||||
array('href' => $manage_uri),
|
||||
pht('Manage Dashboard'))));
|
||||
->setNavigation($navigation)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,7 +15,11 @@ final class PhabricatorDashboardPanelTabsCustomField
|
|||
$value = array();
|
||||
|
||||
$names = $request->getArr($this->getFieldKey().'_name');
|
||||
$panels = $request->getArr($this->getFieldKey().'_panelID');
|
||||
$panel_ids = $request->getArr($this->getFieldKey().'_panelID');
|
||||
$panels = array();
|
||||
foreach ($panel_ids as $panel_id) {
|
||||
$panels[] = $panel_id[0];
|
||||
}
|
||||
foreach ($names as $idx => $name) {
|
||||
$panel_id = idx($panels, $idx);
|
||||
if (strlen($name) && $panel_id) {
|
||||
|
@ -29,26 +33,54 @@ final class PhabricatorDashboardPanelTabsCustomField
|
|||
$this->setFieldValue($value);
|
||||
}
|
||||
|
||||
public function getApplicationTransactionTitle(
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
$author_phid = $xaction->getAuthorPHID();
|
||||
$old = $xaction->getOldValue();
|
||||
$new = $xaction->getNewValue();
|
||||
|
||||
$new_tabs = array();
|
||||
if ($new) {
|
||||
foreach ($new as $new_tab) {
|
||||
$new_tabs[] = $new_tab['name'];
|
||||
}
|
||||
$new_tabs = implode(' | ', $new_tabs);
|
||||
}
|
||||
|
||||
$old_tabs = array();
|
||||
if ($old) {
|
||||
foreach ($old as $old_tab) {
|
||||
$old_tabs[] = $old_tab['name'];
|
||||
}
|
||||
$old_tabs = implode(' | ', $old_tabs);
|
||||
}
|
||||
|
||||
if (!$old) {
|
||||
// In case someone makes a tab panel with no tabs.
|
||||
if ($new) {
|
||||
return pht(
|
||||
'%s set the tabs to "%s".',
|
||||
$xaction->renderHandleLink($author_phid),
|
||||
$new_tabs);
|
||||
}
|
||||
} else if (!$new) {
|
||||
return pht(
|
||||
'%s removed tabs.',
|
||||
$xaction->renderHandleLink($author_phid));
|
||||
} else {
|
||||
return pht(
|
||||
'%s changed the tabs from "%s" to "%s".',
|
||||
$xaction->renderHandleLink($author_phid),
|
||||
$old_tabs,
|
||||
$new_tabs);
|
||||
}
|
||||
}
|
||||
|
||||
public function renderEditControl(array $handles) {
|
||||
// NOTE: This includes archived panels so we don't mutate the tabs
|
||||
// when saving a tab panel that includes archied panels. This whole UI is
|
||||
// hopefully temporary anyway.
|
||||
|
||||
$panels = id(new PhabricatorDashboardPanelQuery())
|
||||
->setViewer($this->getViewer())
|
||||
->execute();
|
||||
|
||||
$panel_map = array();
|
||||
foreach ($panels as $panel) {
|
||||
$panel_map[$panel->getID()] = pht(
|
||||
'%s %s',
|
||||
$panel->getMonogram(),
|
||||
$panel->getName());
|
||||
}
|
||||
$panel_map = array(
|
||||
'' => pht('(None)'),
|
||||
) + $panel_map;
|
||||
|
||||
$value = $this->getFieldValue();
|
||||
if (!is_array($value)) {
|
||||
$value = array();
|
||||
|
@ -57,15 +89,22 @@ final class PhabricatorDashboardPanelTabsCustomField
|
|||
$out = array();
|
||||
for ($ii = 1; $ii <= 6; $ii++) {
|
||||
$tab = idx($value, ($ii - 1), array());
|
||||
$panel = idx($tab, 'panelID', null);
|
||||
$panel_id = array();
|
||||
if ($panel) {
|
||||
$panel_id[] = $panel;
|
||||
}
|
||||
$out[] = id(new AphrontFormTextControl())
|
||||
->setName($this->getFieldKey().'_name[]')
|
||||
->setValue(idx($tab, 'name'))
|
||||
->setLabel(pht('Tab %d Name', $ii));
|
||||
|
||||
$out[] = id(new AphrontFormSelectControl())
|
||||
$out[] = id(new AphrontFormTokenizerControl())
|
||||
->setUser($this->getViewer())
|
||||
->setDatasource(new PhabricatorDashboardPanelDatasource())
|
||||
->setName($this->getFieldKey().'_panelID[]')
|
||||
->setValue(idx($tab, 'panelID'))
|
||||
->setOptions($panel_map)
|
||||
->setValue($panel_id)
|
||||
->setLimit(1)
|
||||
->setLabel(pht('Tab %d Panel', $ii));
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
|||
private $parentPanelPHIDs;
|
||||
private $headerMode = self::HEADER_MODE_NORMAL;
|
||||
private $dashboardID;
|
||||
private $movable = true;
|
||||
|
||||
public function setDashboardID($id) {
|
||||
$this->dashboardID = $id;
|
||||
|
@ -63,6 +64,15 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function setMovable($movable) {
|
||||
$this->movable = $movable;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMovable() {
|
||||
return $this->movable;
|
||||
}
|
||||
|
||||
public function getPanel() {
|
||||
return $this->panel;
|
||||
}
|
||||
|
@ -78,7 +88,6 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
|||
|
||||
public function renderPanel() {
|
||||
$panel = $this->getPanel();
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
if (!$panel) {
|
||||
return $this->renderErrorPanel(
|
||||
|
@ -107,7 +116,7 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
|||
}
|
||||
}
|
||||
|
||||
return $this->renderNormalPanel($viewer, $panel, $this);
|
||||
return $this->renderNormalPanel();
|
||||
} catch (Exception $ex) {
|
||||
return $this->renderErrorPanel(
|
||||
$panel->getName(),
|
||||
|
@ -221,8 +230,13 @@ final class PhabricatorDashboardPanelRenderingEngine extends Phobject {
|
|||
$box
|
||||
->setHeader($header)
|
||||
->setID($id)
|
||||
->addClass('dashboard-box')
|
||||
->addSigil('dashboard-panel');
|
||||
|
||||
if ($this->getMovable()) {
|
||||
$box->addSigil('panel-movable');
|
||||
}
|
||||
|
||||
if ($panel) {
|
||||
$box->setMetadata(
|
||||
array(
|
||||
|
|
|
@ -81,17 +81,43 @@ final class PhabricatorDashboardRenderingEngine extends Phobject {
|
|||
}
|
||||
|
||||
if ($this->arrangeMode) {
|
||||
$footer = null;
|
||||
Javelin::initBehavior(
|
||||
'dashboard-move-panels',
|
||||
array(
|
||||
'dashboardID' => $dashboard_id,
|
||||
'moveURI' => '/dashboard/movepanel/'.$dashboard->getID().'/',
|
||||
));
|
||||
} else {
|
||||
$name = $dashboard->getName();
|
||||
$icon = id(new PHUIIconView())
|
||||
->setIcon($dashboard->getIcon())
|
||||
->addClass('msr');
|
||||
$footer_left = phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'class' => 'dashboard-footer-name',
|
||||
'href' => '/dashboard/view/'.$dashboard->getID().'/',
|
||||
),
|
||||
array(
|
||||
$icon,
|
||||
$name,
|
||||
));
|
||||
|
||||
$footer = phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'dashboard-footer-view',
|
||||
),
|
||||
array(
|
||||
$footer_left,
|
||||
));
|
||||
}
|
||||
|
||||
$view = id(new PHUIBoxView())
|
||||
->addClass('dashboard-view')
|
||||
->appendChild($result);
|
||||
->appendChild($result)
|
||||
->appendChild($footer);
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
@ -123,7 +149,6 @@ final class PhabricatorDashboardRenderingEngine extends Phobject {
|
|||
->setTag('a')
|
||||
->setHref($create_uri)
|
||||
->setWorkflow(true)
|
||||
->setColor(PHUIButtonView::GREY)
|
||||
->setText(pht('Create Panel'))
|
||||
->addClass(PHUI::MARGIN_MEDIUM);
|
||||
|
||||
|
@ -131,7 +156,6 @@ final class PhabricatorDashboardRenderingEngine extends Phobject {
|
|||
->setTag('a')
|
||||
->setHref($add_uri)
|
||||
->setWorkflow(true)
|
||||
->setColor(PHUIButtonView::GREY)
|
||||
->setText(pht('Add Existing Panel'))
|
||||
->addClass(PHUI::MARGIN_MEDIUM);
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ abstract class PhabricatorDashboardPanelType extends Phobject {
|
|||
abstract public function getPanelTypeName();
|
||||
abstract public function getPanelTypeDescription();
|
||||
abstract public function getFieldSpecifications();
|
||||
abstract public function getIcon();
|
||||
|
||||
abstract public function renderPanelContent(
|
||||
PhabricatorUser $viewer,
|
||||
|
|
|
@ -11,6 +11,10 @@ final class PhabricatorDashboardQueryPanelType
|
|||
return pht('Query Panel');
|
||||
}
|
||||
|
||||
public function getIcon() {
|
||||
return 'fa-search';
|
||||
}
|
||||
|
||||
public function getPanelTypeDescription() {
|
||||
return pht(
|
||||
'Show results of a search query, like the most recently filed tasks or '.
|
||||
|
|
|
@ -11,6 +11,10 @@ final class PhabricatorDashboardTabsPanelType
|
|||
return pht('Tab Panel');
|
||||
}
|
||||
|
||||
public function getIcon() {
|
||||
return 'fa-window-maximize';
|
||||
}
|
||||
|
||||
public function getPanelTypeDescription() {
|
||||
return pht('Use tabs to switch between several other panels.');
|
||||
}
|
||||
|
@ -93,6 +97,7 @@ final class PhabricatorDashboardTabsPanelType
|
|||
->setPanel($panel)
|
||||
->setPanelPHID($panel->getPHID())
|
||||
->setHeaderMode($no_headers)
|
||||
->setMovable(false)
|
||||
->renderPanel();
|
||||
} else {
|
||||
$panel_content = pht('(Invalid Panel)');
|
||||
|
|
|
@ -11,6 +11,10 @@ final class PhabricatorDashboardTextPanelType
|
|||
return pht('Text Panel');
|
||||
}
|
||||
|
||||
public function getIcon() {
|
||||
return 'fa-paragraph';
|
||||
}
|
||||
|
||||
public function getPanelTypeDescription() {
|
||||
return pht(
|
||||
'Add some static text to the dashboard. This can be used to '.
|
||||
|
|
|
@ -13,7 +13,7 @@ final class PhabricatorDashboardSearchEngine
|
|||
|
||||
public function newQuery() {
|
||||
return id(new PhabricatorDashboardQuery())
|
||||
->needProjects(true);
|
||||
->needPanels(true);
|
||||
}
|
||||
|
||||
protected function buildCustomSearchFields() {
|
||||
|
@ -98,100 +98,53 @@ final class PhabricatorDashboardSearchEngine
|
|||
PhabricatorSavedQuery $query,
|
||||
array $handles) {
|
||||
|
||||
$dashboards = mpull($dashboards, null, 'getPHID');
|
||||
$viewer = $this->requireViewer();
|
||||
|
||||
if ($dashboards) {
|
||||
$installs = id(new PhabricatorDashboardInstall())
|
||||
->loadAllWhere(
|
||||
'objectPHID IN (%Ls) AND dashboardPHID IN (%Ls)',
|
||||
array(
|
||||
PhabricatorHomeApplication::DASHBOARD_DEFAULT,
|
||||
$viewer->getPHID(),
|
||||
),
|
||||
array_keys($dashboards));
|
||||
$installs = mpull($installs, null, 'getDashboardPHID');
|
||||
} else {
|
||||
$installs = array();
|
||||
}
|
||||
|
||||
$proj_phids = array();
|
||||
$phids = array();
|
||||
foreach ($dashboards as $dashboard) {
|
||||
foreach ($dashboard->getProjectPHIDs() as $project_phid) {
|
||||
$proj_phids[] = $project_phid;
|
||||
$author_phid = $dashboard->getAuthorPHID();
|
||||
if ($author_phid) {
|
||||
$phids[] = $author_phid;
|
||||
}
|
||||
}
|
||||
|
||||
$proj_handles = id(new PhabricatorHandleQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs($proj_phids)
|
||||
->execute();
|
||||
$handles = $viewer->loadHandles($phids);
|
||||
|
||||
$list = new PHUIObjectItemListView();
|
||||
$list->setUser($viewer);
|
||||
$list->initBehavior('phabricator-tooltips', array());
|
||||
$list->requireResource('aphront-tooltip-css');
|
||||
$list = id(new PHUIObjectItemListView())
|
||||
->setUser($viewer);
|
||||
|
||||
foreach ($dashboards as $dashboard_phid => $dashboard) {
|
||||
foreach ($dashboards as $dashboard) {
|
||||
$id = $dashboard->getID();
|
||||
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setObjectName(pht('Dashboard %d', $id))
|
||||
->setUser($viewer)
|
||||
->setHeader($dashboard->getName())
|
||||
->setHref($this->getApplicationURI("view/{$id}/"))
|
||||
->setObject($dashboard);
|
||||
|
||||
if (isset($installs[$dashboard_phid])) {
|
||||
$install = $installs[$dashboard_phid];
|
||||
if ($install->getObjectPHID() == $viewer->getPHID()) {
|
||||
$attrs = array(
|
||||
'tip' => pht(
|
||||
'This dashboard is installed to your personal homepage.'),
|
||||
);
|
||||
$item->addIcon('fa-user', pht('Installed'), $attrs);
|
||||
} else {
|
||||
$attrs = array(
|
||||
'tip' => pht(
|
||||
'This dashboard is the default homepage for all users.'),
|
||||
);
|
||||
$item->addIcon('fa-globe', pht('Installed'), $attrs);
|
||||
}
|
||||
}
|
||||
|
||||
$project_handles = array_select_keys(
|
||||
$proj_handles,
|
||||
$dashboard->getProjectPHIDs());
|
||||
|
||||
$item->addAttribute(
|
||||
id(new PHUIHandleTagListView())
|
||||
->setLimit(4)
|
||||
->setNoDataString(pht('No Projects'))
|
||||
->setSlim(true)
|
||||
->setHandles($project_handles));
|
||||
|
||||
if ($dashboard->isArchived()) {
|
||||
$item->setDisabled(true);
|
||||
}
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$dashboard,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
$panels = $dashboard->getPanels();
|
||||
foreach ($panels as $panel) {
|
||||
$item->addAttribute($panel->getName());
|
||||
}
|
||||
|
||||
$href_view = $this->getApplicationURI("manage/{$id}/");
|
||||
$item->addAction(
|
||||
id(new PHUIListItemView())
|
||||
->setName(pht('Manage'))
|
||||
->setIcon('fa-th')
|
||||
->setHref($href_view));
|
||||
if (empty($panels)) {
|
||||
$empty = phutil_tag('em', array(), pht('No panels.'));
|
||||
$item->addAttribute($empty);
|
||||
}
|
||||
|
||||
$href_edit = $this->getApplicationURI("edit/{$id}/");
|
||||
$item->addAction(
|
||||
id(new PHUIListItemView())
|
||||
->setName(pht('Edit'))
|
||||
->setIcon('fa-pencil')
|
||||
->setHref($href_edit)
|
||||
->setDisabled(!$can_edit));
|
||||
$icon = id(new PHUIIconView())
|
||||
->setIcon($dashboard->getIcon())
|
||||
->setBackground('bg-dark');
|
||||
$item->setImageIcon($icon);
|
||||
$item->setEpoch($dashboard->getDateModified());
|
||||
|
||||
$author_phid = $dashboard->getAuthorPHID();
|
||||
$author_name = $handles[$author_phid]->renderLink();
|
||||
$item->addByline(pht('Author: %s', $author_name));
|
||||
|
||||
$list->addItem($item);
|
||||
}
|
||||
|
|
|
@ -47,16 +47,6 @@ final class PhabricatorDashboard extends PhabricatorDashboardDAO
|
|||
);
|
||||
}
|
||||
|
||||
public static function copyDashboard(
|
||||
PhabricatorDashboard $dst,
|
||||
PhabricatorDashboard $src) {
|
||||
|
||||
$dst->name = $src->name;
|
||||
$dst->layoutConfig = $src->layoutConfig;
|
||||
|
||||
return $dst;
|
||||
}
|
||||
|
||||
protected function getConfiguration() {
|
||||
return array(
|
||||
self::CONFIG_AUX_PHID => true,
|
||||
|
|
|
@ -31,19 +31,6 @@ final class PhabricatorDashboardPanel
|
|||
->setEditPolicy($actor->getPHID());
|
||||
}
|
||||
|
||||
public static function copyPanel(
|
||||
PhabricatorDashboardPanel $dst,
|
||||
PhabricatorDashboardPanel $src,
|
||||
PhabricatorUser $user) {
|
||||
|
||||
$dst->name = $src->name;
|
||||
$dst->panelType = $src->panelType;
|
||||
$dst->properties = $src->properties;
|
||||
$dst->authorPHID = $user->getPHID();
|
||||
|
||||
return $dst;
|
||||
}
|
||||
|
||||
protected function getConfiguration() {
|
||||
return array(
|
||||
self::CONFIG_AUX_PHID => true,
|
||||
|
|
|
@ -56,11 +56,11 @@ final class PhabricatorDashboardTransaction
|
|||
case self::TYPE_STATUS:
|
||||
if ($new == PhabricatorDashboard::STATUS_ACTIVE) {
|
||||
return pht(
|
||||
'%s activated this dashboard',
|
||||
'%s activated this dashboard.',
|
||||
$author_link);
|
||||
} else {
|
||||
return pht(
|
||||
'%s archived this dashboard',
|
||||
'%s archived this dashboard.',
|
||||
$author_link);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -16,9 +16,19 @@ final class PhabricatorDashboardPanelDatasource
|
|||
}
|
||||
|
||||
public function loadResults() {
|
||||
$query = id(new PhabricatorDashboardPanelQuery());
|
||||
$results = $this->buildResults();
|
||||
return $this->filterResultsAgainstTokens($results);
|
||||
}
|
||||
|
||||
|
||||
protected function renderSpecialTokens(array $values) {
|
||||
return $this->renderTokensFromResults($this->buildResults(), $values);
|
||||
}
|
||||
|
||||
public function buildResults() {
|
||||
$query = id(new PhabricatorDashboardPanelQuery());
|
||||
$panels = $this->executeQuery($query);
|
||||
|
||||
$results = array();
|
||||
foreach ($panels as $panel) {
|
||||
$impl = $panel->getImplementation();
|
||||
|
@ -27,20 +37,29 @@ final class PhabricatorDashboardPanelDatasource
|
|||
} else {
|
||||
$type_text = nonempty($panel->getPanelType(), pht('Unknown Type'));
|
||||
}
|
||||
$id = $panel->getID();
|
||||
$monogram = $panel->getMonogram();
|
||||
$properties = $panel->getProperties();
|
||||
|
||||
$result = id(new PhabricatorTypeaheadResult())
|
||||
->setName($panel->getName())
|
||||
->setPHID($panel->getPHID())
|
||||
->setDisplayName($monogram.' '.$panel->getName())
|
||||
->setPHID($id)
|
||||
->setIcon($impl->getIcon())
|
||||
->addAttribute($type_text);
|
||||
|
||||
if (!empty($properties['class'])) {
|
||||
$result->addAttribute($properties['class']);
|
||||
}
|
||||
|
||||
if ($panel->getIsArchived()) {
|
||||
$result->setClosed(pht('Archived'));
|
||||
}
|
||||
|
||||
$results[] = $result;
|
||||
$results[$id] = $result;
|
||||
}
|
||||
|
||||
return $this->filterResultsAgainstTokens($results);
|
||||
return $results;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -111,8 +111,8 @@ abstract class DifferentialCustomField
|
|||
* @task diff
|
||||
*/
|
||||
public function renderDiffPropertyViewLabel(DifferentialDiff $diff) {
|
||||
if ($this->proxy) {
|
||||
return $this->proxy->renderDiffPropertyViewLabel($diff);
|
||||
if ($this->getProxy()) {
|
||||
return $this->getProxy()->renderDiffPropertyViewLabel($diff);
|
||||
}
|
||||
return $this->getFieldName();
|
||||
}
|
||||
|
@ -122,8 +122,8 @@ abstract class DifferentialCustomField
|
|||
* @task diff
|
||||
*/
|
||||
public function renderDiffPropertyViewValue(DifferentialDiff $diff) {
|
||||
if ($this->proxy) {
|
||||
return $this->proxy->renderDiffPropertyViewValue($diff);
|
||||
if ($this->getProxy()) {
|
||||
return $this->getProxy()->renderDiffPropertyViewValue($diff);
|
||||
}
|
||||
throw new PhabricatorCustomFieldImplementationIncompleteException($this);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ final class DifferentialRevisionRequiredActionResultBucket
|
|||
|
||||
$this->objects = $objects;
|
||||
|
||||
$phids = $query->getEvaluatedParameter('responsiblePHIDs', array());
|
||||
$phids = $query->getEvaluatedParameter('responsiblePHIDs');
|
||||
if (!$phids) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
|
|
|
@ -201,7 +201,7 @@ final class DiffusionDiffQueryConduitAPIMethod
|
|||
|
||||
$effective_commit = $this->getEffectiveCommit($request);
|
||||
if (!$effective_commit) {
|
||||
return $this->getEmptyResult(1);
|
||||
return $this->getEmptyResult();
|
||||
}
|
||||
|
||||
$raw_query = DiffusionRawDiffQuery::newFromDiffusionRequest($drequest)
|
||||
|
@ -209,7 +209,7 @@ final class DiffusionDiffQueryConduitAPIMethod
|
|||
|
||||
$raw_diff = $raw_query->executeInline();
|
||||
if (!$raw_diff) {
|
||||
return $this->getEmptyResult(2);
|
||||
return $this->getEmptyResult();
|
||||
}
|
||||
|
||||
$parser = $this->getDefaultParser();
|
||||
|
|
|
@ -44,7 +44,7 @@ final class DiffusionBrowseController extends DiffusionController {
|
|||
$is_file = ($reason == DiffusionBrowseResultSet::REASON_IS_FILE);
|
||||
|
||||
if ($is_file) {
|
||||
return $this->browseFile($results);
|
||||
return $this->browseFile();
|
||||
} else {
|
||||
$paths = $results->getPaths();
|
||||
$paths = $pager->sliceResults($paths);
|
||||
|
|
|
@ -705,7 +705,11 @@ final class DiffusionCommitController extends DiffusionController {
|
|||
$timeline = $this->buildTransactionTimeline(
|
||||
$commit,
|
||||
new PhabricatorAuditTransactionQuery());
|
||||
|
||||
$commit->willRenderTimeline($timeline, $this->getRequest());
|
||||
|
||||
$timeline->setQuoteRef($commit->getMonogram());
|
||||
|
||||
return $timeline;
|
||||
}
|
||||
|
||||
|
|
|
@ -357,7 +357,7 @@ abstract class DiffusionController extends PhabricatorController {
|
|||
$stable_commit = $drequest->getStableCommit();
|
||||
|
||||
$stable_commit_hash = PhabricatorHash::digestForIndex($stable_commit);
|
||||
$readme_path_hash = PhabricatorHash::digestForindex($readme_path);
|
||||
$readme_path_hash = PhabricatorHash::digestForIndex($readme_path);
|
||||
|
||||
$cache = PhabricatorCaches::getMutableStructureCache();
|
||||
$cache_key = "diffusion".
|
||||
|
|
|
@ -59,7 +59,7 @@ final class DiffusionHistoryController extends DiffusionController {
|
|||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setTable($history_table);
|
||||
|
||||
$header = $this->buildHeader($drequest, $repository);
|
||||
$header = $this->buildHeader($drequest);
|
||||
|
||||
$crumbs = $this->buildCrumbs(
|
||||
array(
|
||||
|
|
|
@ -241,7 +241,7 @@ final class DiffusionRepositoryStatusManagementPanel
|
|||
}
|
||||
}
|
||||
|
||||
$doc_href = PhabricatorEnv::getDocLink('Managing Daemons with phd');
|
||||
$doc_href = PhabricatorEnv::getDoclink('Managing Daemons with phd');
|
||||
|
||||
$daemon_instructions = pht(
|
||||
'Use %s to start daemons. See %s.',
|
||||
|
|
|
@ -335,7 +335,8 @@ final class DiffusionRepositoryClusterEngine extends Phobject {
|
|||
pht(
|
||||
'Failed to acquire write lock after waiting %s second(s). You '.
|
||||
'may be able to retry later.',
|
||||
new PhutilNumber($lock_wait)));
|
||||
new PhutilNumber($lock_wait)),
|
||||
$ex);
|
||||
}
|
||||
|
||||
$versions = PhabricatorRepositoryWorkingCopyVersion::loadVersions(
|
||||
|
|
|
@ -17,7 +17,7 @@ final class DiffusionCommitRequiredActionResultBucket
|
|||
|
||||
$this->objects = $objects;
|
||||
|
||||
$phids = $query->getEvaluatedParameter('responsiblePHIDs', array());
|
||||
$phids = $query->getEvaluatedParameter('responsiblePHIDs');
|
||||
if (!$phids) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
|
|
|
@ -43,7 +43,7 @@ final class DivinerAtom extends Phobject {
|
|||
$this->getContext(),
|
||||
$this->getName(),
|
||||
$this->getFile(),
|
||||
sprintf('%08', $this->getLine()),
|
||||
sprintf('%08d', $this->getLine()),
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ final class DivinerDefaultRenderer extends DivinerRenderer {
|
|||
|
||||
$this->pushAtomStack($atom);
|
||||
$description = $engine->markupText($text);
|
||||
$this->popAtomStack($atom);
|
||||
$this->popAtomStack();
|
||||
|
||||
return phutil_tag(
|
||||
'div',
|
||||
|
|
|
@ -33,8 +33,8 @@ final class DivinerLiveSymbolFulltextEngine
|
|||
|
||||
$document->addRelationship(
|
||||
$atom->getGraphHash()
|
||||
? PhabricatorSearchRelationship::RELATIONSHIP_CLOSED
|
||||
: PhabricatorSearchRelationship::RELATIONSHIP_OPEN,
|
||||
? PhabricatorSearchRelationship::RELATIONSHIP_OPEN
|
||||
: PhabricatorSearchRelationship::RELATIONSHIP_CLOSED,
|
||||
$atom->getBookPHID(),
|
||||
DivinerBookPHIDType::TYPECONST,
|
||||
PhabricatorTime::getNow());
|
||||
|
|
|
@ -61,7 +61,7 @@ abstract class DivinerWorkflow extends PhabricatorManagementWorkflow {
|
|||
}
|
||||
|
||||
foreach (idx($book, 'groups', array()) as $group) {
|
||||
PhutilTypeSpec::checkmap(
|
||||
PhutilTypeSpec::checkMap(
|
||||
$group,
|
||||
array(
|
||||
'name' => 'string',
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
final class PhabricatorFileLightboxController
|
||||
extends PhabricatorFileController {
|
||||
|
||||
public function shouldAllowPublic() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
$phid = $request->getURIData('phid');
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
abstract class HeraldController extends PhabricatorController {
|
||||
|
||||
public function buildApplicationMenu() {
|
||||
return $this->buildSideNavView(true)->getMenu();
|
||||
return $this->buildSideNavView()->getMenu();
|
||||
}
|
||||
|
||||
protected function buildApplicationCrumbs() {
|
||||
|
|
|
@ -40,11 +40,6 @@ final class HeraldRuleQuery extends PhabricatorCursorPagedPolicyAwareQuery {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function withExecutableRules($executable) {
|
||||
$this->executable = $executable;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withDisabled($disabled) {
|
||||
$this->disabled = $disabled;
|
||||
return $this;
|
||||
|
|
|
@ -213,7 +213,7 @@ final class LegalpadDocumentEditController extends LegalpadController {
|
|||
->setPolicies($policies)
|
||||
->setName('can_edit'));
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs($this->buildSideNav());
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$submit = new AphrontFormSubmitControl();
|
||||
if ($is_create) {
|
||||
$submit->setValue(pht('Create Document'));
|
||||
|
|
|
@ -54,7 +54,7 @@ final class LegalpadDocumentManageController extends LegalpadController {
|
|||
|
||||
$add_comment = $this->buildAddCommentView($document, $comment_form_id);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs($this->buildSideNav());
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb(
|
||||
$document->getMonogram(),
|
||||
'/'.$document->getMonogram());
|
||||
|
|
|
@ -52,9 +52,6 @@ final class LegalpadDocumentBody extends LegalpadDAO
|
|||
case self::MARKUP_FIELD_TEXT:
|
||||
$text = $this->getText();
|
||||
break;
|
||||
case self::MARKUP_FIELD_TITLE:
|
||||
$text = $this->getTitle();
|
||||
break;
|
||||
default:
|
||||
throw new Exception(pht('Unknown field: %s', $field));
|
||||
break;
|
||||
|
|
|
@ -98,8 +98,10 @@ abstract class PhabricatorTestDataGenerator extends Phobject {
|
|||
->loadOneWhere('1 = 1 ORDER BY RAND() LIMIT 1');
|
||||
} catch (PhutilMissingSymbolException $ex) {
|
||||
throw new PhutilMissingSymbolException(
|
||||
$classname,
|
||||
pht('class'),
|
||||
pht(
|
||||
'Unable to load symbol %s: this class does not exit.',
|
||||
'Unable to load symbol %s: this class does not exist.',
|
||||
$classname));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
abstract class ManiphestController extends PhabricatorController {
|
||||
|
||||
public function buildApplicationMenu() {
|
||||
return $this->buildSideNavView(true)->getMenu();
|
||||
return $this->buildSideNavView()->getMenu();
|
||||
}
|
||||
|
||||
public function buildSideNavView() {
|
||||
|
|
|
@ -219,7 +219,7 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
|||
|
||||
$status = $task->getStatus();
|
||||
$status_name = ManiphestTaskStatus::renderFullDescription(
|
||||
$status, $priority_name, $priority_color);
|
||||
$status, $priority_name);
|
||||
$view->addProperty(PHUIHeaderView::PROPERTY_STATUS, $status_name);
|
||||
|
||||
$view->setHeaderIcon(ManiphestTaskStatus::getStatusIcon(
|
||||
|
|
|
@ -10,8 +10,7 @@ final class ManiphestConfiguredCustomField
|
|||
|
||||
public function createFields($object) {
|
||||
$config = PhabricatorEnv::getEnvConfig(
|
||||
'maniphest.custom-field-definitions',
|
||||
array());
|
||||
'maniphest.custom-field-definitions');
|
||||
$fields = PhabricatorStandardCustomField::buildStandardFields(
|
||||
$this,
|
||||
$config);
|
||||
|
|
|
@ -767,7 +767,7 @@ final class ManiphestTransaction
|
|||
$new_name);
|
||||
} else {
|
||||
return pht(
|
||||
'%s changed the status of %s, a subtasktask of %s, '.
|
||||
'%s changed the status of %s, a subtask of %s, '.
|
||||
'from "%s" to "%s".',
|
||||
$this->renderHandleLink($author_phid),
|
||||
$this->renderHandleLink($blocker_phid),
|
||||
|
|
|
@ -15,7 +15,7 @@ final class PhabricatorMailImplementationPHPMailerAdapter
|
|||
$this->mailer = new PHPMailer($use_exceptions = true);
|
||||
$this->mailer->CharSet = 'utf-8';
|
||||
|
||||
$encoding = PhabricatorEnv::getEnvConfig('phpmailer.smtp-encoding', '8bit');
|
||||
$encoding = PhabricatorEnv::getEnvConfig('phpmailer.smtp-encoding');
|
||||
$this->mailer->Encoding = $encoding;
|
||||
|
||||
// By default, PHPMailer sends one mail per recipient. We handle
|
||||
|
|
|
@ -18,7 +18,7 @@ class PhabricatorMailImplementationPHPMailerLiteAdapter
|
|||
$this->mailer = new PHPMailerLite($use_exceptions = true);
|
||||
$this->mailer->CharSet = 'utf-8';
|
||||
|
||||
$encoding = PhabricatorEnv::getEnvConfig('phpmailer.smtp-encoding', '8bit');
|
||||
$encoding = PhabricatorEnv::getEnvConfig('phpmailer.smtp-encoding');
|
||||
$this->mailer->Encoding = $encoding;
|
||||
|
||||
// By default, PHPMailerLite sends one mail per recipient. We handle
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorMailManagementUnverifyWorkflow
|
||||
extends PhabricatorMailManagementWorkflow {
|
||||
|
||||
protected function didConstruct() {
|
||||
$this
|
||||
->setName('unverify')
|
||||
->setSynopsis(
|
||||
pht('Unverify an email address so it no longer receives mail.'))
|
||||
->setExamples('**unverify** __address__ ...')
|
||||
->setArguments(
|
||||
array(
|
||||
array(
|
||||
'name' => 'addresses',
|
||||
'wildcard' => true,
|
||||
'help' => pht('Address (or addresses) to unverify.'),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
public function execute(PhutilArgumentParser $args) {
|
||||
$console = PhutilConsole::getConsole();
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$addresses = $args->getArg('addresses');
|
||||
if (!$addresses) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht('Specify one or more email addresses to unverify.'));
|
||||
}
|
||||
|
||||
foreach ($addresses as $address) {
|
||||
$email = id(new PhabricatorUserEmail())->loadOneWhere(
|
||||
'address = %s',
|
||||
$address);
|
||||
if (!$email) {
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht(
|
||||
'Address "%s" is unknown.',
|
||||
$address));
|
||||
continue;
|
||||
}
|
||||
|
||||
$user_phid = $email->getUserPHID();
|
||||
|
||||
$user = id(new PhabricatorPeopleQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($user_phid))
|
||||
->executeOne();
|
||||
|
||||
if (!$user) {
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht(
|
||||
'Address "%s" belongs to invalid user "%s".',
|
||||
$address,
|
||||
$user_phid));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$email->getIsVerified()) {
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht(
|
||||
'Address "%s" (owned by "%s") is already unveriifed.',
|
||||
$address,
|
||||
$user->getUsername()));
|
||||
continue;
|
||||
}
|
||||
|
||||
$email->openTransaction();
|
||||
|
||||
$email
|
||||
->setIsVerified(0)
|
||||
->save();
|
||||
|
||||
if ($email->getIsPrimary()) {
|
||||
$user
|
||||
->setIsEmailVerified(0)
|
||||
->save();
|
||||
}
|
||||
|
||||
$email->saveTransaction();
|
||||
|
||||
if ($email->getIsPrimary()) {
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht(
|
||||
'Unverified "%s", the primary address for "%s".',
|
||||
$address,
|
||||
$user->getUsername()));
|
||||
} else {
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht(
|
||||
'Unverified "%s", an address for "%s".',
|
||||
$address,
|
||||
$user->getUsername()));
|
||||
}
|
||||
}
|
||||
|
||||
echo tsprintf(
|
||||
"%s\n",
|
||||
pht('Done.'));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
|
@ -20,12 +20,14 @@ final class PhabricatorMetaMTAActor extends Phobject {
|
|||
const REASON_FORCE_HERALD = 'force-herald';
|
||||
const REASON_ROUTE_AS_NOTIFICATION = 'route-as-notification';
|
||||
const REASON_ROUTE_AS_MAIL = 'route-as-mail';
|
||||
const REASON_UNVERIFIED = 'unverified';
|
||||
|
||||
private $phid;
|
||||
private $emailAddress;
|
||||
private $name;
|
||||
private $status = self::STATUS_DELIVERABLE;
|
||||
private $reasons = array();
|
||||
private $isVerified = false;
|
||||
|
||||
public function setName($name) {
|
||||
$this->name = $name;
|
||||
|
@ -45,6 +47,15 @@ final class PhabricatorMetaMTAActor extends Phobject {
|
|||
return $this->emailAddress;
|
||||
}
|
||||
|
||||
public function setIsVerified($is_verified) {
|
||||
$this->isVerified = $is_verified;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getIsVerified() {
|
||||
return $this->isVerified;
|
||||
}
|
||||
|
||||
public function setPHID($phid) {
|
||||
$this->phid = $phid;
|
||||
return $this;
|
||||
|
@ -104,6 +115,7 @@ final class PhabricatorMetaMTAActor extends Phobject {
|
|||
self::REASON_FORCE_HERALD => pht('Forced by Herald'),
|
||||
self::REASON_ROUTE_AS_NOTIFICATION => pht('Route as Notification'),
|
||||
self::REASON_ROUTE_AS_MAIL => pht('Route as Mail'),
|
||||
self::REASON_UNVERIFIED => pht('Address Not Verified'),
|
||||
);
|
||||
|
||||
return idx($names, $reason, pht('Unknown ("%s")', $reason));
|
||||
|
@ -158,6 +170,8 @@ final class PhabricatorMetaMTAActor extends Phobject {
|
|||
self::REASON_ROUTE_AS_MAIL => pht(
|
||||
'This message was upgraded to email by outbound mail rules '.
|
||||
'in Herald.'),
|
||||
self::REASON_UNVERIFIED => pht(
|
||||
'This recipient does not have a verified primary email address.'),
|
||||
);
|
||||
|
||||
return idx($descriptions, $reason, pht('Unknown Reason ("%s")', $reason));
|
||||
|
|
|
@ -89,6 +89,7 @@ final class PhabricatorMetaMTAActorQuery extends PhabricatorQuery {
|
|||
$actor->setUndeliverable(PhabricatorMetaMTAActor::REASON_NO_ADDRESS);
|
||||
} else {
|
||||
$actor->setEmailAddress($email->getAddress());
|
||||
$actor->setIsVerified($email->getIsVerified());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -119,6 +120,13 @@ final class PhabricatorMetaMTAActorQuery extends PhabricatorQuery {
|
|||
}
|
||||
|
||||
$actor->setEmailAddress($xuser->getAccountID());
|
||||
|
||||
// NOTE: This effectively drops all outbound mail to unrecognized
|
||||
// addresses unless "phabricator.allow-email-users" is set. See T12237
|
||||
// for context.
|
||||
$allow_key = 'phabricator.allow-email-users';
|
||||
$allow_value = PhabricatorEnv::getEnvConfig($allow_key);
|
||||
$actor->setIsVerified((bool)$allow_value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -153,6 +153,10 @@ abstract class PhabricatorMailReceiver extends Phobject {
|
|||
->loadOneOrCreate();
|
||||
return $xuser->getPhabricatorUser();
|
||||
} else {
|
||||
// NOTE: Currently, we'll always drop this mail (since it's headed to
|
||||
// an unverified recipient). See T12237. These details are still useful
|
||||
// because they'll appear in the mail logs and Mail web UI.
|
||||
|
||||
$reasons[] = pht(
|
||||
'Phabricator is also not configured to allow unknown external users '.
|
||||
'to send mail to the system using just an email address.');
|
||||
|
@ -174,14 +178,14 @@ abstract class PhabricatorMailReceiver extends Phobject {
|
|||
if ($user) {
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
|
||||
$reasons[] = pht(
|
||||
"Phabricator is misconfigured, the application email ".
|
||||
"'%s' is set to user '%s' but that user does not exist.",
|
||||
'Phabricator is misconfigured: the application email '.
|
||||
'"%s" is set to user "%s", but that user does not exist.',
|
||||
$application_email->getAddress(),
|
||||
$default_user_phid);
|
||||
}
|
||||
}
|
||||
|
||||
$reasons = implode("\n\n", $reasons);
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ final class PhabricatorMetaMTAAttachment extends Phobject {
|
|||
public function toDictionary() {
|
||||
return array(
|
||||
'filename' => $this->getFilename(),
|
||||
'mimetype' => $this->getMimetype(),
|
||||
'mimetype' => $this->getMimeType(),
|
||||
'data' => $this->getData(),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -951,6 +951,16 @@ final class PhabricatorMetaMTAMail
|
|||
}
|
||||
}
|
||||
|
||||
// Unless delivery was forced earlier (password resets, confirmation mail),
|
||||
// never send mail to unverified addresses.
|
||||
foreach ($actors as $phid => $actor) {
|
||||
if ($actor->getIsVerified()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$actor->setUndeliverable(PhabricatorMetaMTAActor::REASON_UNVERIFIED);
|
||||
}
|
||||
|
||||
return $actors;
|
||||
}
|
||||
|
||||
|
|
|
@ -153,6 +153,22 @@ final class PhabricatorMetaMTAMailTestCase extends PhabricatorTestCase {
|
|||
$this->assertTrue(
|
||||
in_array($phid, $mail->buildRecipientList()),
|
||||
'Recipients restored after tag preference removed.');
|
||||
|
||||
$email = id(new PhabricatorUserEmail())->loadOneWhere(
|
||||
'userPHID = %s AND isPrimary = 1',
|
||||
$phid);
|
||||
|
||||
$email->setIsVerified(0)->save();
|
||||
|
||||
$this->assertFalse(
|
||||
in_array($phid, $mail->buildRecipientList()),
|
||||
pht('Mail not sent to unverified address.'));
|
||||
|
||||
$email->setIsVerified(1)->save();
|
||||
|
||||
$this->assertTrue(
|
||||
in_array($phid, $mail->buildRecipientList()),
|
||||
pht('Mail sent to verified address.'));
|
||||
}
|
||||
|
||||
public function testThreadIDHeaders() {
|
||||
|
|
|
@ -9,9 +9,7 @@ final class PhabricatorOwnersConfiguredCustomField
|
|||
}
|
||||
|
||||
public function createFields($object) {
|
||||
$config = PhabricatorEnv::getEnvConfig(
|
||||
'owners.custom-field-definitions',
|
||||
array());
|
||||
$config = PhabricatorEnv::getEnvConfig('owners.custom-field-definitions');
|
||||
|
||||
$fields = PhabricatorStandardCustomField::buildStandardFields(
|
||||
$this,
|
||||
|
|
|
@ -292,7 +292,7 @@ final class PhabricatorPasteQuery
|
|||
foreach ($pastes as $paste) {
|
||||
$key = $this->getSnippetCacheKey($paste);
|
||||
if (isset($caches[$key])) {
|
||||
$snippet_data = phutil_json_decode($caches[$key], true);
|
||||
$snippet_data = phutil_json_decode($caches[$key]);
|
||||
$snippet = new PhabricatorPasteSnippet(
|
||||
phutil_safe_html($snippet_data['content']),
|
||||
$snippet_data['type'],
|
||||
|
|
|
@ -15,7 +15,7 @@ final class PhabricatorPasteTitleTransaction
|
|||
|
||||
public function getTitle() {
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNeWValue();
|
||||
$new = $this->getNewValue();
|
||||
|
||||
if (strlen($old) && strlen($new)) {
|
||||
return pht(
|
||||
|
@ -38,7 +38,7 @@ final class PhabricatorPasteTitleTransaction
|
|||
|
||||
public function getTitleForFeed() {
|
||||
$old = $this->getOldValue();
|
||||
$new = $this->getNeWValue();
|
||||
$new = $this->getNewValue();
|
||||
|
||||
if (strlen($old) && strlen($new)) {
|
||||
return pht(
|
||||
|
|
|
@ -103,6 +103,8 @@ abstract class PhabricatorPeopleProfileController
|
|||
|
||||
if ($user->getIsDisabled()) {
|
||||
$header->setStatus('fa-ban', 'red', pht('Disabled'));
|
||||
} else if (!$user->getIsEmailVerified()) {
|
||||
$header->setStatus('fa-envelope', 'red', pht('Email Not Verified'));
|
||||
} else {
|
||||
$header->setStatus($profile_icon, 'bluegrey', $profile_title);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ final class PhabricatorPeopleProfileViewController
|
|||
$home = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->addClass('project-view-home')
|
||||
->addClass('project-view-people-home')
|
||||
->setMainColumn(
|
||||
array(
|
||||
$properties,
|
||||
|
@ -87,8 +88,13 @@ final class PhabricatorPeopleProfileViewController
|
|||
return null;
|
||||
}
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('User Details'));
|
||||
|
||||
$view = id(new PHUIObjectBoxView())
|
||||
->appendChild($view)
|
||||
->setHeader($header)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->addClass('project-view-properties');
|
||||
|
||||
return $view;
|
||||
|
@ -143,7 +149,7 @@ final class PhabricatorPeopleProfileViewController
|
|||
$box = id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->appendChild($list)
|
||||
->setBackground(PHUIObjectBoxView::GREY);
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY);
|
||||
|
||||
return $box;
|
||||
}
|
||||
|
@ -217,7 +223,7 @@ final class PhabricatorPeopleProfileViewController
|
|||
->setHeader($header)
|
||||
->appendChild($day_view)
|
||||
->addClass('calendar-profile-box')
|
||||
->setBackground(PHUIObjectBoxView::GREY);
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY);
|
||||
|
||||
return $box;
|
||||
}
|
||||
|
@ -317,7 +323,7 @@ final class PhabricatorPeopleProfileViewController
|
|||
->setHeader($header)
|
||||
->addClass('project-view-badges')
|
||||
->appendChild($flex)
|
||||
->setBackground(PHUIObjectBoxView::GREY);
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY);
|
||||
|
||||
return $box;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ final class PhabricatorUserConfiguredCustomField
|
|||
public function createFields($object) {
|
||||
return PhabricatorStandardCustomField::buildStandardFields(
|
||||
$this,
|
||||
PhabricatorEnv::getEnvConfig('user.custom-field-definitions', array()));
|
||||
PhabricatorEnv::getEnvConfig('user.custom-field-definitions'));
|
||||
}
|
||||
|
||||
public function newStorageObject() {
|
||||
|
|
|
@ -150,7 +150,7 @@ final class PhabricatorMentionRemarkupRule extends PhutilRemarkupRule {
|
|||
$tag->addClass('phabricator-remarkup-mention-nopermission');
|
||||
}
|
||||
|
||||
if (!$user->isUserActivated()) {
|
||||
if (!$user->isResponsive()) {
|
||||
$tag->setDotColor(PHUITagView::COLOR_GREY);
|
||||
} else {
|
||||
if ($user->getAwayUntil()) {
|
||||
|
|
|
@ -61,7 +61,7 @@ final class PhabricatorPeopleUserPHIDType extends PhabricatorPHIDType {
|
|||
}
|
||||
|
||||
$availability = null;
|
||||
if (!$user->isUserActivated()) {
|
||||
if (!$user->isResponsive()) {
|
||||
$availability = PhabricatorObjectHandle::AVAILABILITY_DISABLED;
|
||||
} else {
|
||||
$until = $user->getAwayUntil();
|
||||
|
|
|
@ -120,6 +120,32 @@ final class PhabricatorUser
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Is this a user who we can reasonably expect to respond to requests?
|
||||
*
|
||||
* This is used to provide a grey "disabled/unresponsive" dot cue when
|
||||
* rendering handles and tags, so it isn't a surprise if you get ignored
|
||||
* when you ask things of users who will not receive notifications or could
|
||||
* not respond to them (because they are disabled, unapproved, do not have
|
||||
* verified email addresses, etc).
|
||||
*
|
||||
* @return bool True if this user can receive and respond to requests from
|
||||
* other humans.
|
||||
*/
|
||||
public function isResponsive() {
|
||||
if (!$this->isUserActivated()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->getIsEmailVerified()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public function canEstablishWebSessions() {
|
||||
if ($this->getIsMailingList()) {
|
||||
return false;
|
||||
|
|
|
@ -52,17 +52,44 @@ final class PhabricatorUserCardView extends AphrontTagView {
|
|||
|
||||
require_celerity_resource('project-card-view-css');
|
||||
|
||||
$profile_icon = PhabricatorPeopleIconSet::getIconIcon($profile->getIcon());
|
||||
$profile_title = $profile->getDisplayTitle();
|
||||
// We don't have a ton of room on the hovercard, so we're trying to show
|
||||
// the most important tag. Users can click through to the profile to get
|
||||
// more details.
|
||||
|
||||
if ($user->getIsDisabled()) {
|
||||
$tag_icon = 'fa-ban';
|
||||
$tag_title = pht('Disabled');
|
||||
$tag_shade = PHUITagView::COLOR_RED;
|
||||
} else if (!$user->getIsApproved()) {
|
||||
$tag_icon = 'fa-ban';
|
||||
$tag_title = pht('Unapproved Account');
|
||||
$tag_shade = PHUITagView::COLOR_RED;
|
||||
} else if (!$user->getIsEmailVerified()) {
|
||||
$tag_icon = 'fa-envelope';
|
||||
$tag_title = pht('Email Not Verified');
|
||||
$tag_shade = PHUITagView::COLOR_RED;
|
||||
} else if ($user->getIsAdmin()) {
|
||||
$tag_icon = 'fa-star';
|
||||
$tag_title = pht('Administrator');
|
||||
$tag_shade = PHUITagView::COLOR_INDIGO;
|
||||
} else {
|
||||
$tag_icon = PhabricatorPeopleIconSet::getIconIcon($profile->getIcon());
|
||||
$tag_title = $profile->getDisplayTitle();
|
||||
$tag_shade = null;
|
||||
}
|
||||
|
||||
$tag = id(new PHUITagView())
|
||||
->setIcon($profile_icon)
|
||||
->setName($profile_title)
|
||||
->addClass('project-view-header-tag')
|
||||
->setIcon($tag_icon)
|
||||
->setName($tag_title)
|
||||
->setType(PHUITagView::TYPE_SHADE);
|
||||
|
||||
if ($tag_shade !== null) {
|
||||
$tag->setShade($tag_shade);
|
||||
}
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(array($user->getFullName(), $tag))
|
||||
->setHeader($user->getFullName())
|
||||
->addTag($tag)
|
||||
->setUser($viewer)
|
||||
->setImage($picture);
|
||||
|
||||
|
@ -70,7 +97,7 @@ final class PhabricatorUserCardView extends AphrontTagView {
|
|||
|
||||
$body[] = $this->addItem(
|
||||
pht('User Since'),
|
||||
phabricator_date($profile->getDateCreated(), $viewer));
|
||||
phabricator_date($user->getDateCreated(), $viewer));
|
||||
|
||||
if (PhabricatorApplication::isClassInstalledForViewer(
|
||||
'PhabricatorCalendarApplication',
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue