44
44
const FIELD_TASK_STATUS = 'taskstatus';
45
45
const FIELD_PUSHER_IS_COMMITTER = 'pusher-is-committer';
46
46
const FIELD_PATH = 'path';
47
const FIELD_SPACE = 'space';
48
49
const CONDITION_CONTAINS = 'contains';
49
50
const CONDITION_NOT_CONTAINS = '!contains';
110
112
private $queuedTransactions = array();
111
113
private $emailPHIDs = array();
112
114
private $forcedEmailPHIDs = array();
115
private $unsubscribedPHIDs;
114
117
public function getEmailPHIDs() {
115
118
return array_values($this->emailPHIDs);
197
200
case self::FIELD_IS_NEW_OBJECT:
198
201
return $this->getIsNewObject();
203
$object = $this->getObject();
205
if (!($object instanceof PhabricatorSubscribableInterface)) {
208
'Adapter object (of class "%s") does not implement interface '.
209
'"%s", so the subscribers field value can not be determined.',
211
'PhabricatorSubscribableInterface'));
214
$phid = $object->getPHID();
215
return PhabricatorSubscribersQuery::loadSubscribersForPHID($phid);
199
216
case self::FIELD_APPLICATION_EMAIL:
200
217
$value = array();
201
218
// while there is only one match by implementation, we do set
204
221
$value[] = $this->getApplicationEmail()->getPHID();
224
case self::FIELD_SPACE:
225
$object = $this->getObject();
227
if (!($object instanceof PhabricatorSpacesInterface)) {
230
'Adapter object (of class "%s") does not implement interface '.
231
'"%s", so the Space field value can not be determined.',
233
'PhabricatorSpacesInterface'));
236
return PhabricatorSpacesNamespaceQuery::getObjectSpacePHID($object);
208
238
if ($this->isHeraldCustomKey($field_name)) {
209
239
return $this->getCustomFieldValue($field_name);
385
415
self::FIELD_TASK_STATUS => pht('Task status'),
386
416
self::FIELD_PUSHER_IS_COMMITTER => pht('Pusher same as committer'),
387
417
self::FIELD_PATH => pht('Path'),
418
self::FIELD_SPACE => pht('Space'),
388
419
) + $this->getCustomFieldNameMap();
1541
1575
case self::ACTION_ADD_PROJECTS:
1542
1576
case self::ACTION_REMOVE_PROJECTS:
1543
1577
return $this->applyProjectsEffect($effect);
1578
case self::ACTION_ADD_CC:
1579
case self::ACTION_REMOVE_CC:
1580
return $this->applySubscribersEffect($effect);
1544
1581
case self::ACTION_FLAG:
1545
1582
return $this->applyFlagEffect($effect);
1546
1583
case self::ACTION_EMAIL:
1547
1584
return $this->applyEmailEffect($effect);
1585
case self::ACTION_NOTHING:
1586
return $this->applyNothingEffect($effect);
1593
1638
pht('Added projects.'));
1644
private function applySubscribersEffect(HeraldEffect $effect) {
1645
if ($effect->getAction() == self::ACTION_ADD_CC) {
1653
$subscriber_phids = array_fuse($effect->getTarget());
1654
if (!$subscriber_phids) {
1655
return new HeraldApplyTranscript(
1658
pht('This action lists no users or objects to affect.'));
1661
// The "Add Subscribers" rule only adds subscribers who haven't previously
1662
// unsubscribed from the object explicitly. Filter these subscribers out
1663
// before continuing.
1664
$unsubscribed = array();
1666
if ($this->unsubscribedPHIDs === null) {
1667
$this->unsubscribedPHIDs = PhabricatorEdgeQuery::loadDestinationPHIDs(
1668
$this->getObject()->getPHID(),
1669
PhabricatorObjectHasUnsubscriberEdgeType::EDGECONST);
1672
foreach ($this->unsubscribedPHIDs as $phid) {
1673
if (isset($subscriber_phids[$phid])) {
1674
$unsubscribed[$phid] = $phid;
1675
unset($subscriber_phids[$phid]);
1680
if (!$subscriber_phids) {
1681
return new HeraldApplyTranscript(
1684
pht('All targets have previously unsubscribed explicitly.'));
1687
// Filter out PHIDs which aren't valid subscribers. Lower levels of the
1688
// stack will fail loudly if we try to add subscribers with invalid PHIDs
1689
// or unknown PHID types, so drop them here.
1691
foreach ($subscriber_phids as $phid) {
1692
$type = phid_get_type($phid);
1694
case PhabricatorPeopleUserPHIDType::TYPECONST:
1695
case PhabricatorProjectProjectPHIDType::TYPECONST:
1698
$invalid[$phid] = $phid;
1699
unset($subscriber_phids[$phid]);
1704
if (!$subscriber_phids) {
1705
return new HeraldApplyTranscript(
1708
pht('All targets are invalid as subscribers.'));
1711
$xaction = $this->newTransaction()
1712
->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS)
1715
$kind => $subscriber_phids,
1718
$this->queueTransaction($xaction);
1720
// TODO: We could be more detailed about this, but doing it meaningfully
1721
// probably requires substantial changes to how transactions are rendered
1724
$message = pht('Subscribed targets.');
1726
$message = pht('Unsubscribed targets.');
1729
return new HeraldApplyTranscript($effect, true, $message);