diff --git a/src/applications/audit/controller/PhabricatorAuditController.php b/src/applications/audit/controller/PhabricatorAuditController.php index fe367bbdff..ad1b22d99e 100644 --- a/src/applications/audit/controller/PhabricatorAuditController.php +++ b/src/applications/audit/controller/PhabricatorAuditController.php @@ -1,25 +1,25 @@ getRequest()->getUser(); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); id(new PhabricatorCommitSearchEngine()) ->setViewer($user) ->addNavigationItems($nav->getMenu()); $nav->selectFilter(null); return $nav; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNavView()->getMenu(); } } diff --git a/src/applications/auth/controller/config/PhabricatorAuthProviderConfigController.php b/src/applications/auth/controller/config/PhabricatorAuthProviderConfigController.php index a52b0195d1..848d99cf76 100644 --- a/src/applications/auth/controller/config/PhabricatorAuthProviderConfigController.php +++ b/src/applications/auth/controller/config/PhabricatorAuthProviderConfigController.php @@ -1,38 +1,38 @@ setBaseURI(new PhutilURI($this->getApplicationURI())); if ($for_app) { $nav->addLabel(pht('Create')); $nav->addFilter('', pht('Add Authentication Provider'), $this->getApplicationURI('/config/new/')); } return $nav; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNavView($for_app = true)->getMenu(); } protected function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); $can_create = $this->hasApplicationCapability( AuthManageProvidersCapability::CAPABILITY); $crumbs->addAction( id(new PHUIListItemView()) ->setName(pht('Add Authentication Provider')) ->setHref($this->getApplicationURI('/config/new/')) ->setDisabled(!$can_create) ->setIcon('fa-plus-square')); return $crumbs; } } diff --git a/src/applications/base/controller/PhabricatorController.php b/src/applications/base/controller/PhabricatorController.php index 9fe102b9d7..16a92f2b16 100644 --- a/src/applications/base/controller/PhabricatorController.php +++ b/src/applications/base/controller/PhabricatorController.php @@ -1,577 +1,577 @@ shouldRequireLogin()) { return false; } if (!$this->shouldRequireEnabledUser()) { return false; } if ($this->shouldAllowPartialSessions()) { return false; } $user = $this->getRequest()->getUser(); if (!$user->getIsStandardUser()) { return false; } return PhabricatorEnv::getEnvConfig('security.require-multi-factor-auth'); } public function willBeginExecution() { $request = $this->getRequest(); if ($request->getUser()) { // NOTE: Unit tests can set a user explicitly. Normal requests are not // permitted to do this. PhabricatorTestCase::assertExecutingUnitTests(); $user = $request->getUser(); } else { $user = new PhabricatorUser(); $session_engine = new PhabricatorAuthSessionEngine(); $phsid = $request->getCookie(PhabricatorCookies::COOKIE_SESSION); if (strlen($phsid)) { $session_user = $session_engine->loadUserForSession( PhabricatorAuthSession::TYPE_WEB, $phsid); if ($session_user) { $user = $session_user; } } else { // If the client doesn't have a session token, generate an anonymous // session. This is used to provide CSRF protection to logged-out users. $phsid = $session_engine->establishSession( PhabricatorAuthSession::TYPE_WEB, null, $partial = false); // This may be a resource request, in which case we just don't set // the cookie. if ($request->canSetCookies()) { $request->setCookie(PhabricatorCookies::COOKIE_SESSION, $phsid); } } if (!$user->isLoggedIn()) { $user->attachAlternateCSRFString(PhabricatorHash::digest($phsid)); } $request->setUser($user); } $translation = $user->getTranslation(); if ($translation && $translation != PhabricatorEnv::getEnvConfig('translation.provider')) { $translation = newv($translation, array()); PhutilTranslator::getInstance() ->setLanguage($translation->getLanguage()) ->addTranslations($translation->getCleanTranslations()); } $preferences = $user->loadPreferences(); if (PhabricatorEnv::getEnvConfig('darkconsole.enabled')) { $dark_console = PhabricatorUserPreferences::PREFERENCE_DARK_CONSOLE; if ($preferences->getPreference($dark_console) || PhabricatorEnv::getEnvConfig('darkconsole.always-on')) { $console = new DarkConsoleCore(); $request->getApplicationConfiguration()->setConsole($console); } } // NOTE: We want to set up the user first so we can render a real page // here, but fire this before any real logic. $restricted = array( 'code', ); foreach ($restricted as $parameter) { if ($request->getExists($parameter)) { if (!$this->shouldAllowRestrictedParameter($parameter)) { throw new Exception( pht( 'Request includes restricted parameter "%s", but this '. 'controller ("%s") does not whitelist it. Refusing to '. 'serve this request because it might be part of a redirection '. 'attack.', $parameter, get_class($this))); } } } if ($this->shouldRequireEnabledUser()) { if ($user->isLoggedIn() && !$user->getIsApproved()) { $controller = new PhabricatorAuthNeedsApprovalController(); return $this->delegateToController($controller); } if ($user->getIsDisabled()) { $controller = new PhabricatorDisabledUserController(); return $this->delegateToController($controller); } } $event = new PhabricatorEvent( PhabricatorEventType::TYPE_CONTROLLER_CHECKREQUEST, array( 'request' => $request, 'controller' => $this, )); $event->setUser($user); PhutilEventEngine::dispatchEvent($event); $checker_controller = $event->getValue('controller'); if ($checker_controller != $this) { return $this->delegateToController($checker_controller); } $auth_class = 'PhabricatorAuthApplication'; $auth_application = PhabricatorApplication::getByClass($auth_class); // Require partial sessions to finish login before doing anything. if (!$this->shouldAllowPartialSessions()) { if ($user->hasSession() && $user->getSession()->getIsPartial()) { $login_controller = new PhabricatorAuthFinishController(); $this->setCurrentApplication($auth_application); return $this->delegateToController($login_controller); } } // Check if the user needs to configure MFA. $need_mfa = $this->shouldRequireMultiFactorEnrollment(); $have_mfa = $user->getIsEnrolledInMultiFactor(); if ($need_mfa && !$have_mfa) { // Check if the cache is just out of date. Otherwise, roadblock the user // and require MFA enrollment. $user->updateMultiFactorEnrollment(); if (!$user->getIsEnrolledInMultiFactor()) { $mfa_controller = new PhabricatorAuthNeedsMultiFactorController(); $this->setCurrentApplication($auth_application); return $this->delegateToController($mfa_controller); } } if ($this->shouldRequireLogin()) { // This actually means we need either: // - a valid user, or a public controller; and // - permission to see the application. $allow_public = $this->shouldAllowPublic() && PhabricatorEnv::getEnvConfig('policy.allow-public'); // If this controller isn't public, and the user isn't logged in, require // login. if (!$allow_public && !$user->isLoggedIn()) { $login_controller = new PhabricatorAuthStartController(); $this->setCurrentApplication($auth_application); return $this->delegateToController($login_controller); } if ($user->isLoggedIn()) { if ($this->shouldRequireEmailVerification()) { if (!$user->getIsEmailVerified()) { $controller = new PhabricatorMustVerifyEmailController(); $this->setCurrentApplication($auth_application); return $this->delegateToController($controller); } } } // If the user doesn't have access to the application, don't let them use // any of its controllers. We query the application in order to generate // a policy exception if the viewer doesn't have permission. $application = $this->getCurrentApplication(); if ($application) { id(new PhabricatorApplicationQuery()) ->setViewer($user) ->withPHIDs(array($application->getPHID())) ->executeOne(); } } // NOTE: We do this last so that users get a login page instead of a 403 // if they need to login. if ($this->shouldRequireAdmin() && !$user->getIsAdmin()) { return new Aphront403Response(); } } public function buildStandardPageView() { $view = new PhabricatorStandardPageView(); $view->setRequest($this->getRequest()); $view->setController($this); return $view; } public function buildStandardPageResponse($view, array $data) { $page = $this->buildStandardPageView(); $page->appendChild($view); $response = new AphrontWebpageResponse(); $response->setContent($page->render()); return $response; } public function getApplicationURI($path = '') { if (!$this->getCurrentApplication()) { throw new Exception('No application!'); } return $this->getCurrentApplication()->getApplicationURI($path); } public function buildApplicationPage($view, array $options) { $page = $this->buildStandardPageView(); $title = PhabricatorEnv::getEnvConfig('phabricator.serious-business') ? 'Phabricator' : pht('Bacon Ice Cream for Breakfast'); $application = $this->getCurrentApplication(); $page->setTitle(idx($options, 'title', $title)); if ($application) { $page->setApplicationName($application->getName()); if ($application->getTitleGlyph()) { $page->setGlyph($application->getTitleGlyph()); } } if (!($view instanceof AphrontSideNavFilterView)) { $nav = new AphrontSideNavFilterView(); $nav->appendChild($view); $view = $nav; } $user = $this->getRequest()->getUser(); $view->setUser($user); $page->appendChild($view); $object_phids = idx($options, 'pageObjects', array()); if ($object_phids) { $page->appendPageObjects($object_phids); foreach ($object_phids as $object_phid) { PhabricatorFeedStoryNotification::updateObjectNotificationViews( $user, $object_phid); } } if (idx($options, 'device', true)) { $page->setDeviceReady(true); } $page->setShowFooter(idx($options, 'showFooter', true)); $page->setShowChrome(idx($options, 'chrome', true)); $application_menu = $this->buildApplicationMenu(); if ($application_menu) { $page->setApplicationMenu($application_menu); } $response = new AphrontWebpageResponse(); return $response->setContent($page->render()); } public function didProcessRequest($response) { // If a bare DialogView is returned, wrap it in a DialogResponse. if ($response instanceof AphrontDialogView) { $response = id(new AphrontDialogResponse())->setDialog($response); } $request = $this->getRequest(); $response->setRequest($request); $seen = array(); while ($response instanceof AphrontProxyResponse) { $hash = spl_object_hash($response); if (isset($seen[$hash])) { $seen[] = get_class($response); throw new Exception( 'Cycle while reducing proxy responses: '. implode(' -> ', $seen)); } $seen[$hash] = get_class($response); $response = $response->reduceProxyResponse(); } if ($response instanceof AphrontDialogResponse) { if (!$request->isAjax()) { $dialog = $response->getDialog(); $title = $dialog->getTitle(); $short = $dialog->getShortTitle(); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(coalesce($short, $title)); $page_content = array( $crumbs, $response->buildResponseString(), ); $view = id(new PhabricatorStandardPageView()) ->setRequest($request) ->setController($this) ->setDeviceReady(true) ->setTitle($title) ->appendChild($page_content); $response = id(new AphrontWebpageResponse()) ->setContent($view->render()) ->setHTTPResponseCode($response->getHTTPResponseCode()); } else { $response->getDialog()->setIsStandalone(true); return id(new AphrontAjaxResponse()) ->setContent(array( 'dialog' => $response->buildResponseString(), )); } } else if ($response instanceof AphrontRedirectResponse) { if ($request->isAjax()) { return id(new AphrontAjaxResponse()) ->setContent( array( 'redirect' => $response->getURI(), )); } } return $response; } protected function getHandle($phid) { if (empty($this->handles[$phid])) { throw new Exception( "Attempting to access handle which wasn't loaded: {$phid}"); } return $this->handles[$phid]; } protected function loadHandles(array $phids) { $phids = array_filter($phids); $this->handles = $this->loadViewerHandles($phids); return $this; } protected function getLoadedHandles() { return $this->handles; } protected function loadViewerHandles(array $phids) { return id(new PhabricatorHandleQuery()) ->setViewer($this->getRequest()->getUser()) ->withPHIDs($phids) ->execute(); } /** * Render a list of links to handles, identified by PHIDs. The handles must * already be loaded. * * @param list List of PHIDs to render links to. * @param string Style, one of "\n" (to put each item on its own line) * or "," (to list items inline, separated by commas). * @return string Rendered list of handle links. */ protected function renderHandlesForPHIDs(array $phids, $style = "\n") { $style_map = array( "\n" => phutil_tag('br'), ',' => ', ', ); if (empty($style_map[$style])) { throw new Exception("Unknown handle list style '{$style}'!"); } return implode_selected_handle_links($style_map[$style], $this->getLoadedHandles(), array_filter($phids)); } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return null; } protected function buildApplicationCrumbs() { $crumbs = array(); $application = $this->getCurrentApplication(); if ($application) { $sprite = $application->getIconName(); if (!$sprite) { $sprite = 'application'; } $crumbs[] = id(new PhabricatorCrumbView()) ->setHref($this->getApplicationURI()) ->setAural($application->getName()) ->setIcon($sprite); } $view = new PhabricatorCrumbsView(); foreach ($crumbs as $crumb) { $view->addCrumb($crumb); } return $view; } protected function hasApplicationCapability($capability) { return PhabricatorPolicyFilter::hasCapability( $this->getRequest()->getUser(), $this->getCurrentApplication(), $capability); } protected function requireApplicationCapability($capability) { PhabricatorPolicyFilter::requireCapability( $this->getRequest()->getUser(), $this->getCurrentApplication(), $capability); } protected function explainApplicationCapability( $capability, $positive_message, $negative_message) { $can_act = $this->hasApplicationCapability($capability); if ($can_act) { $message = $positive_message; $icon_name = 'fa-play-circle-o lightgreytext'; } else { $message = $negative_message; $icon_name = 'fa-lock'; } $icon = id(new PHUIIconView()) ->setIconFont($icon_name); require_celerity_resource('policy-css'); $phid = $this->getCurrentApplication()->getPHID(); $explain_uri = "/policy/explain/{$phid}/{$capability}/"; $message = phutil_tag( 'div', array( 'class' => 'policy-capability-explanation', ), array( $icon, javelin_tag( 'a', array( 'href' => $explain_uri, 'sigil' => 'workflow', ), $message), )); return array($can_act, $message); } public function getDefaultResourceSource() { return 'phabricator'; } /** * Create a new @{class:AphrontDialogView} with defaults filled in. * * @return AphrontDialogView New dialog. */ public function newDialog() { $submit_uri = new PhutilURI($this->getRequest()->getRequestURI()); $submit_uri = $submit_uri->getPath(); return id(new AphrontDialogView()) ->setUser($this->getRequest()->getUser()) ->setSubmitURI($submit_uri); } protected function buildTransactionTimeline( PhabricatorApplicationTransactionInterface $object, PhabricatorApplicationTransactionQuery $query, PhabricatorMarkupEngine $engine = null, $render_data = array()) { $viewer = $this->getRequest()->getUser(); $xaction = $object->getApplicationTransactionTemplate(); $view = $xaction->getApplicationTransactionViewObject(); $pager = id(new AphrontCursorPagerView()) ->readFromRequest($this->getRequest()) ->setURI(new PhutilURI( '/transactions/showolder/'.$object->getPHID().'/')); $xactions = $query ->setViewer($viewer) ->withObjectPHIDs(array($object->getPHID())) ->needComments(true) ->setReversePaging(false) ->executeWithCursorPager($pager); $xactions = array_reverse($xactions); if ($engine) { foreach ($xactions as $xaction) { if ($xaction->getComment()) { $engine->addObject( $xaction->getComment(), PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT); } } $engine->process(); $view->setMarkupEngine($engine); } $timeline = $view ->setUser($viewer) ->setObjectPHID($object->getPHID()) ->setTransactions($xactions) ->setPager($pager) ->setRenderData($render_data) ->setQuoteTargetID($this->getRequest()->getStr('quoteTargetID')) ->setQuoteRef($this->getRequest()->getStr('quoteRef')); $object->willRenderTimeline($timeline, $this->getRequest()); return $timeline; } } diff --git a/src/applications/calendar/controller/PhabricatorCalendarController.php b/src/applications/calendar/controller/PhabricatorCalendarController.php index 4f591329b6..49eab46623 100644 --- a/src/applications/calendar/controller/PhabricatorCalendarController.php +++ b/src/applications/calendar/controller/PhabricatorCalendarController.php @@ -1,39 +1,39 @@ setBaseURI(new PhutilURI($this->getApplicationURI())); $nav->addLabel(pht('Calendar')); $nav->addFilter('/', pht('My Events')); $nav->addFilter('all/', pht('View All')); $nav->addFilter('event/create/', pht('Create Event')); if ($status && $status->getID()) { $nav->addFilter('event/edit/'.$status->getID().'/', pht('Edit Event')); } $nav->addFilter('event/', pht('Upcoming Events')); return $nav; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNavView()->getMenu(); } protected function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); $crumbs->addAction( id(new PHUIListItemView()) ->setName(pht('Create Event')) ->setHref($this->getApplicationURI().'event/create') ->setIcon('fa-plus-square')); return $crumbs; } } diff --git a/src/applications/conduit/controller/PhabricatorConduitController.php b/src/applications/conduit/controller/PhabricatorConduitController.php index c7ceaf4ce6..4643511952 100644 --- a/src/applications/conduit/controller/PhabricatorConduitController.php +++ b/src/applications/conduit/controller/PhabricatorConduitController.php @@ -1,27 +1,27 @@ getRequest()->getUser(); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); id(new PhabricatorConduitSearchEngine()) ->setViewer($viewer) ->addNavigationItems($nav->getMenu()); $nav->addLabel('Logs'); $nav->addFilter('log', pht('Call Logs')); $nav->selectFilter(null); return $nav; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNavView()->getMenu(); } } diff --git a/src/applications/config/controller/PhabricatorConfigController.php b/src/applications/config/controller/PhabricatorConfigController.php index b892d5eb80..43c5ee0da8 100644 --- a/src/applications/config/controller/PhabricatorConfigController.php +++ b/src/applications/config/controller/PhabricatorConfigController.php @@ -1,33 +1,33 @@ getRequest()->getUser(); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); $nav->addLabel(pht('Configuration')); $nav->addFilter('/', pht('Browse Settings')); $nav->addFilter('all/', pht('All Settings')); $nav->addFilter('history/', pht('Settings History')); $nav->addLabel(pht('Setup')); $nav->addFilter('issue/', pht('Setup Issues')); $nav->addLabel(pht('Database')); $nav->addFilter('database/', pht('Database Status')); $nav->addFilter('dbissue/', pht('Database Issues')); $nav->addLabel(pht('Welcome')); $nav->addFilter('welcome/', pht('Welcome Screen')); return $nav; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNavView(null, true)->getMenu(); } } diff --git a/src/applications/conpherence/controller/ConpherenceController.php b/src/applications/conpherence/controller/ConpherenceController.php index 268d2210ad..deef52267d 100644 --- a/src/applications/conpherence/controller/ConpherenceController.php +++ b/src/applications/conpherence/controller/ConpherenceController.php @@ -1,155 +1,155 @@ newLink( pht('New Message'), $this->getApplicationURI('new/')); $nav->addMenuItem( id(new PHUIListItemView()) ->setName(pht('Add Participants')) ->setType(PHUIListItemView::TYPE_LINK) ->setHref('#') ->addSigil('conpherence-widget-adder') ->setMetadata(array('widget' => 'widgets-people'))); $nav->addMenuItem( id(new PHUIListItemView()) ->setName(pht('New Calendar Item')) ->setType(PHUIListItemView::TYPE_LINK) ->setHref('/calendar/event/create/') ->addSigil('conpherence-widget-adder') ->setMetadata(array('widget' => 'widgets-calendar'))); return $nav; } protected function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); $crumbs ->addAction( id(new PHUIListItemView()) ->setName(pht('New Message')) ->setHref($this->getApplicationURI('new/')) ->setIcon('fa-plus-square') ->setWorkflow(true)) ->addAction( id(new PHUIListItemView()) ->setName(pht('Thread')) ->setHref('#') ->setIcon('fa-bars') ->setStyle('display: none;') ->addClass('device-widgets-selector') ->addSigil('device-widgets-selector')); return $crumbs; } protected function buildHeaderPaneContent(ConpherenceThread $conpherence) { $crumbs = $this->buildApplicationCrumbs(); if ($conpherence->getTitle()) { $title = $conpherence->getTitle(); } else { $title = pht('[No Title]'); } $crumbs->addCrumb( id(new PhabricatorCrumbView()) ->setName($title) ->setHref($this->getApplicationURI('update/'.$conpherence->getID().'/')) ->setWorkflow(true)); return hsprintf( '%s', array( phutil_tag( 'div', array( 'class' => 'header-loading-mask', ), ''), $crumbs, )); } protected function renderConpherenceTransactions( ConpherenceThread $conpherence) { $user = $this->getRequest()->getUser(); $transactions = $conpherence->getTransactions(); $oldest_transaction_id = 0; $too_many = ConpherenceThreadQuery::TRANSACTION_LIMIT + 1; if (count($transactions) == $too_many) { $last_transaction = end($transactions); unset($transactions[$last_transaction->getID()]); $oldest_transaction = end($transactions); $oldest_transaction_id = $oldest_transaction->getID(); } $transactions = array_reverse($transactions); $handles = $conpherence->getHandles(); $rendered_transactions = array(); $engine = id(new PhabricatorMarkupEngine()) ->setViewer($user); foreach ($transactions as $key => $transaction) { if ($transaction->shouldHide()) { unset($transactions[$key]); continue; } if ($transaction->getComment()) { $engine->addObject( $transaction->getComment(), PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT); } } $engine->process(); // we're going to insert a dummy date marker transaction for breaks // between days. some setup required! $previous_transaction = null; $date_marker_transaction = id(new ConpherenceTransaction()) ->setTransactionType(ConpherenceTransactionType::TYPE_DATE_MARKER) ->makeEphemeral(); $date_marker_transaction_view = id(new ConpherenceTransactionView()) ->setUser($user) ->setConpherenceTransaction($date_marker_transaction) ->setHandles($handles) ->setMarkupEngine($engine); foreach ($transactions as $transaction) { if ($previous_transaction) { $previous_day = phabricator_format_local_time( $previous_transaction->getDateCreated(), $user, 'Ymd'); $current_day = phabricator_format_local_time( $transaction->getDateCreated(), $user, 'Ymd'); // date marker transaction time! if ($previous_day != $current_day) { $date_marker_transaction->setDateCreated( $transaction->getDateCreated()); $rendered_transactions[] = $date_marker_transaction_view->render(); } } $rendered_transactions[] = id(new ConpherenceTransactionView()) ->setUser($user) ->setConpherenceTransaction($transaction) ->setHandles($handles) ->setMarkupEngine($engine) ->render(); $previous_transaction = $transaction; } $latest_transaction_id = $transaction->getID(); return array( 'transactions' => $rendered_transactions, 'latest_transaction_id' => $latest_transaction_id, 'oldest_transaction_id' => $oldest_transaction_id, ); } } diff --git a/src/applications/countdown/controller/PhabricatorCountdownController.php b/src/applications/countdown/controller/PhabricatorCountdownController.php index 31f1543b78..3817f2b1d8 100644 --- a/src/applications/countdown/controller/PhabricatorCountdownController.php +++ b/src/applications/countdown/controller/PhabricatorCountdownController.php @@ -1,40 +1,40 @@ getRequest()->getUser(); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); if ($for_app) { $nav->addFilter('create', pht('Create Countdown')); } id(new PhabricatorCountdownSearchEngine()) ->setViewer($user) ->addNavigationItems($nav->getMenu()); $nav->selectFilter(null); return $nav; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNavView($for_app = true)->getMenu(); } protected function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); $crumbs->addAction( id(new PHUIListItemView()) ->setName(pht('Create Countdown')) ->setHref($this->getApplicationURI('edit/')) ->setIcon('fa-plus-square')); return $crumbs; } } diff --git a/src/applications/differential/controller/DifferentialController.php b/src/applications/differential/controller/DifferentialController.php index 9c366c7c74..964f989ae5 100644 --- a/src/applications/differential/controller/DifferentialController.php +++ b/src/applications/differential/controller/DifferentialController.php @@ -1,36 +1,36 @@ addAction( id(new PHUIListItemView()) ->setHref($this->getApplicationURI('/diff/create/')) ->setName(pht('Create Diff')) ->setIcon('fa-plus-square')); return $crumbs; } public function buildSideNavView($for_app = false) { $viewer = $this->getRequest()->getUser(); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); id(new DifferentialRevisionSearchEngine()) ->setViewer($viewer) ->addNavigationItems($nav->getMenu()); $nav->selectFilter(null); return $nav; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNavView(true)->getMenu(); } } diff --git a/src/applications/diviner/controller/DivinerController.php b/src/applications/diviner/controller/DivinerController.php index 691581ff42..cf4c9e197c 100644 --- a/src/applications/diviner/controller/DivinerController.php +++ b/src/applications/diviner/controller/DivinerController.php @@ -1,55 +1,55 @@ buildMenu(); return AphrontSideNavFilterView::newFromMenu($menu); } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildMenu(); } private function buildMenu() { $menu = new PHUIListView(); id(new DivinerAtomSearchEngine()) ->setViewer($this->getRequest()->getUser()) ->addNavigationItems($menu); return $menu; } protected function renderAtomList(array $symbols) { assert_instances_of($symbols, 'DivinerLiveSymbol'); $request = $this->getRequest(); $user = $request->getUser(); $list = array(); foreach ($symbols as $symbol) { switch ($symbol->getType()) { case DivinerAtom::TYPE_FUNCTION: $title = $symbol->getTitle().'()'; break; default: $title = $symbol->getTitle(); break; } $item = id(new DivinerBookItemView()) ->setTitle($title) ->setHref($symbol->getURI()) ->setSubtitle($symbol->getSummary()) ->setType(DivinerAtom::getAtomTypeNameString( $symbol->getType())); $list[] = $item; } return $list; } } diff --git a/src/applications/drydock/controller/DrydockController.php b/src/applications/drydock/controller/DrydockController.php index f8ee24f18e..8f79c89897 100644 --- a/src/applications/drydock/controller/DrydockController.php +++ b/src/applications/drydock/controller/DrydockController.php @@ -1,11 +1,11 @@ buildSideNavView()->getMenu(); } } diff --git a/src/applications/feed/controller/PhabricatorFeedController.php b/src/applications/feed/controller/PhabricatorFeedController.php index f698af41fb..ce7a9afe76 100644 --- a/src/applications/feed/controller/PhabricatorFeedController.php +++ b/src/applications/feed/controller/PhabricatorFeedController.php @@ -1,44 +1,44 @@ buildStandardPageView(); $page->setApplicationName(pht('Feed')); $page->setBaseURI('/feed/'); $page->setTitle(idx($data, 'title')); $page->setGlyph("\xE2\x88\x9E"); $page->appendChild($view); $response = new AphrontWebpageResponse(); if (!empty($data['public'])) { $page->setFrameable(true); $page->setShowChrome(false); $response->setFrameable(true); } return $response->setContent($page->render()); } protected function buildSideNavView() { $user = $this->getRequest()->getUser(); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); id(new PhabricatorFeedSearchEngine()) ->setViewer($user) ->addNavigationItems($nav->getMenu()); $nav->selectFilter(null); return $nav; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNavView()->getMenu(); } } diff --git a/src/applications/files/controller/PhabricatorFileController.php b/src/applications/files/controller/PhabricatorFileController.php index bbdbd21e07..48d0445a55 100644 --- a/src/applications/files/controller/PhabricatorFileController.php +++ b/src/applications/files/controller/PhabricatorFileController.php @@ -1,29 +1,29 @@ buildMenu($for_devices = false); return AphrontSideNavFilterView::newFromMenu($menu); } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildMenu($for_devices = true); } private function buildMenu($for_devices) { $menu = new PHUIListView(); if ($for_devices) { $menu->newLink(pht('Upload File'), $this->getApplicationURI('/upload/')); } id(new PhabricatorFileSearchEngine()) ->setViewer($this->getRequest()->getUser()) ->addNavigationItems($menu); return $menu; } } diff --git a/src/applications/harbormaster/controller/HarbormasterBuildableListController.php b/src/applications/harbormaster/controller/HarbormasterBuildableListController.php index 7e8808da9f..aac41dc57b 100644 --- a/src/applications/harbormaster/controller/HarbormasterBuildableListController.php +++ b/src/applications/harbormaster/controller/HarbormasterBuildableListController.php @@ -1,46 +1,46 @@ queryKey = idx($data, 'queryKey'); } public function processRequest() { $controller = id(new PhabricatorApplicationSearchController()) ->setQueryKey($this->queryKey) ->setSearchEngine(new HarbormasterBuildableSearchEngine()) ->setNavigation($this->buildSideNavView()); return $this->delegateToController($controller); } public function buildSideNavView($for_app = false) { $user = $this->getRequest()->getUser(); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); id(new HarbormasterBuildableSearchEngine()) ->setViewer($user) ->addNavigationItems($nav->getMenu()); $nav->addLabel(pht('Build Plans')); $nav->addFilter('plan/', pht('Manage Build Plans')); $nav->selectFilter(null); return $nav; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNavView(true)->getMenu(); } } diff --git a/src/applications/harbormaster/controller/HarbormasterPlanListController.php b/src/applications/harbormaster/controller/HarbormasterPlanListController.php index c88e971ce1..0e2cb3e233 100644 --- a/src/applications/harbormaster/controller/HarbormasterPlanListController.php +++ b/src/applications/harbormaster/controller/HarbormasterPlanListController.php @@ -1,47 +1,47 @@ queryKey = idx($data, 'queryKey'); } public function processRequest() { $controller = id(new PhabricatorApplicationSearchController()) ->setQueryKey($this->queryKey) ->setSearchEngine(new HarbormasterBuildPlanSearchEngine()) ->setNavigation($this->buildSideNavView()); return $this->delegateToController($controller); } public function buildSideNavView($for_app = false) { $user = $this->getRequest()->getUser(); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); if ($for_app) { $nav->addFilter('new/', pht('New Build Plan')); } id(new HarbormasterBuildPlanSearchEngine()) ->setViewer($user) ->addNavigationItems($nav->getMenu()); $nav->selectFilter(null); return $nav; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNavView(true)->getMenu(); } } diff --git a/src/applications/herald/controller/HeraldController.php b/src/applications/herald/controller/HeraldController.php index cb71518f30..71d7c3b3b9 100644 --- a/src/applications/herald/controller/HeraldController.php +++ b/src/applications/herald/controller/HeraldController.php @@ -1,60 +1,60 @@ buildStandardPageView(); $page->setApplicationName(pht('Herald')); $page->setBaseURI('/herald/'); $page->setTitle(idx($data, 'title')); $page->setGlyph("\xE2\x98\xBF"); $page->appendChild($view); $response = new AphrontWebpageResponse(); return $response->setContent($page->render()); } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNavView(true)->getMenu(); } protected function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); $crumbs->addAction( id(new PHUIListItemView()) ->setName(pht('Create Herald Rule')) ->setHref($this->getApplicationURI('new/')) ->setIcon('fa-plus-square')); return $crumbs; } public function buildSideNavView($for_app = false) { $user = $this->getRequest()->getUser(); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); if ($for_app) { $nav->addFilter('new', pht('Create Rule')); } id(new HeraldRuleSearchEngine()) ->setViewer($user) ->addNavigationItems($nav->getMenu()); $nav ->addLabel(pht('Utilities')) ->addFilter('test', pht('Test Console')) ->addFilter('transcript', pht('Transcripts')) ->addFilter('history', pht('Edit Log')); $nav->selectFilter(null); return $nav; } } diff --git a/src/applications/legalpad/controller/LegalpadController.php b/src/applications/legalpad/controller/LegalpadController.php index e4a4aa0078..fbfb7038f4 100644 --- a/src/applications/legalpad/controller/LegalpadController.php +++ b/src/applications/legalpad/controller/LegalpadController.php @@ -1,29 +1,29 @@ getRequest()->getUser(); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); if ($for_app) { $nav->addFilter('create/', pht('Create Document')); } id(new LegalpadDocumentSearchEngine()) ->setViewer($user) ->addNavigationItems($nav->getMenu()); $nav->addLabel(pht('Signatures')); $nav->addFilter('signatures/', pht('Find Signatures')); return $nav; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNav(true)->getMenu(); } } diff --git a/src/applications/macro/controller/PhabricatorMacroController.php b/src/applications/macro/controller/PhabricatorMacroController.php index 75f57241dc..eb20975a85 100644 --- a/src/applications/macro/controller/PhabricatorMacroController.php +++ b/src/applications/macro/controller/PhabricatorMacroController.php @@ -1,44 +1,44 @@ setBaseURI(new PhutilURI($this->getApplicationURI())); if ($for_app) { $nav->addLabel(pht('Create')); $nav->addFilter('', pht('Create Macro'), $this->getApplicationURI('/create/')); } id(new PhabricatorMacroSearchEngine()) ->setViewer($this->getRequest()->getUser()) ->addNavigationItems($nav->getMenu()); return $nav; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNavView($for_app = true)->getMenu(); } protected function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); $can_manage = $this->hasApplicationCapability( PhabricatorMacroManageCapability::CAPABILITY); $crumbs->addAction( id(new PHUIListItemView()) ->setName(pht('Create Macro')) ->setHref($this->getApplicationURI('/create/')) ->setIcon('fa-plus-square') ->setDisabled(!$can_manage) ->setWorkflow(!$can_manage)); return $crumbs; } } diff --git a/src/applications/mailinglists/controller/PhabricatorMailingListsController.php b/src/applications/mailinglists/controller/PhabricatorMailingListsController.php index 8bda8c0365..97aa339456 100644 --- a/src/applications/mailinglists/controller/PhabricatorMailingListsController.php +++ b/src/applications/mailinglists/controller/PhabricatorMailingListsController.php @@ -1,40 +1,40 @@ getRequest()->getUser(); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); if ($for_app) { $nav->addFilter('edit', pht('Create List')); } id(new PhabricatorMailingListSearchEngine()) ->setViewer($user) ->addNavigationItems($nav->getMenu()); $nav->selectFilter(null); return $nav; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNavView(true)->getMenu(); } protected function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); $crumbs->addAction( id(new PHUIListItemView()) ->setName(pht('Create List')) ->setHref($this->getApplicationURI('edit/')) ->setIcon('fa-plus-square')); return $crumbs; } } diff --git a/src/applications/meta/controller/PhabricatorApplicationsController.php b/src/applications/meta/controller/PhabricatorApplicationsController.php index 8dac4d878a..e5b035bab4 100644 --- a/src/applications/meta/controller/PhabricatorApplicationsController.php +++ b/src/applications/meta/controller/PhabricatorApplicationsController.php @@ -1,24 +1,24 @@ getRequest()->getUser(); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); id(new PhabricatorAppSearchEngine()) ->setViewer($user) ->addNavigationItems($nav->getMenu()); $nav->selectFilter(null); return $nav; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNavView(true)->getMenu(); } } diff --git a/src/applications/owners/controller/PhabricatorOwnersController.php b/src/applications/owners/controller/PhabricatorOwnersController.php index 78deab1942..65b0292cb0 100644 --- a/src/applications/owners/controller/PhabricatorOwnersController.php +++ b/src/applications/owners/controller/PhabricatorOwnersController.php @@ -1,69 +1,69 @@ filter; } protected function setSideNavFilter($filter) { $this->filter = $filter; return $this; } public function buildSideNavView() { $nav = new AphrontSideNavFilterView(); $base_uri = new PhutilURI('/owners/'); $nav->setBaseURI($base_uri); $nav->addLabel(pht('Packages')); $this->getExtraPackageViews($nav); $nav->addFilter('view/owned', pht('Owned')); $nav->addFilter('view/projects', pht('Projects')); $nav->addFilter('view/all', pht('All')); $nav->selectFilter($this->getSideNavFilter(), 'view/owned'); $filter = $nav->getSelectedFilter(); switch ($filter) { case 'view/owned': $title = pht('Owned Packages'); break; case 'view/all': $title = pht('All Packages'); break; case 'view/projects': $title = pht('Projects'); break; case 'new': $title = pht('New Package'); break; default: $title = pht('Package'); break; } $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb($title); $crumbs->addAction( id(new PHUIListItemView()) ->setName(pht('Create Package')) ->setHref('/owners/new/') ->setIcon('fa-plus-square')); $nav->setCrumbs($crumbs); return $nav; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNavView()->getMenu(); } protected function getExtraPackageViews(AphrontSideNavFilterView $view) { return; } } diff --git a/src/applications/passphrase/controller/PassphraseController.php b/src/applications/passphrase/controller/PassphraseController.php index b05c243b1d..5be0c31a63 100644 --- a/src/applications/passphrase/controller/PassphraseController.php +++ b/src/applications/passphrase/controller/PassphraseController.php @@ -1,40 +1,40 @@ getRequest()->getUser(); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); if ($for_app) { $nav->addFilter('create', pht('Create Credential')); } id(new PassphraseCredentialSearchEngine()) ->setViewer($user) ->addNavigationItems($nav->getMenu()); $nav->selectFilter(null); return $nav; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNavView(true)->getMenu(); } protected function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); $crumbs->addAction( id(new PHUIListItemView()) ->setName(pht('Create Credential')) ->setHref($this->getApplicationURI('create/')) ->setIcon('fa-plus-square')); return $crumbs; } } diff --git a/src/applications/paste/controller/PhabricatorPasteController.php b/src/applications/paste/controller/PhabricatorPasteController.php index bdd7492342..4956e89c28 100644 --- a/src/applications/paste/controller/PhabricatorPasteController.php +++ b/src/applications/paste/controller/PhabricatorPasteController.php @@ -1,54 +1,54 @@ getRequest()->getUser(); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); if ($for_app) { $nav->addFilter('create', pht('Create Paste')); } id(new PhabricatorPasteSearchEngine()) ->setViewer($user) ->addNavigationItems($nav->getMenu()); $nav->selectFilter(null); return $nav; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNavView(true)->getMenu(); } protected function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); $crumbs->addAction( id(new PHUIListItemView()) ->setName(pht('Create Paste')) ->setHref($this->getApplicationURI('create/')) ->setIcon('fa-plus-square')); return $crumbs; } public function buildSourceCodeView( PhabricatorPaste $paste, $max_lines = null, $highlights = array()) { $lines = phutil_split_lines($paste->getContent()); return id(new PhabricatorSourceCodeView()) ->setLimit($max_lines) ->setLines($lines) ->setHighlights($highlights) ->setURI(new PhutilURI($paste->getURI())); } } diff --git a/src/applications/people/controller/PhabricatorPeopleController.php b/src/applications/people/controller/PhabricatorPeopleController.php index 647788a5e3..32e2fcd713 100644 --- a/src/applications/people/controller/PhabricatorPeopleController.php +++ b/src/applications/people/controller/PhabricatorPeopleController.php @@ -1,52 +1,52 @@ setBaseURI(new PhutilURI($this->getApplicationURI())); $viewer = $this->getRequest()->getUser(); id(new PhabricatorPeopleSearchEngine()) ->setViewer($viewer) ->addNavigationItems($nav->getMenu()); if ($viewer->getIsAdmin()) { $nav->addLabel(pht('User Administration')); if (PhabricatorLDAPAuthProvider::getLDAPProvider()) { $nav->addFilter('ldap', pht('Import from LDAP')); } $nav->addFilter('logs', pht('Activity Logs')); } return $nav; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNavView()->getMenu(); } protected function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); $viewer = $this->getRequest()->getUser(); $can_create = $this->hasApplicationCapability( PeopleCreateUsersCapability::CAPABILITY); $crumbs->addAction( id(new PHUIListItemView()) ->setName(pht('Create New User')) ->setHref($this->getApplicationURI('create/')) ->setDisabled(!$can_create) ->setIcon('fa-plus-square')); return $crumbs; } } diff --git a/src/applications/phame/controller/PhameController.php b/src/applications/phame/controller/PhameController.php index d01554b7b9..0b70597548 100644 --- a/src/applications/phame/controller/PhameController.php +++ b/src/applications/phame/controller/PhameController.php @@ -1,124 +1,124 @@ getApplicationURI()); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI($base_uri); $nav->addLabel(pht('Create')); $nav->addFilter('post/new', pht('New Post')); $nav->addFilter('blog/new', pht('New Blog')); $nav->addLabel(pht('Posts')); $nav->addFilter('post/draft', pht('My Drafts')); $nav->addFilter('post', pht('My Posts')); $nav->addFilter('post/all', pht('All Posts')); $nav->addLabel(pht('Blogs')); $nav->addFilter('blog/user', pht('Joinable Blogs')); $nav->addFilter('blog/all', pht('All Blogs')); $nav->selectFilter(null); return $nav; } protected function renderPostList( array $posts, PhabricatorUser $viewer, $nodata) { assert_instances_of($posts, 'PhamePost'); $stories = array(); foreach ($posts as $post) { $blogger = $this->getHandle($post->getBloggerPHID())->renderLink(); $blogger_uri = $this->getHandle($post->getBloggerPHID())->getURI(); $blogger_image = $this->getHandle($post->getBloggerPHID())->getImageURI(); $blog = null; if ($post->getBlog()) { $blog = $this->getHandle($post->getBlog()->getPHID())->renderLink(); } $phame_post = ''; if ($post->getBody()) { $phame_post = PhabricatorMarkupEngine::summarize($post->getBody()); } $blog_view = $post->getViewURI(); $phame_title = phutil_tag('a', array('href' => $blog_view), $post->getTitle()); $blogger = phutil_tag('strong', array(), $blogger); if ($post->isDraft()) { $title = pht('%s drafted a blog post on %s.', $blogger, $blog); $title = phutil_tag('em', array(), $title); } else { $title = pht('%s wrote a blog post on %s.', $blogger, $blog); } $item = id(new PHUIObjectItemView()) ->setObject($post) ->setHeader($post->getTitle()) ->setHref($this->getApplicationURI('post/view/'.$post->getID().'/')); $story = id(new PHUIFeedStoryView()) ->setTitle($title) ->setImage($blogger_image) ->setImageHref($blogger_uri) ->setAppIcon('phame-dark') ->setUser($viewer) ->setPontification($phame_post, $phame_title); if (PhabricatorPolicyFilter::hasCapability( $viewer, $post, PhabricatorPolicyCapability::CAN_EDIT)) { $story->addAction(id(new PHUIIconView()) ->setHref($this->getApplicationURI('post/edit/'.$post->getID().'/')) ->setIconFont('fa-pencil')); } if ($post->getDatePublished()) { $story->setEpoch($post->getDatePublished()); } $stories[] = $story; } if (empty($stories)) { return id(new AphrontErrorView()) ->setSeverity(AphrontErrorView::SEVERITY_NODATA) ->appendChild($nodata); } return $stories; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->renderSideNavFilterView()->getMenu(); } protected function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); $crumbs->addAction( id(new PHUIListItemView()) ->setName(pht('New Blog')) ->setHref($this->getApplicationURI('/blog/new')) ->setIcon('fa-plus-square')); $crumbs->addAction( id(new PHUIListItemView()) ->setName(pht('New Post')) ->setHref($this->getApplicationURI('/post/new')) ->setIcon('fa-pencil')); return $crumbs; } } diff --git a/src/applications/pholio/controller/PholioController.php b/src/applications/pholio/controller/PholioController.php index 60c1ffcb17..ad402eb4e3 100644 --- a/src/applications/pholio/controller/PholioController.php +++ b/src/applications/pholio/controller/PholioController.php @@ -1,40 +1,40 @@ getRequest()->getUser(); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); id(new PholioMockSearchEngine()) ->setViewer($user) ->addNavigationItems($nav->getMenu()); if ($for_app) { $nav->addFilter('new/', pht('Create Mock')); } $nav->selectFilter(null); return $nav; } protected function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); $crumbs->addAction( id(new PHUIListItemView()) ->setName(pht('Create Mock')) ->setHref($this->getApplicationURI('new/')) ->setIcon('fa-plus-square')); return $crumbs; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNavView(true)->getMenu(); } } diff --git a/src/applications/phriction/controller/PhrictionController.php b/src/applications/phriction/controller/PhrictionController.php index 64530096bd..fcd49aae22 100644 --- a/src/applications/phriction/controller/PhrictionController.php +++ b/src/applications/phriction/controller/PhrictionController.php @@ -1,94 +1,94 @@ getRequest()->getUser(); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); if ($for_app) { $nav->addFilter('create', pht('New Document')); $nav->addFilter('/phriction/', pht('Index')); } id(new PhrictionSearchEngine()) ->setViewer($user) ->addNavigationItems($nav->getMenu()); $nav->selectFilter(null); return $nav; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNavView(true)->getMenu(); } protected function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); if (get_class($this) != 'PhrictionListController') { $crumbs->addAction( id(new PHUIListItemView()) ->setName(pht('Index')) ->setHref('/phriction/') ->setIcon('fa-home')); } $crumbs->addAction( id(new PHUIListItemView()) ->setName(pht('New Document')) ->setHref('/phriction/new/?slug='.$this->getDocumentSlug()) ->setWorkflow(true) ->setIcon('fa-plus-square')); return $crumbs; } public function renderBreadcrumbs($slug) { $ancestor_handles = array(); $ancestral_slugs = PhabricatorSlug::getAncestry($slug); $ancestral_slugs[] = $slug; if ($ancestral_slugs) { $empty_slugs = array_fill_keys($ancestral_slugs, null); $ancestors = id(new PhrictionDocumentQuery()) ->setViewer($this->getRequest()->getUser()) ->withSlugs($ancestral_slugs) ->execute(); $ancestors = mpull($ancestors, null, 'getSlug'); $ancestor_phids = mpull($ancestors, 'getPHID'); $handles = array(); if ($ancestor_phids) { $handles = $this->loadViewerHandles($ancestor_phids); } $ancestor_handles = array(); foreach ($ancestral_slugs as $slug) { if (isset($ancestors[$slug])) { $ancestor_handles[] = $handles[$ancestors[$slug]->getPHID()]; } else { $handle = new PhabricatorObjectHandle(); $handle->setName(PhabricatorSlug::getDefaultTitle($slug)); $handle->setURI(PhrictionDocument::getSlugURI($slug)); $ancestor_handles[] = $handle; } } } $breadcrumbs = array(); foreach ($ancestor_handles as $ancestor_handle) { $breadcrumbs[] = id(new PhabricatorCrumbView()) ->setName($ancestor_handle->getName()) ->setHref($ancestor_handle->getUri()); } return $breadcrumbs; } protected function getDocumentSlug() { return ''; } } diff --git a/src/applications/releeph/controller/ReleephController.php b/src/applications/releeph/controller/ReleephController.php index 5d68ab499e..83c94debe9 100644 --- a/src/applications/releeph/controller/ReleephController.php +++ b/src/applications/releeph/controller/ReleephController.php @@ -1,50 +1,50 @@ buildStandardPageView(); $page->setApplicationName(pht('Releeph')); $page->setBaseURI('/releeph/'); $page->setTitle(idx($data, 'title')); $page->setGlyph("\xD3\x82"); $page->appendChild($view); $response = new AphrontWebpageResponse(); return $response->setContent($page->render()); } public function buildSideNavView($for_app = false) { $user = $this->getRequest()->getUser(); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); if ($for_app) { $nav->addFilter('project/create/', pht('Create Product')); } id(new ReleephProductSearchEngine()) ->setViewer($user) ->addNavigationItems($nav->getMenu()); $nav->selectFilter(null); return $nav; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNavView(true)->getMenu(); } protected function getProductViewURI(ReleephProject $product) { return $this->getApplicationURI('project/'.$product->getID().'/'); } protected function getBranchViewURI(ReleephBranch $branch) { return $this->getApplicationURI('branch/'.$branch->getID().'/'); } } diff --git a/src/applications/search/controller/PhabricatorApplicationSearchController.php b/src/applications/search/controller/PhabricatorApplicationSearchController.php index 5ce4ad8553..4699b6e92a 100644 --- a/src/applications/search/controller/PhabricatorApplicationSearchController.php +++ b/src/applications/search/controller/PhabricatorApplicationSearchController.php @@ -1,362 +1,362 @@ preface = $preface; return $this; } public function getPreface() { return $this->preface; } public function setQueryKey($query_key) { $this->queryKey = $query_key; return $this; } protected function getQueryKey() { return $this->queryKey; } public function setNavigation(AphrontSideNavFilterView $navigation) { $this->navigation = $navigation; return $this; } protected function getNavigation() { return $this->navigation; } public function setSearchEngine( PhabricatorApplicationSearchEngine $search_engine) { $this->searchEngine = $search_engine; return $this; } protected function getSearchEngine() { return $this->searchEngine; } protected function validateDelegatingController() { $parent = $this->getDelegatingController(); if (!$parent) { throw new Exception( 'You must delegate to this controller, not invoke it directly.'); } $engine = $this->getSearchEngine(); if (!$engine) { throw new Exception( 'Call setEngine() before delegating to this controller!'); } $nav = $this->getNavigation(); if (!$nav) { throw new Exception( 'Call setNavigation() before delegating to this controller!'); } $engine->setViewer($this->getRequest()->getUser()); $parent = $this->getDelegatingController(); } public function processRequest() { $this->validateDelegatingController(); $key = $this->getQueryKey(); if ($key == 'edit') { return $this->processEditRequest(); } else { return $this->processSearchRequest(); } } private function processSearchRequest() { $parent = $this->getDelegatingController(); $request = $this->getRequest(); $user = $request->getUser(); $engine = $this->getSearchEngine(); $nav = $this->getNavigation(); if ($request->isFormPost()) { $saved_query = $engine->buildSavedQueryFromRequest($request); $engine->saveQuery($saved_query); return id(new AphrontRedirectResponse())->setURI( $engine->getQueryResultsPageURI($saved_query->getQueryKey()).'#R'); } $named_query = null; $run_query = true; $query_key = $this->queryKey; if ($this->queryKey == 'advanced') { $run_query = false; $query_key = $request->getStr('query'); } else if (!strlen($this->queryKey)) { $found_query_data = false; if ($request->isHTTPGet()) { // If this is a GET request and it has some query data, don't // do anything unless it's only before= or after=. We'll build and // execute a query from it below. This allows external tools to build // URIs like "/query/?users=a,b". $pt_data = $request->getPassthroughRequestData(); foreach ($pt_data as $pt_key => $pt_value) { if ($pt_key != 'before' && $pt_key != 'after') { $found_query_data = true; break; } } } if (!$found_query_data) { // Otherwise, there's no query data so just run the user's default // query for this application. $query_key = head_key($engine->loadEnabledNamedQueries()); } } if ($engine->isBuiltinQuery($query_key)) { $saved_query = $engine->buildSavedQueryFromBuiltin($query_key); $named_query = idx($engine->loadEnabledNamedQueries(), $query_key); } else if ($query_key) { $saved_query = id(new PhabricatorSavedQueryQuery()) ->setViewer($user) ->withQueryKeys(array($query_key)) ->executeOne(); if (!$saved_query) { return new Aphront404Response(); } $named_query = idx($engine->loadEnabledNamedQueries(), $query_key); } else { $saved_query = $engine->buildSavedQueryFromRequest($request); // Save the query to generate a query key, so "Save Custom Query..." and // other features like Maniphest's "Export..." work correctly. $engine->saveQuery($saved_query); } $nav->selectFilter( 'query/'.$saved_query->getQueryKey(), 'query/advanced'); $form = id(new AphrontFormView()) ->setUser($user) ->setAction($request->getPath()); $engine->buildSearchForm($form, $saved_query); $errors = $engine->getErrors(); if ($errors) { $run_query = false; $errors = id(new AphrontErrorView()) ->setTitle(pht('Query Errors')) ->setErrors($errors); } $submit = id(new AphrontFormSubmitControl()) ->setValue(pht('Execute Query')); if ($run_query && !$named_query && $user->isLoggedIn()) { $submit->addCancelButton( '/search/edit/'.$saved_query->getQueryKey().'/', pht('Save Custom Query...')); } // TODO: A "Create Dashboard Panel" action goes here somewhere once // we sort out T5307. $form->appendChild($submit); $filter_view = id(new AphrontListFilterView())->appendChild($form); if ($run_query && $named_query) { if ($named_query->getIsBuiltin()) { $description = pht( 'Showing results for query "%s".', $named_query->getQueryName()); } else { $description = pht( 'Showing results for saved query "%s".', $named_query->getQueryName()); } $filter_view->setCollapsed( pht('Edit Query...'), pht('Hide Query'), $description, $this->getApplicationURI('query/advanced/?query='.$query_key)); } if ($this->getPreface()) { $nav->appendChild($this->getPreface()); } $nav->appendChild($filter_view); if ($run_query) { $nav->appendChild( $anchor = id(new PhabricatorAnchorView()) ->setAnchorName('R')); $query = $engine->buildQueryFromSavedQuery($saved_query); $pager = $engine->newPagerForSavedQuery($saved_query); $pager->readFromRequest($request); $objects = $engine->executeQuery($query, $pager); // TODO: To support Dashboard panels, rendering is moving into // SearchEngines. Move it all the way in and then get rid of this. $interface = 'PhabricatorApplicationSearchResultsControllerInterface'; if ($parent instanceof $interface) { $list = $parent->renderResultsList($objects, $saved_query); } else { $engine->setRequest($request); $list = $engine->renderResults( $objects, $saved_query); } $nav->appendChild($list); // TODO: This is a bit hacky. if ($list instanceof PHUIObjectItemListView) { $list->setNoDataString(pht('No results found for this query.')); $list->setPager($pager); } else { if ($pager->willShowPagingControls()) { $pager_box = id(new PHUIBoxView()) ->addPadding(PHUI::PADDING_MEDIUM) ->addMargin(PHUI::MARGIN_LARGE) ->setBorder(true) ->appendChild($pager); $nav->appendChild($pager_box); } } } if ($errors) { $nav->appendChild($errors); } if ($named_query) { $title = pht('Query: %s', $named_query->getQueryName()); } else { $title = pht('Advanced Search'); } $crumbs = $parent ->buildApplicationCrumbs() ->addTextCrumb($title); $nav->setCrumbs($crumbs); return $this->buildApplicationPage( $nav, array( 'title' => $title, )); } private function processEditRequest() { $parent = $this->getDelegatingController(); $request = $this->getRequest(); $user = $request->getUser(); $engine = $this->getSearchEngine(); $nav = $this->getNavigation(); $named_queries = $engine->loadAllNamedQueries(); $list_id = celerity_generate_unique_node_id(); $list = new PHUIObjectItemListView(); $list->setUser($user); $list->setID($list_id); Javelin::initBehavior( 'search-reorder-queries', array( 'listID' => $list_id, 'orderURI' => '/search/order/'.get_class($engine).'/', )); foreach ($named_queries as $named_query) { $class = get_class($engine); $key = $named_query->getQueryKey(); $item = id(new PHUIObjectItemView()) ->setHeader($named_query->getQueryName()) ->setHref($engine->getQueryResultsPageURI($key)); if ($named_query->getIsBuiltin() && $named_query->getIsDisabled()) { $icon = 'fa-plus'; } else { $icon = 'fa-times'; } $item->addAction( id(new PHUIListItemView()) ->setIcon($icon) ->setHref('/search/delete/'.$key.'/'.$class.'/') ->setWorkflow(true)); if ($named_query->getIsBuiltin()) { if ($named_query->getIsDisabled()) { $item->addIcon('fa-times lightgreytext', pht('Disabled')); $item->setDisabled(true); } else { $item->addIcon('fa-lock lightgreytext', pht('Builtin')); } } else { $item->addAction( id(new PHUIListItemView()) ->setIcon('fa-pencil') ->setHref('/search/edit/'.$key.'/')); } $item->setGrippable(true); $item->addSigil('named-query'); $item->setMetadata( array( 'queryKey' => $named_query->getQueryKey(), )); $list->addItem($item); } $list->setNoDataString(pht('No saved queries.')); $crumbs = $parent ->buildApplicationCrumbs() ->addTextCrumb(pht('Saved Queries'), $engine->getQueryManagementURI()); $nav->selectFilter('query/edit'); $nav->setCrumbs($crumbs); $nav->appendChild($list); return $parent->buildApplicationPage( $nav, array( 'title' => pht('Saved Queries'), )); } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->getDelegatingController()->buildApplicationMenu(); } } diff --git a/src/applications/settings/controller/PhabricatorSettingsMainController.php b/src/applications/settings/controller/PhabricatorSettingsMainController.php index 7ac03eb477..9f95b01695 100644 --- a/src/applications/settings/controller/PhabricatorSettingsMainController.php +++ b/src/applications/settings/controller/PhabricatorSettingsMainController.php @@ -1,159 +1,159 @@ user; } private function isSelf() { $viewer_phid = $this->getRequest()->getUser()->getPHID(); $user_phid = $this->getUser()->getPHID(); return ($viewer_phid == $user_phid); } public function willProcessRequest(array $data) { $this->id = idx($data, 'id'); $this->key = idx($data, 'key'); } public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); if ($this->id) { $user = id(new PhabricatorPeopleQuery()) ->setViewer($viewer) ->withIDs(array($this->id)) ->requireCapabilities( array( PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT, )) ->executeOne(); if (!$user) { return new Aphront404Response(); } $this->user = $user; } else { $this->user = $viewer; } $panels = $this->buildPanels(); $nav = $this->renderSideNav($panels); $key = $nav->selectFilter($this->key, head($panels)->getPanelKey()); $panel = $panels[$key]; $panel->setUser($this->getUser()); $panel->setViewer($viewer); $response = $panel->processRequest($request); if ($response instanceof AphrontResponse) { return $response; } $crumbs = $this->buildApplicationCrumbs(); if (!$this->isSelf()) { $crumbs->addTextCrumb( $this->getUser()->getUsername(), '/p/'.$this->getUser()->getUsername().'/'); } $crumbs->addTextCrumb($panel->getPanelName()); $nav->appendChild( array( $crumbs, $response, )); return $this->buildApplicationPage( $nav, array( 'title' => $panel->getPanelName(), )); } private function buildPanels() { $panel_specs = id(new PhutilSymbolLoader()) ->setAncestorClass('PhabricatorSettingsPanel') ->setConcreteOnly(true) ->selectAndLoadSymbols(); $panels = array(); foreach ($panel_specs as $spec) { $class = newv($spec['name'], array()); $panels[] = $class->buildPanels(); } $panels = array_mergev($panels); $panels = mpull($panels, null, 'getPanelKey'); $result = array(); foreach ($panels as $key => $panel) { if (!$panel->isEnabled()) { continue; } if (!$this->isSelf()) { if (!$panel->isEditableByAdministrators()) { continue; } } if (!empty($result[$key])) { throw new Exception(pht( "Two settings panels share the same panel key ('%s'): %s, %s.", $key, get_class($panel), get_class($result[$key]))); } $result[$key] = $panel; } $result = msort($result, 'getPanelSortKey'); if (!$result) { throw new Exception(pht('No settings panels are available.')); } return $result; } private function renderSideNav(array $panels) { $nav = new AphrontSideNavFilterView(); if ($this->isSelf()) { $base_uri = 'panel/'; } else { $base_uri = $this->getUser()->getID().'/panel/'; } $nav->setBaseURI(new PhutilURI($this->getApplicationURI($base_uri))); $group = null; foreach ($panels as $panel) { if ($panel->getPanelGroup() != $group) { $group = $panel->getPanelGroup(); $nav->addLabel($group); } $nav->addFilter($panel->getPanelKey(), $panel->getPanelName()); } return $nav; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { $panels = $this->buildPanels(); return $this->renderSideNav($panels)->getMenu(); } } diff --git a/src/applications/slowvote/controller/PhabricatorSlowvoteController.php b/src/applications/slowvote/controller/PhabricatorSlowvoteController.php index 9c5a155a18..9925dae3d7 100644 --- a/src/applications/slowvote/controller/PhabricatorSlowvoteController.php +++ b/src/applications/slowvote/controller/PhabricatorSlowvoteController.php @@ -1,41 +1,41 @@ getRequest()->getUser(); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); if ($for_app) { $nav->addFilter('', pht('Create Poll'), $this->getApplicationURI('create/')); } id(new PhabricatorSlowvoteSearchEngine()) ->setViewer($user) ->addNavigationItems($nav->getMenu()); $nav->selectFilter(null); return $nav; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNavView(true)->getMenu(); } protected function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); $crumbs->addAction( id(new PHUIListItemView()) ->setName(pht('Create Poll')) ->setHref($this->getApplicationURI('create/')) ->setIcon('fa-plus-square')); return $crumbs; } } diff --git a/src/applications/tokens/controller/PhabricatorTokenController.php b/src/applications/tokens/controller/PhabricatorTokenController.php index 65eb30b514..8cd61b92b6 100644 --- a/src/applications/tokens/controller/PhabricatorTokenController.php +++ b/src/applications/tokens/controller/PhabricatorTokenController.php @@ -1,25 +1,25 @@ setBaseURI(new PhutilURI($this->getApplicationURI())); $nav->addLabel(pht('Tokens')); $nav->addFilter('given/', pht('Tokens Given')); $nav->addFilter('leaders/', pht('Leader Board')); return $nav; } - protected function buildApplicationMenu() { + public function buildApplicationMenu() { return $this->buildSideNav()->getMenu(); } protected function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); return $crumbs; } }