|
29 | 29 | class Esi
|
30 | 30 | {
|
31 | 31 | private $contentTypes;
|
| 32 | + private $phpEscapeMap = array( |
| 33 | + array('<?', '<%', '<s', '<S'), |
| 34 | + array('<?php echo "<?"; ?>', '<?php echo "<%"; ?>', '<?php echo "<s"; ?>', '<?php echo "<S"; ?>'), |
| 35 | + ); |
32 | 36 |
|
33 | 37 | /**
|
34 | 38 | * Constructor.
|
@@ -158,10 +162,34 @@ public function process(Request $request, Response $response)
|
158 | 162 |
|
159 | 163 | // we don't use a proper XML parser here as we can have ESI tags in a plain text response
|
160 | 164 | $content = $response->getContent();
|
161 |
| - $content = str_replace(array('<?', '<%'), array('<?php echo "<?"; ?>', '<?php echo "<%"; ?>'), $content); |
162 |
| - $content = preg_replace_callback('#<esi\:include\s+(.*?)\s*(?:/|</esi\:include)>#', array($this, 'handleEsiIncludeTag'), $content); |
163 |
| - $content = preg_replace('#<esi\:comment[^>]*(?:/|</esi\:comment)>#', '', $content); |
164 | 165 | $content = preg_replace('#<esi\:remove>.*?</esi\:remove>#', '', $content);
|
| 166 | + $content = preg_replace('#<esi\:comment[^>]*(?:/|</esi\:comment)>#', '', $content); |
| 167 | + |
| 168 | + $chunks = preg_split('#<esi\:include\s+(.*?)\s*(?:/|</esi\:include)>#', $content, -1, PREG_SPLIT_DELIM_CAPTURE); |
| 169 | + $chunks[0] = str_replace($this->phpEscapeMap[0], $this->phpEscapeMap[1], $chunks[0]); |
| 170 | + |
| 171 | + $i = 1; |
| 172 | + while (isset($chunks[$i])) { |
| 173 | + $options = array(); |
| 174 | + preg_match_all('/(src|onerror|alt)="([^"]*?)"/', $chunks[$i], $matches, PREG_SET_ORDER); |
| 175 | + foreach ($matches as $set) { |
| 176 | + $options[$set[1]] = $set[2]; |
| 177 | + } |
| 178 | + |
| 179 | + if (!isset($options['src'])) { |
| 180 | + throw new \RuntimeException('Unable to process an ESI tag without a "src" attribute.'); |
| 181 | + } |
| 182 | + |
| 183 | + $chunks[$i] = sprintf('<?php echo $this->esi->handle($this, %s, %s, %s) ?>'."\n", |
| 184 | + var_export($options['src'], true), |
| 185 | + var_export(isset($options['alt']) ? $options['alt'] : '', true), |
| 186 | + isset($options['onerror']) && 'continue' == $options['onerror'] ? 'true' : 'false' |
| 187 | + ); |
| 188 | + ++$i; |
| 189 | + $chunks[$i] = str_replace($this->phpEscapeMap[0], $this->phpEscapeMap[1], $chunks[$i]); |
| 190 | + ++$i; |
| 191 | + } |
| 192 | + $content = implode('', $chunks); |
165 | 193 |
|
166 | 194 | $response->setContent($content);
|
167 | 195 | $response->headers->set('X-Body-Eval', 'ESI');
|
@@ -214,32 +242,4 @@ public function handle(HttpCache $cache, $uri, $alt, $ignoreErrors)
|
214 | 242 | }
|
215 | 243 | }
|
216 | 244 | }
|
217 |
| - |
218 |
| - /** |
219 |
| - * Handles an ESI include tag (called internally). |
220 |
| - * |
221 |
| - * @param array $attributes An array containing the attributes. |
222 |
| - * |
223 |
| - * @return string The response content for the include. |
224 |
| - * |
225 |
| - * @throws \RuntimeException |
226 |
| - */ |
227 |
| - private function handleEsiIncludeTag($attributes) |
228 |
| - { |
229 |
| - $options = array(); |
230 |
| - preg_match_all('/(src|onerror|alt)="([^"]*?)"/', $attributes[1], $matches, PREG_SET_ORDER); |
231 |
| - foreach ($matches as $set) { |
232 |
| - $options[$set[1]] = $set[2]; |
233 |
| - } |
234 |
| - |
235 |
| - if (!isset($options['src'])) { |
236 |
| - throw new \RuntimeException('Unable to process an ESI tag without a "src" attribute.'); |
237 |
| - } |
238 |
| - |
239 |
| - return sprintf('<?php echo $this->esi->handle($this, %s, %s, %s) ?>'."\n", |
240 |
| - var_export($options['src'], true), |
241 |
| - var_export(isset($options['alt']) ? $options['alt'] : '', true), |
242 |
| - isset($options['onerror']) && 'continue' == $options['onerror'] ? 'true' : 'false' |
243 |
| - ); |
244 |
| - } |
245 | 245 | }
|
0 commit comments