1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-29 18:22: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', 'PhabricatorApplicationTransactionWarningException' => 'applications/transactions/exception/PhabricatorApplicationTransactionWarningException.php',
'PhabricatorApplicationTransactionWarningResponse' => 'applications/transactions/response/PhabricatorApplicationTransactionWarningResponse.php', 'PhabricatorApplicationTransactionWarningResponse' => 'applications/transactions/response/PhabricatorApplicationTransactionWarningResponse.php',
'PhabricatorApplicationUninstallController' => 'applications/meta/controller/PhabricatorApplicationUninstallController.php', 'PhabricatorApplicationUninstallController' => 'applications/meta/controller/PhabricatorApplicationUninstallController.php',
'PhabricatorApplicationUninstallTransaction' => 'applications/meta/xactions/PhabricatorApplicationUninstallTransaction.php',
'PhabricatorApplicationsApplication' => 'applications/meta/application/PhabricatorApplicationsApplication.php', 'PhabricatorApplicationsApplication' => 'applications/meta/application/PhabricatorApplicationsApplication.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',
@ -7533,6 +7534,7 @@ phutil_register_library_map(array(
'PhabricatorApplicationTransactionWarningException' => 'Exception', 'PhabricatorApplicationTransactionWarningException' => 'Exception',
'PhabricatorApplicationTransactionWarningResponse' => 'AphrontProxyResponse', 'PhabricatorApplicationTransactionWarningResponse' => 'AphrontProxyResponse',
'PhabricatorApplicationUninstallController' => 'PhabricatorApplicationsController', 'PhabricatorApplicationUninstallController' => 'PhabricatorApplicationsController',
'PhabricatorApplicationUninstallTransaction' => 'PhabricatorApplicationTransactionType',
'PhabricatorApplicationsApplication' => 'PhabricatorApplication', 'PhabricatorApplicationsApplication' => 'PhabricatorApplication',
'PhabricatorApplicationsController' => 'PhabricatorController', 'PhabricatorApplicationsController' => 'PhabricatorController',
'PhabricatorApplicationsListController' => 'PhabricatorApplicationsController', 'PhabricatorApplicationsListController' => 'PhabricatorApplicationsController',

View file

@ -3,17 +3,15 @@
final class PhabricatorApplicationUninstallController final class PhabricatorApplicationUninstallController
extends PhabricatorApplicationsController { extends PhabricatorApplicationsController {
private $application;
private $action;
public function handleRequest(AphrontRequest $request) { public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer(); $viewer = $request->getViewer();
$this->action = $request->getURIData('action'); $user = $request->getUser();
$this->application = $request->getURIData('application'); $action = $request->getURIData('action');
$application_name = $request->getURIData('application');
$selected = id(new PhabricatorApplicationQuery()) $application = id(new PhabricatorApplicationQuery())
->setViewer($viewer) ->setViewer($viewer)
->withClasses(array($this->application)) ->withClasses(array($application_name))
->requireCapabilities( ->requireCapabilities(
array( array(
PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_VIEW,
@ -21,11 +19,11 @@ final class PhabricatorApplicationUninstallController
)) ))
->executeOne(); ->executeOne();
if (!$selected) { if (!$application) {
return new Aphront404Response(); return new Aphront404Response();
} }
$view_uri = $this->getApplicationURI('view/'.$this->application); $view_uri = $this->getApplicationURI('view/'.$application_name);
$prototypes_enabled = PhabricatorEnv::getEnvConfig( $prototypes_enabled = PhabricatorEnv::getEnvConfig(
'phabricator.show-prototypes'); 'phabricator.show-prototypes');
@ -34,7 +32,7 @@ final class PhabricatorApplicationUninstallController
->setUser($viewer) ->setUser($viewer)
->addCancelButton($view_uri); ->addCancelButton($view_uri);
if ($selected->isPrototype() && !$prototypes_enabled) { if ($application->isPrototype() && !$prototypes_enabled) {
$dialog $dialog
->setTitle(pht('Prototypes Not Enabled')) ->setTitle(pht('Prototypes Not Enabled'))
->appendChild( ->appendChild(
@ -46,18 +44,40 @@ final class PhabricatorApplicationUninstallController
} }
if ($request->isDialogFormPost()) { if ($request->isDialogFormPost()) {
$this->manageApplication(); $xactions = array();
return id(new AphrontRedirectResponse())->setURI($view_uri); $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 ($action == 'install') {
if ($selected->canUninstall()) { if ($application->canUninstall()) {
$dialog $dialog
->setTitle(pht('Confirmation')) ->setTitle(pht('Confirmation'))
->appendChild( ->appendChild(
pht( pht(
'Install %s application?', 'Install %s application?',
$selected->getName())) $application->getName()))
->addSubmitButton(pht('Install')); ->addSubmitButton(pht('Install'));
} else { } else {
@ -66,10 +86,10 @@ final class PhabricatorApplicationUninstallController
->appendChild(pht('You cannot install an installed application.')); ->appendChild(pht('You cannot install an installed application.'));
} }
} else { } else {
if ($selected->canUninstall()) { if ($application->canUninstall()) {
$dialog->setTitle(pht('Really Uninstall Application?')); $dialog->setTitle(pht('Really Uninstall Application?'));
if ($selected instanceof PhabricatorHomeApplication) { if ($application instanceof PhabricatorHomeApplication) {
$dialog $dialog
->appendParagraph( ->appendParagraph(
pht( pht(
@ -86,7 +106,7 @@ final class PhabricatorApplicationUninstallController
->appendParagraph( ->appendParagraph(
pht( pht(
'Really uninstall the %s application?', 'Really uninstall the %s application?',
$selected->getName())) $application->getName()))
->addSubmitButton(pht('Uninstall')); ->addSubmitButton(pht('Uninstall'));
} }
} else { } else {
@ -101,23 +121,4 @@ final class PhabricatorApplicationUninstallController
return id(new AphrontDialogResponse())->setDialog($dialog); 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); return $application->getPolicy($capability);
} }
public function applyInternalEffects($object, $value) { public function applyExternalEffects($object, $value) {
$application = $object; $application = $object;
$user = $this->getActor(); $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());
}
}
}