Completed
Pull Request — master (#149)
by
unknown
10:47
created
Classes/Manipulation/RemoveComments.php 1 patch
Indentation   +51 added lines, -51 removed lines patch added patch discarded remove patch
@@ -6,61 +6,61 @@
 block discarded – undo
6 6
 
7 7
 class RemoveComments implements ManipulationInterface
8 8
 {
9
-    /**
10
-     * Patterns for white-listing comments inside content.
11
-     */
12
-    protected array $whiteListCommentsPatterns = [];
9
+	/**
10
+	 * Patterns for white-listing comments inside content.
11
+	 */
12
+	protected array $whiteListCommentsPatterns = [];
13 13
 
14
-    /**
15
-     * @param string $html          The original HTML
16
-     * @param array  $configuration Configuration
17
-     *
18
-     * @return string the manipulated HTML
19
-     */
20
-    public function manipulate(string $html, array $configuration = []): string
21
-    {
22
-        if (isset($configuration['keep.'])) {
23
-            $this->whiteListCommentsPatterns = $configuration['keep.'];
24
-        }
14
+	/**
15
+	 * @param string $html          The original HTML
16
+	 * @param array  $configuration Configuration
17
+	 *
18
+	 * @return string the manipulated HTML
19
+	 */
20
+	public function manipulate(string $html, array $configuration = []): string
21
+	{
22
+		if (isset($configuration['keep.'])) {
23
+			$this->whiteListCommentsPatterns = $configuration['keep.'];
24
+		}
25 25
 
26
-        // match all comments, styles and scripts
27
-        $matches = [];
28
-        preg_match_all(
29
-            '/(?s)((<!--.*?-->)|(<[ \n\r]*style[^>]*>.*?<[ \n\r]*\/style[^>]*>)|(<[ \n\r]*script[^>]*>.*?<[ \n\r]*\/script[^>]*>))/im',
30
-            $html,
31
-            $matches
32
-        );
33
-        foreach ($matches[0] as $tag) {
34
-            if (false === $this->keepComment($tag)) {
35
-                $html = str_replace($tag, '', $html);
36
-            }
37
-        }
26
+		// match all comments, styles and scripts
27
+		$matches = [];
28
+		preg_match_all(
29
+			'/(?s)((<!--.*?-->)|(<[ \n\r]*style[^>]*>.*?<[ \n\r]*\/style[^>]*>)|(<[ \n\r]*script[^>]*>.*?<[ \n\r]*\/script[^>]*>))/im',
30
+			$html,
31
+			$matches
32
+		);
33
+		foreach ($matches[0] as $tag) {
34
+			if (false === $this->keepComment($tag)) {
35
+				$html = str_replace($tag, '', $html);
36
+			}
37
+		}
38 38
 
39
-        return $html;
40
-    }
39
+		return $html;
40
+	}
41 41
 
42
-    /**
43
-     * Check if a comment is defined to be kept in a pattern whiteListOfComments.
44
-     */
45
-    protected function keepComment(string $commentHtml): bool
46
-    {
47
-        // if not even a comment, skip this
48
-        if (!preg_match('/^\<\!\-\-(.*?)\-\-\>$/usi', $commentHtml)) {
49
-            return true;
50
-        }
42
+	/**
43
+	 * Check if a comment is defined to be kept in a pattern whiteListOfComments.
44
+	 */
45
+	protected function keepComment(string $commentHtml): bool
46
+	{
47
+		// if not even a comment, skip this
48
+		if (!preg_match('/^\<\!\-\-(.*?)\-\-\>$/usi', $commentHtml)) {
49
+			return true;
50
+		}
51 51
 
52
-        // if not defined in white list
53
-        if (!empty($this->whiteListCommentsPatterns)) {
54
-            $commentHtml = str_replace('<!--', '', $commentHtml);
55
-            $commentHtml = str_replace('-->', '', $commentHtml);
56
-            $commentHtml = trim($commentHtml);
57
-            foreach ($this->whiteListCommentsPatterns as $pattern) {
58
-                if (!empty($pattern) && preg_match($pattern, $commentHtml)) {
59
-                    return true;
60
-                }
61
-            }
62
-        }
52
+		// if not defined in white list
53
+		if (!empty($this->whiteListCommentsPatterns)) {
54
+			$commentHtml = str_replace('<!--', '', $commentHtml);
55
+			$commentHtml = str_replace('-->', '', $commentHtml);
56
+			$commentHtml = trim($commentHtml);
57
+			foreach ($this->whiteListCommentsPatterns as $pattern) {
58
+				if (!empty($pattern) && preg_match($pattern, $commentHtml)) {
59
+					return true;
60
+				}
61
+			}
62
+		}
63 63
 
64
-        return false;
65
-    }
64
+		return false;
65
+	}
66 66
 }
Please login to merge, or discard this patch.
Classes/Manipulation/ManipulationInterface.php 1 patch
Indentation   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -6,11 +6,11 @@
 block discarded – undo
6 6
 
7 7
 interface ManipulationInterface
8 8
 {
9
-    /**
10
-     * @param string $html          The original HTML
11
-     * @param array  $configuration Configuration
12
-     *
13
-     * @return string the manipulated HTML
14
-     */
15
-    public function manipulate(string $html, array $configuration = []): string;
9
+	/**
10
+	 * @param string $html          The original HTML
11
+	 * @param array  $configuration Configuration
12
+	 *
13
+	 * @return string the manipulated HTML
14
+	 */
15
+	public function manipulate(string $html, array $configuration = []): string;
16 16
 }
Please login to merge, or discard this patch.
Classes/Middleware/AbstractMiddleware.php 1 patch
Indentation   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -13,32 +13,32 @@
 block discarded – undo
13 13
 
14 14
 abstract class AbstractMiddleware implements MiddlewareInterface
15 15
 {
16
-    protected function responseIsAlterable(ResponseInterface $response): bool
17
-    {
18
-        if (!$response instanceof NullResponse) {
19
-            return false;
20
-        }
21
-
22
-        if (!$GLOBALS['TSFE'] instanceof TypoScriptFrontendController) {  // need for configuration
23
-            return false;
24
-        }
25
-
26
-        if ('text/html' !== substr($response->getHeaderLine('Content-Type'), 0, 9)) {
27
-            return false;
28
-        }
29
-
30
-        if (empty($response->getBody())) {
31
-            return false;
32
-        }
33
-
34
-        return true;
35
-    }
36
-
37
-    protected function getStringStream(string $content): StreamInterface
38
-    {
39
-        $body = new Stream('php://temp', 'rw');
40
-        $body->write($content);
41
-
42
-        return $body;
43
-    }
16
+	protected function responseIsAlterable(ResponseInterface $response): bool
17
+	{
18
+		if (!$response instanceof NullResponse) {
19
+			return false;
20
+		}
21
+
22
+		if (!$GLOBALS['TSFE'] instanceof TypoScriptFrontendController) {  // need for configuration
23
+			return false;
24
+		}
25
+
26
+		if ('text/html' !== substr($response->getHeaderLine('Content-Type'), 0, 9)) {
27
+			return false;
28
+		}
29
+
30
+		if (empty($response->getBody())) {
31
+			return false;
32
+		}
33
+
34
+		return true;
35
+	}
36
+
37
+	protected function getStringStream(string $content): StreamInterface
38
+	{
39
+		$body = new Stream('php://temp', 'rw');
40
+		$body->write($content);
41
+
42
+		return $body;
43
+	}
44 44
 }
Please login to merge, or discard this patch.
Classes/Manipulation/RemoveGenerator.php 2 patches
Indentation   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -6,16 +6,16 @@
 block discarded – undo
6 6
 
7 7
 class RemoveGenerator implements ManipulationInterface
8 8
 {
9
-    /**
10
-     * @param string $html          The original HTML
11
-     * @param array  $configuration Configuration
12
-     *
13
-     * @return string the manipulated HTML
14
-     */
15
-    public function manipulate(string $html, array $configuration = []): string
16
-    {
17
-        $regex = '<meta name=["\']?generator["\']? [^>]+>';
9
+	/**
10
+	 * @param string $html          The original HTML
11
+	 * @param array  $configuration Configuration
12
+	 *
13
+	 * @return string the manipulated HTML
14
+	 */
15
+	public function manipulate(string $html, array $configuration = []): string
16
+	{
17
+		$regex = '<meta name=["\']?generator["\']? [^>]+>';
18 18
 
19
-        return (string) preg_replace('/' . $regex . '/is', '', $html);
20
-    }
19
+		return (string) preg_replace('/' . $regex . '/is', '', $html);
20
+	}
21 21
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -16,6 +16,6 @@
 block discarded – undo
16 16
     {
17 17
         $regex = '<meta name=["\']?generator["\']? [^>]+>';
18 18
 
19
-        return (string) preg_replace('/' . $regex . '/is', '', $html);
19
+        return (string) preg_replace('/'.$regex.'/is', '', $html);
20 20
     }
21 21
 }
Please login to merge, or discard this patch.
Classes/Middleware/SvgStoreMiddleware.php 1 patch
Indentation   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -11,20 +11,20 @@
 block discarded – undo
11 11
 
12 12
 class SvgStoreMiddleware extends AbstractMiddleware
13 13
 {
14
-    public function __construct(protected SvgStoreService $svgStoreService) {}
14
+	public function __construct(protected SvgStoreService $svgStoreService) {}
15 15
 
16
-    /**
17
-     * Search/Extract/Merge SVGs @ HTML output.
18
-     */
19
-    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
20
-    {
21
-        $response = $handler->handle($request);
16
+	/**
17
+	 * Search/Extract/Merge SVGs @ HTML output.
18
+	 */
19
+	public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
20
+	{
21
+		$response = $handler->handle($request);
22 22
 
23
-        if ($this->responseIsAlterable($response) && $GLOBALS['TSFE']->config['config']['svgstore.']['enabled'] ?? false) {
24
-            $processedHtml = $this->svgStoreService->process((string) $response->getBody());
25
-            $response = $response->withBody($this->getStringStream($processedHtml));
26
-        }
23
+		if ($this->responseIsAlterable($response) && $GLOBALS['TSFE']->config['config']['svgstore.']['enabled'] ?? false) {
24
+			$processedHtml = $this->svgStoreService->process((string) $response->getBody());
25
+			$response = $response->withBody($this->getStringStream($processedHtml));
26
+		}
27 27
 
28
-        return $response;
29
-    }
28
+		return $response;
29
+	}
30 30
 }
Please login to merge, or discard this patch.
Classes/Middleware/CleanHtmlMiddleware.php 1 patch
Indentation   +16 added lines, -16 removed lines patch added patch discarded remove patch
@@ -11,23 +11,23 @@
 block discarded – undo
11 11
 
12 12
 class CleanHtmlMiddleware extends AbstractMiddleware
13 13
 {
14
-    public function __construct(protected CleanHtmlService $cleanHtmlService) {}
14
+	public function __construct(protected CleanHtmlService $cleanHtmlService) {}
15 15
 
16
-    /**
17
-     * Clean the HTML output.
18
-     */
19
-    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
20
-    {
21
-        $response = $handler->handle($request);
16
+	/**
17
+	 * Clean the HTML output.
18
+	 */
19
+	public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
20
+	{
21
+		$response = $handler->handle($request);
22 22
 
23
-        if ($this->responseIsAlterable($response) && $GLOBALS['TSFE']->config['config']['sourceopt.']['enabled'] ?? false) {
24
-            $processedHtml = $this->cleanHtmlService->clean(
25
-                (string) $response->getBody(),
26
-                (array) $GLOBALS['TSFE']->config['config']['sourceopt.']
27
-            );
28
-            $response = $response->withBody($this->getStringStream($processedHtml));
29
-        }
23
+		if ($this->responseIsAlterable($response) && $GLOBALS['TSFE']->config['config']['sourceopt.']['enabled'] ?? false) {
24
+			$processedHtml = $this->cleanHtmlService->clean(
25
+				(string) $response->getBody(),
26
+				(array) $GLOBALS['TSFE']->config['config']['sourceopt.']
27
+			);
28
+			$response = $response->withBody($this->getStringStream($processedHtml));
29
+		}
30 30
 
31
-        return $response;
32
-    }
31
+		return $response;
32
+	}
33 33
 }
Please login to merge, or discard this patch.
Classes/Middleware/RegExRepMiddleware.php 1 patch
Indentation   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -11,20 +11,20 @@
 block discarded – undo
11 11
 
12 12
 class RegExRepMiddleware extends AbstractMiddleware
13 13
 {
14
-    public function __construct(protected RegExRepService $regExRepService) {}
14
+	public function __construct(protected RegExRepService $regExRepService) {}
15 15
 
16
-    /**
17
-     * RegEx search & replace @ HTML output.
18
-     */
19
-    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
20
-    {
21
-        $response = $handler->handle($request);
16
+	/**
17
+	 * RegEx search & replace @ HTML output.
18
+	 */
19
+	public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
20
+	{
21
+		$response = $handler->handle($request);
22 22
 
23
-        if ($this->responseIsAlterable($response) && $GLOBALS['TSFE']->config['config']['replacer.'] ?? false) {
24
-            $processedHtml = $this->regExRepService->process((string) $response->getBody());
25
-            $response = $response->withBody($this->getStringStream($processedHtml));
26
-        }
23
+		if ($this->responseIsAlterable($response) && $GLOBALS['TSFE']->config['config']['replacer.'] ?? false) {
24
+			$processedHtml = $this->regExRepService->process((string) $response->getBody());
25
+			$response = $response->withBody($this->getStringStream($processedHtml));
26
+		}
27 27
 
28
-        return $response;
29
-    }
28
+		return $response;
29
+	}
30 30
 }
Please login to merge, or discard this patch.
Classes/Service/RegExRepService.php 2 patches
Indentation   +42 added lines, -42 removed lines patch added patch discarded remove patch
@@ -16,46 +16,46 @@
 block discarded – undo
16 16
  */
17 17
 class RegExRepService implements SingletonInterface
18 18
 {
19
-    public function process(string $html): string
20
-    {
21
-        $config = $GLOBALS['TSFE']->config['config']['replacer.'];
22
-
23
-        foreach (['search.', 'replace.'] as $section) {
24
-            if (!isset($config[$section]) || !\is_array($config[$section])) {
25
-                throw new \Exception('missing entry @ config.replacer.' . $section);
26
-            }
27
-
28
-            if (preg_match_all('/"([\w\-]+)\.";/', serialize(array_keys($config[$section])), $matches)) {
29
-                $cObj ??= $GLOBALS['TSFE']->cObj ?? GeneralUtility::makeInstance(ContentObjectRenderer::class);
30
-
31
-                foreach ($matches[1] as $key) {
32
-                    $config[$section][$key] = $cObj
33
-                        ->stdWrap(
34
-                            $config[$section][$key],
35
-                            $config[$section][$key . '.']
36
-                        )
37
-                    ;
38
-                    unset($config[$section][$key . '.']); // keep!
39
-                }
40
-            }
41
-
42
-            ksort($config[$section], \SORT_NATURAL); // safety
43
-        }
44
-
45
-        if (Environment::getContext()->isDevelopment()) {
46
-            foreach ($config['search.'] as $key => $val) {
47
-                if (false === @preg_match($val, '')) {
48
-                    throw new \Exception(preg_last_error_msg() . ' : please check your regex syntax @ ' . "{$key} = {$val}");
49
-                }
50
-            }
51
-        }
52
-
53
-        $arrIntersectKeysCnt = 2 * \count(array_intersect_key($config['search.'], $config['replace.']));
54
-
55
-        if ((bool) (\count($config['search.']) + \count($config['replace.']) - $arrIntersectKeysCnt)) {
56
-            throw new \Exception('config.replacer requests have diverged');
57
-        }
58
-
59
-        return preg_replace($config['search.'], $config['replace.'], $html);
60
-    }
19
+	public function process(string $html): string
20
+	{
21
+		$config = $GLOBALS['TSFE']->config['config']['replacer.'];
22
+
23
+		foreach (['search.', 'replace.'] as $section) {
24
+			if (!isset($config[$section]) || !\is_array($config[$section])) {
25
+				throw new \Exception('missing entry @ config.replacer.' . $section);
26
+			}
27
+
28
+			if (preg_match_all('/"([\w\-]+)\.";/', serialize(array_keys($config[$section])), $matches)) {
29
+				$cObj ??= $GLOBALS['TSFE']->cObj ?? GeneralUtility::makeInstance(ContentObjectRenderer::class);
30
+
31
+				foreach ($matches[1] as $key) {
32
+					$config[$section][$key] = $cObj
33
+						->stdWrap(
34
+							$config[$section][$key],
35
+							$config[$section][$key . '.']
36
+						)
37
+					;
38
+					unset($config[$section][$key . '.']); // keep!
39
+				}
40
+			}
41
+
42
+			ksort($config[$section], \SORT_NATURAL); // safety
43
+		}
44
+
45
+		if (Environment::getContext()->isDevelopment()) {
46
+			foreach ($config['search.'] as $key => $val) {
47
+				if (false === @preg_match($val, '')) {
48
+					throw new \Exception(preg_last_error_msg() . ' : please check your regex syntax @ ' . "{$key} = {$val}");
49
+				}
50
+			}
51
+		}
52
+
53
+		$arrIntersectKeysCnt = 2 * \count(array_intersect_key($config['search.'], $config['replace.']));
54
+
55
+		if ((bool) (\count($config['search.']) + \count($config['replace.']) - $arrIntersectKeysCnt)) {
56
+			throw new \Exception('config.replacer requests have diverged');
57
+		}
58
+
59
+		return preg_replace($config['search.'], $config['replace.'], $html);
60
+	}
61 61
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -22,7 +22,7 @@  discard block
 block discarded – undo
22 22
 
23 23
         foreach (['search.', 'replace.'] as $section) {
24 24
             if (!isset($config[$section]) || !\is_array($config[$section])) {
25
-                throw new \Exception('missing entry @ config.replacer.' . $section);
25
+                throw new \Exception('missing entry @ config.replacer.'.$section);
26 26
             }
27 27
 
28 28
             if (preg_match_all('/"([\w\-]+)\.";/', serialize(array_keys($config[$section])), $matches)) {
@@ -32,10 +32,10 @@  discard block
 block discarded – undo
32 32
                     $config[$section][$key] = $cObj
33 33
                         ->stdWrap(
34 34
                             $config[$section][$key],
35
-                            $config[$section][$key . '.']
35
+                            $config[$section][$key.'.']
36 36
                         )
37 37
                     ;
38
-                    unset($config[$section][$key . '.']); // keep!
38
+                    unset($config[$section][$key.'.']); // keep!
39 39
                 }
40 40
             }
41 41
 
@@ -45,7 +45,7 @@  discard block
 block discarded – undo
45 45
         if (Environment::getContext()->isDevelopment()) {
46 46
             foreach ($config['search.'] as $key => $val) {
47 47
                 if (false === @preg_match($val, '')) {
48
-                    throw new \Exception(preg_last_error_msg() . ' : please check your regex syntax @ ' . "{$key} = {$val}");
48
+                    throw new \Exception(preg_last_error_msg().' : please check your regex syntax @ '."{$key} = {$val}");
49 49
                 }
50 50
             }
51 51
         }
Please login to merge, or discard this patch.
Classes/Service/SvgStoreService.php 2 patches
Spacing   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -66,11 +66,11 @@  discard block
 block discarded – undo
66 66
         $this->svgFileArr = $this->svgCache->get('svgFileArr') ?: [];
67 67
 
68 68
         if (empty($this->spritePath) && !$this->populateCache()) {
69
-            throw new \Exception('could not write file: ' . $this->sitePath . $this->spritePath);
69
+            throw new \Exception('could not write file: '.$this->sitePath.$this->spritePath);
70 70
         }
71 71
 
72
-        if (!file_exists($this->sitePath . $this->spritePath)) {
73
-            throw new \Exception('file does not exists: ' . $this->sitePath . $this->spritePath);
72
+        if (!file_exists($this->sitePath.$this->spritePath)) {
73
+            throw new \Exception('file does not exists: '.$this->sitePath.$this->spritePath);
74 74
         }
75 75
     }
76 76
 
@@ -87,26 +87,26 @@  discard block
 block discarded – undo
87 87
         }
88 88
 
89 89
         // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attributes
90
-        $dom['body'] = preg_replace_callback('/<img(?<pre>[^>]*)src="(?:https?:)?(?:\/\/[^\/]+?)?(?<src>\/[^"]+\.svg)"(?<post>[^>]*?)[\s\/]*>(?!\s*<\/picture>)/s', function (array $match): string { // ^[/]
90
+        $dom['body'] = preg_replace_callback('/<img(?<pre>[^>]*)src="(?:https?:)?(?:\/\/[^\/]+?)?(?<src>\/[^"]+\.svg)"(?<post>[^>]*?)[\s\/]*>(?!\s*<\/picture>)/s', function(array $match): string { // ^[/]
91 91
             if (!isset($this->svgFileArr[$match['src']])) { // check usage
92 92
                 return $match[0];
93 93
             }
94
-            $attr = preg_replace('/\s(?:alt|ismap|loading|title|sizes|srcset|usemap|crossorigin|decoding|fetchpriority|referrerpolicy)="[^"]*"/', '', $match['pre'] . $match['post']); // cleanup
94
+            $attr = preg_replace('/\s(?:alt|ismap|loading|title|sizes|srcset|usemap|crossorigin|decoding|fetchpriority|referrerpolicy)="[^"]*"/', '', $match['pre'].$match['post']); // cleanup
95 95
 
96 96
             return \sprintf('<svg %s %s><use href="%s#%s"/></svg>', $this->svgFileArr[$match['src']]['attr'], trim($attr), $this->spritePath, $this->convertFilePath($match['src']));
97 97
         }, $dom['body']);
98 98
 
99 99
         // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object#attributes
100
-        $dom['body'] = preg_replace_callback('/<object(?<pre>[^>]*)data="(?<data>\/[^"]+\.svg)"(?<post>[^>]*?)[\s\/]*>(?:<\/object>)/s', function (array $match): string { // ^[/]
100
+        $dom['body'] = preg_replace_callback('/<object(?<pre>[^>]*)data="(?<data>\/[^"]+\.svg)"(?<post>[^>]*?)[\s\/]*>(?:<\/object>)/s', function(array $match): string { // ^[/]
101 101
             if (!isset($this->svgFileArr[$match['data']])) { // check usage
102 102
                 return $match[0];
103 103
             }
104
-            $attr = preg_replace('/\s(?:form|name|type|usemap)="[^"]*"/', '', $match['pre'] . $match['post']); // cleanup
104
+            $attr = preg_replace('/\s(?:form|name|type|usemap)="[^"]*"/', '', $match['pre'].$match['post']); // cleanup
105 105
 
106 106
             return \sprintf('<svg %s %s><use href="%s#%s"/></svg>', $this->svgFileArr[$match['data']]['attr'], trim($attr), $this->spritePath, $this->convertFilePath($match['data']));
107 107
         }, $dom['body']);
108 108
 
109
-        return $dom['head'] . $dom['body'];
109
+        return $dom['head'].$dom['body'];
110 110
     }
111 111
 
112 112
     private function convertFilePath(string $path): string
@@ -116,11 +116,11 @@  discard block
 block discarded – undo
116 116
 
117 117
     private function addFileToSpriteArr(string $hash, string $path, array $attr = []): ?array
118 118
     {
119
-        if (!file_exists($this->sitePath . $path)) {
119
+        if (!file_exists($this->sitePath.$path)) {
120 120
             return null;
121 121
         }
122 122
 
123
-        $svg = file_get_contents($this->sitePath . $path);
123
+        $svg = file_get_contents($this->sitePath.$path);
124 124
 
125 125
         if (preg_match('/(?:;base64|i:a?i?pgf)/', $svg)) { // noop!
126 126
             return null;
@@ -150,7 +150,7 @@  discard block
 block discarded – undo
150 150
         // }, $svg);
151 151
 
152 152
         // https://developer.mozilla.org/en-US/docs/Web/SVG/Element/svg#attributes
153
-        $svg = preg_replace_callback('/([^>]*)\s*(?=>)/s', function (array $match) use (&$attr): string {
153
+        $svg = preg_replace_callback('/([^>]*)\s*(?=>)/s', function(array $match) use (&$attr): string {
154 154
             if (false === preg_match_all('/(?!\s)(?<attr>[a-z\-]+)="\s*(?<value>[^"]+)\s*"/i', $match[1], $matches)) {
155 155
                 return $match[0];
156 156
             }
@@ -197,7 +197,7 @@  discard block
 block discarded – undo
197 197
 
198 198
         $fileArr = GeneralUtility::makeInstance(SvgFileRepository::class)->findAllByStorageUids(array_keys($storageArr));
199 199
         foreach ($fileArr as $file) {
200
-            $file['path'] = '/' . $storageArr[$file['storage']] . $file['identifier']; // ^[/]
200
+            $file['path'] = '/'.$storageArr[$file['storage']].$file['identifier']; // ^[/]
201 201
             $file['defs'] = $this->addFileToSpriteArr($file['sha1'], $file['path']);
202 202
 
203 203
             if (null !== $file['defs']) {
@@ -211,17 +211,17 @@  discard block
 block discarded – undo
211 211
 
212 212
         $svg = preg_replace_callback(
213 213
             '/<use(?<pre>.*?)(?:xlink:)?href="(?<href>\/.+?\.svg)(?:#[^"]*?)?"(?<post>.*?)[\s\/]*>(?:<\/use>)?/s',
214
-            function (array $match): string {
214
+            function(array $match): string {
215 215
                 if (!isset($this->svgFileArr[$match['href']])) { // check usage
216 216
                     return $match[0];
217 217
                 }
218 218
 
219
-                return \sprintf('<use%s href="#%s"/>', $match['pre'] . $match['post'], $this->convertFilePath($match['href']));
219
+                return \sprintf('<use%s href="#%s"/>', $match['pre'].$match['post'], $this->convertFilePath($match['href']));
220 220
             },
221 221
             '<svg xmlns="http://www.w3.org/2000/svg">'
222 222
             // ."\n<style>\n".implode("\n", $this->styl)."\n</style>"
223 223
             // ."\n<defs>\n".implode("\n", $this->defs)."\n</defs>"
224
-            . "\n<symbol " . implode("</symbol>\n<symbol ", $this->svgs) . "</symbol>\n"
224
+            . "\n<symbol ".implode("</symbol>\n<symbol ", $this->svgs)."</symbol>\n"
225 225
             . '</svg>'
226 226
         );
227 227
 
@@ -234,12 +234,12 @@  discard block
 block discarded – undo
234 234
         $svg = preg_replace('/<([a-z\-]+)\s*(\/|>\s*<\/\1)>\s*|\s+(?=\/>)/i', '', $svg); // remove emtpy TAGs & shorten endings
235 235
         $svg = preg_replace('/<((circle|ellipse|line|path|polygon|polyline|rect|stop|use)\s[^>]+?)\s*>\s*<\/\2>/', '<$1/>', $svg); // shorten/minify TAG syntax
236 236
 
237
-        if (!is_dir($this->sitePath . $this->outputDir)) {
238
-            GeneralUtility::mkdir_deep($this->sitePath . $this->outputDir);
237
+        if (!is_dir($this->sitePath.$this->outputDir)) {
238
+            GeneralUtility::mkdir_deep($this->sitePath.$this->outputDir);
239 239
         }
240 240
 
241
-        $this->spritePath = $this->outputDir . hash('sha1', serialize($this->svgFileArr)) . '.svg';
242
-        if (false === file_put_contents($this->sitePath . $this->spritePath, $svg)) {
241
+        $this->spritePath = $this->outputDir.hash('sha1', serialize($this->svgFileArr)).'.svg';
242
+        if (false === file_put_contents($this->sitePath.$this->spritePath, $svg)) {
243 243
             return false;
244 244
         }
245 245
 
Please login to merge, or discard this patch.
Indentation   +231 added lines, -231 removed lines patch added patch discarded remove patch
@@ -18,235 +18,235 @@
 block discarded – undo
18 18
  */
19 19
 class SvgStoreService implements \TYPO3\CMS\Core\SingletonInterface
20 20
 {
21
-    /**
22
-     * SVG-Sprite relativ storage directory.
23
-     */
24
-    protected string $outputDir = '/typo3temp/assets/svg/';
25
-
26
-    /**
27
-     * TYPO3 absolute path to public web.
28
-     */
29
-    protected string $sitePath = '';
30
-
31
-    /**
32
-     * Final TYPO3 Frontend-Cache object.
33
-     */
34
-    protected FrontendInterface $svgCache;
35
-
36
-    /**
37
-     * Cached SVG-Sprite relativ file path.
38
-     */
39
-    protected string $spritePath = '';
40
-
41
-    /**
42
-     * Cached used SVG files (incl. defs).
43
-     */
44
-    protected array $svgFileArr = [];
45
-
46
-    /**
47
-     * Final SVG-Sprite Vectors.
48
-     */
49
-    protected array $svgs = [];
50
-
51
-    /**
52
-     * Final SVG-Sprite Styles.
53
-     */
54
-    protected array $styl = []; // ToFix ; https://stackoverflow.com/questions/39583880/external-svg-fails-to-apply-internal-css
55
-
56
-    /**
57
-     * Final SVG-Sprite Objects.
58
-     */
59
-    protected array $defs = []; // ToFix ; https://bugs.chromium.org/p/chromium/issues/detail?id=751733#c14
60
-
61
-    public function __construct()
62
-    {
63
-        $this->sitePath = Environment::getPublicPath(); // [^/]$
64
-        $this->svgCache = GeneralUtility::makeInstance(CacheManager::class)->getCache('svgstore');
65
-
66
-        $this->spritePath = $this->svgCache->get('spritePath') ?: '';
67
-        $this->svgFileArr = $this->svgCache->get('svgFileArr') ?: [];
68
-
69
-        if (empty($this->spritePath) && !$this->populateCache()) {
70
-            throw new \Exception('could not write file: ' . $this->sitePath . $this->spritePath);
71
-        }
72
-
73
-        if (!file_exists($this->sitePath . $this->spritePath)) {
74
-            throw new \Exception('file does not exists: ' . $this->sitePath . $this->spritePath);
75
-        }
76
-    }
77
-
78
-    public function process(string $html): string
79
-    {
80
-        if (empty($this->svgFileArr)) {
81
-            return $html;
82
-        }
83
-
84
-        if ($GLOBALS['TSFE']->config['config']['disableAllHeaderCode'] ?? false) {
85
-            $dom = ['head' => '', 'body' => $html];
86
-        } elseif (!preg_match('/(?<head>.+?<\/head>)(?<body>.+)/s', $html, $dom)) {
87
-            return $html;
88
-        }
89
-
90
-        // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attributes
91
-        $dom['body'] = preg_replace_callback('/<img(?<pre>[^>]*)src="(?:https?:)?(?:\/\/[^\/]+?)?(?<src>\/[^"]+\.svg)"(?<post>[^>]*?)[\s\/]*>(?!\s*<\/picture>)/s', function (array $match): string { // ^[/]
92
-            if (!isset($this->svgFileArr[$match['src']])) { // check usage
93
-                return $match[0];
94
-            }
95
-            $attr = preg_replace('/\s(?:alt|ismap|loading|title|sizes|srcset|usemap|crossorigin|decoding|fetchpriority|referrerpolicy)="[^"]*"/', '', $match['pre'] . $match['post']); // cleanup
96
-
97
-            return \sprintf('<svg %s %s><use href="%s#%s"/></svg>', $this->svgFileArr[$match['src']]['attr'], trim($attr), $this->spritePath, $this->convertFilePath($match['src']));
98
-        }, $dom['body']);
99
-
100
-        // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object#attributes
101
-        $dom['body'] = preg_replace_callback('/<object(?<pre>[^>]*)data="(?<data>\/[^"]+\.svg)"(?<post>[^>]*?)[\s\/]*>(?:<\/object>)/s', function (array $match): string { // ^[/]
102
-            if (!isset($this->svgFileArr[$match['data']])) { // check usage
103
-                return $match[0];
104
-            }
105
-            $attr = preg_replace('/\s(?:form|name|type|usemap)="[^"]*"/', '', $match['pre'] . $match['post']); // cleanup
106
-
107
-            return \sprintf('<svg %s %s><use href="%s#%s"/></svg>', $this->svgFileArr[$match['data']]['attr'], trim($attr), $this->spritePath, $this->convertFilePath($match['data']));
108
-        }, $dom['body']);
109
-
110
-        return $dom['head'] . $dom['body'];
111
-    }
112
-
113
-    private function convertFilePath(string $path): string
114
-    {
115
-        return preg_replace('/.svg$|[^\w\-]/', '', str_replace('/', '-', ltrim($path, '/'))); // ^[^/]
116
-    }
117
-
118
-    private function addFileToSpriteArr(string $hash, string $path, array $attr = []): ?array
119
-    {
120
-        if (!file_exists($this->sitePath . $path)) {
121
-            return null;
122
-        }
123
-
124
-        $svg = file_get_contents($this->sitePath . $path);
125
-
126
-        if (preg_match('/(?:;base64|i:a?i?pgf)/', $svg)) { // noop!
127
-            return null;
128
-        }
129
-
130
-        if (preg_match('/<(?:style|defs)|url\(/', $svg)) {
131
-            return null; // check links @ __construct
132
-        }
133
-
134
-        // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href
135
-        $svg = preg_replace('/^.*?<svg|\s*(<\/svg>)(?!.*\1).*$|xlink:|\s(?:(?:version|xmlns)|(?:[a-z\-]+\:[a-z\-]+))="[^"]*"/s', '', $svg); // cleanup
136
-
137
-        // $svg = preg_replace('/(?<=(?:id|class)=")/', $hash.'__', $svg); // extend  IDs
138
-        // $svg = preg_replace('/(?<=href="|url\()#/', $hash.'__', $svg); // recover IDs
139
-
140
-        // $svg = preg_replace_callback('/<style[^>]*>(?<styl>.+?)<\/style>|<defs[^>]*>(?<defs>.+?)<\/defs>/s', function(array $match) use($hash): string {
141
-        //
142
-        //    if(isset($match['styl']))
143
-        //    {
144
-        //        $this->styl[] = preg_replace('/\s*(\.|#){1}(.+?)\s*\{/', '$1'.$hash.'__$2{', $match['styl']); // patch CSS # https://mathiasbynens.be/notes/css-escapes
145
-        //    }
146
-        //    if(isset($match['defs']))
147
-        //    {
148
-        //        $this->defs[] = trim($match['defs']);
149
-        //    }
150
-        //    return '';
151
-        // }, $svg);
152
-
153
-        // https://developer.mozilla.org/en-US/docs/Web/SVG/Element/svg#attributes
154
-        $svg = preg_replace_callback('/([^>]*)\s*(?=>)/s', function (array $match) use (&$attr): string {
155
-            if (false === preg_match_all('/(?!\s)(?<attr>[a-z\-]+)="\s*(?<value>[^"]+)\s*"/i', $match[1], $matches)) {
156
-                return $match[0];
157
-            }
158
-            foreach ($matches['attr'] as $index => $attribute) {
159
-                switch ($attribute) {
160
-                    case 'id':
161
-                    case 'width':
162
-                    case 'height':
163
-                        unset($matches[0][$index]);
164
-                        break;
165
-
166
-                    case 'viewBox':
167
-                        if (false !== preg_match('/(?<minX>[-+]?[\d\.]+)\s(?<minY>[-+]?[\d\.]+)\s\+?(?<width>[\d\.]+)\s\+?(?<height>[\d\.]+)/', $matches['value'][$index], $match)) {
168
-                            $attr[] = \sprintf('%s="%s %s %s %s"', $attribute, $match['minX'], $match['minY'], $match['width'], $match['height']); // save!
169
-                        }
170
-                }
171
-            }
172
-
173
-            return implode(' ', $matches[0]);
174
-        }, $svg, 1);
175
-
176
-        if (empty($attr)) {
177
-            return null;
178
-        }
179
-
180
-        $this->svgs[] = \sprintf('id="%s" %s', $this->convertFilePath($path), $svg); // prepend ID
181
-
182
-        return ['attr' => implode(' ', $attr), 'hash' => $hash];
183
-    }
184
-
185
-    private function populateCache(): bool
186
-    {
187
-        $storageArr = GeneralUtility::makeInstance(StorageRepository::class)->findByStorageType('Local');
188
-        foreach ($storageArr as $storage) {
189
-            $storageConfig = $storage->getConfiguration();
190
-            if (!\is_array($storageConfig) || !isset($storageConfig['pathType'], $storageConfig['basePath'])) {
191
-                continue;
192
-            }
193
-            if ('relative' == $storageConfig['pathType']) {
194
-                $storageArr[$storage->getUid()] = rtrim($storageConfig['basePath'], '/'); // [^/]$
195
-            }
196
-        }
197
-        unset($storageArr[0]); // keep!
198
-
199
-        $fileArr = GeneralUtility::makeInstance(SvgFileRepository::class)->findAllByStorageUids(array_keys($storageArr));
200
-        foreach ($fileArr as $file) {
201
-            $file['path'] = '/' . $storageArr[$file['storage']] . $file['identifier']; // ^[/]
202
-            $file['defs'] = $this->addFileToSpriteArr($file['sha1'], $file['path']);
203
-
204
-            if (null !== $file['defs']) {
205
-                $this->svgFileArr[$file['path']] = $file['defs'];
206
-            }
207
-        }
208
-
209
-        if (empty($this->svgFileArr)) {
210
-            return true;
211
-        }
212
-
213
-        $svg = preg_replace_callback(
214
-            '/<use(?<pre>.*?)(?:xlink:)?href="(?<href>\/.+?\.svg)(?:#[^"]*?)?"(?<post>.*?)[\s\/]*>(?:<\/use>)?/s',
215
-            function (array $match): string {
216
-                if (!isset($this->svgFileArr[$match['href']])) { // check usage
217
-                    return $match[0];
218
-                }
219
-
220
-                return \sprintf('<use%s href="#%s"/>', $match['pre'] . $match['post'], $this->convertFilePath($match['href']));
221
-            },
222
-            '<svg xmlns="http://www.w3.org/2000/svg">'
223
-            // ."\n<style>\n".implode("\n", $this->styl)."\n</style>"
224
-            // ."\n<defs>\n".implode("\n", $this->defs)."\n</defs>"
225
-            . "\n<symbol " . implode("</symbol>\n<symbol ", $this->svgs) . "</symbol>\n"
226
-            . '</svg>'
227
-        );
228
-
229
-        if ($GLOBALS['TSFE']->config['config']['sourceopt.']['formatHtml'] ?? false) {
230
-            $svg = preg_replace('/(?<=>)\s+(?=<)/', '', $svg); // remove emptiness
231
-            $svg = preg_replace('/[\t\v]/', ' ', $svg); // prepare shrinkage
232
-            $svg = preg_replace('/\s{2,}/', ' ', $svg); // shrink whitespace
233
-        }
234
-
235
-        $svg = preg_replace('/<([a-z\-]+)\s*(\/|>\s*<\/\1)>\s*|\s+(?=\/>)/i', '', $svg); // remove emtpy TAGs & shorten endings
236
-        $svg = preg_replace('/<((circle|ellipse|line|path|polygon|polyline|rect|stop|use)\s[^>]+?)\s*>\s*<\/\2>/', '<$1/>', $svg); // shorten/minify TAG syntax
237
-
238
-        if (!is_dir($this->sitePath . $this->outputDir)) {
239
-            GeneralUtility::mkdir_deep($this->sitePath . $this->outputDir);
240
-        }
241
-
242
-        $this->spritePath = $this->outputDir . hash('sha1', serialize($this->svgFileArr)) . '.svg';
243
-        if (false === file_put_contents($this->sitePath . $this->spritePath, $svg)) {
244
-            return false;
245
-        }
246
-
247
-        $this->svgCache->set('spritePath', $this->spritePath);
248
-        $this->svgCache->set('svgFileArr', $this->svgFileArr);
249
-
250
-        return true;
251
-    }
21
+	/**
22
+	 * SVG-Sprite relativ storage directory.
23
+	 */
24
+	protected string $outputDir = '/typo3temp/assets/svg/';
25
+
26
+	/**
27
+	 * TYPO3 absolute path to public web.
28
+	 */
29
+	protected string $sitePath = '';
30
+
31
+	/**
32
+	 * Final TYPO3 Frontend-Cache object.
33
+	 */
34
+	protected FrontendInterface $svgCache;
35
+
36
+	/**
37
+	 * Cached SVG-Sprite relativ file path.
38
+	 */
39
+	protected string $spritePath = '';
40
+
41
+	/**
42
+	 * Cached used SVG files (incl. defs).
43
+	 */
44
+	protected array $svgFileArr = [];
45
+
46
+	/**
47
+	 * Final SVG-Sprite Vectors.
48
+	 */
49
+	protected array $svgs = [];
50
+
51
+	/**
52
+	 * Final SVG-Sprite Styles.
53
+	 */
54
+	protected array $styl = []; // ToFix ; https://stackoverflow.com/questions/39583880/external-svg-fails-to-apply-internal-css
55
+
56
+	/**
57
+	 * Final SVG-Sprite Objects.
58
+	 */
59
+	protected array $defs = []; // ToFix ; https://bugs.chromium.org/p/chromium/issues/detail?id=751733#c14
60
+
61
+	public function __construct()
62
+	{
63
+		$this->sitePath = Environment::getPublicPath(); // [^/]$
64
+		$this->svgCache = GeneralUtility::makeInstance(CacheManager::class)->getCache('svgstore');
65
+
66
+		$this->spritePath = $this->svgCache->get('spritePath') ?: '';
67
+		$this->svgFileArr = $this->svgCache->get('svgFileArr') ?: [];
68
+
69
+		if (empty($this->spritePath) && !$this->populateCache()) {
70
+			throw new \Exception('could not write file: ' . $this->sitePath . $this->spritePath);
71
+		}
72
+
73
+		if (!file_exists($this->sitePath . $this->spritePath)) {
74
+			throw new \Exception('file does not exists: ' . $this->sitePath . $this->spritePath);
75
+		}
76
+	}
77
+
78
+	public function process(string $html): string
79
+	{
80
+		if (empty($this->svgFileArr)) {
81
+			return $html;
82
+		}
83
+
84
+		if ($GLOBALS['TSFE']->config['config']['disableAllHeaderCode'] ?? false) {
85
+			$dom = ['head' => '', 'body' => $html];
86
+		} elseif (!preg_match('/(?<head>.+?<\/head>)(?<body>.+)/s', $html, $dom)) {
87
+			return $html;
88
+		}
89
+
90
+		// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attributes
91
+		$dom['body'] = preg_replace_callback('/<img(?<pre>[^>]*)src="(?:https?:)?(?:\/\/[^\/]+?)?(?<src>\/[^"]+\.svg)"(?<post>[^>]*?)[\s\/]*>(?!\s*<\/picture>)/s', function (array $match): string { // ^[/]
92
+			if (!isset($this->svgFileArr[$match['src']])) { // check usage
93
+				return $match[0];
94
+			}
95
+			$attr = preg_replace('/\s(?:alt|ismap|loading|title|sizes|srcset|usemap|crossorigin|decoding|fetchpriority|referrerpolicy)="[^"]*"/', '', $match['pre'] . $match['post']); // cleanup
96
+
97
+			return \sprintf('<svg %s %s><use href="%s#%s"/></svg>', $this->svgFileArr[$match['src']]['attr'], trim($attr), $this->spritePath, $this->convertFilePath($match['src']));
98
+		}, $dom['body']);
99
+
100
+		// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object#attributes
101
+		$dom['body'] = preg_replace_callback('/<object(?<pre>[^>]*)data="(?<data>\/[^"]+\.svg)"(?<post>[^>]*?)[\s\/]*>(?:<\/object>)/s', function (array $match): string { // ^[/]
102
+			if (!isset($this->svgFileArr[$match['data']])) { // check usage
103
+				return $match[0];
104
+			}
105
+			$attr = preg_replace('/\s(?:form|name|type|usemap)="[^"]*"/', '', $match['pre'] . $match['post']); // cleanup
106
+
107
+			return \sprintf('<svg %s %s><use href="%s#%s"/></svg>', $this->svgFileArr[$match['data']]['attr'], trim($attr), $this->spritePath, $this->convertFilePath($match['data']));
108
+		}, $dom['body']);
109
+
110
+		return $dom['head'] . $dom['body'];
111
+	}
112
+
113
+	private function convertFilePath(string $path): string
114
+	{
115
+		return preg_replace('/.svg$|[^\w\-]/', '', str_replace('/', '-', ltrim($path, '/'))); // ^[^/]
116
+	}
117
+
118
+	private function addFileToSpriteArr(string $hash, string $path, array $attr = []): ?array
119
+	{
120
+		if (!file_exists($this->sitePath . $path)) {
121
+			return null;
122
+		}
123
+
124
+		$svg = file_get_contents($this->sitePath . $path);
125
+
126
+		if (preg_match('/(?:;base64|i:a?i?pgf)/', $svg)) { // noop!
127
+			return null;
128
+		}
129
+
130
+		if (preg_match('/<(?:style|defs)|url\(/', $svg)) {
131
+			return null; // check links @ __construct
132
+		}
133
+
134
+		// https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href
135
+		$svg = preg_replace('/^.*?<svg|\s*(<\/svg>)(?!.*\1).*$|xlink:|\s(?:(?:version|xmlns)|(?:[a-z\-]+\:[a-z\-]+))="[^"]*"/s', '', $svg); // cleanup
136
+
137
+		// $svg = preg_replace('/(?<=(?:id|class)=")/', $hash.'__', $svg); // extend  IDs
138
+		// $svg = preg_replace('/(?<=href="|url\()#/', $hash.'__', $svg); // recover IDs
139
+
140
+		// $svg = preg_replace_callback('/<style[^>]*>(?<styl>.+?)<\/style>|<defs[^>]*>(?<defs>.+?)<\/defs>/s', function(array $match) use($hash): string {
141
+		//
142
+		//    if(isset($match['styl']))
143
+		//    {
144
+		//        $this->styl[] = preg_replace('/\s*(\.|#){1}(.+?)\s*\{/', '$1'.$hash.'__$2{', $match['styl']); // patch CSS # https://mathiasbynens.be/notes/css-escapes
145
+		//    }
146
+		//    if(isset($match['defs']))
147
+		//    {
148
+		//        $this->defs[] = trim($match['defs']);
149
+		//    }
150
+		//    return '';
151
+		// }, $svg);
152
+
153
+		// https://developer.mozilla.org/en-US/docs/Web/SVG/Element/svg#attributes
154
+		$svg = preg_replace_callback('/([^>]*)\s*(?=>)/s', function (array $match) use (&$attr): string {
155
+			if (false === preg_match_all('/(?!\s)(?<attr>[a-z\-]+)="\s*(?<value>[^"]+)\s*"/i', $match[1], $matches)) {
156
+				return $match[0];
157
+			}
158
+			foreach ($matches['attr'] as $index => $attribute) {
159
+				switch ($attribute) {
160
+					case 'id':
161
+					case 'width':
162
+					case 'height':
163
+						unset($matches[0][$index]);
164
+						break;
165
+
166
+					case 'viewBox':
167
+						if (false !== preg_match('/(?<minX>[-+]?[\d\.]+)\s(?<minY>[-+]?[\d\.]+)\s\+?(?<width>[\d\.]+)\s\+?(?<height>[\d\.]+)/', $matches['value'][$index], $match)) {
168
+							$attr[] = \sprintf('%s="%s %s %s %s"', $attribute, $match['minX'], $match['minY'], $match['width'], $match['height']); // save!
169
+						}
170
+				}
171
+			}
172
+
173
+			return implode(' ', $matches[0]);
174
+		}, $svg, 1);
175
+
176
+		if (empty($attr)) {
177
+			return null;
178
+		}
179
+
180
+		$this->svgs[] = \sprintf('id="%s" %s', $this->convertFilePath($path), $svg); // prepend ID
181
+
182
+		return ['attr' => implode(' ', $attr), 'hash' => $hash];
183
+	}
184
+
185
+	private function populateCache(): bool
186
+	{
187
+		$storageArr = GeneralUtility::makeInstance(StorageRepository::class)->findByStorageType('Local');
188
+		foreach ($storageArr as $storage) {
189
+			$storageConfig = $storage->getConfiguration();
190
+			if (!\is_array($storageConfig) || !isset($storageConfig['pathType'], $storageConfig['basePath'])) {
191
+				continue;
192
+			}
193
+			if ('relative' == $storageConfig['pathType']) {
194
+				$storageArr[$storage->getUid()] = rtrim($storageConfig['basePath'], '/'); // [^/]$
195
+			}
196
+		}
197
+		unset($storageArr[0]); // keep!
198
+
199
+		$fileArr = GeneralUtility::makeInstance(SvgFileRepository::class)->findAllByStorageUids(array_keys($storageArr));
200
+		foreach ($fileArr as $file) {
201
+			$file['path'] = '/' . $storageArr[$file['storage']] . $file['identifier']; // ^[/]
202
+			$file['defs'] = $this->addFileToSpriteArr($file['sha1'], $file['path']);
203
+
204
+			if (null !== $file['defs']) {
205
+				$this->svgFileArr[$file['path']] = $file['defs'];
206
+			}
207
+		}
208
+
209
+		if (empty($this->svgFileArr)) {
210
+			return true;
211
+		}
212
+
213
+		$svg = preg_replace_callback(
214
+			'/<use(?<pre>.*?)(?:xlink:)?href="(?<href>\/.+?\.svg)(?:#[^"]*?)?"(?<post>.*?)[\s\/]*>(?:<\/use>)?/s',
215
+			function (array $match): string {
216
+				if (!isset($this->svgFileArr[$match['href']])) { // check usage
217
+					return $match[0];
218
+				}
219
+
220
+				return \sprintf('<use%s href="#%s"/>', $match['pre'] . $match['post'], $this->convertFilePath($match['href']));
221
+			},
222
+			'<svg xmlns="http://www.w3.org/2000/svg">'
223
+			// ."\n<style>\n".implode("\n", $this->styl)."\n</style>"
224
+			// ."\n<defs>\n".implode("\n", $this->defs)."\n</defs>"
225
+			. "\n<symbol " . implode("</symbol>\n<symbol ", $this->svgs) . "</symbol>\n"
226
+			. '</svg>'
227
+		);
228
+
229
+		if ($GLOBALS['TSFE']->config['config']['sourceopt.']['formatHtml'] ?? false) {
230
+			$svg = preg_replace('/(?<=>)\s+(?=<)/', '', $svg); // remove emptiness
231
+			$svg = preg_replace('/[\t\v]/', ' ', $svg); // prepare shrinkage
232
+			$svg = preg_replace('/\s{2,}/', ' ', $svg); // shrink whitespace
233
+		}
234
+
235
+		$svg = preg_replace('/<([a-z\-]+)\s*(\/|>\s*<\/\1)>\s*|\s+(?=\/>)/i', '', $svg); // remove emtpy TAGs & shorten endings
236
+		$svg = preg_replace('/<((circle|ellipse|line|path|polygon|polyline|rect|stop|use)\s[^>]+?)\s*>\s*<\/\2>/', '<$1/>', $svg); // shorten/minify TAG syntax
237
+
238
+		if (!is_dir($this->sitePath . $this->outputDir)) {
239
+			GeneralUtility::mkdir_deep($this->sitePath . $this->outputDir);
240
+		}
241
+
242
+		$this->spritePath = $this->outputDir . hash('sha1', serialize($this->svgFileArr)) . '.svg';
243
+		if (false === file_put_contents($this->sitePath . $this->spritePath, $svg)) {
244
+			return false;
245
+		}
246
+
247
+		$this->svgCache->set('spritePath', $this->spritePath);
248
+		$this->svgCache->set('svgFileArr', $this->svgFileArr);
249
+
250
+		return true;
251
+	}
252 252
 }
Please login to merge, or discard this patch.