Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14477591
D7847.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
10 KB
Referenced Files
None
Subscribers
None
D7847.diff
View Options
Index: resources/sql/patches/20131227.heraldobject.sql
===================================================================
--- /dev/null
+++ resources/sql/patches/20131227.heraldobject.sql
@@ -0,0 +1,6 @@
+ALTER TABLE {$NAMESPACE}_herald.herald_rule
+ ADD triggerObjectPHID VARCHAR(64) COLLATE utf8_bin;
+
+ALTER TABLE {$NAMESPACE}_herald.herald_rule
+ ADD KEY `key_trigger` (triggerObjectPHID);
+
Index: src/applications/herald/config/HeraldRuleTypeConfig.php
===================================================================
--- src/applications/herald/config/HeraldRuleTypeConfig.php
+++ src/applications/herald/config/HeraldRuleTypeConfig.php
@@ -3,12 +3,14 @@
final class HeraldRuleTypeConfig {
const RULE_TYPE_GLOBAL = 'global';
+ const RULE_TYPE_OBJECT = 'object';
const RULE_TYPE_PERSONAL = 'personal';
public static function getRuleTypeMap() {
$map = array(
- self::RULE_TYPE_GLOBAL => pht('Global'),
- self::RULE_TYPE_PERSONAL => pht('Personal'),
+ self::RULE_TYPE_PERSONAL => pht('Personal'),
+ self::RULE_TYPE_OBJECT => pht('Object'),
+ self::RULE_TYPE_GLOBAL => pht('Global'),
);
return $map;
}
Index: src/applications/herald/controller/HeraldDisableController.php
===================================================================
--- src/applications/herald/controller/HeraldDisableController.php
+++ src/applications/herald/controller/HeraldDisableController.php
@@ -28,7 +28,7 @@
return new Aphront404Response();
}
- if ($rule->getRuleType() == HeraldRuleTypeConfig::RULE_TYPE_GLOBAL) {
+ if ($rule->isGlobalRule()) {
$this->requireApplicationCapability(
HeraldCapabilityManageGlobalRules::CAPABILITY);
}
Index: src/applications/herald/controller/HeraldNewController.php
===================================================================
--- src/applications/herald/controller/HeraldNewController.php
+++ src/applications/herald/controller/HeraldNewController.php
@@ -147,13 +147,18 @@
private function renderRuleTypeControl(array $rule_type_map, $e_rule) {
$request = $this->getRequest();
- // Reorder array to put "personal" first.
+ // Reorder array to put less powerful rules first.
$rule_type_map = array_select_keys(
$rule_type_map,
array(
HeraldRuleTypeConfig::RULE_TYPE_PERSONAL,
+ HeraldRuleTypeConfig::RULE_TYPE_OBJECT,
+ HeraldRuleTypeConfig::RULE_TYPE_GLOBAL,
)) + $rule_type_map;
+ // TODO: Enable this.
+ unset($rule_type_map[HeraldRuleTypeConfig::RULE_TYPE_OBJECT]);
+
list($can_global, $global_link) = $this->explainApplicationCapability(
HeraldCapabilityManageGlobalRules::CAPABILITY,
pht('You have permission to create and manage global rules.'),
Index: src/applications/herald/controller/HeraldRuleController.php
===================================================================
--- src/applications/herald/controller/HeraldRuleController.php
+++ src/applications/herald/controller/HeraldRuleController.php
@@ -49,7 +49,7 @@
$cancel_uri = $this->getApplicationURI();
}
- if ($rule->getRuleType() == HeraldRuleTypeConfig::RULE_TYPE_GLOBAL) {
+ if ($rule->isGlobalRule()) {
$this->requireApplicationCapability(
HeraldCapabilityManageGlobalRules::CAPABILITY);
}
@@ -561,7 +561,17 @@
->withContentTypes(array($rule->getContentType()))
->execute();
- if ($rule->getRuleType() == HeraldRuleTypeConfig::RULE_TYPE_PERSONAL) {
+ if ($rule->isObjectRule()) {
+ // Object rules may depend on other rules for the same object.
+ $all_rules += id(new HeraldRuleQuery())
+ ->setViewer($viewer)
+ ->withRuleTypes(array(HeraldRuleTypeConfig::RULE_TYPE_OBJECT))
+ ->withContentTypes(array($rule->getContentType()))
+ ->withTriggerObjectPHIDs(array($rule->getTriggerObjectPHID()))
+ ->execute();
+ }
+
+ if ($rule->isPersonalRule()) {
// Personal rules may depend upon your other personal rules.
$all_rules += id(new HeraldRuleQuery())
->setViewer($viewer)
Index: src/applications/herald/engine/HeraldEngine.php
===================================================================
--- src/applications/herald/engine/HeraldEngine.php
+++ src/applications/herald/engine/HeraldEngine.php
@@ -256,6 +256,11 @@
"Rule failed automatically because it is a personal rule and its ".
"owner can not see the object.");
$result = false;
+ } else if (!$this->canRuleApplyToObject($rule, $object)) {
+ $reason = pht(
+ "Rule failed automatically because it is an object rule which is ".
+ "not relevant for this object.");
+ $result = false;
} else {
foreach ($conditions as $condition) {
$match = $this->doesConditionMatch($rule, $condition, $object);
@@ -381,8 +386,8 @@
HeraldRule $rule,
HeraldAdapter $adapter) {
- // Authorship is irrelevant for global rules.
- if ($rule->isGlobalRule()) {
+ // Authorship is irrelevant for global rules and object rules.
+ if ($rule->isGlobalRule() || $rule->isObjectRule()) {
return true;
}
@@ -405,4 +410,25 @@
PhabricatorPolicyCapability::CAN_VIEW);
}
+ private function canRuleApplyToObject(
+ HeraldRule $rule,
+ HeraldAdapter $adapter) {
+
+ // Rules which are not object rules can apply to anything.
+ if (!$rule->isObjectRule()) {
+ return true;
+ }
+
+ $trigger_phid = $rule->getTriggerObjectPHID();
+ $object_phid = $adapter->getPHID();
+
+ if ($trigger_phid == $object_phid) {
+ return true;
+ }
+
+ // TODO: We should also handle projects.
+
+ return false;
+ }
+
}
Index: src/applications/herald/query/HeraldRuleQuery.php
===================================================================
--- src/applications/herald/query/HeraldRuleQuery.php
+++ src/applications/herald/query/HeraldRuleQuery.php
@@ -9,6 +9,7 @@
private $ruleTypes;
private $contentTypes;
private $disabled;
+ private $triggerObjectPHIDs;
private $needConditionsAndActions;
private $needAppliedToPHIDs;
@@ -49,6 +50,11 @@
return $this;
}
+ public function withTriggerObjectPHIDs(array $phids) {
+ $this->triggerObjectPHIDs = $phids;
+ return $this;
+ }
+
public function needConditionsAndActions($need) {
$this->needConditionsAndActions = $need;
return $this;
@@ -137,6 +143,35 @@
}
}
+ $object_phids = array();
+ foreach ($rules as $rule) {
+ if ($rule->isObjectRule()) {
+ $object_phids[] = $rule->getTriggerObjectPHID();
+ }
+ }
+
+ if ($object_phids) {
+ $objects = id(new PhabricatorObjectQuery())
+ ->setParentQuery($this)
+ ->setViewer($this->getViewer())
+ ->withPHIDs($object_phids)
+ ->execute();
+ $objects = mpull($objects, null, 'getPHID');
+ } else {
+ $objects = array();
+ }
+
+ foreach ($rules as $key => $rule) {
+ if ($rule->isObjectRule()) {
+ $object = idx($objects, $rule->getTriggerObjectPHID());
+ if (!$object) {
+ unset($rules[$key]);
+ continue;
+ }
+ $rule->attachTriggerObject($object);
+ }
+ }
+
return $rules;
}
@@ -185,6 +220,13 @@
(int)$this->disabled);
}
+ if ($this->triggerObjectPHIDs) {
+ $where[] = qsprintf(
+ $conn_r,
+ 'rule.triggerObjectPHID IN (%Ls)',
+ $this->triggerObjectPHIDs);
+ }
+
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
@@ -192,9 +234,9 @@
private function validateRuleAuthors(array $rules) {
- // "Global" rules always have valid authors.
+ // "Global" and "Object" rules always have valid authors.
foreach ($rules as $key => $rule) {
- if ($rule->isGlobalRule()) {
+ if ($rule->isGlobalRule() || $rule->isObjectRule()) {
$rule->attachValidAuthor(true);
unset($rules[$key]);
continue;
Index: src/applications/herald/storage/HeraldRule.php
===================================================================
--- src/applications/herald/storage/HeraldRule.php
+++ src/applications/herald/storage/HeraldRule.php
@@ -15,8 +15,9 @@
protected $repetitionPolicy;
protected $ruleType;
protected $isDisabled = 0;
+ protected $triggerObjectPHID;
- protected $configVersion = 21;
+ protected $configVersion = 22;
// phids for which this rule has been applied
private $ruleApplied = self::ATTACHABLE;
@@ -24,6 +25,7 @@
private $author = self::ATTACHABLE;
private $conditions;
private $actions;
+ private $triggerObject = self::ATTACHABLE;
public function getConfiguration() {
return array(
@@ -146,9 +148,7 @@
}
public function delete() {
-
-// TODO:
-// $this->openTransaction();
+ $this->openTransaction();
queryfx(
$this->establishConnection('w'),
'DELETE FROM %T WHERE ruleID = %d',
@@ -159,8 +159,10 @@
'DELETE FROM %T WHERE ruleID = %d',
id(new HeraldAction())->getTableName(),
$this->getID());
- parent::delete();
-// $this->saveTransaction();
+ $result = parent::delete();
+ $this->saveTransaction();
+
+ return $result;
}
public function hasValidAuthor() {
@@ -189,6 +191,19 @@
return ($this->getRuleType() === HeraldRuleTypeConfig::RULE_TYPE_PERSONAL);
}
+ public function isObjectRule() {
+ return ($this->getRuleType() == HeraldRuleTypeConfig::RULE_TYPE_OBJECT);
+ }
+
+ public function attachTriggerObject($trigger_object) {
+ $this->triggerObject = $trigger_object;
+ return $this;
+ }
+
+ public function getTriggerObject() {
+ return $this->assertAttached($this->triggerObject);
+ }
+
/* -( PhabricatorPolicyInterface )----------------------------------------- */
@@ -211,6 +226,8 @@
$global = HeraldCapabilityManageGlobalRules::CAPABILITY;
return $herald->getPolicy($global);
}
+ } else if ($this->isObjectRule()) {
+ return $this->getTriggerObject()->getPolicy($capability);
} else {
return PhabricatorPolicies::POLICY_NOONE;
}
@@ -227,6 +244,8 @@
public function describeAutomaticCapability($capability) {
if ($this->isPersonalRule()) {
return pht("A personal rule's owner can always view and edit it.");
+ } else if ($this->isObjectRule()) {
+ return pht("Object rules inherit the policies of their objects.");
}
return null;
Index: src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
===================================================================
--- src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
+++ src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
@@ -1852,6 +1852,10 @@
'type' => 'sql',
'name' => $this->getPatchPath('20131224.harbormanual.sql'),
),
+ '20131227.heraldobject.sql' => array(
+ 'type' => 'sql',
+ 'name' => $this->getPatchPath('20131227.heraldobject.sql'),
+ ),
);
}
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Dec 29, 2:46 PM (8 h, 8 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6942562
Default Alt Text
D7847.diff (10 KB)
Attached To
Mode
D7847: Lay most groundwork for Herald object rules
Attached
Detach File
Event Timeline
Log In to Comment