Esempio n. 1
0
 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;
 }
Esempio n. 2
0
 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;
 }