@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.

Separate the "{img ...}" remarkup rule into separate parse and markup phases

Summary:
Ref T13101. Ref T4190. This rule is currently single-phase but I'd like to check for a valid proxied image in cache already and just emit an `<img ... />` tag pointing at it if we have one.

To support batching these lookups, split the rule into a parse phase (where we extract URIs) and a markup phase (where we build tags).

Test Plan: Used `{img ...}` in Remarkup with no apparent behavioral changes. (This change should do nothing on its own.)

Maniphest Tasks: T13101, T4190

Differential Revision: https://secure.phabricator.com/D19192

+60 -7
+60 -7
src/applications/files/markup/PhabricatorImageRemarkupRule.php
··· 1 1 <?php 2 2 3 3 final class PhabricatorImageRemarkupRule extends PhutilRemarkupRule { 4 + 5 + const KEY_RULE_EXTERNAL_IMAGE = 'rule.external-image'; 6 + 4 7 public function getPriority() { 5 8 return 200.0; 6 9 } ··· 16 19 if (!$this->isFlatText($matches[0])) { 17 20 return $matches[0]; 18 21 } 22 + 19 23 $args = array(); 20 24 $defaults = array( 21 25 'uri' => null, ··· 23 27 'width' => null, 24 28 'height' => null, 25 29 ); 30 + 26 31 $trimmed_match = trim($matches[2]); 27 32 if ($this->isURI($trimmed_match)) { 28 - $args['uri'] = new PhutilURI($trimmed_match); 33 + $args['uri'] = $trimmed_match; 29 34 } else { 30 35 $parser = new PhutilSimpleOptions(); 31 36 $keys = $parser->parse($trimmed_match); ··· 37 42 } 38 43 } 39 44 if ($uri_key) { 40 - $args['uri'] = new PhutilURI($keys[$uri_key]); 45 + $args['uri'] = $keys[$uri_key]; 41 46 } 42 47 $args += $keys; 43 48 } 44 49 45 50 $args += $defaults; 46 51 47 - if ($args['uri']) { 52 + if (!strlen($args['uri'])) { 53 + return $matches[0]; 54 + } 55 + 56 + // Make sure this is something that looks roughly like a real URI. We'll 57 + // validate it more carefully before proxying it, but if whatever the user 58 + // has typed isn't even close, just decline to activate the rule behavior. 59 + try { 60 + $uri = new PhutilURI($args['uri']); 61 + 62 + if (!strlen($uri->getProtocol())) { 63 + return $matches[0]; 64 + } 65 + 66 + $args['uri'] = (string)$uri; 67 + } catch (Exception $ex) { 68 + return $matches[0]; 69 + } 70 + 71 + $engine = $this->getEngine(); 72 + $metadata_key = self::KEY_RULE_EXTERNAL_IMAGE; 73 + $metadata = $engine->getTextMetadata($metadata_key, array()); 74 + 75 + $token = $engine->storeText('<img>'); 76 + 77 + $metadata[] = array( 78 + 'token' => $token, 79 + 'args' => $args, 80 + ); 81 + 82 + $engine->setTextMetadata($metadata_key, $metadata); 83 + 84 + return $token; 85 + } 86 + 87 + public function didMarkupText() { 88 + $engine = $this->getEngine(); 89 + $metadata_key = self::KEY_RULE_EXTERNAL_IMAGE; 90 + $images = $engine->getTextMetadata($metadata_key, array()); 91 + $engine->setTextMetadata($metadata_key, array()); 92 + 93 + if (!$images) { 94 + return; 95 + } 96 + 97 + foreach ($images as $image) { 98 + $args = $image['args']; 99 + 48 100 $src_uri = id(new PhutilURI('/file/imageproxy/')) 49 - ->setQueryParam('uri', (string)$args['uri']); 101 + ->setQueryParam('uri', $args['uri']); 102 + 50 103 $img = $this->newTag( 51 104 'img', 52 105 array( ··· 55 108 'width' => $args['width'], 56 109 'height' => $args['height'], 57 110 )); 58 - return $this->getEngine()->storeText($img); 59 - } else { 60 - return $matches[0]; 111 + 112 + $engine->overwriteStoredText($image['token'], $img); 61 113 } 62 114 } 63 115 ··· 66 118 // If it does, we'll try to treat it like a valid URI 67 119 return preg_match('~^https?\:\/\/.*\z~i', $uri_string); 68 120 } 121 + 69 122 }