Differential D13939 Diff 33700 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 63 Lines • ▼ Show 20 Lines | abstract class PhabricatorApplicationTransactionEditor | ||||
private $heraldEmailPHIDs = array(); | private $heraldEmailPHIDs = array(); | ||||
private $heraldForcedEmailPHIDs = array(); | private $heraldForcedEmailPHIDs = array(); | ||||
private $heraldHeader; | private $heraldHeader; | ||||
private $mailToPHIDs = array(); | private $mailToPHIDs = array(); | ||||
private $mailCCPHIDs = array(); | private $mailCCPHIDs = array(); | ||||
private $feedNotifyPHIDs = array(); | private $feedNotifyPHIDs = array(); | ||||
private $feedRelatedPHIDs = array(); | private $feedRelatedPHIDs = array(); | ||||
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. | ||||
* | * | ||||
* Uninstalling the application will disable the editor. | * Uninstalling the application will disable the editor. | ||||
* | * | ||||
* @return string Editor's application class name. | * @return string Editor's application class name. | ||||
*/ | */ | ||||
abstract public function getEditorApplicationClass(); | abstract public function getEditorApplicationClass(); | ||||
▲ Show 20 Lines • Show All 2,552 Lines • ▼ Show 20 Lines | if ($object instanceof PhabricatorCustomFieldInterface) { | ||||
$body, | $body, | ||||
$this, | $this, | ||||
$xactions); | $xactions); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
/** | |||||
* @task mail | |||||
*/ | |||||
private function runHeraldMailRules(array $messages) { | |||||
foreach ($messages as $message) { | |||||
$engine = new HeraldEngine(); | |||||
$adapter = id(new PhabricatorMailOutboundMailHeraldAdapter()) | |||||
->setObject($message); | |||||
$rules = $engine->loadRulesForAdapter($adapter); | |||||
$effects = $engine->applyRules($rules, $adapter); | |||||
$engine->applyEffects($effects, $adapter, $rules); | |||||
} | |||||
} | |||||
chad: Intended to be in this diff? | |||||
Not Done Inline ActionsYeah, this was just lower down in the file and I moved it up to be with similar code. (I added it not-the-best place a few diffs ago.) epriestley: Yeah, this was just lower down in the file and I moved it up to be with similar code. (I added… | |||||
/* -( Publishing Feed Stories )-------------------------------------------- */ | /* -( Publishing Feed Stories )-------------------------------------------- */ | ||||
/** | /** | ||||
* @task feed | * @task feed | ||||
*/ | */ | ||||
protected function shouldPublishFeedStory( | protected function shouldPublishFeedStory( | ||||
▲ Show 20 Lines • Show All 407 Lines • ▼ Show 20 Lines | /* -( Workers )------------------------------------------------------------ */ | ||||
* @task workers | * @task workers | ||||
*/ | */ | ||||
final private function getWorkerState() { | final private function getWorkerState() { | ||||
$state = array(); | $state = array(); | ||||
foreach ($this->getAutomaticStateProperties() as $property) { | foreach ($this->getAutomaticStateProperties() as $property) { | ||||
$state[$property] = $this->$property; | $state[$property] = $this->$property; | ||||
} | } | ||||
$custom_state = $this->getCustomWorkerState(); | |||||
$custom_encoding = $this->getCustomWorkerStateEncoding(); | |||||
$state += array( | $state += array( | ||||
'excludeMailRecipientPHIDs' => $this->getExcludeMailRecipientPHIDs(), | 'excludeMailRecipientPHIDs' => $this->getExcludeMailRecipientPHIDs(), | ||||
'custom' => $this->getCustomWorkerState(), | 'custom' => $this->encodeStateForStorage($custom_state, $custom_encoding), | ||||
'custom.encoding' => $custom_encoding, | |||||
); | ); | ||||
return $state; | return $state; | ||||
} | } | ||||
/** | /** | ||||
* Hook; return custom properties which need to be passed to workers. | * Hook; return custom properties which need to be passed to workers. | ||||
* | * | ||||
* @return dict<string, wild> Custom properties. | * @return dict<string, wild> Custom properties. | ||||
* @task workers | * @task workers | ||||
*/ | */ | ||||
protected function getCustomWorkerState() { | protected function getCustomWorkerState() { | ||||
return array(); | return array(); | ||||
} | } | ||||
/** | /** | ||||
* Hook; return storage encoding for custom properties which need to be | |||||
* passed to workers. | |||||
* | |||||
* This primarily allows binary data to be passed to workers and survive | |||||
* JSON encoding. | |||||
* | |||||
* @return dict<string, string> Property encodings. | |||||
* @task workers | |||||
*/ | |||||
protected function getCustomWorkerStateEncoding() { | |||||
return array(); | |||||
} | |||||
/** | |||||
* Load editor state using a dictionary emitted by @{method:getWorkerState}. | * Load editor state using a dictionary emitted by @{method:getWorkerState}. | ||||
* | * | ||||
* This method is used to load state when running worker operations. | * This method is used to load state when running worker operations. | ||||
* | * | ||||
* @param dict<string, wild> Editor state, from @{method:getWorkerState}. | * @param dict<string, wild> Editor state, from @{method:getWorkerState}. | ||||
* @return this | * @return this | ||||
* @task workers | * @task workers | ||||
*/ | */ | ||||
final public function loadWorkerState(array $state) { | final public function loadWorkerState(array $state) { | ||||
foreach ($this->getAutomaticStateProperties() as $property) { | foreach ($this->getAutomaticStateProperties() as $property) { | ||||
$this->$property = idx($state, $property); | $this->$property = idx($state, $property); | ||||
} | } | ||||
$exclude = idx($state, 'excludeMailRecipientPHIDs', array()); | $exclude = idx($state, 'excludeMailRecipientPHIDs', array()); | ||||
$this->setExcludeMailRecipientPHIDs($exclude); | $this->setExcludeMailRecipientPHIDs($exclude); | ||||
$custom = idx($state, 'custom', array()); | $custom_state = idx($state, 'custom', array()); | ||||
$custom_encodings = idx($state, 'custom.encoding', array()); | |||||
$custom = $this->decodeStateFromStorage($custom_state, $custom_encodings); | |||||
$this->loadCustomWorkerState($custom); | $this->loadCustomWorkerState($custom); | ||||
return $this; | return $this; | ||||
} | } | ||||
/** | /** | ||||
* Hook; set custom properties on the editor from data emitted by | * Hook; set custom properties on the editor from data emitted by | ||||
Show All 29 Lines | return array( | ||||
'heraldHeader', | 'heraldHeader', | ||||
'mailToPHIDs', | 'mailToPHIDs', | ||||
'mailCCPHIDs', | 'mailCCPHIDs', | ||||
'feedNotifyPHIDs', | 'feedNotifyPHIDs', | ||||
'feedRelatedPHIDs', | 'feedRelatedPHIDs', | ||||
); | ); | ||||
} | } | ||||
private function runHeraldMailRules(array $messages) { | /** | ||||
foreach ($messages as $message) { | * Apply encodings prior to storage. | ||||
$engine = new HeraldEngine(); | * | ||||
$adapter = id(new PhabricatorMailOutboundMailHeraldAdapter()) | * See @{method:getCustomWorkerStateEncoding}. | ||||
->setObject($message); | * | ||||
* @param map<string, wild> Map of values to encode. | |||||
* @param map<string, string> Map of encodings to apply. | |||||
* @return map<string, wild> Map of encoded values. | |||||
* @task workers | |||||
*/ | |||||
final private function encodeStateForStorage( | |||||
array $state, | |||||
array $encodings) { | |||||
foreach ($state as $key => $value) { | |||||
$encoding = idx($encodings, $key); | |||||
switch ($encoding) { | |||||
case self::STORAGE_ENCODING_BINARY: | |||||
// The mechanics of this encoding (serialize + base64) are a little | |||||
// awkward, but it allows us encode arrays and still be JSON-safe | |||||
// with binary data. | |||||
$rules = $engine->loadRulesForAdapter($adapter); | $value = @serialize($value); | ||||
$effects = $engine->applyRules($rules, $adapter); | if ($value === false) { | ||||
$engine->applyEffects($effects, $adapter, $rules); | throw new Exception( | ||||
pht( | |||||
'Failed to serialize() value for key "%s".', | |||||
$key)); | |||||
} | |||||
$value = base64_encode($value); | |||||
if ($value === false) { | |||||
throw new Exception( | |||||
pht( | |||||
'Failed to base64 encode value for key "%s".', | |||||
$key)); | |||||
} | |||||
break; | |||||
} | |||||
$state[$key] = $value; | |||||
} | |||||
return $state; | |||||
} | } | ||||
/** | |||||
* Undo storage encoding applied when storing state. | |||||
* | |||||
* See @{method:getCustomWorkerStateEncoding}. | |||||
* | |||||
* @param map<string, wild> Map of encoded values. | |||||
* @param map<string, string> Map of encodings. | |||||
* @return map<string, wild> Map of decoded values. | |||||
* @task workers | |||||
*/ | |||||
final private function decodeStateFromStorage( | |||||
array $state, | |||||
array $encodings) { | |||||
foreach ($state as $key => $value) { | |||||
$encoding = idx($encodings, $key); | |||||
switch ($encoding) { | |||||
case self::STORAGE_ENCODING_BINARY: | |||||
$value = base64_decode($value); | |||||
if ($value === false) { | |||||
throw new Exception( | |||||
pht( | |||||
'Failed to base64_decode() value for key "%s".', | |||||
$key)); | |||||
} | |||||
$value = unserialize($value); | |||||
break; | |||||
} | |||||
$state[$key] = $value; | |||||
} | |||||
return $state; | |||||
} | } | ||||
} | } |
Intended to be in this diff?