public function applyRules(array $rules, HeraldObjectAdapter $object) { assert_instances_of($rules, 'HeraldRule'); $t_start = microtime(true); $rules = mpull($rules, null, 'getID'); $this->transcript = new HeraldTranscript(); $this->transcript->setObjectPHID((string) $object->getPHID()); $this->fieldCache = array(); $this->results = array(); $this->rules = $rules; $this->object = $object; $effects = array(); foreach ($rules as $id => $rule) { $this->stack = array(); try { if ($rule->getRepetitionPolicy() == HeraldRepetitionPolicyConfig::FIRST && $rule->getRuleApplied($object->getPHID())) { // This rule is only supposed to be applied a single time, and it's // aleady been applied, so this is an automatic failure. $xscript = id(new HeraldRuleTranscript())->setRuleID($id)->setResult(false)->setRuleName($rule->getName())->setRuleOwner($rule->getAuthorPHID())->setReason("This rule is only supposed to be repeated a single time, " . "and it has already been applied."); $this->transcript->addRuleTranscript($xscript); $rule_matches = false; } else { $rule_matches = $this->doesRuleMatch($rule, $object); } } catch (HeraldRecursiveConditionsException $ex) { $names = array(); foreach ($this->stack as $rule_id => $ignored) { $names[] = '"' . $rules[$rule_id]->getName() . '"'; } $names = implode(', ', $names); foreach ($this->stack as $rule_id => $ignored) { $xscript = new HeraldRuleTranscript(); $xscript->setRuleID($rule_id); $xscript->setResult(false); $xscript->setReason("Rules {$names} are recursively dependent upon one another! " . "Don't do this! You have formed an unresolvable cycle in the " . "dependency graph!"); $xscript->setRuleName($rules[$rule_id]->getName()); $xscript->setRuleOwner($rules[$rule_id]->getAuthorPHID()); $this->transcript->addRuleTranscript($xscript); } $rule_matches = false; } $this->results[$id] = $rule_matches; if ($rule_matches) { foreach ($this->getRuleEffects($rule, $object) as $effect) { $effects[] = $effect; } } } $object_transcript = new HeraldObjectTranscript(); $object_transcript->setPHID($object->getPHID()); $object_transcript->setName($object->getHeraldName()); $object_transcript->setType($object->getHeraldTypeName()); $object_transcript->setFields($this->fieldCache); $this->transcript->setObjectTranscript($object_transcript); $t_end = microtime(true); $this->transcript->setDuration($t_end - $t_start); return $effects; }
public function applyRules(array $rules, HeraldAdapter $object) { assert_instances_of($rules, 'HeraldRule'); $t_start = microtime(true); // Rules execute in a well-defined order: sort them into execution order. $rules = msort($rules, 'getRuleExecutionOrderSortKey'); $rules = mpull($rules, null, 'getPHID'); $this->transcript = new HeraldTranscript(); $this->transcript->setObjectPHID((string) $object->getPHID()); $this->fieldCache = array(); $this->results = array(); $this->rules = $rules; $this->object = $object; $effects = array(); foreach ($rules as $phid => $rule) { $this->stack = array(); $policy_first = HeraldRepetitionPolicyConfig::FIRST; $policy_first_int = HeraldRepetitionPolicyConfig::toInt($policy_first); $is_first_only = $rule->getRepetitionPolicy() == $policy_first_int; try { if (!$this->getDryRun() && $is_first_only && $rule->getRuleApplied($object->getPHID())) { // This is not a dry run, and this rule is only supposed to be // applied a single time, and it's already been applied... // That means automatic failure. $xscript = id(new HeraldRuleTranscript())->setRuleID($rule->getID())->setResult(false)->setRuleName($rule->getName())->setRuleOwner($rule->getAuthorPHID())->setReason(pht('This rule is only supposed to be repeated a single time, ' . 'and it has already been applied.')); $this->transcript->addRuleTranscript($xscript); $rule_matches = false; } else { $rule_matches = $this->doesRuleMatch($rule, $object); } } catch (HeraldRecursiveConditionsException $ex) { $names = array(); foreach ($this->stack as $rule_id => $ignored) { $names[] = '"' . $rules[$rule_id]->getName() . '"'; } $names = implode(', ', $names); foreach ($this->stack as $rule_id => $ignored) { $xscript = new HeraldRuleTranscript(); $xscript->setRuleID($rule_id); $xscript->setResult(false); $xscript->setReason(pht("Rules %s are recursively dependent upon one another! " . "Don't do this! You have formed an unresolvable cycle in the " . "dependency graph!", $names)); $xscript->setRuleName($rules[$rule_id]->getName()); $xscript->setRuleOwner($rules[$rule_id]->getAuthorPHID()); $this->transcript->addRuleTranscript($xscript); } $rule_matches = false; } $this->results[$phid] = $rule_matches; if ($rule_matches) { foreach ($this->getRuleEffects($rule, $object) as $effect) { $effects[] = $effect; } } } $object_transcript = new HeraldObjectTranscript(); $object_transcript->setPHID($object->getPHID()); $object_transcript->setName($object->getHeraldName()); $object_transcript->setType($object->getAdapterContentType()); $object_transcript->setFields($this->fieldCache); $this->transcript->setObjectTranscript($object_transcript); $t_end = microtime(true); $this->transcript->setDuration($t_end - $t_start); return $effects; }