public function __construct(HeraldEffect $effect, $applied, $reason = null)
 {
     $this->setAction($effect->getAction());
     $this->setTarget($effect->getTarget());
     $this->setRuleID($effect->getRuleID());
     $this->setEffector($effect->getEffector());
     $this->setReason($effect->getReason());
     $this->setApplied($applied);
     $this->setAppliedReason($reason);
 }
 public function applyHeraldEffects(array $effects)
 {
     assert_instances_of($effects, 'HeraldEffect');
     $result = array();
     if ($this->explicitCCs) {
         $effect = new HeraldEffect();
         $effect->setAction(HeraldActionConfig::ACTION_ADD_CC);
         $effect->setTarget(array_keys($this->explicitCCs));
         $effect->setReason('CCs provided explicitly by revision author or carried over from a ' . 'previous version of the revision.');
         $result[] = new HeraldApplyTranscript($effect, true, 'Added addresses to CC list.');
     }
     $forbidden_ccs = array_fill_keys(nonempty($this->forbiddenCCs, array()), true);
     foreach ($effects as $effect) {
         $action = $effect->getAction();
         switch ($action) {
             case HeraldActionConfig::ACTION_NOTHING:
                 $result[] = new HeraldApplyTranscript($effect, true, 'OK, did nothing.');
                 break;
             case HeraldActionConfig::ACTION_FLAG:
                 $result[] = parent::applyFlagEffect($effect, $this->revision->getPHID());
                 break;
             case HeraldActionConfig::ACTION_EMAIL:
             case HeraldActionConfig::ACTION_ADD_CC:
                 $op = $action == HeraldActionConfig::ACTION_EMAIL ? 'email' : 'CC';
                 $base_target = $effect->getTarget();
                 $forbidden = array();
                 foreach ($base_target as $key => $fbid) {
                     if (isset($forbidden_ccs[$fbid])) {
                         $forbidden[] = $fbid;
                         unset($base_target[$key]);
                     } else {
                         if ($action == HeraldActionConfig::ACTION_EMAIL) {
                             $this->emailPHIDs[$fbid] = true;
                         } else {
                             $this->newCCs[$fbid] = true;
                         }
                     }
                 }
                 if ($forbidden) {
                     $failed = clone $effect;
                     $failed->setTarget($forbidden);
                     if ($base_target) {
                         $effect->setTarget($base_target);
                         $result[] = new HeraldApplyTranscript($effect, true, 'Added these addresses to ' . $op . ' list. ' . 'Others could not be added.');
                     }
                     $result[] = new HeraldApplyTranscript($failed, false, $op . ' forbidden, these addresses have unsubscribed.');
                 } else {
                     $result[] = new HeraldApplyTranscript($effect, true, 'Added addresses to ' . $op . ' list.');
                 }
                 break;
             case HeraldActionConfig::ACTION_REMOVE_CC:
                 foreach ($effect->getTarget() as $fbid) {
                     $this->remCCs[$fbid] = true;
                 }
                 $result[] = new HeraldApplyTranscript($effect, true, 'Removed addresses from CC list.');
                 break;
             default:
                 throw new Exception("No rules to handle action '{$action}'.");
         }
     }
     return $result;
 }
 /**
  * @task apply
  */
 protected function applyStandardEffect(HeraldEffect $effect)
 {
     $action = $effect->getAction();
     $rule_type = $effect->getRule()->getRuleType();
     $impl = $this->getActionImplementation($action);
     if (!$impl) {
         return new HeraldApplyTranscript($effect, false, array(array(HeraldAction::DO_STANDARD_INVALID_ACTION, $action)));
     }
     if (!$impl->supportsRuleType($rule_type)) {
         return new HeraldApplyTranscript($effect, false, array(array(HeraldAction::DO_STANDARD_WRONG_RULE_TYPE, $rule_type)));
     }
     $impl->applyEffect($this->getObject(), $effect);
     return $impl->getApplyTranscript($effect);
 }
Example #4
0
 /**
  * @task apply
  */
 private function applySubscribersEffect(HeraldEffect $effect)
 {
     if ($effect->getAction() == self::ACTION_ADD_CC) {
         $kind = '+';
         $is_add = true;
     } else {
         $kind = '-';
         $is_add = false;
     }
     $subscriber_phids = array_fuse($effect->getTarget());
     if (!$subscriber_phids) {
         return new HeraldApplyTranscript($effect, false, pht('This action lists no users or objects to affect.'));
     }
     // The "Add Subscribers" rule only adds subscribers who haven't previously
     // unsubscribed from the object explicitly. Filter these subscribers out
     // before continuing.
     $unsubscribed = array();
     if ($is_add) {
         if ($this->unsubscribedPHIDs === null) {
             $this->unsubscribedPHIDs = PhabricatorEdgeQuery::loadDestinationPHIDs($this->getObject()->getPHID(), PhabricatorObjectHasUnsubscriberEdgeType::EDGECONST);
         }
         foreach ($this->unsubscribedPHIDs as $phid) {
             if (isset($subscriber_phids[$phid])) {
                 $unsubscribed[$phid] = $phid;
                 unset($subscriber_phids[$phid]);
             }
         }
     }
     if (!$subscriber_phids) {
         return new HeraldApplyTranscript($effect, false, pht('All targets have previously unsubscribed explicitly.'));
     }
     // Filter out PHIDs which aren't valid subscribers. Lower levels of the
     // stack will fail loudly if we try to add subscribers with invalid PHIDs
     // or unknown PHID types, so drop them here.
     $invalid = array();
     foreach ($subscriber_phids as $phid) {
         $type = phid_get_type($phid);
         switch ($type) {
             case PhabricatorPeopleUserPHIDType::TYPECONST:
             case PhabricatorProjectProjectPHIDType::TYPECONST:
                 break;
             default:
                 $invalid[$phid] = $phid;
                 unset($subscriber_phids[$phid]);
                 break;
         }
     }
     if (!$subscriber_phids) {
         return new HeraldApplyTranscript($effect, false, pht('All targets are invalid as subscribers.'));
     }
     $xaction = $this->newTransaction()->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS)->setNewValue(array($kind => $subscriber_phids));
     $this->queueTransaction($xaction);
     // TODO: We could be more detailed about this, but doing it meaningfully
     // probably requires substantial changes to how transactions are rendered
     // first.
     if ($is_add) {
         $message = pht('Subscribed targets.');
     } else {
         $message = pht('Unsubscribed targets.');
     }
     return new HeraldApplyTranscript($effect, true, $message);
 }
 public function applyHeraldEffects(array $effects)
 {
     assert_instances_of($effects, 'HeraldEffect');
     $result = array();
     if ($this->explicitCCs) {
         $effect = new HeraldEffect();
         $effect->setAction(self::ACTION_ADD_CC);
         $effect->setTarget(array_keys($this->explicitCCs));
         $effect->setReason(pht('CCs provided explicitly by revision author or carried over ' . 'from a previous version of the revision.'));
         $result[] = new HeraldApplyTranscript($effect, true, pht('Added addresses to CC list.'));
     }
     $forbidden_ccs = array_fill_keys(nonempty($this->forbiddenCCs, array()), true);
     foreach ($effects as $effect) {
         $action = $effect->getAction();
         switch ($action) {
             case self::ACTION_NOTHING:
                 $result[] = new HeraldApplyTranscript($effect, true, pht('OK, did nothing.'));
                 break;
             case self::ACTION_FLAG:
                 $result[] = parent::applyFlagEffect($effect, $this->revision->getPHID());
                 break;
             case self::ACTION_EMAIL:
             case self::ACTION_ADD_CC:
                 $op = $action == self::ACTION_EMAIL ? 'email' : 'CC';
                 $base_target = $effect->getTarget();
                 $forbidden = array();
                 foreach ($base_target as $key => $fbid) {
                     if (isset($forbidden_ccs[$fbid])) {
                         $forbidden[] = $fbid;
                         unset($base_target[$key]);
                     } else {
                         if ($action == self::ACTION_EMAIL) {
                             $this->emailPHIDs[$fbid] = true;
                         } else {
                             $this->newCCs[$fbid] = true;
                         }
                     }
                 }
                 if ($forbidden) {
                     $failed = clone $effect;
                     $failed->setTarget($forbidden);
                     if ($base_target) {
                         $effect->setTarget($base_target);
                         $result[] = new HeraldApplyTranscript($effect, true, pht('Added these addresses to %s list. ' . 'Others could not be added.', $op));
                     }
                     $result[] = new HeraldApplyTranscript($failed, false, pht('%s forbidden, these addresses have unsubscribed.', $op));
                 } else {
                     $result[] = new HeraldApplyTranscript($effect, true, pht('Added addresses to %s list.', $op));
                 }
                 break;
             case self::ACTION_REMOVE_CC:
                 foreach ($effect->getTarget() as $fbid) {
                     $this->remCCs[$fbid] = true;
                 }
                 $result[] = new HeraldApplyTranscript($effect, true, pht('Removed addresses from CC list.'));
                 break;
             case self::ACTION_ADD_REVIEWERS:
                 foreach ($effect->getTarget() as $phid) {
                     $this->addReviewerPHIDs[$phid] = true;
                 }
                 $result[] = new HeraldApplyTranscript($effect, true, pht('Added reviewers.'));
                 break;
             case self::ACTION_ADD_BLOCKING_REVIEWERS:
                 // This adds reviewers normally, it just also marks them blocking.
                 foreach ($effect->getTarget() as $phid) {
                     $this->addReviewerPHIDs[$phid] = true;
                     $this->blockingReviewerPHIDs[$phid] = true;
                 }
                 $result[] = new HeraldApplyTranscript($effect, true, pht('Added blocking reviewers.'));
                 break;
             case self::ACTION_APPLY_BUILD_PLANS:
                 foreach ($effect->getTarget() as $phid) {
                     $this->buildPlans[] = $phid;
                 }
                 $result[] = new HeraldApplyTranscript($effect, true, pht('Applied build plans.'));
                 break;
             case self::ACTION_REQUIRE_SIGNATURE:
                 foreach ($effect->getTarget() as $phid) {
                     $this->requiredSignatureDocumentPHIDs[] = $phid;
                 }
                 $result[] = new HeraldApplyTranscript($effect, true, pht('Required signatures.'));
                 break;
             default:
                 $custom_result = parent::handleCustomHeraldEffect($effect);
                 if ($custom_result === null) {
                     throw new Exception(pht("No rules to handle action '%s'.", $action));
                 }
                 $result[] = $custom_result;
                 break;
         }
     }
     return $result;
 }
Example #6
0
 protected function handleCustomHeraldEffect(HeraldEffect $effect)
 {
     $custom_action = idx($this->getCustomActions(), $effect->getAction());
     if ($custom_action !== null) {
         return $custom_action->applyEffect($this, $this->getObject(), $effect);
     }
     return null;
 }