diff --git a/src/applications/base/PhabricatorApplication.php b/src/applications/base/PhabricatorApplication.php index 6bed54389a..0a397e1f4b 100644 --- a/src/applications/base/PhabricatorApplication.php +++ b/src/applications/base/PhabricatorApplication.php @@ -1,291 +1,305 @@ pht('Core Applications'), self::GROUP_COMMUNICATION => pht('Communication'), self::GROUP_ORGANIZATION => pht('Organization'), self::GROUP_UTILITIES => pht('Utilities'), self::GROUP_ADMIN => pht('Administration'), self::GROUP_DEVELOPER => pht('Developer Tools'), self::GROUP_MISC => pht('Miscellaneous Applications'), ); } public static function getTileDisplayName($constant) { $names = array( self::TILE_INVISIBLE => pht('Invisible'), self::TILE_HIDE => pht('Hidden'), self::TILE_SHOW => pht('Show Small Tile'), self::TILE_FULL => pht('Show Large Tile'), ); return idx($names, $constant); } /* -( Application Information )-------------------------------------------- */ public function getName() { return substr(get_class($this), strlen('PhabricatorApplication')); } public function getShortDescription() { return $this->getName().' Application'; } public function isEnabled() { return true; } public function isInstalled() { $uninstalled = PhabricatorEnv::getEnvConfig('phabricator.uninstalled-applications'); if (isset($uninstalled[get_class($this)])) { return false; } else { return true; } } public function isBeta() { return false; } public function canUninstall() { return true; } public function getPHID() { return 'PHID-APPS-'.get_class($this); } public function getTypeaheadURI() { return $this->getBaseURI(); } public function getBaseURI() { return null; } public function getIconURI() { return null; } public function getIconName() { return 'application'; } public function shouldAppearInLaunchView() { return true; } public function getApplicationOrder() { return PHP_INT_MAX; } public function getApplicationGroup() { return self::GROUP_MISC; } public function getTitleGlyph() { return null; } public function getHelpURI() { // TODO: When these applications get created, link to their docs: // // - Drydock // - OAuth Server return null; } public function getEventListeners() { return array(); } public function getDefaultTileDisplay(PhabricatorUser $user) { switch ($this->getApplicationGroup()) { case self::GROUP_CORE: return self::TILE_FULL; case self::GROUP_UTILITIES: case self::GROUP_DEVELOPER: return self::TILE_HIDE; case self::GROUP_ADMIN: if ($user->getIsAdmin()) { return self::TILE_SHOW; } else { return self::TILE_INVISIBLE; } break; default: return self::TILE_SHOW; } } /* -( URI Routing )-------------------------------------------------------- */ public function getRoutes() { return array(); } /* -( Fact Integration )--------------------------------------------------- */ public function getFactObjectsForAnalysis() { return array(); } /* -( UI Integration )----------------------------------------------------- */ /** * Render status elements (like "3 Waiting Reviews") for application list * views. These provide a way to alert users to new or pending action items * in applications. * * @param PhabricatorUser Viewing user. * @return list Application status elements. * @task ui */ public function loadStatus(PhabricatorUser $user) { return array(); } /** * You can provide an optional piece of flavor text for the application. This * is currently rendered in application launch views if the application has no * status elements. * * @return string|null Flavor text. * @task ui */ public function getFlavorText() { return null; } /** * Build items for the main menu. * * @param PhabricatorUser The viewing user. * @param AphrontController The current controller. May be null for special * pages like 404, exception handlers, etc. * @return list List of menu items. * @task ui */ public function buildMainMenuItems( PhabricatorUser $user, PhabricatorController $controller = null) { return array(); } /** * On the Phabricator homepage sidebar, this function returns the URL for * a quick create X link which is displayed in the wide button only. * * @return string * @task ui */ public function getQuickCreateURI() { return null; } /* -( Application Management )--------------------------------------------- */ + public static function getByClass($class_name) { + + $selected = null; + $applications = PhabricatorApplication::getAllApplications(); + + foreach ($applications as $application) { + if (get_class($application) == $class_name) { + $selected = $application; + break; + } + } + return $selected; + } + public static function getAllApplications() { $classes = id(new PhutilSymbolLoader()) ->setAncestorClass(__CLASS__) ->setConcreteOnly(true) ->selectAndLoadSymbols(); $apps = array(); foreach ($classes as $class) { $app = newv($class['name'], array()); $apps[] = $app; } return $apps; } public static function getAllInstalledApplications() { static $applications; $show_beta = PhabricatorEnv::getEnvConfig('phabricator.show-beta-applications'); $uninstalled = PhabricatorEnv::getEnvConfig('phabricator.uninstalled-applications'); if (empty($applications)) { $classes = id(new PhutilSymbolLoader()) ->setAncestorClass(__CLASS__) ->setConcreteOnly(true) ->selectAndLoadSymbols(); $apps = array(); foreach ($classes as $class) { if (isset($uninstalled[$class['name']])) { continue; } $app = newv($class['name'], array()); if (!$app->isEnabled()) { continue; } if (!$show_beta && $app->isBeta()) { continue; } $apps[] = $app; } $applications = $apps; } return $applications; } } diff --git a/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php b/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php index 460dd6b0f1..259b3c7439 100644 --- a/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php +++ b/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php @@ -1,101 +1,93 @@ application = $data['application']; } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); - $selected = null; - $applications = PhabricatorApplication::getAllApplications(); - - foreach ($applications as $application) { - if (get_class($application) == $this->application) { - $selected = $application; - break; - } - } + $selected = PhabricatorApplication::getByClass($this->application); if (!$selected) { return new Aphront404Response(); } $title = $selected->getName(); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addCrumb( id(new PhabricatorCrumbView()) ->setName(pht('Applications')) ->setHref($this->getApplicationURI())); $properties = $this->buildPropertyView($selected); $actions = $this->buildActionView($user, $selected); return $this->buildApplicationPage( array( $crumbs, id(new PhabricatorHeaderView())->setHeader($title), $actions, $properties, ), array( 'title' => $title, 'device' => true, )); } private function buildPropertyView(PhabricatorApplication $selected) { $properties = new PhabricatorPropertyListView(); if ($selected->isInstalled()) { $properties->addProperty( pht('Status'), pht('Installed')); } else { $properties->addProperty( pht('Status'), pht('Uninstalled')); } $properties->addProperty( pht('Description'), $selected->getShortDescription()); return $properties; } private function buildActionView( PhabricatorUser $user, PhabricatorApplication $selected) { if ($selected->canUninstall()) { if ($selected->isInstalled()) { return id(new PhabricatorActionListView()) ->setUser($user) ->addAction( id(new PhabricatorActionView()) ->setName(pht('Uninstall')) ->setIcon('delete') ->setHref( $this->getApplicationURI(get_class($selected).'/uninstall/')) ); } else { return id(new PhabricatorActionListView()) ->setUser($user) ->addAction( id(new PhabricatorActionView()) ->setName(pht('Install')) ->setIcon('new') ->setHref( $this->getApplicationURI(get_class($selected).'/install/')) ); } } } } diff --git a/src/applications/meta/controller/PhabricatorApplicationUninstallController.php b/src/applications/meta/controller/PhabricatorApplicationUninstallController.php index 7ba660d3cf..f9b8ae3f83 100644 --- a/src/applications/meta/controller/PhabricatorApplicationUninstallController.php +++ b/src/applications/meta/controller/PhabricatorApplicationUninstallController.php @@ -1,93 +1,102 @@ application = $data['application']; $this->action = $data['action']; } public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); - $app_name = substr($this->application, strlen('PhabricatorApplication')); + + $selected = PhabricatorApplication::getByClass($this->application); + + if (!$selected) { + return new Aphront404Response(); + } if ($request->isDialogFormPost()) { $this->manageApplication(); return id(new AphrontRedirectResponse())->setURI('/applications/'); } if ($this->action == 'install') { $dialog = id(new AphrontDialogView()) ->setUser($user) ->setTitle('Confirmation') - ->appendChild('Install '. $app_name. ' application ?') + ->appendChild( + 'Install '. $selected->getName(). ' application ?' + ) ->addSubmitButton('Install') ->addCancelButton('/applications/view/'.$this->application); } else { $dialog = id(new AphrontDialogView()) ->setUser($user) ->setTitle('Confirmation') - ->appendChild('Really Uninstall '. $app_name. ' application ?') + ->appendChild( + 'Really Uninstall '. $selected->getName(). ' application ?' + ) ->addSubmitButton('Uninstall') ->addCancelButton('/applications/view/'.$this->application); } return id(new AphrontDialogResponse())->setDialog($dialog); } public function manageApplication() { $key = 'phabricator.uninstalled-applications'; $config_entry = id(new PhabricatorConfigEntry()) ->loadOneWhere( 'configKey = %s AND namespace = %s', $key, 'default'); if (!$config_entry) { $config_entry = id(new PhabricatorConfigEntry()) ->setConfigKey($key) ->setNamespace('default'); } $list = $config_entry->getValue(); $uninstalled = PhabricatorEnv::getEnvConfig($key); if ($uninstalled[$this->application]) { unset($list[$this->application]); } else { $list[$this->application] = true; } $xaction = id(new PhabricatorConfigTransaction()) ->setTransactionType(PhabricatorConfigTransaction::TYPE_EDIT) ->setNewValue( array( 'deleted' => false, 'value' => $list )); $editor = id(new PhabricatorConfigEditor()) ->setActor($this->getRequest()->getUser()) ->setContinueOnNoEffect(true) ->setContentSource( PhabricatorContentSource::newForSource( PhabricatorContentSource::SOURCE_WEB, array( 'ip' => $this->getRequest()->getRemoteAddr(), ))); $editor->applyTransactions($config_entry, array($xaction)); } }