mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 14:52:41 +01:00
Installation & Uninstallion of Applications
Summary: Created Applications application which allows uninstallation & installation of application. Test Plan: In "Applications" application, clicked on uninstalled the application by cliking Uninstall and chekcing whether they are really uninstalled(Disabling URI & in appearance in the side pane). Then Clicked on the install button of the uninstalled application to check whether they are installed. Reviewers: epriestley CC: aran, Korvin Differential Revision: https://secure.phabricator.com/D4715
This commit is contained in:
parent
683df86d54
commit
5017c80b31
18 changed files with 253 additions and 38 deletions
|
@ -839,6 +839,9 @@ return array(
|
|||
// Should Phabricator show beta applications on the homepage
|
||||
'phabricator.show-beta-applications' => false,
|
||||
|
||||
// Contains a list of uninstalled applications
|
||||
'phabricator.uninstalled-applications' => array(),
|
||||
|
||||
// -- Files ----------------------------------------------------------------- //
|
||||
|
||||
// Lists which uploaded file types may be viewed in the browser. If a file
|
||||
|
|
|
@ -673,6 +673,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorApplicationTransactionView' => 'applications/transactions/view/PhabricatorApplicationTransactionView.php',
|
||||
'PhabricatorApplicationTransactions' => 'applications/transactions/application/PhabricatorApplicationTransactions.php',
|
||||
'PhabricatorApplicationUIExamples' => 'applications/uiexample/application/PhabricatorApplicationUIExamples.php',
|
||||
'PhabricatorApplicationUninstallController' => 'applications/meta/controller/PhabricatorApplicationUninstallController.php',
|
||||
'PhabricatorApplicationsController' => 'applications/meta/controller/PhabricatorApplicationsController.php',
|
||||
'PhabricatorApplicationsListController' => 'applications/meta/controller/PhabricatorApplicationsListController.php',
|
||||
'PhabricatorAuditActionConstants' => 'applications/audit/constants/PhabricatorAuditActionConstants.php',
|
||||
|
@ -2103,6 +2104,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorApplicationTransactionView' => 'AphrontView',
|
||||
'PhabricatorApplicationTransactions' => 'PhabricatorApplication',
|
||||
'PhabricatorApplicationUIExamples' => 'PhabricatorApplication',
|
||||
'PhabricatorApplicationUninstallController' => 'PhabricatorApplicationsController',
|
||||
'PhabricatorApplicationsController' => 'PhabricatorController',
|
||||
'PhabricatorApplicationsListController' => 'PhabricatorApplicationsController',
|
||||
'PhabricatorAuditAddCommentController' => 'PhabricatorAuditController',
|
||||
|
|
|
@ -6,6 +6,10 @@ final class PhabricatorApplicationAuth extends PhabricatorApplication {
|
|||
return false;
|
||||
}
|
||||
|
||||
public function canUninstall() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function buildMainMenuItems(
|
||||
PhabricatorUser $user,
|
||||
PhabricatorController $controller = null) {
|
||||
|
|
|
@ -62,10 +62,25 @@ abstract class PhabricatorApplication {
|
|||
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);
|
||||
}
|
||||
|
@ -212,6 +227,22 @@ abstract class PhabricatorApplication {
|
|||
|
||||
/* -( Application Management )--------------------------------------------- */
|
||||
|
||||
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;
|
||||
|
@ -219,6 +250,11 @@ abstract class PhabricatorApplication {
|
|||
$show_beta =
|
||||
PhabricatorEnv::getEnvConfig('phabricator.show-beta-applications');
|
||||
|
||||
$uninstalled =
|
||||
PhabricatorEnv::getEnvConfig('phabricator.uninstalled-applications');
|
||||
|
||||
|
||||
|
||||
if (empty($applications)) {
|
||||
$classes = id(new PhutilSymbolLoader())
|
||||
->setAncestorClass(__CLASS__)
|
||||
|
@ -227,22 +263,29 @@ abstract class PhabricatorApplication {
|
|||
|
||||
$apps = array();
|
||||
foreach ($classes as $class) {
|
||||
$app = newv($class['name'], array());
|
||||
if (!$app->isEnabled()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$show_beta && $app->isBeta()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$apps[] = $app;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,10 @@ final class PhabricatorApplicationConfig extends PhabricatorApplication {
|
|||
return self::GROUP_ADMIN;
|
||||
}
|
||||
|
||||
public function canUninstall() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getRoutes() {
|
||||
return array(
|
||||
'/config/' => array(
|
||||
|
|
|
@ -128,6 +128,11 @@ final class PhabricatorCoreConfigOptions
|
|||
$this->newOption('test.value', 'wild', null)
|
||||
->setLocked(true)
|
||||
->setDescription(pht('Unit test value.')),
|
||||
$this->newOption('phabricator.uninstalled-applications', 'set', array())
|
||||
->setLocked(true)
|
||||
->setDescription(
|
||||
pht('Array containing list of Uninstalled applications.')
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,10 @@ final class PhabricatorApplicationDaemons extends PhabricatorApplication {
|
|||
return self::GROUP_ADMIN;
|
||||
}
|
||||
|
||||
public function canUninstall() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getRoutes() {
|
||||
return array(
|
||||
'/daemon/' => array(
|
||||
|
|
|
@ -14,6 +14,10 @@ final class PhabricatorApplicationFeed extends PhabricatorApplication {
|
|||
return 'feed';
|
||||
}
|
||||
|
||||
public function canUninstall() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getRoutes() {
|
||||
return array(
|
||||
'/feed/' => array(
|
||||
|
|
|
@ -30,6 +30,10 @@ final class PhabricatorApplicationFiles extends PhabricatorApplication {
|
|||
return $this->getBaseURI().'upload/';
|
||||
}
|
||||
|
||||
public function canUninstall() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getRoutes() {
|
||||
return array(
|
||||
'/F(?P<id>[1-9]\d*)' => 'PhabricatorFileShortcutController',
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
|
||||
final class PhabricatorApplicationApplications extends PhabricatorApplication {
|
||||
|
||||
public function canUninstall() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getBaseURI() {
|
||||
return '/applications/';
|
||||
}
|
||||
|
@ -28,7 +32,8 @@ final class PhabricatorApplicationApplications extends PhabricatorApplication {
|
|||
'' => 'PhabricatorApplicationsListController',
|
||||
'view/(?P<application>\w+)/' =>
|
||||
'PhabricatorApplicationDetailViewController',
|
||||
|
||||
'(?P<application>\w+)/(?P<action>install|uninstall)/' =>
|
||||
'PhabricatorApplicationUninstallController',
|
||||
),
|
||||
|
||||
);
|
||||
|
|
|
@ -14,12 +14,12 @@ final class PhabricatorApplicationDetailViewController
|
|||
$user = $request->getUser();
|
||||
|
||||
$selected = null;
|
||||
$applications = PhabricatorApplication::getAllInstalledApplications();
|
||||
$applications = PhabricatorApplication::getAllApplications();
|
||||
|
||||
foreach ($applications as $application) {
|
||||
if (get_class($application) == $this->application) {
|
||||
$selected = $application;
|
||||
break;
|
||||
$selected = $application;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,27 +35,33 @@ final class PhabricatorApplicationDetailViewController
|
|||
->setName(pht('Applications'))
|
||||
->setHref($this->getApplicationURI()));
|
||||
|
||||
$properties = $this->buildPropertyView($selected);
|
||||
$actions = $this->buildActionView($user);
|
||||
$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,
|
||||
));
|
||||
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();
|
||||
|
||||
$properties->addProperty(
|
||||
pht('Status'), pht('Installed'));
|
||||
if ($selected->isInstalled()) {
|
||||
$properties->addProperty(
|
||||
pht('Status'), pht('Installed'));
|
||||
|
||||
} else {
|
||||
$properties->addProperty(
|
||||
pht('Status'), pht('Uninstalled'));
|
||||
}
|
||||
|
||||
$properties->addProperty(
|
||||
pht('Description'), $selected->getShortDescription());
|
||||
|
@ -63,15 +69,33 @@ final class PhabricatorApplicationDetailViewController
|
|||
return $properties;
|
||||
}
|
||||
|
||||
private function buildActionView(PhabricatorUser $user) {
|
||||
private function buildActionView(
|
||||
PhabricatorUser $user, PhabricatorApplication $selected) {
|
||||
|
||||
return id(new PhabricatorActionListView())
|
||||
->setUser($user)
|
||||
->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Uninstall'))
|
||||
->setIcon('delete')
|
||||
);
|
||||
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/'))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorApplicationUninstallController
|
||||
extends PhabricatorApplicationsController {
|
||||
|
||||
private $application;
|
||||
private $action;
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->application = $data['application'];
|
||||
$this->action = $data['action'];
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
$app_name = substr($this->application, strlen('PhabricatorApplication'));
|
||||
|
||||
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 ?')
|
||||
->addSubmitButton('Install')
|
||||
->addCancelButton('/applications/view/'.$this->application);
|
||||
} else {
|
||||
$dialog = id(new AphrontDialogView())
|
||||
->setUser($user)
|
||||
->setTitle('Confirmation')
|
||||
->appendChild('Really Uninstall '. $app_name. ' 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));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ final class PhabricatorApplicationsListController
|
|||
$nav = $this->buildSideNavView();
|
||||
$nav->selectFilter('/');
|
||||
|
||||
$applications = PhabricatorApplication::getAllInstalledApplications();
|
||||
$applications = PhabricatorApplication::getAllApplications();
|
||||
|
||||
$list = $this->buildInstalledApplicationsList($applications);
|
||||
|
||||
|
|
|
@ -22,6 +22,10 @@ final class PhabricatorApplicationMetaMTA extends PhabricatorApplication {
|
|||
return self::GROUP_ADMIN;
|
||||
}
|
||||
|
||||
public function canUninstall() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getRoutes() {
|
||||
return array(
|
||||
$this->getBaseURI() => array(
|
||||
|
|
|
@ -26,6 +26,10 @@ final class PhabricatorApplicationPeople extends PhabricatorApplication {
|
|||
return self::GROUP_ADMIN;
|
||||
}
|
||||
|
||||
public function canUninstall() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getRoutes() {
|
||||
return array(
|
||||
'/people/' => array(
|
||||
|
|
|
@ -14,6 +14,10 @@ final class PhabricatorApplicationSettings extends PhabricatorApplication {
|
|||
return 'settings';
|
||||
}
|
||||
|
||||
public function canUninstall() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getRoutes() {
|
||||
return array(
|
||||
'/settings/' => array(
|
||||
|
|
|
@ -6,6 +6,10 @@ final class PhabricatorApplicationSubscriptions extends PhabricatorApplication {
|
|||
return false;
|
||||
}
|
||||
|
||||
public function canUninstall() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getEventListeners() {
|
||||
return array(
|
||||
new PhabricatorSubscriptionsUIEventListener(),
|
||||
|
|
|
@ -6,6 +6,10 @@ final class PhabricatorApplicationTransactions extends PhabricatorApplication {
|
|||
return false;
|
||||
}
|
||||
|
||||
public function canUninstall() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getRoutes() {
|
||||
return array(
|
||||
'/transactions/' => array(
|
||||
|
|
Loading…
Reference in a new issue