Path: blob/master/src/applications/macro/markup/PhabricatorImageMacroRemarkupRule.php
12241 views
<?php12final class PhabricatorImageMacroRemarkupRule extends PhutilRemarkupRule {34private $macros;56const KEY_RULE_MACRO = 'rule.macro';78public function apply($text) {9return preg_replace_callback(10'@^\s*([a-zA-Z0-9:_\x7f-\xff-]+)$@m',11array($this, 'markupImageMacro'),12$text);13}1415public function markupImageMacro(array $matches) {16if ($this->macros === null) {17$this->macros = array();1819$viewer = $this->getEngine()->getConfig('viewer');20$rows = id(new PhabricatorMacroQuery())21->setViewer($viewer)22->withStatus(PhabricatorMacroQuery::STATUS_ACTIVE)23->execute();2425$this->macros = mpull($rows, 'getPHID', 'getName');26}2728$name = (string)$matches[1];29if (empty($this->macros[$name])) {30return $matches[1];31}3233$engine = $this->getEngine();343536$metadata_key = self::KEY_RULE_MACRO;37$metadata = $engine->getTextMetadata($metadata_key, array());3839$token = $engine->storeText('<macro>');40$metadata[] = array(41'token' => $token,42'phid' => $this->macros[$name],43'original' => $name,44);4546$engine->setTextMetadata($metadata_key, $metadata);4748return $token;49}5051public function didMarkupText() {52$engine = $this->getEngine();53$metadata_key = self::KEY_RULE_MACRO;54$metadata = $engine->getTextMetadata($metadata_key, array());5556if (!$metadata) {57return;58}5960$phids = ipull($metadata, 'phid');61$viewer = $this->getEngine()->getConfig('viewer');6263// Load all the macros.64$macros = id(new PhabricatorMacroQuery())65->setViewer($viewer)66->withStatus(PhabricatorMacroQuery::STATUS_ACTIVE)67->withPHIDs($phids)68->execute();69$macros = mpull($macros, null, 'getPHID');7071// Load all the images and audio.72$file_phids = array_merge(73array_values(mpull($macros, 'getFilePHID')),74array_values(mpull($macros, 'getAudioPHID')));7576$file_phids = array_filter($file_phids);7778$files = array();79if ($file_phids) {80$files = id(new PhabricatorFileQuery())81->setViewer($viewer)82->withPHIDs($file_phids)83->execute();84$files = mpull($files, null, 'getPHID');85}8687// Replace any macros that we couldn't load the macro or image for with88// the original text.89foreach ($metadata as $key => $spec) {90$macro = idx($macros, $spec['phid']);91if ($macro) {92$file = idx($files, $macro->getFilePHID());93if ($file) {94continue;95}96}9798$engine->overwriteStoredText($spec['token'], $spec['original']);99unset($metadata[$key]);100}101102foreach ($metadata as $spec) {103$macro = $macros[$spec['phid']];104$file = $files[$macro->getFilePHID()];105$src_uri = $file->getBestURI();106107if ($this->getEngine()->isTextMode()) {108$result = $spec['original'].' <'.$src_uri.'>';109$engine->overwriteStoredText($spec['token'], $result);110continue;111} else if ($this->getEngine()->isHTMLMailMode()) {112$src_uri = PhabricatorEnv::getProductionURI($src_uri);113}114115$id = null;116$audio = idx($files, $macro->getAudioPHID());117$should_play = ($audio && $macro->getAudioBehavior() !=118PhabricatorFileImageMacro::AUDIO_BEHAVIOR_NONE);119if ($should_play) {120$id = celerity_generate_unique_node_id();121122$loop = null;123switch ($macro->getAudioBehavior()) {124case PhabricatorFileImageMacro::AUDIO_BEHAVIOR_LOOP:125$loop = true;126break;127}128129Javelin::initBehavior(130'audio-source',131array(132'sourceID' => $id,133'audioURI' => $audio->getBestURI(),134'loop' => $loop,135));136}137138$result = $this->newTag(139'img',140array(141'id' => $id,142'src' => $src_uri,143'alt' => $spec['original'],144'title' => $spec['original'],145'height' => $file->getImageHeight(),146'width' => $file->getImageWidth(),147'class' => 'phabricator-remarkup-macro',148));149150$engine->overwriteStoredText($spec['token'], $result);151}152153$engine->setTextMetadata($metadata_key, array());154}155156}157158159