Completed
Push — master ( 2634ce...0c05ed )
by Blizzz
19:50
created
apps/theming/lib/Controller/ThemingController.php 1 patch
Indentation   +408 added lines, -408 removed lines patch added patch discarded remove patch
@@ -62,380 +62,380 @@  discard block
 block discarded – undo
62 62
  * @package OCA\Theming\Controller
63 63
  */
64 64
 class ThemingController extends Controller {
65
-	/** @var ThemingDefaults */
66
-	private $themingDefaults;
67
-	/** @var Util */
68
-	private $util;
69
-	/** @var IL10N */
70
-	private $l10n;
71
-	/** @var IConfig */
72
-	private $config;
73
-	/** @var ITempManager */
74
-	private $tempManager;
75
-	/** @var IAppData */
76
-	private $appData;
77
-	/** @var SCSSCacher */
78
-	private $scssCacher;
79
-	/** @var IURLGenerator */
80
-	private $urlGenerator;
81
-	/** @var IAppManager */
82
-	private $appManager;
83
-	/** @var ImageManager */
84
-	private $imageManager;
85
-
86
-	/**
87
-	 * ThemingController constructor.
88
-	 *
89
-	 * @param string $appName
90
-	 * @param IRequest $request
91
-	 * @param IConfig $config
92
-	 * @param ThemingDefaults $themingDefaults
93
-	 * @param Util $util
94
-	 * @param IL10N $l
95
-	 * @param ITempManager $tempManager
96
-	 * @param IAppData $appData
97
-	 * @param SCSSCacher $scssCacher
98
-	 * @param IURLGenerator $urlGenerator
99
-	 * @param IAppManager $appManager
100
-	 * @param ImageManager $imageManager
101
-	 */
102
-	public function __construct(
103
-		$appName,
104
-		IRequest $request,
105
-		IConfig $config,
106
-		ThemingDefaults $themingDefaults,
107
-		Util $util,
108
-		IL10N $l,
109
-		ITempManager $tempManager,
110
-		IAppData $appData,
111
-		SCSSCacher $scssCacher,
112
-		IURLGenerator $urlGenerator,
113
-		IAppManager $appManager,
114
-		ImageManager $imageManager
115
-	) {
116
-		parent::__construct($appName, $request);
117
-
118
-		$this->themingDefaults = $themingDefaults;
119
-		$this->util = $util;
120
-		$this->l10n = $l;
121
-		$this->config = $config;
122
-		$this->tempManager = $tempManager;
123
-		$this->appData = $appData;
124
-		$this->scssCacher = $scssCacher;
125
-		$this->urlGenerator = $urlGenerator;
126
-		$this->appManager = $appManager;
127
-		$this->imageManager = $imageManager;
128
-	}
129
-
130
-	/**
131
-	 * @param string $setting
132
-	 * @param string $value
133
-	 * @return DataResponse
134
-	 * @throws NotPermittedException
135
-	 */
136
-	public function updateStylesheet($setting, $value) {
137
-		$value = trim($value);
138
-		switch ($setting) {
139
-			case 'name':
140
-				if (strlen($value) > 250) {
141
-					return new DataResponse([
142
-						'data' => [
143
-							'message' => $this->l10n->t('The given name is too long'),
144
-						],
145
-						'status' => 'error'
146
-					]);
147
-				}
148
-				break;
149
-			case 'url':
150
-				if (strlen($value) > 500) {
151
-					return new DataResponse([
152
-						'data' => [
153
-							'message' => $this->l10n->t('The given web address is too long'),
154
-						],
155
-						'status' => 'error'
156
-					]);
157
-				}
158
-				break;
159
-			case 'imprintUrl':
160
-				if (strlen($value) > 500) {
161
-					return new DataResponse([
162
-						'data' => [
163
-							'message' => $this->l10n->t('The given legal notice address is too long'),
164
-						],
165
-						'status' => 'error'
166
-					]);
167
-				}
168
-				break;
169
-			case 'privacyUrl':
170
-				if (strlen($value) > 500) {
171
-					return new DataResponse([
172
-						'data' => [
173
-							'message' => $this->l10n->t('The given privacy policy address is too long'),
174
-						],
175
-						'status' => 'error'
176
-					]);
177
-				}
178
-				break;
179
-			case 'slogan':
180
-				if (strlen($value) > 500) {
181
-					return new DataResponse([
182
-						'data' => [
183
-							'message' => $this->l10n->t('The given slogan is too long'),
184
-						],
185
-						'status' => 'error'
186
-					]);
187
-				}
188
-				break;
189
-			case 'color':
190
-				if (!preg_match('/^\#([0-9a-f]{3}|[0-9a-f]{6})$/i', $value)) {
191
-					return new DataResponse([
192
-						'data' => [
193
-							'message' => $this->l10n->t('The given color is invalid'),
194
-						],
195
-						'status' => 'error'
196
-					]);
197
-				}
198
-				break;
199
-		}
200
-
201
-		$this->themingDefaults->set($setting, $value);
202
-
203
-		// reprocess server scss for preview
204
-		$cssCached = $this->scssCacher->process(\OC::$SERVERROOT, 'core/css/css-variables.scss', 'core');
205
-
206
-		return new DataResponse(
207
-			[
208
-				'data' =>
209
-					[
210
-						'message' => $this->l10n->t('Saved'),
211
-						'serverCssUrl' => $this->urlGenerator->linkTo('', $this->scssCacher->getCachedSCSS('core', '/core/css/css-variables.scss'))
212
-					],
213
-				'status' => 'success'
214
-			]
215
-		);
216
-	}
217
-
218
-	/**
219
-	 * @return DataResponse
220
-	 * @throws NotPermittedException
221
-	 */
222
-	public function uploadImage(): DataResponse {
223
-		// logo / background
224
-		// new: favicon logo-header
225
-		//
226
-		$key = $this->request->getParam('key');
227
-		$image = $this->request->getUploadedFile('image');
228
-		$error = null;
229
-		$phpFileUploadErrors = [
230
-			UPLOAD_ERR_OK => $this->l10n->t('The file was uploaded'),
231
-			UPLOAD_ERR_INI_SIZE => $this->l10n->t('The uploaded file exceeds the upload_max_filesize directive in php.ini'),
232
-			UPLOAD_ERR_FORM_SIZE => $this->l10n->t('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form'),
233
-			UPLOAD_ERR_PARTIAL => $this->l10n->t('The file was only partially uploaded'),
234
-			UPLOAD_ERR_NO_FILE => $this->l10n->t('No file was uploaded'),
235
-			UPLOAD_ERR_NO_TMP_DIR => $this->l10n->t('Missing a temporary folder'),
236
-			UPLOAD_ERR_CANT_WRITE => $this->l10n->t('Could not write file to disk'),
237
-			UPLOAD_ERR_EXTENSION => $this->l10n->t('A PHP extension stopped the file upload'),
238
-		];
239
-		if (empty($image)) {
240
-			$error = $this->l10n->t('No file uploaded');
241
-		}
242
-		if (!empty($image) && array_key_exists('error', $image) && $image['error'] !== UPLOAD_ERR_OK) {
243
-			$error = $phpFileUploadErrors[$image['error']];
244
-		}
245
-
246
-		if ($error !== null) {
247
-			return new DataResponse(
248
-				[
249
-					'data' => [
250
-						'message' => $error
251
-					],
252
-					'status' => 'failure',
253
-				],
254
-				Http::STATUS_UNPROCESSABLE_ENTITY
255
-			);
256
-		}
257
-
258
-		$name = '';
259
-		try {
260
-			$folder = $this->appData->getFolder('images');
261
-		} catch (NotFoundException $e) {
262
-			$folder = $this->appData->newFolder('images');
263
-		}
264
-
265
-		$this->imageManager->delete($key);
266
-
267
-		$target = $folder->newFile($key);
268
-		$supportedFormats = $this->getSupportedUploadImageFormats($key);
269
-		$detectedMimeType = mime_content_type($image['tmp_name']);
270
-		if (!in_array($image['type'], $supportedFormats) || !in_array($detectedMimeType, $supportedFormats)) {
271
-			return new DataResponse(
272
-				[
273
-					'data' => [
274
-						'message' => $this->l10n->t('Unsupported image type'),
275
-					],
276
-					'status' => 'failure',
277
-				],
278
-				Http::STATUS_UNPROCESSABLE_ENTITY
279
-			);
280
-		}
281
-
282
-		$resizeKeys = ['background'];
283
-		if (in_array($key, $resizeKeys, true)) {
284
-			// Optimize the image since some people may upload images that will be
285
-			// either to big or are not progressive rendering.
286
-			$newImage = @imagecreatefromstring(file_get_contents($image['tmp_name'], 'r'));
287
-
288
-			$tmpFile = $this->tempManager->getTemporaryFile();
289
-			$newWidth = imagesx($newImage) < 4096 ? imagesx($newImage) : 4096;
290
-			$newHeight = imagesy($newImage) / (imagesx($newImage) / $newWidth);
291
-			$outputImage = imagescale($newImage, $newWidth, $newHeight);
292
-
293
-			imageinterlace($outputImage, 1);
294
-			imagejpeg($outputImage, $tmpFile, 75);
295
-			imagedestroy($outputImage);
296
-
297
-			$target->putContent(file_get_contents($tmpFile, 'r'));
298
-		} else {
299
-			$target->putContent(file_get_contents($image['tmp_name'], 'r'));
300
-		}
301
-		$name = $image['name'];
302
-
303
-		$this->themingDefaults->set($key.'Mime', $image['type']);
304
-
305
-		$cssCached = $this->scssCacher->process(\OC::$SERVERROOT, 'core/css/css-variables.scss', 'core');
306
-
307
-		return new DataResponse(
308
-			[
309
-				'data' =>
310
-					[
311
-						'name' => $name,
312
-						'url' => $this->imageManager->getImageUrl($key),
313
-						'message' => $this->l10n->t('Saved'),
314
-						'serverCssUrl' => $this->urlGenerator->linkTo('', $this->scssCacher->getCachedSCSS('core', '/core/css/css-variables.scss'))
315
-					],
316
-				'status' => 'success'
317
-			]
318
-		);
319
-	}
320
-
321
-	/**
322
-	 * Returns a list of supported mime types for image uploads.
323
-	 * "favicon" images are only allowed to be SVG when imagemagick with SVG support is available.
324
-	 *
325
-	 * @param string $key The image key, e.g. "favicon"
326
-	 * @return array
327
-	 */
328
-	private function getSupportedUploadImageFormats(string $key): array {
329
-		$supportedFormats = ['image/jpeg', 'image/png', 'image/gif',];
330
-
331
-		if ($key !== 'favicon' || $this->imageManager->shouldReplaceIcons() === true) {
332
-			$supportedFormats[] = 'image/svg+xml';
333
-			$supportedFormats[] = 'image/svg';
334
-		}
335
-
336
-		return $supportedFormats;
337
-	}
338
-
339
-	/**
340
-	 * Revert setting to default value
341
-	 *
342
-	 * @param string $setting setting which should be reverted
343
-	 * @return DataResponse
344
-	 * @throws NotPermittedException
345
-	 */
346
-	public function undo(string $setting): DataResponse {
347
-		$value = $this->themingDefaults->undo($setting);
348
-		// reprocess server scss for preview
349
-		$cssCached = $this->scssCacher->process(\OC::$SERVERROOT, 'core/css/css-variables.scss', 'core');
350
-
351
-		if (strpos($setting, 'Mime') !== -1) {
352
-			$imageKey = str_replace('Mime', '', $setting);
353
-			$this->imageManager->delete($imageKey);
354
-		}
355
-
356
-		return new DataResponse(
357
-			[
358
-				'data' =>
359
-					[
360
-						'value' => $value,
361
-						'message' => $this->l10n->t('Saved'),
362
-						'serverCssUrl' => $this->urlGenerator->linkTo('', $this->scssCacher->getCachedSCSS('core', '/core/css/css-variables.scss'))
363
-					],
364
-				'status' => 'success'
365
-			]
366
-		);
367
-	}
368
-
369
-	/**
370
-	 * @PublicPage
371
-	 * @NoCSRFRequired
372
-	 *
373
-	 * @param string $key
374
-	 * @param bool $useSvg
375
-	 * @return FileDisplayResponse|NotFoundResponse
376
-	 * @throws NotPermittedException
377
-	 */
378
-	public function getImage(string $key, bool $useSvg = true) {
379
-		try {
380
-			$file = $this->imageManager->getImage($key, $useSvg);
381
-		} catch (NotFoundException $e) {
382
-			return new NotFoundResponse();
383
-		}
384
-
385
-		$response = new FileDisplayResponse($file);
386
-		$response->cacheFor(3600);
387
-		$response->addHeader('Content-Type', $this->config->getAppValue($this->appName, $key . 'Mime', ''));
388
-		$response->addHeader('Content-Disposition', 'attachment; filename="' . $key . '"');
389
-		if (!$useSvg) {
390
-			$response->addHeader('Content-Type', 'image/png');
391
-		} else {
392
-			$response->addHeader('Content-Type', $this->config->getAppValue($this->appName, $key . 'Mime', ''));
393
-		}
394
-		return $response;
395
-	}
396
-
397
-	/**
398
-	 * @NoCSRFRequired
399
-	 * @PublicPage
400
-	 * @NoSameSiteCookieRequired
401
-	 *
402
-	 * @return FileDisplayResponse|NotFoundResponse
403
-	 * @throws NotPermittedException
404
-	 * @throws \Exception
405
-	 * @throws \OCP\App\AppPathNotFoundException
406
-	 */
407
-	public function getStylesheet() {
408
-		$appPath = $this->appManager->getAppPath('theming');
409
-
410
-		/* SCSSCacher is required here
65
+    /** @var ThemingDefaults */
66
+    private $themingDefaults;
67
+    /** @var Util */
68
+    private $util;
69
+    /** @var IL10N */
70
+    private $l10n;
71
+    /** @var IConfig */
72
+    private $config;
73
+    /** @var ITempManager */
74
+    private $tempManager;
75
+    /** @var IAppData */
76
+    private $appData;
77
+    /** @var SCSSCacher */
78
+    private $scssCacher;
79
+    /** @var IURLGenerator */
80
+    private $urlGenerator;
81
+    /** @var IAppManager */
82
+    private $appManager;
83
+    /** @var ImageManager */
84
+    private $imageManager;
85
+
86
+    /**
87
+     * ThemingController constructor.
88
+     *
89
+     * @param string $appName
90
+     * @param IRequest $request
91
+     * @param IConfig $config
92
+     * @param ThemingDefaults $themingDefaults
93
+     * @param Util $util
94
+     * @param IL10N $l
95
+     * @param ITempManager $tempManager
96
+     * @param IAppData $appData
97
+     * @param SCSSCacher $scssCacher
98
+     * @param IURLGenerator $urlGenerator
99
+     * @param IAppManager $appManager
100
+     * @param ImageManager $imageManager
101
+     */
102
+    public function __construct(
103
+        $appName,
104
+        IRequest $request,
105
+        IConfig $config,
106
+        ThemingDefaults $themingDefaults,
107
+        Util $util,
108
+        IL10N $l,
109
+        ITempManager $tempManager,
110
+        IAppData $appData,
111
+        SCSSCacher $scssCacher,
112
+        IURLGenerator $urlGenerator,
113
+        IAppManager $appManager,
114
+        ImageManager $imageManager
115
+    ) {
116
+        parent::__construct($appName, $request);
117
+
118
+        $this->themingDefaults = $themingDefaults;
119
+        $this->util = $util;
120
+        $this->l10n = $l;
121
+        $this->config = $config;
122
+        $this->tempManager = $tempManager;
123
+        $this->appData = $appData;
124
+        $this->scssCacher = $scssCacher;
125
+        $this->urlGenerator = $urlGenerator;
126
+        $this->appManager = $appManager;
127
+        $this->imageManager = $imageManager;
128
+    }
129
+
130
+    /**
131
+     * @param string $setting
132
+     * @param string $value
133
+     * @return DataResponse
134
+     * @throws NotPermittedException
135
+     */
136
+    public function updateStylesheet($setting, $value) {
137
+        $value = trim($value);
138
+        switch ($setting) {
139
+            case 'name':
140
+                if (strlen($value) > 250) {
141
+                    return new DataResponse([
142
+                        'data' => [
143
+                            'message' => $this->l10n->t('The given name is too long'),
144
+                        ],
145
+                        'status' => 'error'
146
+                    ]);
147
+                }
148
+                break;
149
+            case 'url':
150
+                if (strlen($value) > 500) {
151
+                    return new DataResponse([
152
+                        'data' => [
153
+                            'message' => $this->l10n->t('The given web address is too long'),
154
+                        ],
155
+                        'status' => 'error'
156
+                    ]);
157
+                }
158
+                break;
159
+            case 'imprintUrl':
160
+                if (strlen($value) > 500) {
161
+                    return new DataResponse([
162
+                        'data' => [
163
+                            'message' => $this->l10n->t('The given legal notice address is too long'),
164
+                        ],
165
+                        'status' => 'error'
166
+                    ]);
167
+                }
168
+                break;
169
+            case 'privacyUrl':
170
+                if (strlen($value) > 500) {
171
+                    return new DataResponse([
172
+                        'data' => [
173
+                            'message' => $this->l10n->t('The given privacy policy address is too long'),
174
+                        ],
175
+                        'status' => 'error'
176
+                    ]);
177
+                }
178
+                break;
179
+            case 'slogan':
180
+                if (strlen($value) > 500) {
181
+                    return new DataResponse([
182
+                        'data' => [
183
+                            'message' => $this->l10n->t('The given slogan is too long'),
184
+                        ],
185
+                        'status' => 'error'
186
+                    ]);
187
+                }
188
+                break;
189
+            case 'color':
190
+                if (!preg_match('/^\#([0-9a-f]{3}|[0-9a-f]{6})$/i', $value)) {
191
+                    return new DataResponse([
192
+                        'data' => [
193
+                            'message' => $this->l10n->t('The given color is invalid'),
194
+                        ],
195
+                        'status' => 'error'
196
+                    ]);
197
+                }
198
+                break;
199
+        }
200
+
201
+        $this->themingDefaults->set($setting, $value);
202
+
203
+        // reprocess server scss for preview
204
+        $cssCached = $this->scssCacher->process(\OC::$SERVERROOT, 'core/css/css-variables.scss', 'core');
205
+
206
+        return new DataResponse(
207
+            [
208
+                'data' =>
209
+                    [
210
+                        'message' => $this->l10n->t('Saved'),
211
+                        'serverCssUrl' => $this->urlGenerator->linkTo('', $this->scssCacher->getCachedSCSS('core', '/core/css/css-variables.scss'))
212
+                    ],
213
+                'status' => 'success'
214
+            ]
215
+        );
216
+    }
217
+
218
+    /**
219
+     * @return DataResponse
220
+     * @throws NotPermittedException
221
+     */
222
+    public function uploadImage(): DataResponse {
223
+        // logo / background
224
+        // new: favicon logo-header
225
+        //
226
+        $key = $this->request->getParam('key');
227
+        $image = $this->request->getUploadedFile('image');
228
+        $error = null;
229
+        $phpFileUploadErrors = [
230
+            UPLOAD_ERR_OK => $this->l10n->t('The file was uploaded'),
231
+            UPLOAD_ERR_INI_SIZE => $this->l10n->t('The uploaded file exceeds the upload_max_filesize directive in php.ini'),
232
+            UPLOAD_ERR_FORM_SIZE => $this->l10n->t('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form'),
233
+            UPLOAD_ERR_PARTIAL => $this->l10n->t('The file was only partially uploaded'),
234
+            UPLOAD_ERR_NO_FILE => $this->l10n->t('No file was uploaded'),
235
+            UPLOAD_ERR_NO_TMP_DIR => $this->l10n->t('Missing a temporary folder'),
236
+            UPLOAD_ERR_CANT_WRITE => $this->l10n->t('Could not write file to disk'),
237
+            UPLOAD_ERR_EXTENSION => $this->l10n->t('A PHP extension stopped the file upload'),
238
+        ];
239
+        if (empty($image)) {
240
+            $error = $this->l10n->t('No file uploaded');
241
+        }
242
+        if (!empty($image) && array_key_exists('error', $image) && $image['error'] !== UPLOAD_ERR_OK) {
243
+            $error = $phpFileUploadErrors[$image['error']];
244
+        }
245
+
246
+        if ($error !== null) {
247
+            return new DataResponse(
248
+                [
249
+                    'data' => [
250
+                        'message' => $error
251
+                    ],
252
+                    'status' => 'failure',
253
+                ],
254
+                Http::STATUS_UNPROCESSABLE_ENTITY
255
+            );
256
+        }
257
+
258
+        $name = '';
259
+        try {
260
+            $folder = $this->appData->getFolder('images');
261
+        } catch (NotFoundException $e) {
262
+            $folder = $this->appData->newFolder('images');
263
+        }
264
+
265
+        $this->imageManager->delete($key);
266
+
267
+        $target = $folder->newFile($key);
268
+        $supportedFormats = $this->getSupportedUploadImageFormats($key);
269
+        $detectedMimeType = mime_content_type($image['tmp_name']);
270
+        if (!in_array($image['type'], $supportedFormats) || !in_array($detectedMimeType, $supportedFormats)) {
271
+            return new DataResponse(
272
+                [
273
+                    'data' => [
274
+                        'message' => $this->l10n->t('Unsupported image type'),
275
+                    ],
276
+                    'status' => 'failure',
277
+                ],
278
+                Http::STATUS_UNPROCESSABLE_ENTITY
279
+            );
280
+        }
281
+
282
+        $resizeKeys = ['background'];
283
+        if (in_array($key, $resizeKeys, true)) {
284
+            // Optimize the image since some people may upload images that will be
285
+            // either to big or are not progressive rendering.
286
+            $newImage = @imagecreatefromstring(file_get_contents($image['tmp_name'], 'r'));
287
+
288
+            $tmpFile = $this->tempManager->getTemporaryFile();
289
+            $newWidth = imagesx($newImage) < 4096 ? imagesx($newImage) : 4096;
290
+            $newHeight = imagesy($newImage) / (imagesx($newImage) / $newWidth);
291
+            $outputImage = imagescale($newImage, $newWidth, $newHeight);
292
+
293
+            imageinterlace($outputImage, 1);
294
+            imagejpeg($outputImage, $tmpFile, 75);
295
+            imagedestroy($outputImage);
296
+
297
+            $target->putContent(file_get_contents($tmpFile, 'r'));
298
+        } else {
299
+            $target->putContent(file_get_contents($image['tmp_name'], 'r'));
300
+        }
301
+        $name = $image['name'];
302
+
303
+        $this->themingDefaults->set($key.'Mime', $image['type']);
304
+
305
+        $cssCached = $this->scssCacher->process(\OC::$SERVERROOT, 'core/css/css-variables.scss', 'core');
306
+
307
+        return new DataResponse(
308
+            [
309
+                'data' =>
310
+                    [
311
+                        'name' => $name,
312
+                        'url' => $this->imageManager->getImageUrl($key),
313
+                        'message' => $this->l10n->t('Saved'),
314
+                        'serverCssUrl' => $this->urlGenerator->linkTo('', $this->scssCacher->getCachedSCSS('core', '/core/css/css-variables.scss'))
315
+                    ],
316
+                'status' => 'success'
317
+            ]
318
+        );
319
+    }
320
+
321
+    /**
322
+     * Returns a list of supported mime types for image uploads.
323
+     * "favicon" images are only allowed to be SVG when imagemagick with SVG support is available.
324
+     *
325
+     * @param string $key The image key, e.g. "favicon"
326
+     * @return array
327
+     */
328
+    private function getSupportedUploadImageFormats(string $key): array {
329
+        $supportedFormats = ['image/jpeg', 'image/png', 'image/gif',];
330
+
331
+        if ($key !== 'favicon' || $this->imageManager->shouldReplaceIcons() === true) {
332
+            $supportedFormats[] = 'image/svg+xml';
333
+            $supportedFormats[] = 'image/svg';
334
+        }
335
+
336
+        return $supportedFormats;
337
+    }
338
+
339
+    /**
340
+     * Revert setting to default value
341
+     *
342
+     * @param string $setting setting which should be reverted
343
+     * @return DataResponse
344
+     * @throws NotPermittedException
345
+     */
346
+    public function undo(string $setting): DataResponse {
347
+        $value = $this->themingDefaults->undo($setting);
348
+        // reprocess server scss for preview
349
+        $cssCached = $this->scssCacher->process(\OC::$SERVERROOT, 'core/css/css-variables.scss', 'core');
350
+
351
+        if (strpos($setting, 'Mime') !== -1) {
352
+            $imageKey = str_replace('Mime', '', $setting);
353
+            $this->imageManager->delete($imageKey);
354
+        }
355
+
356
+        return new DataResponse(
357
+            [
358
+                'data' =>
359
+                    [
360
+                        'value' => $value,
361
+                        'message' => $this->l10n->t('Saved'),
362
+                        'serverCssUrl' => $this->urlGenerator->linkTo('', $this->scssCacher->getCachedSCSS('core', '/core/css/css-variables.scss'))
363
+                    ],
364
+                'status' => 'success'
365
+            ]
366
+        );
367
+    }
368
+
369
+    /**
370
+     * @PublicPage
371
+     * @NoCSRFRequired
372
+     *
373
+     * @param string $key
374
+     * @param bool $useSvg
375
+     * @return FileDisplayResponse|NotFoundResponse
376
+     * @throws NotPermittedException
377
+     */
378
+    public function getImage(string $key, bool $useSvg = true) {
379
+        try {
380
+            $file = $this->imageManager->getImage($key, $useSvg);
381
+        } catch (NotFoundException $e) {
382
+            return new NotFoundResponse();
383
+        }
384
+
385
+        $response = new FileDisplayResponse($file);
386
+        $response->cacheFor(3600);
387
+        $response->addHeader('Content-Type', $this->config->getAppValue($this->appName, $key . 'Mime', ''));
388
+        $response->addHeader('Content-Disposition', 'attachment; filename="' . $key . '"');
389
+        if (!$useSvg) {
390
+            $response->addHeader('Content-Type', 'image/png');
391
+        } else {
392
+            $response->addHeader('Content-Type', $this->config->getAppValue($this->appName, $key . 'Mime', ''));
393
+        }
394
+        return $response;
395
+    }
396
+
397
+    /**
398
+     * @NoCSRFRequired
399
+     * @PublicPage
400
+     * @NoSameSiteCookieRequired
401
+     *
402
+     * @return FileDisplayResponse|NotFoundResponse
403
+     * @throws NotPermittedException
404
+     * @throws \Exception
405
+     * @throws \OCP\App\AppPathNotFoundException
406
+     */
407
+    public function getStylesheet() {
408
+        $appPath = $this->appManager->getAppPath('theming');
409
+
410
+        /* SCSSCacher is required here
411 411
 		 * We cannot rely on automatic caching done by \OC_Util::addStyle,
412 412
 		 * since we need to add the cacheBuster value to the url
413 413
 		 */
414
-		$cssCached = $this->scssCacher->process($appPath, 'css/theming.scss', 'theming');
415
-		if(!$cssCached) {
416
-			return new NotFoundResponse();
417
-		}
418
-
419
-		try {
420
-			$cssFile = $this->scssCacher->getCachedCSS('theming', 'theming.css');
421
-			$response = new FileDisplayResponse($cssFile, Http::STATUS_OK, ['Content-Type' => 'text/css']);
422
-			$response->cacheFor(86400);
423
-			return $response;
424
-		} catch (NotFoundException $e) {
425
-			return new NotFoundResponse();
426
-		}
427
-	}
428
-
429
-	/**
430
-	 * @NoCSRFRequired
431
-	 * @PublicPage
432
-	 * @NoSameSiteCookieRequired
433
-	 *
434
-	 * @return DataDownloadResponse
435
-	 */
436
-	public function getJavascript() {
437
-		$cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
438
-		$responseJS = '(function() {
414
+        $cssCached = $this->scssCacher->process($appPath, 'css/theming.scss', 'theming');
415
+        if(!$cssCached) {
416
+            return new NotFoundResponse();
417
+        }
418
+
419
+        try {
420
+            $cssFile = $this->scssCacher->getCachedCSS('theming', 'theming.css');
421
+            $response = new FileDisplayResponse($cssFile, Http::STATUS_OK, ['Content-Type' => 'text/css']);
422
+            $response->cacheFor(86400);
423
+            return $response;
424
+        } catch (NotFoundException $e) {
425
+            return new NotFoundResponse();
426
+        }
427
+    }
428
+
429
+    /**
430
+     * @NoCSRFRequired
431
+     * @PublicPage
432
+     * @NoSameSiteCookieRequired
433
+     *
434
+     * @return DataDownloadResponse
435
+     */
436
+    public function getJavascript() {
437
+        $cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
438
+        $responseJS = '(function() {
439 439
 	OCA.Theming = {
440 440
 		name: ' . json_encode($this->themingDefaults->getName()) . ',
441 441
 		url: ' . json_encode($this->themingDefaults->getBaseUrl()) . ',
@@ -447,41 +447,41 @@  discard block
 block discarded – undo
447 447
 		cacheBuster: ' . json_encode($cacheBusterValue) . '
448 448
 	};
449 449
 })();';
450
-		$response = new DataDownloadResponse($responseJS, 'javascript', 'text/javascript');
451
-		$response->cacheFor(3600);
452
-		return $response;
453
-	}
454
-
455
-	/**
456
-	 * @NoCSRFRequired
457
-	 * @PublicPage
458
-	 *
459
-	 * @return Http\JSONResponse
460
-	 */
461
-	public function getManifest($app) {
462
-		$cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
463
-		$responseJS = [
464
-			'name' => $this->themingDefaults->getName(),
465
-			'start_url' => $this->urlGenerator->getBaseUrl(),
466
-			'icons' =>
467
-				[
468
-					[
469
-						'src' => $this->urlGenerator->linkToRoute('theming.Icon.getTouchIcon',
470
-								['app' => $app]) . '?v=' . $cacheBusterValue,
471
-						'type'=> 'image/png',
472
-						'sizes'=> '128x128'
473
-					],
474
-					[
475
-						'src' => $this->urlGenerator->linkToRoute('theming.Icon.getFavicon',
476
-								['app' => $app]) . '?v=' . $cacheBusterValue,
477
-						'type' => 'image/svg+xml',
478
-						'sizes' => '16x16'
479
-					]
480
-				],
481
-			'display' => 'standalone'
482
-		];
483
-		$response = new Http\JSONResponse($responseJS);
484
-		$response->cacheFor(3600);
485
-		return $response;
486
-	}
450
+        $response = new DataDownloadResponse($responseJS, 'javascript', 'text/javascript');
451
+        $response->cacheFor(3600);
452
+        return $response;
453
+    }
454
+
455
+    /**
456
+     * @NoCSRFRequired
457
+     * @PublicPage
458
+     *
459
+     * @return Http\JSONResponse
460
+     */
461
+    public function getManifest($app) {
462
+        $cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
463
+        $responseJS = [
464
+            'name' => $this->themingDefaults->getName(),
465
+            'start_url' => $this->urlGenerator->getBaseUrl(),
466
+            'icons' =>
467
+                [
468
+                    [
469
+                        'src' => $this->urlGenerator->linkToRoute('theming.Icon.getTouchIcon',
470
+                                ['app' => $app]) . '?v=' . $cacheBusterValue,
471
+                        'type'=> 'image/png',
472
+                        'sizes'=> '128x128'
473
+                    ],
474
+                    [
475
+                        'src' => $this->urlGenerator->linkToRoute('theming.Icon.getFavicon',
476
+                                ['app' => $app]) . '?v=' . $cacheBusterValue,
477
+                        'type' => 'image/svg+xml',
478
+                        'sizes' => '16x16'
479
+                    ]
480
+                ],
481
+            'display' => 'standalone'
482
+        ];
483
+        $response = new Http\JSONResponse($responseJS);
484
+        $response->cacheFor(3600);
485
+        return $response;
486
+    }
487 487
 }
Please login to merge, or discard this patch.
core/Controller/JsController.php 1 patch
Indentation   +60 added lines, -60 removed lines patch added patch discarded remove patch
@@ -40,74 +40,74 @@
 block discarded – undo
40 40
 
41 41
 class JsController extends Controller {
42 42
 
43
-	/** @var IAppData */
44
-	protected $appData;
43
+    /** @var IAppData */
44
+    protected $appData;
45 45
 
46
-	/** @var ITimeFactory */
47
-	protected $timeFactory;
46
+    /** @var ITimeFactory */
47
+    protected $timeFactory;
48 48
 
49
-	public function __construct($appName, IRequest $request, Factory $appDataFactory, ITimeFactory $timeFactory) {
50
-		parent::__construct($appName, $request);
49
+    public function __construct($appName, IRequest $request, Factory $appDataFactory, ITimeFactory $timeFactory) {
50
+        parent::__construct($appName, $request);
51 51
 
52
-		$this->appData = $appDataFactory->get('js');
53
-		$this->timeFactory = $timeFactory;
54
-	}
52
+        $this->appData = $appDataFactory->get('js');
53
+        $this->timeFactory = $timeFactory;
54
+    }
55 55
 
56
-	/**
57
-	 * @PublicPage
58
-	 * @NoCSRFRequired
59
-	 * @NoSameSiteCookieRequired
60
-	 *
61
-	 * @param string $fileName js filename with extension
62
-	 * @param string $appName js folder name
63
-	 * @return FileDisplayResponse|NotFoundResponse
64
-	 */
65
-	public function getJs(string $fileName, string $appName): Response {
66
-		try {
67
-			$folder = $this->appData->getFolder($appName);
68
-			$gzip = false;
69
-			$file = $this->getFile($folder, $fileName, $gzip);
70
-		} catch(NotFoundException $e) {
71
-			return new NotFoundResponse();
72
-		}
56
+    /**
57
+     * @PublicPage
58
+     * @NoCSRFRequired
59
+     * @NoSameSiteCookieRequired
60
+     *
61
+     * @param string $fileName js filename with extension
62
+     * @param string $appName js folder name
63
+     * @return FileDisplayResponse|NotFoundResponse
64
+     */
65
+    public function getJs(string $fileName, string $appName): Response {
66
+        try {
67
+            $folder = $this->appData->getFolder($appName);
68
+            $gzip = false;
69
+            $file = $this->getFile($folder, $fileName, $gzip);
70
+        } catch(NotFoundException $e) {
71
+            return new NotFoundResponse();
72
+        }
73 73
 
74
-		$response = new FileDisplayResponse($file, Http::STATUS_OK, ['Content-Type' => 'application/javascript']);
75
-		if ($gzip) {
76
-			$response->addHeader('Content-Encoding', 'gzip');
77
-		}
74
+        $response = new FileDisplayResponse($file, Http::STATUS_OK, ['Content-Type' => 'application/javascript']);
75
+        if ($gzip) {
76
+            $response->addHeader('Content-Encoding', 'gzip');
77
+        }
78 78
 
79
-		$ttl = 31536000;
80
-		$response->addHeader('Cache-Control', 'max-age='.$ttl.', immutable');
79
+        $ttl = 31536000;
80
+        $response->addHeader('Cache-Control', 'max-age='.$ttl.', immutable');
81 81
 
82
-		$expires = new \DateTime();
83
-		$expires->setTimestamp($this->timeFactory->getTime());
84
-		$expires->add(new \DateInterval('PT'.$ttl.'S'));
85
-		$response->addHeader('Expires', $expires->format(\DateTime::RFC1123));
86
-		$response->addHeader('Pragma', 'cache');
87
-		return $response;
88
-	}
82
+        $expires = new \DateTime();
83
+        $expires->setTimestamp($this->timeFactory->getTime());
84
+        $expires->add(new \DateInterval('PT'.$ttl.'S'));
85
+        $response->addHeader('Expires', $expires->format(\DateTime::RFC1123));
86
+        $response->addHeader('Pragma', 'cache');
87
+        return $response;
88
+    }
89 89
 
90
-	/**
91
-	 * @param ISimpleFolder $folder
92
-	 * @param string $fileName
93
-	 * @param bool $gzip is set to true if we use the gzip file
94
-	 * @return ISimpleFile
95
-	 *
96
-	 * @throws NotFoundException
97
-	 */
98
-	private function getFile(ISimpleFolder $folder, string $fileName, bool &$gzip): ISimpleFile {
99
-		$encoding = $this->request->getHeader('Accept-Encoding');
90
+    /**
91
+     * @param ISimpleFolder $folder
92
+     * @param string $fileName
93
+     * @param bool $gzip is set to true if we use the gzip file
94
+     * @return ISimpleFile
95
+     *
96
+     * @throws NotFoundException
97
+     */
98
+    private function getFile(ISimpleFolder $folder, string $fileName, bool &$gzip): ISimpleFile {
99
+        $encoding = $this->request->getHeader('Accept-Encoding');
100 100
 
101
-		if (strpos($encoding, 'gzip') !== false) {
102
-			try {
103
-				$gzip = true;
104
-				return $folder->getFile($fileName . '.gzip'); # Safari doesn't like .gz
105
-			} catch (NotFoundException $e) {
106
-				// continue
107
-			}
108
-		}
101
+        if (strpos($encoding, 'gzip') !== false) {
102
+            try {
103
+                $gzip = true;
104
+                return $folder->getFile($fileName . '.gzip'); # Safari doesn't like .gz
105
+            } catch (NotFoundException $e) {
106
+                // continue
107
+            }
108
+        }
109 109
 
110
-		$gzip = false;
111
-		return $folder->getFile($fileName);
112
-	}
110
+        $gzip = false;
111
+        return $folder->getFile($fileName);
112
+    }
113 113
 }
Please login to merge, or discard this patch.
core/Controller/CssController.php 1 patch
Indentation   +62 added lines, -62 removed lines patch added patch discarded remove patch
@@ -43,76 +43,76 @@
 block discarded – undo
43 43
 
44 44
 class CssController extends Controller {
45 45
 
46
-	/** @var IAppData */
47
-	protected $appData;
46
+    /** @var IAppData */
47
+    protected $appData;
48 48
 
49
-	/** @var ITimeFactory */
50
-	protected $timeFactory;
49
+    /** @var ITimeFactory */
50
+    protected $timeFactory;
51 51
 
52
-	public function __construct(string $appName,
53
-								IRequest $request,
54
-								Factory $appDataFactory,
55
-								ITimeFactory $timeFactory) {
56
-		parent::__construct($appName, $request);
52
+    public function __construct(string $appName,
53
+                                IRequest $request,
54
+                                Factory $appDataFactory,
55
+                                ITimeFactory $timeFactory) {
56
+        parent::__construct($appName, $request);
57 57
 
58
-		$this->appData = $appDataFactory->get('css');
59
-		$this->timeFactory = $timeFactory;
60
-	}
58
+        $this->appData = $appDataFactory->get('css');
59
+        $this->timeFactory = $timeFactory;
60
+    }
61 61
 
62
-	/**
63
-	 * @PublicPage
64
-	 * @NoCSRFRequired
65
-	 * @NoSameSiteCookieRequired
66
-	 *
67
-	 * @param string $fileName css filename with extension
68
-	 * @param string $appName css folder name
69
-	 * @return FileDisplayResponse|NotFoundResponse
70
-	 */
71
-	public function getCss(string $fileName, string $appName): Response {
72
-		try {
73
-			$folder = $this->appData->getFolder($appName);
74
-			$gzip = false;
75
-			$file = $this->getFile($folder, $fileName, $gzip);
76
-		} catch(NotFoundException $e) {
77
-			return new NotFoundResponse();
78
-		}
62
+    /**
63
+     * @PublicPage
64
+     * @NoCSRFRequired
65
+     * @NoSameSiteCookieRequired
66
+     *
67
+     * @param string $fileName css filename with extension
68
+     * @param string $appName css folder name
69
+     * @return FileDisplayResponse|NotFoundResponse
70
+     */
71
+    public function getCss(string $fileName, string $appName): Response {
72
+        try {
73
+            $folder = $this->appData->getFolder($appName);
74
+            $gzip = false;
75
+            $file = $this->getFile($folder, $fileName, $gzip);
76
+        } catch(NotFoundException $e) {
77
+            return new NotFoundResponse();
78
+        }
79 79
 
80
-		$response = new FileDisplayResponse($file, Http::STATUS_OK, ['Content-Type' => 'text/css']);
81
-		if ($gzip) {
82
-			$response->addHeader('Content-Encoding', 'gzip');
83
-		}
80
+        $response = new FileDisplayResponse($file, Http::STATUS_OK, ['Content-Type' => 'text/css']);
81
+        if ($gzip) {
82
+            $response->addHeader('Content-Encoding', 'gzip');
83
+        }
84 84
 
85
-		$ttl = 31536000;
86
-		$response->addHeader('Cache-Control', 'max-age='.$ttl.', immutable');
85
+        $ttl = 31536000;
86
+        $response->addHeader('Cache-Control', 'max-age='.$ttl.', immutable');
87 87
 
88
-		$expires = new \DateTime();
89
-		$expires->setTimestamp($this->timeFactory->getTime());
90
-		$expires->add(new \DateInterval('PT'.$ttl.'S'));
91
-		$response->addHeader('Expires', $expires->format(\DateTime::RFC1123));
92
-		$response->addHeader('Pragma', 'cache');
93
-		return $response;
94
-	}
88
+        $expires = new \DateTime();
89
+        $expires->setTimestamp($this->timeFactory->getTime());
90
+        $expires->add(new \DateInterval('PT'.$ttl.'S'));
91
+        $response->addHeader('Expires', $expires->format(\DateTime::RFC1123));
92
+        $response->addHeader('Pragma', 'cache');
93
+        return $response;
94
+    }
95 95
 
96
-	/**
97
-	 * @param ISimpleFolder $folder
98
-	 * @param string $fileName
99
-	 * @param bool $gzip is set to true if we use the gzip file
100
-	 * @return ISimpleFile
101
-	 * @throws NotFoundException
102
-	 */
103
-	private function getFile(ISimpleFolder $folder, string $fileName, bool &$gzip): ISimpleFile {
104
-		$encoding = $this->request->getHeader('Accept-Encoding');
96
+    /**
97
+     * @param ISimpleFolder $folder
98
+     * @param string $fileName
99
+     * @param bool $gzip is set to true if we use the gzip file
100
+     * @return ISimpleFile
101
+     * @throws NotFoundException
102
+     */
103
+    private function getFile(ISimpleFolder $folder, string $fileName, bool &$gzip): ISimpleFile {
104
+        $encoding = $this->request->getHeader('Accept-Encoding');
105 105
 
106
-		if (strpos($encoding, 'gzip') !== false) {
107
-			try {
108
-				$gzip = true;
109
-				return $folder->getFile($fileName . '.gzip'); # Safari doesn't like .gz
110
-			} catch (NotFoundException $e) {
111
-				// continue
112
-			}
113
-		}
106
+        if (strpos($encoding, 'gzip') !== false) {
107
+            try {
108
+                $gzip = true;
109
+                return $folder->getFile($fileName . '.gzip'); # Safari doesn't like .gz
110
+            } catch (NotFoundException $e) {
111
+                // continue
112
+            }
113
+        }
114 114
 
115
-		$gzip = false;
116
-		return $folder->getFile($fileName);
117
-	}
115
+        $gzip = false;
116
+        return $folder->getFile($fileName);
117
+    }
118 118
 }
Please login to merge, or discard this patch.
core/Controller/SvgController.php 1 patch
Indentation   +106 added lines, -106 removed lines patch added patch discarded remove patch
@@ -34,110 +34,110 @@
 block discarded – undo
34 34
 
35 35
 class SvgController extends Controller {
36 36
 
37
-	/** @var string */
38
-	protected $serverRoot;
39
-
40
-	/** @var ITimeFactory */
41
-	protected $timeFactory;
42
-
43
-	/** @var IAppManager */
44
-	protected $appManager;
45
-
46
-	public function __construct(string $appName,
47
-								IRequest $request,
48
-								ITimeFactory $timeFactory,
49
-								IAppManager $appManager) {
50
-		parent::__construct($appName, $request);
51
-
52
-		$this->serverRoot  = \OC::$SERVERROOT;
53
-		$this->timeFactory = $timeFactory;
54
-		$this->appManager = $appManager;
55
-	}
56
-
57
-	/**
58
-	 * @PublicPage
59
-	 * @NoCSRFRequired
60
-	 * @NoSameSiteCookieRequired
61
-	 *
62
-	 * Generate svg from filename with the requested color
63
-	 *
64
-	 * @param string $folder
65
-	 * @param string $fileName
66
-	 * @param string $color
67
-	 * @return DataDisplayResponse|NotFoundResponse
68
-	 */
69
-	public function getSvgFromCore(string $folder, string $fileName, string $color = 'ffffff') {
70
-		$path = $this->serverRoot . "/core/img/$folder/$fileName.svg";
71
-		return $this->getSvg($path, $color, $fileName);
72
-	}
73
-
74
-	/**
75
-	 * @PublicPage
76
-	 * @NoCSRFRequired
77
-	 * @NoSameSiteCookieRequired
78
-	 *
79
-	 * Generate svg from filename with the requested color
80
-	 *
81
-	 * @param string $app
82
-	 * @param string $fileName
83
-	 * @param string $color
84
-	 * @return DataDisplayResponse|NotFoundResponse
85
-	 */
86
-	public function getSvgFromApp(string $app, string $fileName, string $color = 'ffffff') {
87
-
88
-		if ($app === 'settings') {
89
-			$path = $this->serverRoot . "/settings/img/$fileName.svg";
90
-			return $this->getSvg($path, $color, $fileName);
91
-		}
92
-
93
-		$appRootPath = $this->appManager->getAppPath($app);
94
-		$appPath = substr($appRootPath, strlen($this->serverRoot));
95
-
96
-		if (!$appPath) {
97
-			return new NotFoundResponse();
98
-		}
99
-		$path = $this->serverRoot . $appPath ."/img/$fileName.svg";
100
-		return $this->getSvg($path, $color, $fileName);
101
-	}
102
-
103
-	/**
104
-	 * Generate svg from filename with the requested color
105
-	 *
106
-	 * @param string $path
107
-	 * @param string $color
108
-	 * @return DataDisplayResponse|NotFoundResponse
109
-	 */
110
-	private function getSvg(string $path, string $color, string $fileName) {
111
-		if (!file_exists($path)) {
112
-			return new NotFoundResponse();
113
-		}
114
-
115
-		$svg = file_get_contents($path);
116
-
117
-		if (is_null($svg)) {
118
-			return new NotFoundResponse();
119
-		}
120
-
121
-		// add fill (fill is not present on black elements)
122
-		$fillRe = '/<((circle|rect|path)((?!fill)[a-z0-9 =".\-#():;])+)\/>/mi';
123
-		$svg = preg_replace($fillRe, '<$1 fill="#' . $color . '"/>', $svg);
124
-
125
-		// replace any fill or stroke colors
126
-		$svg = preg_replace('/stroke="#([a-z0-9]{3,6})"/mi', 'stroke="#' . $color . '"', $svg);
127
-		$svg = preg_replace('/fill="#([a-z0-9]{3,6})"/mi', 'fill="#' . $color . '"', $svg);
128
-
129
-		$response = new DataDisplayResponse($svg, Http::STATUS_OK, ['Content-Type' => 'image/svg+xml']);
130
-
131
-		// Set cache control
132
-		$ttl = 31536000;
133
-		$response->cacheFor($ttl);
134
-		$response->addHeader('Content-Disposition', 'inline; filename="' . $fileName . '.svg"');
135
-		$expires = new \DateTime();
136
-		$expires->setTimestamp($this->timeFactory->getTime());
137
-		$expires->add(new \DateInterval('PT' . $ttl . 'S'));
138
-		$response->addHeader('Expires', $expires->format(\DateTime::RFC1123));
139
-		$response->addHeader('Pragma', 'cache');
140
-
141
-		return $response;
142
-	}
37
+    /** @var string */
38
+    protected $serverRoot;
39
+
40
+    /** @var ITimeFactory */
41
+    protected $timeFactory;
42
+
43
+    /** @var IAppManager */
44
+    protected $appManager;
45
+
46
+    public function __construct(string $appName,
47
+                                IRequest $request,
48
+                                ITimeFactory $timeFactory,
49
+                                IAppManager $appManager) {
50
+        parent::__construct($appName, $request);
51
+
52
+        $this->serverRoot  = \OC::$SERVERROOT;
53
+        $this->timeFactory = $timeFactory;
54
+        $this->appManager = $appManager;
55
+    }
56
+
57
+    /**
58
+     * @PublicPage
59
+     * @NoCSRFRequired
60
+     * @NoSameSiteCookieRequired
61
+     *
62
+     * Generate svg from filename with the requested color
63
+     *
64
+     * @param string $folder
65
+     * @param string $fileName
66
+     * @param string $color
67
+     * @return DataDisplayResponse|NotFoundResponse
68
+     */
69
+    public function getSvgFromCore(string $folder, string $fileName, string $color = 'ffffff') {
70
+        $path = $this->serverRoot . "/core/img/$folder/$fileName.svg";
71
+        return $this->getSvg($path, $color, $fileName);
72
+    }
73
+
74
+    /**
75
+     * @PublicPage
76
+     * @NoCSRFRequired
77
+     * @NoSameSiteCookieRequired
78
+     *
79
+     * Generate svg from filename with the requested color
80
+     *
81
+     * @param string $app
82
+     * @param string $fileName
83
+     * @param string $color
84
+     * @return DataDisplayResponse|NotFoundResponse
85
+     */
86
+    public function getSvgFromApp(string $app, string $fileName, string $color = 'ffffff') {
87
+
88
+        if ($app === 'settings') {
89
+            $path = $this->serverRoot . "/settings/img/$fileName.svg";
90
+            return $this->getSvg($path, $color, $fileName);
91
+        }
92
+
93
+        $appRootPath = $this->appManager->getAppPath($app);
94
+        $appPath = substr($appRootPath, strlen($this->serverRoot));
95
+
96
+        if (!$appPath) {
97
+            return new NotFoundResponse();
98
+        }
99
+        $path = $this->serverRoot . $appPath ."/img/$fileName.svg";
100
+        return $this->getSvg($path, $color, $fileName);
101
+    }
102
+
103
+    /**
104
+     * Generate svg from filename with the requested color
105
+     *
106
+     * @param string $path
107
+     * @param string $color
108
+     * @return DataDisplayResponse|NotFoundResponse
109
+     */
110
+    private function getSvg(string $path, string $color, string $fileName) {
111
+        if (!file_exists($path)) {
112
+            return new NotFoundResponse();
113
+        }
114
+
115
+        $svg = file_get_contents($path);
116
+
117
+        if (is_null($svg)) {
118
+            return new NotFoundResponse();
119
+        }
120
+
121
+        // add fill (fill is not present on black elements)
122
+        $fillRe = '/<((circle|rect|path)((?!fill)[a-z0-9 =".\-#():;])+)\/>/mi';
123
+        $svg = preg_replace($fillRe, '<$1 fill="#' . $color . '"/>', $svg);
124
+
125
+        // replace any fill or stroke colors
126
+        $svg = preg_replace('/stroke="#([a-z0-9]{3,6})"/mi', 'stroke="#' . $color . '"', $svg);
127
+        $svg = preg_replace('/fill="#([a-z0-9]{3,6})"/mi', 'fill="#' . $color . '"', $svg);
128
+
129
+        $response = new DataDisplayResponse($svg, Http::STATUS_OK, ['Content-Type' => 'image/svg+xml']);
130
+
131
+        // Set cache control
132
+        $ttl = 31536000;
133
+        $response->cacheFor($ttl);
134
+        $response->addHeader('Content-Disposition', 'inline; filename="' . $fileName . '.svg"');
135
+        $expires = new \DateTime();
136
+        $expires->setTimestamp($this->timeFactory->getTime());
137
+        $expires->add(new \DateInterval('PT' . $ttl . 'S'));
138
+        $response->addHeader('Expires', $expires->format(\DateTime::RFC1123));
139
+        $response->addHeader('Pragma', 'cache');
140
+
141
+        return $response;
142
+    }
143 143
 }
Please login to merge, or discard this patch.