Completed
Pull Request — master (#141)
by
unknown
13:15
created
Classes/Service/SvgStoreService.php 1 patch
Indentation   +244 added lines, -244 removed lines patch added patch discarded remove patch
@@ -13,248 +13,248 @@
 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 ($GLOBALS['TSFE']->config['config']['disableAllHeaderCode'] ?? false) {
92
-            $dom = ['head' => '', 'body' => $html];
93
-        } elseif (!preg_match('/(?<head>.+?<\/head>)(?<body>.+)/s', $html, $dom)) {
94
-            return $html;
95
-        }
96
-
97
-        // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attributes
98
-        $dom['body'] = preg_replace_callback('/<img(?<pre>[^>]*)src="(?:https?:)?(?:\/\/[^\/]+?)?(?<src>\/[^"]+\.svg)"(?<post>[^>]*?)[\s\/]*>(?!\s*<\/picture>)/s', function (array $match): string { // ^[/]
99
-            if (!isset($this->svgFileArr[$match['src']])) { // check usage
100
-                return $match[0];
101
-            }
102
-            $attr = preg_replace('/\s(?:alt|ismap|loading|title|sizes|srcset|usemap|crossorigin|decoding|fetchpriority|referrerpolicy)="[^"]*"/', '', $match['pre'].$match['post']); // cleanup
103
-
104
-            return sprintf('<svg %s %s><use href="%s#%s"/></svg>', $this->svgFileArr[$match['src']]['attr'], trim($attr), $this->spritePath, $this->convertFilePath($match['src']));
105
-        }, $dom['body']);
106
-
107
-        // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object#attributes
108
-        $dom['body'] = preg_replace_callback('/<object(?<pre>[^>]*)data="(?<data>\/[^"]+\.svg)"(?<post>[^>]*?)[\s\/]*>(?:<\/object>)/s', function (array $match): string { // ^[/]
109
-            if (!isset($this->svgFileArr[$match['data']])) { // check usage
110
-                return $match[0];
111
-            }
112
-            $attr = preg_replace('/\s(?:form|name|type|usemap)="[^"]*"/', '', $match['pre'].$match['post']); // cleanup
113
-
114
-            return sprintf('<svg %s %s><use href="%s#%s"/></svg>', $this->svgFileArr[$match['data']]['attr'], trim($attr), $this->spritePath, $this->convertFilePath($match['data']));
115
-        }, $dom['body']);
116
-
117
-        return $dom['head'].$dom['body'];
118
-    }
119
-
120
-    private function convertFilePath(string $path): string
121
-    {
122
-        return preg_replace('/.svg$|[^\w\-]/', '', str_replace('/', '-', ltrim($path, '/'))); // ^[^/]
123
-    }
124
-
125
-    private function addFileToSpriteArr(string $hash, string $path, array $attr = []): ?array
126
-    {
127
-        if (!file_exists($this->sitePath.$path)) {
128
-            return null;
129
-        }
130
-
131
-        $svg = file_get_contents($this->sitePath.$path);
132
-
133
-        if (preg_match('/(?:;base64|i:a?i?pgf)/', $svg)) { // noop!
134
-            return null;
135
-        }
136
-
137
-        if (preg_match('/<(?:style|defs)|url\(/', $svg)) {
138
-            return null; // check links @ __construct
139
-        }
140
-
141
-        // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href
142
-        $svg = preg_replace('/^.*?<svg|\s*(<\/svg>)(?!.*\1).*$|xlink:|\s(?:(?:version|xmlns)|(?:[a-z\-]+\:[a-z\-]+))="[^"]*"/s', '', $svg); // cleanup
143
-
144
-        // $svg = preg_replace('/(?<=(?:id|class)=")/', $hash.'__', $svg); // extend  IDs
145
-        // $svg = preg_replace('/(?<=href="|url\()#/', $hash.'__', $svg); // recover IDs
146
-
147
-        // $svg = preg_replace_callback('/<style[^>]*>(?<styl>.+?)<\/style>|<defs[^>]*>(?<defs>.+?)<\/defs>/s', function(array $match) use($hash): string {
148
-        //
149
-        //    if(isset($match['styl']))
150
-        //    {
151
-        //        $this->styl[] = preg_replace('/\s*(\.|#){1}(.+?)\s*\{/', '$1'.$hash.'__$2{', $match['styl']); // patch CSS # https://mathiasbynens.be/notes/css-escapes
152
-        //    }
153
-        //    if(isset($match['defs']))
154
-        //    {
155
-        //        $this->defs[] = trim($match['defs']);
156
-        //    }
157
-        //    return '';
158
-        // }, $svg);
159
-
160
-        // https://developer.mozilla.org/en-US/docs/Web/SVG/Element/svg#attributes
161
-        $svg = preg_replace_callback('/([^>]*)\s*(?=>)/s', function (array $match) use (&$attr): string {
162
-            if (false === preg_match_all('/(?!\s)(?<attr>[\w\-]+)="\s*(?<value>[^"]+)\s*"/', $match[1], $matches)) {
163
-                return $match[0];
164
-            }
165
-            foreach ($matches['attr'] as $index => $attribute) {
166
-                switch ($attribute) {
167
-                    case 'id':
168
-                    case 'width':
169
-                    case 'height':
170
-                        unset($matches[0][$index]);
171
-                        break;
172
-
173
-                    case 'viewBox':
174
-                        if (false !== preg_match('/\S+\s\S+\s\+?(?<width>[\d\.]+)\s\+?(?<height>[\d\.]+)/', $matches['value'][$index], $match)) {
175
-                            $attr[] = sprintf('%s="0 0 %s %s"', $attribute, $match['width'], $match['height']); // save!
176
-                        }
177
-                }
178
-            }
179
-
180
-            return implode(' ', $matches[0]);
181
-        }, $svg, 1);
182
-
183
-        if (empty($attr)) {
184
-            return null;
185
-        }
186
-
187
-        $this->svgs[] = sprintf('id="%s" %s', $this->convertFilePath($path), $svg); // prepend ID
188
-
189
-        return ['attr' => implode(' ', $attr), 'hash' => $hash];
190
-    }
191
-
192
-    private function populateCache(): bool
193
-    {
194
-        $storageArr = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\StorageRepository::class)->findByStorageType('Local');
195
-        foreach ($storageArr as $storage) {
196
-            $storageConfig = $storage->getConfiguration();
197
-            if (!is_array($storageConfig) || !isset($storageConfig['pathType'], $storageConfig['basePath'])) {
198
-              continue;
199
-            }
200
-            if ('relative' == $storageConfig['pathType']) {
201
-                $storageArr[$storage->getUid()] = rtrim($storageConfig['basePath'], '/'); // [^/]$
202
-            }
203
-        }
204
-        unset($storageArr[0]); // keep!
205
-
206
-        $fileArr = GeneralUtility::makeInstance(\HTML\Sourceopt\Resource\SvgFileRepository::class)->findAllByStorageUids(array_keys($storageArr));
207
-        foreach ($fileArr as $file) {
208
-            $file['path'] = '/'.$storageArr[$file['storage']].$file['identifier']; // ^[/]
209
-            $file['defs'] = $this->addFileToSpriteArr($file['sha1'], $file['path']);
210
-
211
-            if (null !== $file['defs']) {
212
-                $this->svgFileArr[$file['path']] = $file['defs'];
213
-            }
214
-        }
215
-        unset($storageArr, $storage, $fileArr, $file); // save MEM
216
-
217
-        $svg = preg_replace_callback(
218
-            '/<use(?<pre>.*?)(?:xlink:)?href="(?<href>\/.+?\.svg)(?:#[^"]*?)?"(?<post>.*?)[\s\/]*>(?:<\/use>)?/s',
219
-            function (array $match): string {
220
-                if (!isset($this->svgFileArr[$match['href']])) { // check usage
221
-                    return $match[0];
222
-                }
223
-
224
-                return sprintf('<use%s href="#%s"/>', $match['pre'].$match['post'], $this->convertFilePath($match['href']));
225
-            },
226
-            '<svg xmlns="http://www.w3.org/2000/svg">'
227
-            // ."\n<style>\n".implode("\n", $this->styl)."\n</style>"
228
-            // ."\n<defs>\n".implode("\n", $this->defs)."\n</defs>"
229
-            ."\n<symbol ".implode("</symbol>\n<symbol ", $this->svgs)."</symbol>\n"
230
-            .'</svg>'
231
-        );
232
-
233
-        // unset($this->styl); // save MEM
234
-        // unset($this->defs); // save MEM
235
-        unset($this->svgs); // save MEM
236
-
237
-        if ($GLOBALS['TSFE']->config['config']['sourceopt.']['formatHtml'] ?? false) {
238
-            $svg = preg_replace('/(?<=>)\s+(?=<)/', '', $svg); // remove emptiness
239
-            $svg = preg_replace('/[\t\v]/', ' ', $svg); // prepare shrinkage
240
-            $svg = preg_replace('/\s{2,}/', ' ', $svg); // shrink whitespace
241
-        }
242
-
243
-        $svg = preg_replace('/<([a-z]+)\s*(\/|>\s*<\/\1)>\s*|\s+(?=\/>)/i', '', $svg); // remove emtpy TAGs & shorten endings
244
-        $svg = preg_replace('/<((circle|ellipse|line|path|polygon|polyline|rect|stop|use)\s[^>]+?)\s*>\s*<\/\2>/', '<$1/>', $svg); // shorten/minify TAG syntax
245
-
246
-        if (!is_dir($this->sitePath.$this->outputDir)) {
247
-            GeneralUtility::mkdir_deep($this->sitePath.$this->outputDir);
248
-        }
249
-
250
-        $this->spritePath = $this->outputDir.hash('sha1', serialize($this->svgFileArr)).'.svg';
251
-        if (false === file_put_contents($this->sitePath.$this->spritePath, $svg)) {
252
-            return false;
253
-        }
254
-
255
-        $this->svgCache->set('spritePath', $this->spritePath);
256
-        $this->svgCache->set('svgFileArr', $this->svgFileArr);
257
-
258
-        return true;
259
-    }
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 ($GLOBALS['TSFE']->config['config']['disableAllHeaderCode'] ?? false) {
92
+			$dom = ['head' => '', 'body' => $html];
93
+		} elseif (!preg_match('/(?<head>.+?<\/head>)(?<body>.+)/s', $html, $dom)) {
94
+			return $html;
95
+		}
96
+
97
+		// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attributes
98
+		$dom['body'] = preg_replace_callback('/<img(?<pre>[^>]*)src="(?:https?:)?(?:\/\/[^\/]+?)?(?<src>\/[^"]+\.svg)"(?<post>[^>]*?)[\s\/]*>(?!\s*<\/picture>)/s', function (array $match): string { // ^[/]
99
+			if (!isset($this->svgFileArr[$match['src']])) { // check usage
100
+				return $match[0];
101
+			}
102
+			$attr = preg_replace('/\s(?:alt|ismap|loading|title|sizes|srcset|usemap|crossorigin|decoding|fetchpriority|referrerpolicy)="[^"]*"/', '', $match['pre'].$match['post']); // cleanup
103
+
104
+			return sprintf('<svg %s %s><use href="%s#%s"/></svg>', $this->svgFileArr[$match['src']]['attr'], trim($attr), $this->spritePath, $this->convertFilePath($match['src']));
105
+		}, $dom['body']);
106
+
107
+		// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object#attributes
108
+		$dom['body'] = preg_replace_callback('/<object(?<pre>[^>]*)data="(?<data>\/[^"]+\.svg)"(?<post>[^>]*?)[\s\/]*>(?:<\/object>)/s', function (array $match): string { // ^[/]
109
+			if (!isset($this->svgFileArr[$match['data']])) { // check usage
110
+				return $match[0];
111
+			}
112
+			$attr = preg_replace('/\s(?:form|name|type|usemap)="[^"]*"/', '', $match['pre'].$match['post']); // cleanup
113
+
114
+			return sprintf('<svg %s %s><use href="%s#%s"/></svg>', $this->svgFileArr[$match['data']]['attr'], trim($attr), $this->spritePath, $this->convertFilePath($match['data']));
115
+		}, $dom['body']);
116
+
117
+		return $dom['head'].$dom['body'];
118
+	}
119
+
120
+	private function convertFilePath(string $path): string
121
+	{
122
+		return preg_replace('/.svg$|[^\w\-]/', '', str_replace('/', '-', ltrim($path, '/'))); // ^[^/]
123
+	}
124
+
125
+	private function addFileToSpriteArr(string $hash, string $path, array $attr = []): ?array
126
+	{
127
+		if (!file_exists($this->sitePath.$path)) {
128
+			return null;
129
+		}
130
+
131
+		$svg = file_get_contents($this->sitePath.$path);
132
+
133
+		if (preg_match('/(?:;base64|i:a?i?pgf)/', $svg)) { // noop!
134
+			return null;
135
+		}
136
+
137
+		if (preg_match('/<(?:style|defs)|url\(/', $svg)) {
138
+			return null; // check links @ __construct
139
+		}
140
+
141
+		// https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href
142
+		$svg = preg_replace('/^.*?<svg|\s*(<\/svg>)(?!.*\1).*$|xlink:|\s(?:(?:version|xmlns)|(?:[a-z\-]+\:[a-z\-]+))="[^"]*"/s', '', $svg); // cleanup
143
+
144
+		// $svg = preg_replace('/(?<=(?:id|class)=")/', $hash.'__', $svg); // extend  IDs
145
+		// $svg = preg_replace('/(?<=href="|url\()#/', $hash.'__', $svg); // recover IDs
146
+
147
+		// $svg = preg_replace_callback('/<style[^>]*>(?<styl>.+?)<\/style>|<defs[^>]*>(?<defs>.+?)<\/defs>/s', function(array $match) use($hash): string {
148
+		//
149
+		//    if(isset($match['styl']))
150
+		//    {
151
+		//        $this->styl[] = preg_replace('/\s*(\.|#){1}(.+?)\s*\{/', '$1'.$hash.'__$2{', $match['styl']); // patch CSS # https://mathiasbynens.be/notes/css-escapes
152
+		//    }
153
+		//    if(isset($match['defs']))
154
+		//    {
155
+		//        $this->defs[] = trim($match['defs']);
156
+		//    }
157
+		//    return '';
158
+		// }, $svg);
159
+
160
+		// https://developer.mozilla.org/en-US/docs/Web/SVG/Element/svg#attributes
161
+		$svg = preg_replace_callback('/([^>]*)\s*(?=>)/s', function (array $match) use (&$attr): string {
162
+			if (false === preg_match_all('/(?!\s)(?<attr>[\w\-]+)="\s*(?<value>[^"]+)\s*"/', $match[1], $matches)) {
163
+				return $match[0];
164
+			}
165
+			foreach ($matches['attr'] as $index => $attribute) {
166
+				switch ($attribute) {
167
+					case 'id':
168
+					case 'width':
169
+					case 'height':
170
+						unset($matches[0][$index]);
171
+						break;
172
+
173
+					case 'viewBox':
174
+						if (false !== preg_match('/\S+\s\S+\s\+?(?<width>[\d\.]+)\s\+?(?<height>[\d\.]+)/', $matches['value'][$index], $match)) {
175
+							$attr[] = sprintf('%s="0 0 %s %s"', $attribute, $match['width'], $match['height']); // save!
176
+						}
177
+				}
178
+			}
179
+
180
+			return implode(' ', $matches[0]);
181
+		}, $svg, 1);
182
+
183
+		if (empty($attr)) {
184
+			return null;
185
+		}
186
+
187
+		$this->svgs[] = sprintf('id="%s" %s', $this->convertFilePath($path), $svg); // prepend ID
188
+
189
+		return ['attr' => implode(' ', $attr), 'hash' => $hash];
190
+	}
191
+
192
+	private function populateCache(): bool
193
+	{
194
+		$storageArr = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\StorageRepository::class)->findByStorageType('Local');
195
+		foreach ($storageArr as $storage) {
196
+			$storageConfig = $storage->getConfiguration();
197
+			if (!is_array($storageConfig) || !isset($storageConfig['pathType'], $storageConfig['basePath'])) {
198
+			  continue;
199
+			}
200
+			if ('relative' == $storageConfig['pathType']) {
201
+				$storageArr[$storage->getUid()] = rtrim($storageConfig['basePath'], '/'); // [^/]$
202
+			}
203
+		}
204
+		unset($storageArr[0]); // keep!
205
+
206
+		$fileArr = GeneralUtility::makeInstance(\HTML\Sourceopt\Resource\SvgFileRepository::class)->findAllByStorageUids(array_keys($storageArr));
207
+		foreach ($fileArr as $file) {
208
+			$file['path'] = '/'.$storageArr[$file['storage']].$file['identifier']; // ^[/]
209
+			$file['defs'] = $this->addFileToSpriteArr($file['sha1'], $file['path']);
210
+
211
+			if (null !== $file['defs']) {
212
+				$this->svgFileArr[$file['path']] = $file['defs'];
213
+			}
214
+		}
215
+		unset($storageArr, $storage, $fileArr, $file); // save MEM
216
+
217
+		$svg = preg_replace_callback(
218
+			'/<use(?<pre>.*?)(?:xlink:)?href="(?<href>\/.+?\.svg)(?:#[^"]*?)?"(?<post>.*?)[\s\/]*>(?:<\/use>)?/s',
219
+			function (array $match): string {
220
+				if (!isset($this->svgFileArr[$match['href']])) { // check usage
221
+					return $match[0];
222
+				}
223
+
224
+				return sprintf('<use%s href="#%s"/>', $match['pre'].$match['post'], $this->convertFilePath($match['href']));
225
+			},
226
+			'<svg xmlns="http://www.w3.org/2000/svg">'
227
+			// ."\n<style>\n".implode("\n", $this->styl)."\n</style>"
228
+			// ."\n<defs>\n".implode("\n", $this->defs)."\n</defs>"
229
+			."\n<symbol ".implode("</symbol>\n<symbol ", $this->svgs)."</symbol>\n"
230
+			.'</svg>'
231
+		);
232
+
233
+		// unset($this->styl); // save MEM
234
+		// unset($this->defs); // save MEM
235
+		unset($this->svgs); // save MEM
236
+
237
+		if ($GLOBALS['TSFE']->config['config']['sourceopt.']['formatHtml'] ?? false) {
238
+			$svg = preg_replace('/(?<=>)\s+(?=<)/', '', $svg); // remove emptiness
239
+			$svg = preg_replace('/[\t\v]/', ' ', $svg); // prepare shrinkage
240
+			$svg = preg_replace('/\s{2,}/', ' ', $svg); // shrink whitespace
241
+		}
242
+
243
+		$svg = preg_replace('/<([a-z]+)\s*(\/|>\s*<\/\1)>\s*|\s+(?=\/>)/i', '', $svg); // remove emtpy TAGs & shorten endings
244
+		$svg = preg_replace('/<((circle|ellipse|line|path|polygon|polyline|rect|stop|use)\s[^>]+?)\s*>\s*<\/\2>/', '<$1/>', $svg); // shorten/minify TAG syntax
245
+
246
+		if (!is_dir($this->sitePath.$this->outputDir)) {
247
+			GeneralUtility::mkdir_deep($this->sitePath.$this->outputDir);
248
+		}
249
+
250
+		$this->spritePath = $this->outputDir.hash('sha1', serialize($this->svgFileArr)).'.svg';
251
+		if (false === file_put_contents($this->sitePath.$this->spritePath, $svg)) {
252
+			return false;
253
+		}
254
+
255
+		$this->svgCache->set('spritePath', $this->spritePath);
256
+		$this->svgCache->set('svgFileArr', $this->svgFileArr);
257
+
258
+		return true;
259
+	}
260 260
 }
Please login to merge, or discard this patch.