f228f9b57f737ea7847a8ea624778fe2e4d87196
[Packages/TYPO3.CMS.git] / typo3 / sysext / fluid / Classes / Core / Parser / PreProcessor / XmlnsNamespaceTemplatePreProcessor.php
1 <?php
2 namespace TYPO3\CMS\Fluid\Core\Parser\PreProcessor;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3Fluid\Fluid\Core\Parser\TemplateProcessorInterface;
18 use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
19
20 /**
21 * Class XmlnsNamespaceTemplatePreProcessor
22 */
23 class XmlnsNamespaceTemplatePreProcessor implements TemplateProcessorInterface
24 {
25 /**
26 * @var RenderingContextInterface
27 */
28 protected $renderingContext;
29
30 /**
31 * @param RenderingContextInterface $renderingContext
32 * @return void
33 */
34 public function setRenderingContext(RenderingContextInterface $renderingContext)
35 {
36 $this->renderingContext = $renderingContext;
37 }
38
39 /**
40 * Pre-process the template source before it is returned to the TemplateParser or passed to
41 * the next TemplateProcessorInterface instance.
42 *
43 * Detects all tags that carry an `xmlns:` definition using a Fluid-compatible prefix and a
44 * conventional namespace URL (http://typo3.org/ns/). Extracts the detected namespaces and
45 * removes the detected tag.
46 *
47 * @param string $templateSource
48 * @return string
49 */
50 public function preProcessSource($templateSource)
51 {
52 $matches = [];
53 $namespacePattern = 'xmlns:([a-z0-9]+)="(http\\:\\/\\/typo3\\.org\\/ns\\/[^"]+)"';
54 $matched = preg_match('/<([a-z0-9]+)(?:[^>]*?)\\s+' . $namespacePattern . '[^>]*>/', $templateSource, $matches);
55 if ($matched) {
56 $namespaces = [];
57 preg_match_all('/' . $namespacePattern . '/', $matches[0], $namespaces, PREG_SET_ORDER);
58 foreach ($namespaces as $set) {
59 $namespaceUrl = $set[2];
60 $namespaceUri = substr($namespaceUrl, 20);
61 $namespacePhp = str_replace('/', '\\', $namespaceUri);
62 $this->renderingContext->getViewHelperResolver()->addNamespace($set[1], $namespacePhp);
63 }
64 if (strpos($matches[0], 'data-namespace-typo3-fluid="true"')) {
65 $templateSource = str_replace($matches[0], '', $templateSource);
66 $closingTagName = $matches[1];
67 $closingTag = '</' . $closingTagName . '>';
68 if (strpos($templateSource, $closingTag)) {
69 $templateSource = substr($templateSource, 0, strrpos($templateSource, $closingTag)) .
70 substr($templateSource, strrpos($templateSource, $closingTag) + strlen($closingTag));
71 }
72 } else {
73 if (!empty($namespaces)) {
74 $namespaceAttributesToRemove = [];
75 foreach ($namespaces as $namespace) {
76 $namespaceAttributesToRemove[] = preg_quote($namespace[1], '/') . '="' . preg_quote($namespace[2], '/') . '"';
77 }
78 $matchWithRemovedNamespaceAttributes = preg_replace('/(?:\\s*+xmlns:(?:' . implode('|', $namespaceAttributesToRemove) . ')\\s*+)++/', ' ', $matches[0]);
79 $templateSource = str_replace($matches[0], $matchWithRemovedNamespaceAttributes, $templateSource);
80 }
81 }
82 }
83 return $templateSource;
84 }
85 }