1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-22 14:52:41 +01:00

Add transactions for installing/uninstalling applications

Summary: Fixes T11476.

Test Plan:
 - Installed/uninstalled the Conpherence application
 - Observed correct timeline stories
 - Observed correct config in database
 - Observed 404 for application page

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin

Maniphest Tasks: T11476

Differential Revision: https://secure.phabricator.com/D19339
This commit is contained in:
Austin McKinley 2018-04-11 08:46:38 -07:00
parent d398bcd67c
commit 0755482bf0
4 changed files with 120 additions and 38 deletions

View file

@ -2069,6 +2069,7 @@ phutil_register_library_map(array(
'PhabricatorApplicationTransactionWarningException' => 'applications/transactions/exception/PhabricatorApplicationTransactionWarningException.php',
'PhabricatorApplicationTransactionWarningResponse' => 'applications/transactions/response/PhabricatorApplicationTransactionWarningResponse.php',
'PhabricatorApplicationUninstallController' => 'applications/meta/controller/PhabricatorApplicationUninstallController.php',
'PhabricatorApplicationUninstallTransaction' => 'applications/meta/xactions/PhabricatorApplicationUninstallTransaction.php',
'PhabricatorApplicationsApplication' => 'applications/meta/application/PhabricatorApplicationsApplication.php',
'PhabricatorApplicationsController' => 'applications/meta/controller/PhabricatorApplicationsController.php',
'PhabricatorApplicationsListController' => 'applications/meta/controller/PhabricatorApplicationsListController.php',
@ -7533,6 +7534,7 @@ phutil_register_library_map(array(
'PhabricatorApplicationTransactionWarningException' => 'Exception',
'PhabricatorApplicationTransactionWarningResponse' => 'AphrontProxyResponse',
'PhabricatorApplicationUninstallController' => 'PhabricatorApplicationsController',
'PhabricatorApplicationUninstallTransaction' => 'PhabricatorApplicationTransactionType',
'PhabricatorApplicationsApplication' => 'PhabricatorApplication',
'PhabricatorApplicationsController' => 'PhabricatorController',
'PhabricatorApplicationsListController' => 'PhabricatorApplicationsController',

View file

@ -3,17 +3,15 @@
final class PhabricatorApplicationUninstallController
extends PhabricatorApplicationsController {
private $application;
private $action;
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$this->action = $request->getURIData('action');
$this->application = $request->getURIData('application');
$user = $request->getUser();
$action = $request->getURIData('action');
$application_name = $request->getURIData('application');
$selected = id(new PhabricatorApplicationQuery())
$application = id(new PhabricatorApplicationQuery())
->setViewer($viewer)
->withClasses(array($this->application))
->withClasses(array($application_name))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
@ -21,11 +19,11 @@ final class PhabricatorApplicationUninstallController
))
->executeOne();
if (!$selected) {
if (!$application) {
return new Aphront404Response();
}
$view_uri = $this->getApplicationURI('view/'.$this->application);
$view_uri = $this->getApplicationURI('view/'.$application_name);
$prototypes_enabled = PhabricatorEnv::getEnvConfig(
'phabricator.show-prototypes');
@ -34,7 +32,7 @@ final class PhabricatorApplicationUninstallController
->setUser($viewer)
->addCancelButton($view_uri);
if ($selected->isPrototype() && !$prototypes_enabled) {
if ($application->isPrototype() && !$prototypes_enabled) {
$dialog
->setTitle(pht('Prototypes Not Enabled'))
->appendChild(
@ -46,18 +44,40 @@ final class PhabricatorApplicationUninstallController
}
if ($request->isDialogFormPost()) {
$this->manageApplication();
return id(new AphrontRedirectResponse())->setURI($view_uri);
$xactions = array();
$template = $application->getApplicationTransactionTemplate();
$xactions[] = id(clone $template)
->setTransactionType(
PhabricatorApplicationUninstallTransaction::TRANSACTIONTYPE)
->setNewValue($action);
$editor = id(new PhabricatorApplicationEditor())
->setActor($user)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true)
->setContinueOnMissingFields(true);
try {
$editor->applyTransactions($application, $xactions);
return id(new AphrontRedirectResponse())->setURI($view_uri);
} catch (PhabricatorApplicationTransactionValidationException $ex) {
$validation_exception = $ex;
}
return $this->newDialog()
->setTitle(pht('Validation Failed'))
->setValidationException($validation_exception)
->addCancelButton($view_uri);
}
if ($this->action == 'install') {
if ($selected->canUninstall()) {
if ($action == 'install') {
if ($application->canUninstall()) {
$dialog
->setTitle(pht('Confirmation'))
->appendChild(
pht(
'Install %s application?',
$selected->getName()))
$application->getName()))
->addSubmitButton(pht('Install'));
} else {
@ -66,10 +86,10 @@ final class PhabricatorApplicationUninstallController
->appendChild(pht('You cannot install an installed application.'));
}
} else {
if ($selected->canUninstall()) {
if ($application->canUninstall()) {
$dialog->setTitle(pht('Really Uninstall Application?'));
if ($selected instanceof PhabricatorHomeApplication) {
if ($application instanceof PhabricatorHomeApplication) {
$dialog
->appendParagraph(
pht(
@ -86,7 +106,7 @@ final class PhabricatorApplicationUninstallController
->appendParagraph(
pht(
'Really uninstall the %s application?',
$selected->getName()))
$application->getName()))
->addSubmitButton(pht('Uninstall'));
}
} else {
@ -101,23 +121,4 @@ final class PhabricatorApplicationUninstallController
return id(new AphrontDialogResponse())->setDialog($dialog);
}
public function manageApplication() {
$key = 'phabricator.uninstalled-applications';
$config_entry = PhabricatorConfigEntry::loadConfigEntry($key);
$list = $config_entry->getValue();
$uninstalled = PhabricatorEnv::getEnvConfig($key);
if (isset($uninstalled[$this->application])) {
unset($list[$this->application]);
} else {
$list[$this->application] = true;
}
PhabricatorConfigEditor::storeNewValue(
$this->getViewer(),
$config_entry,
$list,
PhabricatorContentSource::newFromRequest($this->getRequest()));
}
}

View file

@ -14,7 +14,7 @@ final class PhabricatorApplicationPolicyChangeTransaction
return $application->getPolicy($capability);
}
public function applyInternalEffects($object, $value) {
public function applyExternalEffects($object, $value) {
$application = $object;
$user = $this->getActor();

View file

@ -0,0 +1,79 @@
<?php
final class PhabricatorApplicationUninstallTransaction
extends PhabricatorApplicationTransactionType {
const TRANSACTIONTYPE = 'application.uninstall';
public function generateOldValue($object) {
$key = 'phabricator.uninstalled-applications';
$config_entry = PhabricatorConfigEntry::loadConfigEntry($key);
$list = $config_entry->getValue();
$uninstalled = PhabricatorEnv::getEnvConfig($key);
if (isset($uninstalled[get_class($object)])) {
return 'uninstalled';
} else {
return 'installed';
}
}
public function generateNewValue($object, $value) {
if ($value === 'uninstall') {
return 'uninstalled';
} else {
return 'installed';
}
}
public function applyExternalEffects($object, $value) {
$application = $object;
$user = $this->getActor();
$key = 'phabricator.uninstalled-applications';
$config_entry = PhabricatorConfigEntry::loadConfigEntry($key);
$list = $config_entry->getValue();
$uninstalled = PhabricatorEnv::getEnvConfig($key);
if (isset($uninstalled[get_class($application)])) {
unset($list[get_class($application)]);
} else {
$list[get_class($application)] = true;
}
$editor = $this->getEditor();
$content_source = $editor->getContentSource();
PhabricatorConfigEditor::storeNewValue(
$user,
$config_entry,
$list,
$content_source);
}
public function getTitle() {
if ($this->getNewValue() === 'uninstalled') {
return pht(
'%s uninstalled this application.',
$this->renderAuthor());
} else {
return pht(
'%s installed this application.',
$this->renderAuthor());
}
}
public function getTitleForFeed() {
if ($this->getNewValue() === 'uninstalled') {
return pht(
'%s uninstalled %s.',
$this->renderAuthor(),
$this->renderObject());
} else {
return pht(
'%s installed %s.',
$this->renderAuthor(),
$this->renderObject());
}
}
}