@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at recaptime-dev/main 157 lines 4.3 kB view raw
1<?php 2 3final class PhabricatorImageMacroRemarkupRule extends PhutilRemarkupRule { 4 5 private $macros; 6 7 const KEY_RULE_MACRO = 'rule.macro'; 8 9 public function apply($text) { 10 return preg_replace_callback( 11 '@^\s*([a-zA-Z0-9:_\x7f-\xff-]+)$@m', 12 array($this, 'markupImageMacro'), 13 $text); 14 } 15 16 public function markupImageMacro(array $matches) { 17 if ($this->macros === null) { 18 $this->macros = array(); 19 20 $viewer = $this->getEngine()->getConfig('viewer'); 21 $rows = id(new PhabricatorMacroQuery()) 22 ->setViewer($viewer) 23 ->withStatus(PhabricatorMacroQuery::STATUS_ACTIVE) 24 ->execute(); 25 26 $this->macros = mpull($rows, 'getPHID', 'getName'); 27 } 28 29 $name = (string)$matches[1]; 30 if (empty($this->macros[$name])) { 31 return $matches[1]; 32 } 33 34 $engine = $this->getEngine(); 35 36 37 $metadata_key = self::KEY_RULE_MACRO; 38 $metadata = $engine->getTextMetadata($metadata_key, array()); 39 40 $token = $engine->storeText('<macro>'); 41 $metadata[] = array( 42 'token' => $token, 43 'phid' => $this->macros[$name], 44 'original' => $name, 45 ); 46 47 $engine->setTextMetadata($metadata_key, $metadata); 48 49 return $token; 50 } 51 52 public function didMarkupText() { 53 $engine = $this->getEngine(); 54 $metadata_key = self::KEY_RULE_MACRO; 55 $metadata = $engine->getTextMetadata($metadata_key, array()); 56 57 if (!$metadata) { 58 return; 59 } 60 61 $phids = ipull($metadata, 'phid'); 62 $viewer = $this->getEngine()->getConfig('viewer'); 63 64 // Load all the macros. 65 $macros = id(new PhabricatorMacroQuery()) 66 ->setViewer($viewer) 67 ->withStatus(PhabricatorMacroQuery::STATUS_ACTIVE) 68 ->withPHIDs($phids) 69 ->execute(); 70 $macros = mpull($macros, null, 'getPHID'); 71 72 // Load all the images and audio. 73 $file_phids = array_merge( 74 array_values(mpull($macros, 'getFilePHID')), 75 array_values(mpull($macros, 'getAudioPHID'))); 76 77 $file_phids = array_filter($file_phids); 78 79 $files = array(); 80 if ($file_phids) { 81 $files = id(new PhabricatorFileQuery()) 82 ->setViewer($viewer) 83 ->withPHIDs($file_phids) 84 ->execute(); 85 $files = mpull($files, null, 'getPHID'); 86 } 87 88 // Replace any macros that we couldn't load the macro or image for with 89 // the original text. 90 foreach ($metadata as $key => $spec) { 91 $macro = idx($macros, $spec['phid']); 92 if ($macro) { 93 $file = idx($files, $macro->getFilePHID()); 94 if ($file) { 95 continue; 96 } 97 } 98 99 $engine->overwriteStoredText($spec['token'], $spec['original']); 100 unset($metadata[$key]); 101 } 102 103 foreach ($metadata as $spec) { 104 $macro = $macros[$spec['phid']]; 105 $file = $files[$macro->getFilePHID()]; 106 $src_uri = $file->getBestURI(); 107 108 if ($this->getEngine()->isTextMode()) { 109 $result = $spec['original'].' <'.$src_uri.'>'; 110 $engine->overwriteStoredText($spec['token'], $result); 111 continue; 112 } else if ($this->getEngine()->isHTMLMailMode()) { 113 $src_uri = PhabricatorEnv::getProductionURI($src_uri); 114 } 115 116 $id = null; 117 $audio = idx($files, $macro->getAudioPHID()); 118 $should_play = ($audio && $macro->getAudioBehavior() != 119 PhabricatorFileImageMacro::AUDIO_BEHAVIOR_NONE); 120 if ($should_play) { 121 $id = celerity_generate_unique_node_id(); 122 123 $loop = null; 124 switch ($macro->getAudioBehavior()) { 125 case PhabricatorFileImageMacro::AUDIO_BEHAVIOR_LOOP: 126 $loop = true; 127 break; 128 } 129 130 Javelin::initBehavior( 131 'audio-source', 132 array( 133 'sourceID' => $id, 134 'audioURI' => $audio->getBestURI(), 135 'loop' => $loop, 136 )); 137 } 138 139 $result = $this->newTag( 140 'img', 141 array( 142 'id' => $id, 143 'src' => $src_uri, 144 'alt' => $spec['original'], 145 'title' => $spec['original'], 146 'height' => $file->getImageHeight(), 147 'width' => $file->getImageWidth(), 148 'class' => 'phabricator-remarkup-macro', 149 )); 150 151 $engine->overwriteStoredText($spec['token'], $result); 152 } 153 154 $engine->setTextMetadata($metadata_key, array()); 155 } 156 157}