mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-29 10:12: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
|
// Should Phabricator show beta applications on the homepage
|
||||||
'phabricator.show-beta-applications' => false,
|
'phabricator.show-beta-applications' => false,
|
||||||
|
|
||||||
|
// Contains a list of uninstalled applications
|
||||||
|
'phabricator.uninstalled-applications' => array(),
|
||||||
|
|
||||||
// -- Files ----------------------------------------------------------------- //
|
// -- Files ----------------------------------------------------------------- //
|
||||||
|
|
||||||
// Lists which uploaded file types may be viewed in the browser. If a file
|
// 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',
|
'PhabricatorApplicationTransactionView' => 'applications/transactions/view/PhabricatorApplicationTransactionView.php',
|
||||||
'PhabricatorApplicationTransactions' => 'applications/transactions/application/PhabricatorApplicationTransactions.php',
|
'PhabricatorApplicationTransactions' => 'applications/transactions/application/PhabricatorApplicationTransactions.php',
|
||||||
'PhabricatorApplicationUIExamples' => 'applications/uiexample/application/PhabricatorApplicationUIExamples.php',
|
'PhabricatorApplicationUIExamples' => 'applications/uiexample/application/PhabricatorApplicationUIExamples.php',
|
||||||
|
'PhabricatorApplicationUninstallController' => 'applications/meta/controller/PhabricatorApplicationUninstallController.php',
|
||||||
'PhabricatorApplicationsController' => 'applications/meta/controller/PhabricatorApplicationsController.php',
|
'PhabricatorApplicationsController' => 'applications/meta/controller/PhabricatorApplicationsController.php',
|
||||||
'PhabricatorApplicationsListController' => 'applications/meta/controller/PhabricatorApplicationsListController.php',
|
'PhabricatorApplicationsListController' => 'applications/meta/controller/PhabricatorApplicationsListController.php',
|
||||||
'PhabricatorAuditActionConstants' => 'applications/audit/constants/PhabricatorAuditActionConstants.php',
|
'PhabricatorAuditActionConstants' => 'applications/audit/constants/PhabricatorAuditActionConstants.php',
|
||||||
|
@ -2103,6 +2104,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorApplicationTransactionView' => 'AphrontView',
|
'PhabricatorApplicationTransactionView' => 'AphrontView',
|
||||||
'PhabricatorApplicationTransactions' => 'PhabricatorApplication',
|
'PhabricatorApplicationTransactions' => 'PhabricatorApplication',
|
||||||
'PhabricatorApplicationUIExamples' => 'PhabricatorApplication',
|
'PhabricatorApplicationUIExamples' => 'PhabricatorApplication',
|
||||||
|
'PhabricatorApplicationUninstallController' => 'PhabricatorApplicationsController',
|
||||||
'PhabricatorApplicationsController' => 'PhabricatorController',
|
'PhabricatorApplicationsController' => 'PhabricatorController',
|
||||||
'PhabricatorApplicationsListController' => 'PhabricatorApplicationsController',
|
'PhabricatorApplicationsListController' => 'PhabricatorApplicationsController',
|
||||||
'PhabricatorAuditAddCommentController' => 'PhabricatorAuditController',
|
'PhabricatorAuditAddCommentController' => 'PhabricatorAuditController',
|
||||||
|
|
|
@ -6,6 +6,10 @@ final class PhabricatorApplicationAuth extends PhabricatorApplication {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function canUninstall() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function buildMainMenuItems(
|
public function buildMainMenuItems(
|
||||||
PhabricatorUser $user,
|
PhabricatorUser $user,
|
||||||
PhabricatorController $controller = null) {
|
PhabricatorController $controller = null) {
|
||||||
|
|
|
@ -62,10 +62,25 @@ abstract class PhabricatorApplication {
|
||||||
return true;
|
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() {
|
public function isBeta() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function canUninstall() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public function getPHID() {
|
public function getPHID() {
|
||||||
return 'PHID-APPS-'.get_class($this);
|
return 'PHID-APPS-'.get_class($this);
|
||||||
}
|
}
|
||||||
|
@ -212,6 +227,22 @@ abstract class PhabricatorApplication {
|
||||||
|
|
||||||
/* -( Application Management )--------------------------------------------- */
|
/* -( 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() {
|
public static function getAllInstalledApplications() {
|
||||||
static $applications;
|
static $applications;
|
||||||
|
@ -219,6 +250,11 @@ abstract class PhabricatorApplication {
|
||||||
$show_beta =
|
$show_beta =
|
||||||
PhabricatorEnv::getEnvConfig('phabricator.show-beta-applications');
|
PhabricatorEnv::getEnvConfig('phabricator.show-beta-applications');
|
||||||
|
|
||||||
|
$uninstalled =
|
||||||
|
PhabricatorEnv::getEnvConfig('phabricator.uninstalled-applications');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (empty($applications)) {
|
if (empty($applications)) {
|
||||||
$classes = id(new PhutilSymbolLoader())
|
$classes = id(new PhutilSymbolLoader())
|
||||||
->setAncestorClass(__CLASS__)
|
->setAncestorClass(__CLASS__)
|
||||||
|
@ -227,7 +263,13 @@ abstract class PhabricatorApplication {
|
||||||
|
|
||||||
$apps = array();
|
$apps = array();
|
||||||
foreach ($classes as $class) {
|
foreach ($classes as $class) {
|
||||||
|
|
||||||
|
if (isset($uninstalled[$class['name']])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$app = newv($class['name'], array());
|
$app = newv($class['name'], array());
|
||||||
|
|
||||||
if (!$app->isEnabled()) {
|
if (!$app->isEnabled()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -238,11 +280,12 @@ abstract class PhabricatorApplication {
|
||||||
|
|
||||||
$apps[] = $app;
|
$apps[] = $app;
|
||||||
}
|
}
|
||||||
|
|
||||||
$applications = $apps;
|
$applications = $apps;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $applications;
|
return $applications;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,10 @@ final class PhabricatorApplicationConfig extends PhabricatorApplication {
|
||||||
return self::GROUP_ADMIN;
|
return self::GROUP_ADMIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function canUninstall() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function getRoutes() {
|
public function getRoutes() {
|
||||||
return array(
|
return array(
|
||||||
'/config/' => array(
|
'/config/' => array(
|
||||||
|
|
|
@ -128,6 +128,11 @@ final class PhabricatorCoreConfigOptions
|
||||||
$this->newOption('test.value', 'wild', null)
|
$this->newOption('test.value', 'wild', null)
|
||||||
->setLocked(true)
|
->setLocked(true)
|
||||||
->setDescription(pht('Unit test value.')),
|
->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;
|
return self::GROUP_ADMIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function canUninstall() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function getRoutes() {
|
public function getRoutes() {
|
||||||
return array(
|
return array(
|
||||||
'/daemon/' => array(
|
'/daemon/' => array(
|
||||||
|
|
|
@ -14,6 +14,10 @@ final class PhabricatorApplicationFeed extends PhabricatorApplication {
|
||||||
return 'feed';
|
return 'feed';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function canUninstall() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function getRoutes() {
|
public function getRoutes() {
|
||||||
return array(
|
return array(
|
||||||
'/feed/' => array(
|
'/feed/' => array(
|
||||||
|
|
|
@ -30,6 +30,10 @@ final class PhabricatorApplicationFiles extends PhabricatorApplication {
|
||||||
return $this->getBaseURI().'upload/';
|
return $this->getBaseURI().'upload/';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function canUninstall() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function getRoutes() {
|
public function getRoutes() {
|
||||||
return array(
|
return array(
|
||||||
'/F(?P<id>[1-9]\d*)' => 'PhabricatorFileShortcutController',
|
'/F(?P<id>[1-9]\d*)' => 'PhabricatorFileShortcutController',
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
final class PhabricatorApplicationApplications extends PhabricatorApplication {
|
final class PhabricatorApplicationApplications extends PhabricatorApplication {
|
||||||
|
|
||||||
|
public function canUninstall() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function getBaseURI() {
|
public function getBaseURI() {
|
||||||
return '/applications/';
|
return '/applications/';
|
||||||
}
|
}
|
||||||
|
@ -28,7 +32,8 @@ final class PhabricatorApplicationApplications extends PhabricatorApplication {
|
||||||
'' => 'PhabricatorApplicationsListController',
|
'' => 'PhabricatorApplicationsListController',
|
||||||
'view/(?P<application>\w+)/' =>
|
'view/(?P<application>\w+)/' =>
|
||||||
'PhabricatorApplicationDetailViewController',
|
'PhabricatorApplicationDetailViewController',
|
||||||
|
'(?P<application>\w+)/(?P<action>install|uninstall)/' =>
|
||||||
|
'PhabricatorApplicationUninstallController',
|
||||||
),
|
),
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
|
@ -14,7 +14,7 @@ final class PhabricatorApplicationDetailViewController
|
||||||
$user = $request->getUser();
|
$user = $request->getUser();
|
||||||
|
|
||||||
$selected = null;
|
$selected = null;
|
||||||
$applications = PhabricatorApplication::getAllInstalledApplications();
|
$applications = PhabricatorApplication::getAllApplications();
|
||||||
|
|
||||||
foreach ($applications as $application) {
|
foreach ($applications as $application) {
|
||||||
if (get_class($application) == $this->application) {
|
if (get_class($application) == $this->application) {
|
||||||
|
@ -36,7 +36,7 @@ final class PhabricatorApplicationDetailViewController
|
||||||
->setHref($this->getApplicationURI()));
|
->setHref($this->getApplicationURI()));
|
||||||
|
|
||||||
$properties = $this->buildPropertyView($selected);
|
$properties = $this->buildPropertyView($selected);
|
||||||
$actions = $this->buildActionView($user);
|
$actions = $this->buildActionView($user, $selected);
|
||||||
|
|
||||||
return $this->buildApplicationPage(
|
return $this->buildApplicationPage(
|
||||||
array(
|
array(
|
||||||
|
@ -54,16 +54,26 @@ final class PhabricatorApplicationDetailViewController
|
||||||
private function buildPropertyView(PhabricatorApplication $selected) {
|
private function buildPropertyView(PhabricatorApplication $selected) {
|
||||||
$properties = new PhabricatorPropertyListView();
|
$properties = new PhabricatorPropertyListView();
|
||||||
|
|
||||||
|
if ($selected->isInstalled()) {
|
||||||
$properties->addProperty(
|
$properties->addProperty(
|
||||||
pht('Status'), pht('Installed'));
|
pht('Status'), pht('Installed'));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$properties->addProperty(
|
||||||
|
pht('Status'), pht('Uninstalled'));
|
||||||
|
}
|
||||||
|
|
||||||
$properties->addProperty(
|
$properties->addProperty(
|
||||||
pht('Description'), $selected->getShortDescription());
|
pht('Description'), $selected->getShortDescription());
|
||||||
|
|
||||||
return $properties;
|
return $properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildActionView(PhabricatorUser $user) {
|
private function buildActionView(
|
||||||
|
PhabricatorUser $user, PhabricatorApplication $selected) {
|
||||||
|
|
||||||
|
if ($selected->canUninstall()) {
|
||||||
|
if ($selected->isInstalled()) {
|
||||||
|
|
||||||
return id(new PhabricatorActionListView())
|
return id(new PhabricatorActionListView())
|
||||||
->setUser($user)
|
->setUser($user)
|
||||||
|
@ -71,7 +81,21 @@ final class PhabricatorApplicationDetailViewController
|
||||||
id(new PhabricatorActionView())
|
id(new PhabricatorActionView())
|
||||||
->setName(pht('Uninstall'))
|
->setName(pht('Uninstall'))
|
||||||
->setIcon('delete')
|
->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 = $this->buildSideNavView();
|
||||||
$nav->selectFilter('/');
|
$nav->selectFilter('/');
|
||||||
|
|
||||||
$applications = PhabricatorApplication::getAllInstalledApplications();
|
$applications = PhabricatorApplication::getAllApplications();
|
||||||
|
|
||||||
$list = $this->buildInstalledApplicationsList($applications);
|
$list = $this->buildInstalledApplicationsList($applications);
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,10 @@ final class PhabricatorApplicationMetaMTA extends PhabricatorApplication {
|
||||||
return self::GROUP_ADMIN;
|
return self::GROUP_ADMIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function canUninstall() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function getRoutes() {
|
public function getRoutes() {
|
||||||
return array(
|
return array(
|
||||||
$this->getBaseURI() => array(
|
$this->getBaseURI() => array(
|
||||||
|
|
|
@ -26,6 +26,10 @@ final class PhabricatorApplicationPeople extends PhabricatorApplication {
|
||||||
return self::GROUP_ADMIN;
|
return self::GROUP_ADMIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function canUninstall() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function getRoutes() {
|
public function getRoutes() {
|
||||||
return array(
|
return array(
|
||||||
'/people/' => array(
|
'/people/' => array(
|
||||||
|
|
|
@ -14,6 +14,10 @@ final class PhabricatorApplicationSettings extends PhabricatorApplication {
|
||||||
return 'settings';
|
return 'settings';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function canUninstall() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function getRoutes() {
|
public function getRoutes() {
|
||||||
return array(
|
return array(
|
||||||
'/settings/' => array(
|
'/settings/' => array(
|
||||||
|
|
|
@ -6,6 +6,10 @@ final class PhabricatorApplicationSubscriptions extends PhabricatorApplication {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function canUninstall() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function getEventListeners() {
|
public function getEventListeners() {
|
||||||
return array(
|
return array(
|
||||||
new PhabricatorSubscriptionsUIEventListener(),
|
new PhabricatorSubscriptionsUIEventListener(),
|
||||||
|
|
|
@ -6,6 +6,10 @@ final class PhabricatorApplicationTransactions extends PhabricatorApplication {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function canUninstall() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public function getRoutes() {
|
public function getRoutes() {
|
||||||
return array(
|
return array(
|
||||||
'/transactions/' => array(
|
'/transactions/' => array(
|
||||||
|
|
Loading…
Reference in a new issue