Differential D18991 Diff 45558 src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
| Show First 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | abstract class PhabricatorApplicationTransactionEditor | ||||
| private $mailCCPHIDs = array(); | private $mailCCPHIDs = array(); | ||||
| private $feedNotifyPHIDs = array(); | private $feedNotifyPHIDs = array(); | ||||
| private $feedRelatedPHIDs = array(); | private $feedRelatedPHIDs = array(); | ||||
| private $feedShouldPublish = false; | private $feedShouldPublish = false; | ||||
| private $mailShouldSend = false; | private $mailShouldSend = false; | ||||
| private $modularTypes; | private $modularTypes; | ||||
| private $silent; | private $silent; | ||||
| private $mustEncrypt; | private $mustEncrypt; | ||||
| private $stampTemplates = array(); | |||||
| private $mailStamps = array(); | |||||
| private $transactionQueue = array(); | private $transactionQueue = array(); | ||||
| const STORAGE_ENCODING_BINARY = 'binary'; | const STORAGE_ENCODING_BINARY = 'binary'; | ||||
| /** | /** | ||||
| * Get the class name for the application this editor is a part of. | * Get the class name for the application this editor is a part of. | ||||
| * | * | ||||
| ▲ Show 20 Lines • Show All 1,093 Lines • ▼ Show 20 Lines | final public function applyTransactions( | ||||
| // Editors need to pass into workers. | // Editors need to pass into workers. | ||||
| $object = $this->willPublish($object, $xactions); | $object = $this->willPublish($object, $xactions); | ||||
| if (!$this->getIsSilent()) { | if (!$this->getIsSilent()) { | ||||
| if ($this->shouldSendMail($object, $xactions)) { | if ($this->shouldSendMail($object, $xactions)) { | ||||
| $this->mailShouldSend = true; | $this->mailShouldSend = true; | ||||
| $this->mailToPHIDs = $this->getMailTo($object); | $this->mailToPHIDs = $this->getMailTo($object); | ||||
| $this->mailCCPHIDs = $this->getMailCC($object); | $this->mailCCPHIDs = $this->getMailCC($object); | ||||
| $mail_xactions = $this->getTransactionsForMail($object, $xactions); | |||||
| $stamps = $this->newMailStamps($object, $xactions); | |||||
| foreach ($stamps as $stamp) { | |||||
| $this->mailStamps[] = $stamp->toDictionary(); | |||||
| } | |||||
| } | } | ||||
| if ($this->shouldPublishFeedStory($object, $xactions)) { | if ($this->shouldPublishFeedStory($object, $xactions)) { | ||||
| $this->feedShouldPublish = true; | $this->feedShouldPublish = true; | ||||
| $this->feedRelatedPHIDs = $this->getFeedRelatedPHIDs( | $this->feedRelatedPHIDs = $this->getFeedRelatedPHIDs( | ||||
| $object, | $object, | ||||
| $xactions); | $xactions); | ||||
| $this->feedNotifyPHIDs = $this->getFeedNotifyPHIDs( | $this->feedNotifyPHIDs = $this->getFeedNotifyPHIDs( | ||||
| ▲ Show 20 Lines • Show All 1,414 Lines • ▼ Show 20 Lines | private function buildMailForTarget( | ||||
| $mail_xactions = $this->getTransactionsForMail($object, $xactions); | $mail_xactions = $this->getTransactionsForMail($object, $xactions); | ||||
| $mail = $this->buildMailTemplate($object); | $mail = $this->buildMailTemplate($object); | ||||
| $body = $this->buildMailBody($object, $mail_xactions); | $body = $this->buildMailBody($object, $mail_xactions); | ||||
| $mail_tags = $this->getMailTags($object, $mail_xactions); | $mail_tags = $this->getMailTags($object, $mail_xactions); | ||||
| $action = $this->getMailAction($object, $mail_xactions); | $action = $this->getMailAction($object, $mail_xactions); | ||||
| $stamps = $this->generateMailStamps($object, $this->mailStamps); | |||||
| if (PhabricatorEnv::getEnvConfig('metamta.email-preferences')) { | if (PhabricatorEnv::getEnvConfig('metamta.email-preferences')) { | ||||
| $this->addEmailPreferenceSectionToMailBody( | $this->addEmailPreferenceSectionToMailBody( | ||||
| $body, | $body, | ||||
| $object, | $object, | ||||
| $mail_xactions); | $mail_xactions); | ||||
| } | } | ||||
| Show All 22 Lines | private function buildMailForTarget( | ||||
| if ($object instanceof PhabricatorProjectInterface) { | if ($object instanceof PhabricatorProjectInterface) { | ||||
| $this->addMailProjectMetadata($object, $mail); | $this->addMailProjectMetadata($object, $mail); | ||||
| } | } | ||||
| if ($this->getParentMessageID()) { | if ($this->getParentMessageID()) { | ||||
| $mail->setParentMessageID($this->getParentMessageID()); | $mail->setParentMessageID($this->getParentMessageID()); | ||||
| } | } | ||||
| // If we have stamps, attach the raw dictionary version (not the actual | |||||
| // objects) to the mail so that debugging tools can see what we used to | |||||
| // render the final list. | |||||
| if ($this->mailStamps) { | |||||
| $mail->setMailStampMetadata($this->mailStamps); | |||||
| } | |||||
| // If we have rendered stamps, attach them to the mail. | |||||
| if ($stamps) { | |||||
| $mail->setMailStamps($stamps); | |||||
| } | |||||
| return $target->willSendMail($mail); | return $target->willSendMail($mail); | ||||
| } | } | ||||
| private function addMailProjectMetadata( | private function addMailProjectMetadata( | ||||
| PhabricatorLiskDAO $object, | PhabricatorLiskDAO $object, | ||||
| PhabricatorMetaMTAMail $template) { | PhabricatorMetaMTAMail $template) { | ||||
| $project_phids = PhabricatorEdgeQuery::loadDestinationPHIDs( | $project_phids = PhabricatorEdgeQuery::loadDestinationPHIDs( | ||||
| ▲ Show 20 Lines • Show All 904 Lines • ▼ Show 20 Lines | return array( | ||||
| 'heraldHeader', | 'heraldHeader', | ||||
| 'mailToPHIDs', | 'mailToPHIDs', | ||||
| 'mailCCPHIDs', | 'mailCCPHIDs', | ||||
| 'feedNotifyPHIDs', | 'feedNotifyPHIDs', | ||||
| 'feedRelatedPHIDs', | 'feedRelatedPHIDs', | ||||
| 'feedShouldPublish', | 'feedShouldPublish', | ||||
| 'mailShouldSend', | 'mailShouldSend', | ||||
| 'mustEncrypt', | 'mustEncrypt', | ||||
| 'mailStamps', | |||||
| ); | ); | ||||
| } | } | ||||
| /** | /** | ||||
| * Apply encodings prior to storage. | * Apply encodings prior to storage. | ||||
| * | * | ||||
| * See @{method:getCustomWorkerStateEncoding}. | * See @{method:getCustomWorkerStateEncoding}. | ||||
| * | * | ||||
| ▲ Show 20 Lines • Show All 376 Lines • ▼ Show 20 Lines | private function newQueueEditor() { | ||||
| if ($this->actingAsPHID !== null) { | if ($this->actingAsPHID !== null) { | ||||
| $editor->setActingAsPHID($this->actingAsPHID); | $editor->setActingAsPHID($this->actingAsPHID); | ||||
| } | } | ||||
| return $editor; | return $editor; | ||||
| } | } | ||||
| /* -( Stamps )------------------------------------------------------------- */ | |||||
| public function newMailStampTemplates($object) { | |||||
| $actor = $this->getActor(); | |||||
| $templates = array(); | |||||
| $extensions = $this->newMailExtensions($object); | |||||
| foreach ($extensions as $extension) { | |||||
| $stamps = $extension->newMailStampTemplates($object); | |||||
| foreach ($stamps as $stamp) { | |||||
| $key = $stamp->getKey(); | |||||
| if (isset($templates[$key])) { | |||||
| throw new Exception( | |||||
| pht( | |||||
| 'Mail extension ("%s") defines a stamp template with the '. | |||||
| 'same key ("%s") as another template. Each stamp template '. | |||||
| 'must have a unique key.', | |||||
| get_class($extension), | |||||
| $key)); | |||||
| } | |||||
| $stamp->setViewer($actor); | |||||
| $templates[$key] = $stamp; | |||||
| } | |||||
| } | |||||
| return $templates; | |||||
| } | |||||
| final public function getMailStamp($key) { | |||||
| if (!isset($this->stampTemplates)) { | |||||
| throw new PhutilInvalidStateException('newMailStampTemplates'); | |||||
| } | |||||
| if (!isset($this->stampTemplates[$key])) { | |||||
| throw new Exception( | |||||
| pht( | |||||
| 'Editor ("%s") has no mail stamp template with provided key ("%s").', | |||||
| get_class($this), | |||||
| $key)); | |||||
| } | |||||
| return $this->stampTemplates[$key]; | |||||
| } | |||||
| private function newMailStamps($object, array $xactions) { | |||||
| $actor = $this->getActor(); | |||||
| $this->stampTemplates = $this->newMailStampTemplates($object); | |||||
| $extensions = $this->newMailExtensions($object); | |||||
| $stamps = array(); | |||||
| foreach ($extensions as $extension) { | |||||
| $extension->newMailStamps($object, $xactions); | |||||
| } | |||||
| return $this->stampTemplates; | |||||
| } | |||||
| private function newMailExtensions($object) { | |||||
| $actor = $this->getActor(); | |||||
| $all_extensions = PhabricatorMailEngineExtension::getAllExtensions(); | |||||
| $extensions = array(); | |||||
| foreach ($all_extensions as $key => $template) { | |||||
| $extension = id(clone $template) | |||||
| ->setViewer($actor) | |||||
| ->setEditor($this); | |||||
| if ($extension->supportsObject($object)) { | |||||
| $extensions[$key] = $extension; | |||||
| } | |||||
| } | |||||
| return $extensions; | |||||
| } | |||||
| private function generateMailStamps($object, $data) { | |||||
| if (!$data || !is_array($data)) { | |||||
| return null; | |||||
| } | |||||
| $templates = $this->newMailStampTemplates($object); | |||||
| foreach ($data as $spec) { | |||||
| if (!is_array($spec)) { | |||||
| continue; | |||||
| } | |||||
| $key = idx($spec, 'key'); | |||||
| if (!isset($templates[$key])) { | |||||
| continue; | |||||
| } | |||||
| $type = idx($spec, 'type'); | |||||
| if ($templates[$key]->getStampType() !== $type) { | |||||
| continue; | |||||
| } | |||||
| $value = idx($spec, 'value'); | |||||
| $templates[$key]->setValueFromDictionary($value); | |||||
| } | |||||
| $results = array(); | |||||
| foreach ($templates as $template) { | |||||
| $value = $template->getValueForRendering(); | |||||
| $rendered = $template->renderStamps($value); | |||||
| if ($rendered === null) { | |||||
| continue; | |||||
| } | |||||
| $rendered = (array)$rendered; | |||||
| foreach ($rendered as $stamp) { | |||||
| $results[] = $stamp; | |||||
| } | |||||
| } | |||||
| sort($results); | |||||
| return $results; | |||||
| } | |||||
| } | } | ||||