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