mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 14:52:41 +01:00
Allow Herald rules to be disabled, instead of deleted
Summary: Ref T603. Ref T1279. Further improves transaction and policy support for Herald. - Instead of deleting rules (which wipes out history and can't be undone) allow them to be disabled. - Track disables with transactions. - Gate disables with policy controls. - Show policy and status information in the headers. - Show transaction history on rule detail screens. - Remove the delete controller. - Support disabled queries in the ApplicationSearch. Test Plan: - Enabled and disabled rules. - Searched for enabled/disabled rules. - Verified disabled rules don't activate. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T1279, T603 Differential Revision: https://secure.phabricator.com/D7247
This commit is contained in:
parent
c6add6ae73
commit
953ff197bf
20 changed files with 408 additions and 96 deletions
2
resources/sql/patches/20131006.hdisable.sql
Normal file
2
resources/sql/patches/20131006.hdisable.sql
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_herald.herald_rule
|
||||||
|
ADD isDisabled INT UNSIGNED NOT NULL DEFAULT 0;
|
|
@ -631,8 +631,8 @@ phutil_register_library_map(array(
|
||||||
'HeraldConditionTranscript' => 'applications/herald/storage/transcript/HeraldConditionTranscript.php',
|
'HeraldConditionTranscript' => 'applications/herald/storage/transcript/HeraldConditionTranscript.php',
|
||||||
'HeraldController' => 'applications/herald/controller/HeraldController.php',
|
'HeraldController' => 'applications/herald/controller/HeraldController.php',
|
||||||
'HeraldDAO' => 'applications/herald/storage/HeraldDAO.php',
|
'HeraldDAO' => 'applications/herald/storage/HeraldDAO.php',
|
||||||
'HeraldDeleteController' => 'applications/herald/controller/HeraldDeleteController.php',
|
|
||||||
'HeraldDifferentialRevisionAdapter' => 'applications/herald/adapter/HeraldDifferentialRevisionAdapter.php',
|
'HeraldDifferentialRevisionAdapter' => 'applications/herald/adapter/HeraldDifferentialRevisionAdapter.php',
|
||||||
|
'HeraldDisableController' => 'applications/herald/controller/HeraldDisableController.php',
|
||||||
'HeraldEditLogQuery' => 'applications/herald/query/HeraldEditLogQuery.php',
|
'HeraldEditLogQuery' => 'applications/herald/query/HeraldEditLogQuery.php',
|
||||||
'HeraldEffect' => 'applications/herald/engine/HeraldEffect.php',
|
'HeraldEffect' => 'applications/herald/engine/HeraldEffect.php',
|
||||||
'HeraldEngine' => 'applications/herald/engine/HeraldEngine.php',
|
'HeraldEngine' => 'applications/herald/engine/HeraldEngine.php',
|
||||||
|
@ -651,6 +651,7 @@ phutil_register_library_map(array(
|
||||||
'HeraldRuleEdit' => 'applications/herald/storage/HeraldRuleEdit.php',
|
'HeraldRuleEdit' => 'applications/herald/storage/HeraldRuleEdit.php',
|
||||||
'HeraldRuleEditHistoryController' => 'applications/herald/controller/HeraldRuleEditHistoryController.php',
|
'HeraldRuleEditHistoryController' => 'applications/herald/controller/HeraldRuleEditHistoryController.php',
|
||||||
'HeraldRuleEditHistoryView' => 'applications/herald/view/HeraldRuleEditHistoryView.php',
|
'HeraldRuleEditHistoryView' => 'applications/herald/view/HeraldRuleEditHistoryView.php',
|
||||||
|
'HeraldRuleEditor' => 'applications/herald/editor/HeraldRuleEditor.php',
|
||||||
'HeraldRuleListController' => 'applications/herald/controller/HeraldRuleListController.php',
|
'HeraldRuleListController' => 'applications/herald/controller/HeraldRuleListController.php',
|
||||||
'HeraldRuleQuery' => 'applications/herald/query/HeraldRuleQuery.php',
|
'HeraldRuleQuery' => 'applications/herald/query/HeraldRuleQuery.php',
|
||||||
'HeraldRuleSearchEngine' => 'applications/herald/query/HeraldRuleSearchEngine.php',
|
'HeraldRuleSearchEngine' => 'applications/herald/query/HeraldRuleSearchEngine.php',
|
||||||
|
@ -660,6 +661,7 @@ phutil_register_library_map(array(
|
||||||
'HeraldRuleTypeConfig' => 'applications/herald/config/HeraldRuleTypeConfig.php',
|
'HeraldRuleTypeConfig' => 'applications/herald/config/HeraldRuleTypeConfig.php',
|
||||||
'HeraldRuleViewController' => 'applications/herald/controller/HeraldRuleViewController.php',
|
'HeraldRuleViewController' => 'applications/herald/controller/HeraldRuleViewController.php',
|
||||||
'HeraldTestConsoleController' => 'applications/herald/controller/HeraldTestConsoleController.php',
|
'HeraldTestConsoleController' => 'applications/herald/controller/HeraldTestConsoleController.php',
|
||||||
|
'HeraldTransactionQuery' => 'applications/herald/query/HeraldTransactionQuery.php',
|
||||||
'HeraldTranscript' => 'applications/herald/storage/transcript/HeraldTranscript.php',
|
'HeraldTranscript' => 'applications/herald/storage/transcript/HeraldTranscript.php',
|
||||||
'HeraldTranscriptController' => 'applications/herald/controller/HeraldTranscriptController.php',
|
'HeraldTranscriptController' => 'applications/herald/controller/HeraldTranscriptController.php',
|
||||||
'HeraldTranscriptListController' => 'applications/herald/controller/HeraldTranscriptListController.php',
|
'HeraldTranscriptListController' => 'applications/herald/controller/HeraldTranscriptListController.php',
|
||||||
|
@ -2724,8 +2726,8 @@ phutil_register_library_map(array(
|
||||||
'HeraldCondition' => 'HeraldDAO',
|
'HeraldCondition' => 'HeraldDAO',
|
||||||
'HeraldController' => 'PhabricatorController',
|
'HeraldController' => 'PhabricatorController',
|
||||||
'HeraldDAO' => 'PhabricatorLiskDAO',
|
'HeraldDAO' => 'PhabricatorLiskDAO',
|
||||||
'HeraldDeleteController' => 'HeraldController',
|
|
||||||
'HeraldDifferentialRevisionAdapter' => 'HeraldAdapter',
|
'HeraldDifferentialRevisionAdapter' => 'HeraldAdapter',
|
||||||
|
'HeraldDisableController' => 'HeraldController',
|
||||||
'HeraldEditLogQuery' => 'PhabricatorOffsetPagedQuery',
|
'HeraldEditLogQuery' => 'PhabricatorOffsetPagedQuery',
|
||||||
'HeraldInvalidActionException' => 'Exception',
|
'HeraldInvalidActionException' => 'Exception',
|
||||||
'HeraldInvalidConditionException' => 'Exception',
|
'HeraldInvalidConditionException' => 'Exception',
|
||||||
|
@ -2744,6 +2746,7 @@ phutil_register_library_map(array(
|
||||||
'HeraldRuleEdit' => 'HeraldDAO',
|
'HeraldRuleEdit' => 'HeraldDAO',
|
||||||
'HeraldRuleEditHistoryController' => 'HeraldController',
|
'HeraldRuleEditHistoryController' => 'HeraldController',
|
||||||
'HeraldRuleEditHistoryView' => 'AphrontView',
|
'HeraldRuleEditHistoryView' => 'AphrontView',
|
||||||
|
'HeraldRuleEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||||
'HeraldRuleListController' =>
|
'HeraldRuleListController' =>
|
||||||
array(
|
array(
|
||||||
0 => 'HeraldController',
|
0 => 'HeraldController',
|
||||||
|
@ -2755,6 +2758,7 @@ phutil_register_library_map(array(
|
||||||
'HeraldRuleTransactionComment' => 'PhabricatorApplicationTransactionComment',
|
'HeraldRuleTransactionComment' => 'PhabricatorApplicationTransactionComment',
|
||||||
'HeraldRuleViewController' => 'HeraldController',
|
'HeraldRuleViewController' => 'HeraldController',
|
||||||
'HeraldTestConsoleController' => 'HeraldController',
|
'HeraldTestConsoleController' => 'HeraldController',
|
||||||
|
'HeraldTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||||
'HeraldTranscript' =>
|
'HeraldTranscript' =>
|
||||||
array(
|
array(
|
||||||
0 => 'HeraldDAO',
|
0 => 'HeraldDAO',
|
||||||
|
|
|
@ -41,8 +41,9 @@ final class PhabricatorApplicationHerald extends PhabricatorApplication {
|
||||||
=> 'HeraldNewController',
|
=> 'HeraldNewController',
|
||||||
'rule/(?P<id>[1-9]\d*)/' => 'HeraldRuleViewController',
|
'rule/(?P<id>[1-9]\d*)/' => 'HeraldRuleViewController',
|
||||||
'edit/(?:(?P<id>[1-9]\d*)/)?' => 'HeraldRuleController',
|
'edit/(?:(?P<id>[1-9]\d*)/)?' => 'HeraldRuleController',
|
||||||
|
'disable/(?P<id>[1-9]\d*)/(?P<action>\w+)/' =>
|
||||||
|
'HeraldDisableController',
|
||||||
'history/(?:(?P<id>[1-9]\d*)/)?' => 'HeraldRuleEditHistoryController',
|
'history/(?:(?P<id>[1-9]\d*)/)?' => 'HeraldRuleEditHistoryController',
|
||||||
'delete/(?P<id>[1-9]\d*)/' => 'HeraldDeleteController',
|
|
||||||
'test/' => 'HeraldTestConsoleController',
|
'test/' => 'HeraldTestConsoleController',
|
||||||
'transcript/' => 'HeraldTranscriptListController',
|
'transcript/' => 'HeraldTranscriptListController',
|
||||||
'transcript/(?P<id>[1-9]\d*)/(?:(?P<filter>\w+)/)?'
|
'transcript/(?P<id>[1-9]\d*)/(?:(?P<filter>\w+)/)?'
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class HeraldDeleteController extends HeraldController {
|
|
||||||
|
|
||||||
private $id;
|
|
||||||
|
|
||||||
public function getFilter() {
|
|
||||||
// note this controller is only used from a dialog-context at the moment
|
|
||||||
// and there is actually no "delete" filter
|
|
||||||
return 'delete';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function willProcessRequest(array $data) {
|
|
||||||
$this->id = $data['id'];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function processRequest() {
|
|
||||||
|
|
||||||
$rule = id(new HeraldRule())->load($this->id);
|
|
||||||
if (!$rule) {
|
|
||||||
return new Aphront404Response();
|
|
||||||
}
|
|
||||||
|
|
||||||
$request = $this->getRequest();
|
|
||||||
$user = $request->getUser();
|
|
||||||
|
|
||||||
// Anyone can delete a global rule, but only the rule owner can delete a
|
|
||||||
// personal one.
|
|
||||||
if ($rule->getRuleType() == HeraldRuleTypeConfig::RULE_TYPE_PERSONAL) {
|
|
||||||
if ($user->getPHID() != $rule->getAuthorPHID()) {
|
|
||||||
return new Aphront400Response();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($request->isFormPost()) {
|
|
||||||
$rule->openTransaction();
|
|
||||||
$rule->logEdit($user->getPHID(), 'delete');
|
|
||||||
$rule->delete();
|
|
||||||
$rule->saveTransaction();
|
|
||||||
return id(new AphrontReloadResponse())->setURI('/herald/');
|
|
||||||
}
|
|
||||||
|
|
||||||
$dialog = new AphrontDialogView();
|
|
||||||
$dialog->setUser($request->getUser());
|
|
||||||
$dialog->setTitle(pht('Really delete this rule?'));
|
|
||||||
$dialog->appendChild(pht(
|
|
||||||
"Are you sure you want to delete the rule: %s?",
|
|
||||||
$rule->getName()));
|
|
||||||
$dialog->addSubmitButton(pht('Delete'));
|
|
||||||
$dialog->addCancelButton('/herald/');
|
|
||||||
$dialog->setSubmitURI($request->getPath());
|
|
||||||
|
|
||||||
return id(new AphrontDialogResponse())->setDialog($dialog);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class HeraldDisableController extends HeraldController {
|
||||||
|
|
||||||
|
private $id;
|
||||||
|
private $action;
|
||||||
|
|
||||||
|
public function willProcessRequest(array $data) {
|
||||||
|
$this->id = $data['id'];
|
||||||
|
$this->action = $data['action'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$viewer = $request->getUser();
|
||||||
|
$id = $this->id;
|
||||||
|
|
||||||
|
$rule = id(new HeraldRuleQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withIDs(array($id))
|
||||||
|
->requireCapabilities(
|
||||||
|
array(
|
||||||
|
PhabricatorPolicyCapability::CAN_VIEW,
|
||||||
|
PhabricatorPolicyCapability::CAN_EDIT,
|
||||||
|
))
|
||||||
|
->executeOne();
|
||||||
|
if (!$rule) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($rule->getRuleType() == HeraldRuleTypeConfig::RULE_TYPE_GLOBAL) {
|
||||||
|
$this->requireApplicationCapability(
|
||||||
|
PhabricatorApplicationHerald::CAN_CREATE_GLOBAL_RULE);
|
||||||
|
}
|
||||||
|
|
||||||
|
$view_uri = $this->getApplicationURI("rule/{$id}/");
|
||||||
|
|
||||||
|
$is_disable = ($this->action === 'disable');
|
||||||
|
|
||||||
|
if ($request->isFormPost()) {
|
||||||
|
$xaction = id(new HeraldRuleTransaction())
|
||||||
|
->setTransactionType(HeraldRuleTransaction::TYPE_DISABLE)
|
||||||
|
->setNewValue($is_disable);
|
||||||
|
|
||||||
|
id(new HeraldRuleEditor())
|
||||||
|
->setActor($viewer)
|
||||||
|
->setContinueOnNoEffect(true)
|
||||||
|
->setContentSourceFromRequest($request)
|
||||||
|
->applyTransactions($rule, array($xaction));
|
||||||
|
|
||||||
|
return id(new AphrontRedirectResponse())->setURI($view_uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($is_disable) {
|
||||||
|
$title = pht('Really disable this rule?');
|
||||||
|
$body = pht('This rule will no longer activate.');
|
||||||
|
$button = pht('Disable Rule');
|
||||||
|
} else {
|
||||||
|
$title = pht('Really enable this rule?');
|
||||||
|
$body = pht('This rule will become active again.');
|
||||||
|
$button = pht('Enable Rule');
|
||||||
|
}
|
||||||
|
|
||||||
|
$dialog = id(new AphrontDialogView())
|
||||||
|
->setUser($viewer)
|
||||||
|
->setTitle($title)
|
||||||
|
->appendChild($body)
|
||||||
|
->addSubmitButton($button)
|
||||||
|
->addCancelButton($view_uri);
|
||||||
|
|
||||||
|
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -54,18 +54,17 @@ final class HeraldRuleListController extends HeraldController
|
||||||
$item->addIcon('world', pht('Global Rule'));
|
$item->addIcon('world', pht('Global Rule'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($rule->getIsDisabled()) {
|
||||||
|
$item->setDisabled(true);
|
||||||
|
$item->addIcon('disable-grey', pht('Disabled'));
|
||||||
|
}
|
||||||
|
|
||||||
$item->addAction(
|
$item->addAction(
|
||||||
id(new PHUIListItemView())
|
id(new PHUIListItemView())
|
||||||
->setHref($this->getApplicationURI("history/{$id}/"))
|
->setHref($this->getApplicationURI("history/{$id}/"))
|
||||||
->setIcon('transcript')
|
->setIcon('transcript')
|
||||||
->setName(pht('Edit Log')));
|
->setName(pht('Edit Log')));
|
||||||
|
|
||||||
$item->addAction(
|
|
||||||
id(new PHUIListItemView())
|
|
||||||
->setHref('/herald/delete/'.$rule->getID().'/')
|
|
||||||
->setIcon('delete')
|
|
||||||
->setWorkflow(true));
|
|
||||||
|
|
||||||
$content_type_name = idx($content_type_map, $rule->getContentType());
|
$content_type_name = idx($content_type_map, $rule->getContentType());
|
||||||
$item->addAttribute(pht('Affects: %s', $content_type_name));
|
$item->addAttribute(pht('Affects: %s', $content_type_name));
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,21 @@ final class HeraldRuleViewController extends HeraldController {
|
||||||
}
|
}
|
||||||
|
|
||||||
$header = id(new PHUIHeaderView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setHeader($rule->getName());
|
->setUser($viewer)
|
||||||
|
->setHeader($rule->getName())
|
||||||
|
->setPolicyObject($rule);
|
||||||
|
|
||||||
|
if ($rule->getIsDisabled()) {
|
||||||
|
$header->setStatus(
|
||||||
|
'oh-open',
|
||||||
|
'red',
|
||||||
|
pht('Disabled'));
|
||||||
|
} else {
|
||||||
|
$header->setStatus(
|
||||||
|
'oh-open',
|
||||||
|
null,
|
||||||
|
pht('Active'));
|
||||||
|
}
|
||||||
|
|
||||||
$actions = $this->buildActionView($rule);
|
$actions = $this->buildActionView($rule);
|
||||||
$properties = $this->buildPropertyView($rule);
|
$properties = $this->buildPropertyView($rule);
|
||||||
|
@ -37,10 +51,13 @@ final class HeraldRuleViewController extends HeraldController {
|
||||||
->setActionList($actions)
|
->setActionList($actions)
|
||||||
->setPropertyList($properties);
|
->setPropertyList($properties);
|
||||||
|
|
||||||
|
$timeline = $this->buildTimeline($rule);
|
||||||
|
|
||||||
return $this->buildApplicationPage(
|
return $this->buildApplicationPage(
|
||||||
array(
|
array(
|
||||||
$crumbs,
|
$crumbs,
|
||||||
$object_box,
|
$object_box,
|
||||||
|
$timeline,
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'title' => $rule->getName(),
|
'title' => $rule->getName(),
|
||||||
|
@ -70,6 +87,25 @@ final class HeraldRuleViewController extends HeraldController {
|
||||||
->setDisabled(!$can_edit)
|
->setDisabled(!$can_edit)
|
||||||
->setWorkflow(!$can_edit));
|
->setWorkflow(!$can_edit));
|
||||||
|
|
||||||
|
if ($rule->getIsDisabled()) {
|
||||||
|
$disable_uri = "disable/{$id}/enable/";
|
||||||
|
$disable_icon = 'enable';
|
||||||
|
$disable_name = pht('Enable Rule');
|
||||||
|
} else {
|
||||||
|
$disable_uri = "disable/{$id}/disable/";
|
||||||
|
$disable_icon = 'disable';
|
||||||
|
$disable_name = pht('Disable Rule');
|
||||||
|
}
|
||||||
|
|
||||||
|
$view->addAction(
|
||||||
|
id(new PhabricatorActionView())
|
||||||
|
->setName(pht('Disable Rule'))
|
||||||
|
->setHref($this->getApplicationURI($disable_uri))
|
||||||
|
->setIcon($disable_icon)
|
||||||
|
->setName($disable_name)
|
||||||
|
->setDisabled(!$can_edit)
|
||||||
|
->setWorkflow(true));
|
||||||
|
|
||||||
return $view;
|
return $view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,4 +151,31 @@ final class HeraldRuleViewController extends HeraldController {
|
||||||
return $view;
|
return $view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function buildTimeline(HeraldRule $rule) {
|
||||||
|
$viewer = $this->getRequest()->getUser();
|
||||||
|
|
||||||
|
$xactions = id(new HeraldTransactionQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withObjectPHIDs(array($rule->getPHID()))
|
||||||
|
->needComments(true)
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
$engine = id(new PhabricatorMarkupEngine())
|
||||||
|
->setViewer($viewer);
|
||||||
|
foreach ($xactions as $xaction) {
|
||||||
|
if ($xaction->getComment()) {
|
||||||
|
$engine->addObject(
|
||||||
|
$xaction->getComment(),
|
||||||
|
PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$engine->process();
|
||||||
|
|
||||||
|
return id(new PhabricatorApplicationTransactionView())
|
||||||
|
->setUser($viewer)
|
||||||
|
->setObjectPHID($rule->getPHID())
|
||||||
|
->setTransactions($xactions)
|
||||||
|
->setMarkupEngine($engine);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,7 @@ final class HeraldTestConsoleController extends HeraldController {
|
||||||
$rules = id(new HeraldRuleQuery())
|
$rules = id(new HeraldRuleQuery())
|
||||||
->setViewer($user)
|
->setViewer($user)
|
||||||
->withContentTypes(array($adapter->getAdapterContentType()))
|
->withContentTypes(array($adapter->getAdapterContentType()))
|
||||||
|
->withDisabled(false)
|
||||||
->needConditionsAndActions(true)
|
->needConditionsAndActions(true)
|
||||||
->needAppliedToPHIDs(array($object->getPHID()))
|
->needAppliedToPHIDs(array($object->getPHID()))
|
||||||
->needValidateAuthors(true)
|
->needValidateAuthors(true)
|
||||||
|
|
54
src/applications/herald/editor/HeraldRuleEditor.php
Normal file
54
src/applications/herald/editor/HeraldRuleEditor.php
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class HeraldRuleEditor
|
||||||
|
extends PhabricatorApplicationTransactionEditor {
|
||||||
|
|
||||||
|
public function getTransactionTypes() {
|
||||||
|
$types = parent::getTransactionTypes();
|
||||||
|
|
||||||
|
$types[] = PhabricatorTransactions::TYPE_COMMENT;
|
||||||
|
$types[] = HeraldRuleTransaction::TYPE_DISABLE;
|
||||||
|
|
||||||
|
return $types;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getCustomTransactionOldValue(
|
||||||
|
PhabricatorLiskDAO $object,
|
||||||
|
PhabricatorApplicationTransaction $xaction) {
|
||||||
|
|
||||||
|
switch ($xaction->getTransactionType()) {
|
||||||
|
case HeraldRuleTransaction::TYPE_DISABLE:
|
||||||
|
return (int)$object->getIsDisabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getCustomTransactionNewValue(
|
||||||
|
PhabricatorLiskDAO $object,
|
||||||
|
PhabricatorApplicationTransaction $xaction) {
|
||||||
|
|
||||||
|
switch ($xaction->getTransactionType()) {
|
||||||
|
case HeraldRuleTransaction::TYPE_DISABLE:
|
||||||
|
return (int)$xaction->getNewValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function applyCustomInternalTransaction(
|
||||||
|
PhabricatorLiskDAO $object,
|
||||||
|
PhabricatorApplicationTransaction $xaction) {
|
||||||
|
|
||||||
|
switch ($xaction->getTransactionType()) {
|
||||||
|
case HeraldRuleTransaction::TYPE_DISABLE:
|
||||||
|
return $object->setIsDisabled($xaction->getNewValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function applyCustomExternalTransaction(
|
||||||
|
PhabricatorLiskDAO $object,
|
||||||
|
PhabricatorApplicationTransaction $xaction) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -27,6 +27,7 @@ final class HeraldEngine {
|
||||||
public static function loadAndApplyRules(HeraldAdapter $adapter) {
|
public static function loadAndApplyRules(HeraldAdapter $adapter) {
|
||||||
$rules = id(new HeraldRuleQuery())
|
$rules = id(new HeraldRuleQuery())
|
||||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||||
|
->withDisabled(false)
|
||||||
->withContentTypes(array($adapter->getAdapterContentType()))
|
->withContentTypes(array($adapter->getAdapterContentType()))
|
||||||
->needConditionsAndActions(true)
|
->needConditionsAndActions(true)
|
||||||
->needAppliedToPHIDs(array($adapter->getPHID()))
|
->needAppliedToPHIDs(array($adapter->getPHID()))
|
||||||
|
|
|
@ -8,6 +8,7 @@ final class HeraldRuleQuery
|
||||||
private $authorPHIDs;
|
private $authorPHIDs;
|
||||||
private $ruleTypes;
|
private $ruleTypes;
|
||||||
private $contentTypes;
|
private $contentTypes;
|
||||||
|
private $disabled;
|
||||||
|
|
||||||
private $needConditionsAndActions;
|
private $needConditionsAndActions;
|
||||||
private $needAppliedToPHIDs;
|
private $needAppliedToPHIDs;
|
||||||
|
@ -43,6 +44,11 @@ final class HeraldRuleQuery
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function withDisabled($disabled) {
|
||||||
|
$this->disabled = $disabled;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function needConditionsAndActions($need) {
|
public function needConditionsAndActions($need) {
|
||||||
$this->needConditionsAndActions = $need;
|
$this->needConditionsAndActions = $need;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -82,6 +88,7 @@ final class HeraldRuleQuery
|
||||||
$types = HeraldAdapter::getEnabledAdapterMap($this->getViewer());
|
$types = HeraldAdapter::getEnabledAdapterMap($this->getViewer());
|
||||||
foreach ($rules as $key => $rule) {
|
foreach ($rules as $key => $rule) {
|
||||||
if (empty($types[$rule->getContentType()])) {
|
if (empty($types[$rule->getContentType()])) {
|
||||||
|
$this->didRejectResult($rule);
|
||||||
unset($rules[$key]);
|
unset($rules[$key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,6 +178,13 @@ final class HeraldRuleQuery
|
||||||
$this->contentTypes);
|
$this->contentTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->disabled !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'rule.isDisabled = %d',
|
||||||
|
(int)$this->disabled);
|
||||||
|
}
|
||||||
|
|
||||||
$where[] = $this->buildPagingClause($conn_r);
|
$where[] = $this->buildPagingClause($conn_r);
|
||||||
|
|
||||||
return $this->formatWhereClause($where);
|
return $this->formatWhereClause($where);
|
||||||
|
|
|
@ -12,6 +12,9 @@ final class HeraldRuleSearchEngine
|
||||||
|
|
||||||
$saved->setParameter('contentType', $request->getStr('contentType'));
|
$saved->setParameter('contentType', $request->getStr('contentType'));
|
||||||
$saved->setParameter('ruleType', $request->getStr('ruleType'));
|
$saved->setParameter('ruleType', $request->getStr('ruleType'));
|
||||||
|
$saved->setParameter(
|
||||||
|
'disabled',
|
||||||
|
$this->readBoolFromRequest($request, 'disabled'));
|
||||||
|
|
||||||
return $saved;
|
return $saved;
|
||||||
}
|
}
|
||||||
|
@ -36,6 +39,11 @@ final class HeraldRuleSearchEngine
|
||||||
$query->withRuleTypes(array($rule_type));
|
$query->withRuleTypes(array($rule_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$disabled = $saved->getParameter('disabled');
|
||||||
|
if ($disabled !== null) {
|
||||||
|
$query->withDisabled($disabled);
|
||||||
|
}
|
||||||
|
|
||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +79,18 @@ final class HeraldRuleSearchEngine
|
||||||
->setName('ruleType')
|
->setName('ruleType')
|
||||||
->setLabel(pht('Rule Type'))
|
->setLabel(pht('Rule Type'))
|
||||||
->setValue($rule_type)
|
->setValue($rule_type)
|
||||||
->setOptions($this->getRuleTypeOptions()));
|
->setOptions($this->getRuleTypeOptions()))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormSelectControl())
|
||||||
|
->setName('disabled')
|
||||||
|
->setLabel(pht('Rule Status'))
|
||||||
|
->setValue($this->getBoolFromQuery($saved_query, 'disabled'))
|
||||||
|
->setOptions(
|
||||||
|
array(
|
||||||
|
'' => pht('Show Enabled and Disabled Rules'),
|
||||||
|
'false' => pht('Show Only Enabled Rules'),
|
||||||
|
'true' => pht('Show Only Disabled Rules'),
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getURI($path) {
|
protected function getURI($path) {
|
||||||
|
@ -85,6 +104,7 @@ final class HeraldRuleSearchEngine
|
||||||
$names['authored'] = pht('Authored');
|
$names['authored'] = pht('Authored');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$names['active'] = pht('Active');
|
||||||
$names['all'] = pht('All');
|
$names['all'] = pht('All');
|
||||||
|
|
||||||
return $names;
|
return $names;
|
||||||
|
@ -95,13 +115,17 @@ final class HeraldRuleSearchEngine
|
||||||
$query = $this->newSavedQuery();
|
$query = $this->newSavedQuery();
|
||||||
$query->setQueryKey($query_key);
|
$query->setQueryKey($query_key);
|
||||||
|
|
||||||
|
$viewer_phid = $this->requireViewer()->getPHID();
|
||||||
|
|
||||||
switch ($query_key) {
|
switch ($query_key) {
|
||||||
case 'all':
|
case 'all':
|
||||||
return $query;
|
return $query;
|
||||||
|
case 'active':
|
||||||
|
return $query->setParameter('disabled', false);
|
||||||
case 'authored':
|
case 'authored':
|
||||||
return $query->setParameter(
|
return $query
|
||||||
'authorPHIDs',
|
->setParameter('authorPHIDs', array($viewer_phid))
|
||||||
array($this->requireViewer()->getPHID()));
|
->setParameter('disabled', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::buildSavedQueryFromBuiltin($query_key);
|
return parent::buildSavedQueryFromBuiltin($query_key);
|
||||||
|
|
10
src/applications/herald/query/HeraldTransactionQuery.php
Normal file
10
src/applications/herald/query/HeraldTransactionQuery.php
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class HeraldTransactionQuery
|
||||||
|
extends PhabricatorApplicationTransactionQuery {
|
||||||
|
|
||||||
|
public function getTemplateApplicationTransaction() {
|
||||||
|
return new HeraldRuleTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -12,6 +12,7 @@ final class HeraldRule extends HeraldDAO
|
||||||
protected $mustMatchAll;
|
protected $mustMatchAll;
|
||||||
protected $repetitionPolicy;
|
protected $repetitionPolicy;
|
||||||
protected $ruleType;
|
protected $ruleType;
|
||||||
|
protected $isDisabled = 0;
|
||||||
|
|
||||||
protected $configVersion = 14;
|
protected $configVersion = 14;
|
||||||
|
|
||||||
|
@ -198,7 +199,15 @@ final class HeraldRule extends HeraldDAO
|
||||||
|
|
||||||
public function getPolicy($capability) {
|
public function getPolicy($capability) {
|
||||||
if ($this->isGlobalRule()) {
|
if ($this->isGlobalRule()) {
|
||||||
return PhabricatorPolicies::POLICY_USER;
|
switch ($capability) {
|
||||||
|
case PhabricatorPolicyCapability::CAN_VIEW:
|
||||||
|
return PhabricatorPolicies::POLICY_USER;
|
||||||
|
case PhabricatorPolicyCapability::CAN_EDIT:
|
||||||
|
$app = 'PhabricatorApplicationHerald';
|
||||||
|
$herald = PhabricatorApplication::getByClass($app);
|
||||||
|
$global = PhabricatorApplicationHerald::CAN_CREATE_GLOBAL_RULE;
|
||||||
|
return $herald->getPolicy($global);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return PhabricatorPolicies::POLICY_NOONE;
|
return PhabricatorPolicies::POLICY_NOONE;
|
||||||
}
|
}
|
||||||
|
@ -213,9 +222,11 @@ final class HeraldRule extends HeraldDAO
|
||||||
}
|
}
|
||||||
|
|
||||||
public function describeAutomaticCapability($capability) {
|
public function describeAutomaticCapability($capability) {
|
||||||
// TODO: (T603) Sort this out.
|
if ($this->isPersonalRule()) {
|
||||||
|
return pht("A personal rule's owner can always view and edit it.");
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ final class HeraldRuleTransaction
|
||||||
extends PhabricatorApplicationTransaction {
|
extends PhabricatorApplicationTransaction {
|
||||||
|
|
||||||
const TYPE_EDIT = 'herald:edit';
|
const TYPE_EDIT = 'herald:edit';
|
||||||
|
const TYPE_DISABLE = 'herald:disable';
|
||||||
|
|
||||||
public function getApplicationName() {
|
public function getApplicationName() {
|
||||||
return 'herald';
|
return 'herald';
|
||||||
|
@ -17,5 +18,75 @@ final class HeraldRuleTransaction
|
||||||
return new HeraldRuleTransactionComment();
|
return new HeraldRuleTransactionComment();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
public function getColor() {
|
||||||
|
$old = $this->getOldValue();
|
||||||
|
$new = $this->getNewValue();
|
||||||
|
|
||||||
|
switch ($this->getTransactionType()) {
|
||||||
|
case self::TYPE_DISABLE:
|
||||||
|
if ($new) {
|
||||||
|
return 'red';
|
||||||
|
} else {
|
||||||
|
return 'green';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::getColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getActionName() {
|
||||||
|
$old = $this->getOldValue();
|
||||||
|
$new = $this->getNewValue();
|
||||||
|
|
||||||
|
switch ($this->getTransactionType()) {
|
||||||
|
case self::TYPE_DISABLE:
|
||||||
|
if ($new) {
|
||||||
|
return pht('Disabled');
|
||||||
|
} else {
|
||||||
|
return pht('Enabled');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::getActionName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIcon() {
|
||||||
|
$old = $this->getOldValue();
|
||||||
|
$new = $this->getNewValue();
|
||||||
|
|
||||||
|
switch ($this->getTransactionType()) {
|
||||||
|
case self::TYPE_DISABLE:
|
||||||
|
if ($new) {
|
||||||
|
return 'disable';
|
||||||
|
} else {
|
||||||
|
return 'enable';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::getIcon();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getTitle() {
|
||||||
|
$author_phid = $this->getAuthorPHID();
|
||||||
|
|
||||||
|
$old = $this->getOldValue();
|
||||||
|
$new = $this->getNewValue();
|
||||||
|
|
||||||
|
switch ($this->getTransactionType()) {
|
||||||
|
case self::TYPE_DISABLE:
|
||||||
|
if ($new) {
|
||||||
|
return pht(
|
||||||
|
'%s disabled this rule.',
|
||||||
|
$this->renderHandleLink($author_phid));
|
||||||
|
} else {
|
||||||
|
return pht(
|
||||||
|
'%s enabled this rule.',
|
||||||
|
$this->renderHandleLink($author_phid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::getTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -12,9 +12,15 @@ final class PhabricatorAppSearchEngine
|
||||||
|
|
||||||
$saved->setParameter('name', $request->getStr('name'));
|
$saved->setParameter('name', $request->getStr('name'));
|
||||||
|
|
||||||
$saved->setParameter('installed', $this->readBool($request, 'installed'));
|
$saved->setParameter(
|
||||||
$saved->setParameter('beta', $this->readBool($request, 'beta'));
|
'installed',
|
||||||
$saved->setParameter('firstParty', $this->readBool($request, 'firstParty'));
|
$this->readBoolFromRequest($request, 'installed'));
|
||||||
|
$saved->setParameter(
|
||||||
|
'beta',
|
||||||
|
$this->readBoolFromRequest($request, 'beta'));
|
||||||
|
$saved->setParameter(
|
||||||
|
'firstParty',
|
||||||
|
$this->readBoolFromRequest($request, 'firstParty'));
|
||||||
|
|
||||||
return $saved;
|
return $saved;
|
||||||
}
|
}
|
||||||
|
@ -61,7 +67,7 @@ final class PhabricatorAppSearchEngine
|
||||||
id(new AphrontFormSelectControl())
|
id(new AphrontFormSelectControl())
|
||||||
->setLabel(pht('Installed'))
|
->setLabel(pht('Installed'))
|
||||||
->setName('installed')
|
->setName('installed')
|
||||||
->setValue($this->getBool($saved, 'installed'))
|
->setValue($this->getBoolFromQuery($saved, 'installed'))
|
||||||
->setOptions(
|
->setOptions(
|
||||||
array(
|
array(
|
||||||
'' => pht('Show All Applications'),
|
'' => pht('Show All Applications'),
|
||||||
|
@ -72,7 +78,7 @@ final class PhabricatorAppSearchEngine
|
||||||
id(new AphrontFormSelectControl())
|
id(new AphrontFormSelectControl())
|
||||||
->setLabel(pht('Beta'))
|
->setLabel(pht('Beta'))
|
||||||
->setName('beta')
|
->setName('beta')
|
||||||
->setValue($this->getBool($saved, 'beta'))
|
->setValue($this->getBoolFromQuery($saved, 'beta'))
|
||||||
->setOptions(
|
->setOptions(
|
||||||
array(
|
array(
|
||||||
'' => pht('Show All Applications'),
|
'' => pht('Show All Applications'),
|
||||||
|
@ -83,7 +89,7 @@ final class PhabricatorAppSearchEngine
|
||||||
id(new AphrontFormSelectControl())
|
id(new AphrontFormSelectControl())
|
||||||
->setLabel(pht('Provenance'))
|
->setLabel(pht('Provenance'))
|
||||||
->setName('firstParty')
|
->setName('firstParty')
|
||||||
->setValue($this->getBool($saved, 'firstParty'))
|
->setValue($this->getBoolFromQuery($saved, 'firstParty'))
|
||||||
->setOptions(
|
->setOptions(
|
||||||
array(
|
array(
|
||||||
'' => pht('Show All Applications'),
|
'' => pht('Show All Applications'),
|
||||||
|
@ -118,19 +124,4 @@ final class PhabricatorAppSearchEngine
|
||||||
return parent::buildSavedQueryFromBuiltin($query_key);
|
return parent::buildSavedQueryFromBuiltin($query_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function readBool(AphrontRequest $request, $key) {
|
|
||||||
if (!strlen($request->getStr($key))) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return $request->getBool($key);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getBool(PhabricatorSavedQuery $query, $key) {
|
|
||||||
$value = $query->getParameter($key);
|
|
||||||
if ($value === null) {
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
return $value ? 'true' : 'false';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ final class PhabricatorRepositoryCommitHeraldWorker
|
||||||
$rules = id(new HeraldRuleQuery())
|
$rules = id(new HeraldRuleQuery())
|
||||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||||
->withContentTypes(array($adapter->getAdapterContentType()))
|
->withContentTypes(array($adapter->getAdapterContentType()))
|
||||||
|
->withDisabled(false)
|
||||||
->needConditionsAndActions(true)
|
->needConditionsAndActions(true)
|
||||||
->needAppliedToPHIDs(array($adapter->getPHID()))
|
->needAppliedToPHIDs(array($adapter->getPHID()))
|
||||||
->needValidateAuthors(true)
|
->needValidateAuthors(true)
|
||||||
|
|
|
@ -299,6 +299,25 @@ abstract class PhabricatorApplicationSearchEngine {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected function readBoolFromRequest(
|
||||||
|
AphrontRequest $request,
|
||||||
|
$key) {
|
||||||
|
if (!strlen($request->getStr($key))) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return $request->getBool($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected function getBoolFromQuery(PhabricatorSavedQuery $query, $key) {
|
||||||
|
$value = $query->getParameter($key);
|
||||||
|
if ($value === null) {
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
return $value ? 'true' : 'false';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -( Dates )-------------------------------------------------------------- */
|
/* -( Dates )-------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1660,6 +1660,10 @@ final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList {
|
||||||
'type' => 'php',
|
'type' => 'php',
|
||||||
'name' => $this->getPatchPath('20131004.dxreviewers.php'),
|
'name' => $this->getPatchPath('20131004.dxreviewers.php'),
|
||||||
),
|
),
|
||||||
|
'20131006.hdisable.sql' => array(
|
||||||
|
'type' => 'sql',
|
||||||
|
'name' => $this->getPatchPath('20131006.hdisable.sql'),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,31 @@ final class PHUIHeaderView extends AphrontView {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setStatus($icon, $color, $name) {
|
||||||
|
$header_class = 'phui-header-status';
|
||||||
|
|
||||||
|
if ($color) {
|
||||||
|
$icon = $icon.'-'.$color;
|
||||||
|
$header_class = $header_class.'-'.$color;
|
||||||
|
}
|
||||||
|
|
||||||
|
$img = id(new PHUIIconView())
|
||||||
|
->setSpriteSheet(PHUIIconView::SPRITE_STATUS)
|
||||||
|
->setSpriteIcon($icon);
|
||||||
|
|
||||||
|
$tag = phutil_tag(
|
||||||
|
'span',
|
||||||
|
array(
|
||||||
|
'class' => "{$header_class} plr",
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
$img,
|
||||||
|
$name,
|
||||||
|
));
|
||||||
|
|
||||||
|
return $this->addProperty(self::PROPERTY_STATUS, $tag);
|
||||||
|
}
|
||||||
|
|
||||||
public function render() {
|
public function render() {
|
||||||
require_celerity_resource('phui-header-view-css');
|
require_celerity_resource('phui-header-view-css');
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue