diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 2db41f0a69..bb6aeb20a1 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -4648,6 +4648,7 @@ phutil_register_library_map(array( 'PhabricatorSearchEngineExtensionModule' => 'applications/search/engineextension/PhabricatorSearchEngineExtensionModule.php', 'PhabricatorSearchFerretNgramGarbageCollector' => 'applications/search/garbagecollector/PhabricatorSearchFerretNgramGarbageCollector.php', 'PhabricatorSearchField' => 'applications/search/field/PhabricatorSearchField.php', + 'PhabricatorSearchHandleController' => 'applications/search/controller/PhabricatorSearchHandleController.php', 'PhabricatorSearchHost' => 'infrastructure/cluster/search/PhabricatorSearchHost.php', 'PhabricatorSearchHovercardController' => 'applications/search/controller/PhabricatorSearchHovercardController.php', 'PhabricatorSearchIndexVersion' => 'applications/search/storage/PhabricatorSearchIndexVersion.php', @@ -4872,6 +4873,7 @@ phutil_register_library_map(array( 'PhabricatorSystemActionRateLimitException' => 'applications/system/exception/PhabricatorSystemActionRateLimitException.php', 'PhabricatorSystemApplication' => 'applications/system/application/PhabricatorSystemApplication.php', 'PhabricatorSystemDAO' => 'applications/system/storage/PhabricatorSystemDAO.php', + 'PhabricatorSystemDebugUIEventListener' => 'applications/system/events/PhabricatorSystemDebugUIEventListener.php', 'PhabricatorSystemDestructionGarbageCollector' => 'applications/system/garbagecollector/PhabricatorSystemDestructionGarbageCollector.php', 'PhabricatorSystemDestructionLog' => 'applications/system/storage/PhabricatorSystemDestructionLog.php', 'PhabricatorSystemObjectController' => 'applications/system/controller/PhabricatorSystemObjectController.php', @@ -11270,6 +11272,7 @@ phutil_register_library_map(array( 'PhabricatorSearchEngineExtensionModule' => 'PhabricatorConfigModule', 'PhabricatorSearchFerretNgramGarbageCollector' => 'PhabricatorGarbageCollector', 'PhabricatorSearchField' => 'Phobject', + 'PhabricatorSearchHandleController' => 'PhabricatorSearchBaseController', 'PhabricatorSearchHost' => 'Phobject', 'PhabricatorSearchHovercardController' => 'PhabricatorSearchBaseController', 'PhabricatorSearchIndexVersion' => 'PhabricatorSearchDAO', @@ -11511,6 +11514,7 @@ phutil_register_library_map(array( 'PhabricatorSystemActionRateLimitException' => 'Exception', 'PhabricatorSystemApplication' => 'PhabricatorApplication', 'PhabricatorSystemDAO' => 'PhabricatorLiskDAO', + 'PhabricatorSystemDebugUIEventListener' => 'PhabricatorEventListener', 'PhabricatorSystemDestructionGarbageCollector' => 'PhabricatorGarbageCollector', 'PhabricatorSystemDestructionLog' => 'PhabricatorSystemDAO', 'PhabricatorSystemObjectController' => 'PhabricatorController', diff --git a/src/applications/search/application/PhabricatorSearchApplication.php b/src/applications/search/application/PhabricatorSearchApplication.php index 3cf5923b9c..7547506258 100644 --- a/src/applications/search/application/PhabricatorSearchApplication.php +++ b/src/applications/search/application/PhabricatorSearchApplication.php @@ -33,6 +33,8 @@ final class PhabricatorSearchApplication extends PhabricatorApplication { 'index/(?P[^/]+)/' => 'PhabricatorSearchIndexController', 'hovercard/' => 'PhabricatorSearchHovercardController', + 'handle/(?P[^/]+)/' + => 'PhabricatorSearchHandleController', 'edit/' => array( 'key/(?P[^/]+)/' => 'PhabricatorSearchEditController', 'id/(?P[^/]+)/' => 'PhabricatorSearchEditController', diff --git a/src/applications/search/controller/PhabricatorSearchHandleController.php b/src/applications/search/controller/PhabricatorSearchHandleController.php new file mode 100644 index 0000000000..751b4e367d --- /dev/null +++ b/src/applications/search/controller/PhabricatorSearchHandleController.php @@ -0,0 +1,89 @@ +getViewer(); + $phid = $request->getURIData('phid'); + + $handles = $viewer->loadHandles(array($phid)); + $handle = $handles[$phid]; + + $cancel_uri = $handle->getURI(); + if (!$cancel_uri) { + $cancel_uri = '/'; + } + + $rows = array(); + + $rows[] = array( + pht('PHID'), + $phid, + ); + + $rows[] = array( + pht('PHID Type'), + phid_get_type($phid), + ); + + $rows[] = array( + pht('URI'), + $handle->getURI(), + ); + + $icon = $handle->getIcon(); + if ($icon !== null) { + $icon = id(new PHUIIconView()) + ->setIcon($handle->getIcon()); + } + + $rows[] = array( + pht('Icon'), + $icon, + ); + + $rows[] = array( + pht('Object Name'), + $handle->getObjectName(), + ); + + $rows[] = array( + pht('Name'), + $handle->getName(), + ); + + $rows[] = array( + pht('Full Name'), + $handle->getFullName(), + ); + + $rows[] = array( + pht('Tag'), + $handle->renderTag(), + ); + + $rows[] = array( + pht('Link'), + $handle->renderLink(), + ); + + $table = id(new AphrontTableView($rows)) + ->setColumnClasses( + array( + 'header', + 'wide', + )); + + return $this->newDialog() + ->setTitle(pht('Handle: %s', $phid)) + ->setWidth(AphrontDialogView::WIDTH_FORM) + ->appendChild($table) + ->addCancelButton($cancel_uri, pht('Done')); + } + +} diff --git a/src/applications/system/application/PhabricatorSystemApplication.php b/src/applications/system/application/PhabricatorSystemApplication.php index b6cc13050f..88f07ae17c 100644 --- a/src/applications/system/application/PhabricatorSystemApplication.php +++ b/src/applications/system/application/PhabricatorSystemApplication.php @@ -14,6 +14,12 @@ final class PhabricatorSystemApplication extends PhabricatorApplication { return true; } + public function getEventListeners() { + return array( + new PhabricatorSystemDebugUIEventListener(), + ); + } + public function getRoutes() { return array( '/status/' => 'PhabricatorStatusController', diff --git a/src/applications/system/events/PhabricatorSystemDebugUIEventListener.php b/src/applications/system/events/PhabricatorSystemDebugUIEventListener.php new file mode 100644 index 0000000000..18b94323b6 --- /dev/null +++ b/src/applications/system/events/PhabricatorSystemDebugUIEventListener.php @@ -0,0 +1,58 @@ +listen(PhabricatorEventType::TYPE_UI_DIDRENDERACTIONS); + } + + public function handleEvent(PhutilEvent $event) { + switch ($event->getType()) { + case PhabricatorEventType::TYPE_UI_DIDRENDERACTIONS: + $this->handleActionEvent($event); + break; + } + } + + private function handleActionEvent($event) { + $viewer = $event->getUser(); + $object = $event->getValue('object'); + + if (!PhabricatorEnv::getEnvConfig('phabricator.developer-mode')) { + return; + } + + if (!$object || !$object->getPHID()) { + // If we have no object, or the object doesn't have a PHID, we can't + // do anything useful. + return; + } + + $phid = $object->getPHID(); + + $submenu = array(); + + $submenu[] = id(new PhabricatorActionView()) + ->setIcon('fa-asterisk') + ->setName(pht('View Handle')) + ->setHref(urisprintf('/search/handle/%s/', $phid)) + ->setWorkflow(true); + + $submenu[] = id(new PhabricatorActionView()) + ->setIcon('fa-address-card-o') + ->setName(pht('View Hovercard')) + ->setHref(urisprintf('/search/hovercard/?phids[]=%s', $phid)); + + $developer_action = id(new PhabricatorActionView()) + ->setName(pht('Advanced/Developer...')) + ->setIcon('fa-magic') + ->setOrder(9001) + ->setSubmenu($submenu); + + $actions = $event->getValue('actions'); + $actions[] = $developer_action; + $event->setValue('actions', $actions); + } + +} diff --git a/src/view/layout/PhabricatorActionListView.php b/src/view/layout/PhabricatorActionListView.php index 134c336735..22e995ab64 100644 --- a/src/view/layout/PhabricatorActionListView.php +++ b/src/view/layout/PhabricatorActionListView.php @@ -52,6 +52,14 @@ final class PhabricatorActionListView extends AphrontTagView { $action->setViewer($viewer); } + $sort = array(); + foreach ($actions as $key => $action) { + $sort[$key] = id(new PhutilSortVector()) + ->addInt($action->getOrder()); + } + $sort = msortv($sort, 'getSelf'); + $actions = array_select_keys($actions, array_keys($sort)); + require_celerity_resource('phabricator-action-list-view-css'); $items = array();