Test Setup Failed
Push — master ( 4a93bf...5a5f5f )
by Daniel
23:25
created

TemplatesService::getTemplateFolder()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 23
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4.9102

Importance

Changes 0
Metric Value
eloc 14
c 0
b 0
f 0
dl 0
loc 23
ccs 8
cts 13
cp 0.6153
rs 9.7998
cc 4
nc 4
nop 1
crap 4.9102
1
<?php
2
/**
3
 * CMS Pico - Create websites using Pico CMS for Nextcloud.
4
 *
5
 * @copyright Copyright (c) 2017, Maxence Lange (<[email protected]>)
6
 * @copyright Copyright (c) 2019, Daniel Rudolf (<[email protected]>)
7
 *
8
 * @license GNU AGPL version 3 or any later version
9
 *
10
 * This program is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU Affero General Public License as
12
 * published by the Free Software Foundation, either version 3 of the
13
 * License, or (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU Affero General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Affero General Public License
21
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
 */
23
24
declare(strict_types=1);
25
26
namespace OCA\CMSPico\Service;
27
28
use OCA\CMSPico\Exceptions\TemplateAlreadyExistsException;
29
use OCA\CMSPico\Exceptions\TemplateNotCompatibleException;
30
use OCA\CMSPico\Exceptions\TemplateNotFoundException;
31
use OCA\CMSPico\Files\FileInterface;
32
use OCA\CMSPico\Files\FolderInterface;
33
use OCA\CMSPico\Files\StorageFolder;
34
use OCA\CMSPico\Model\Template;
35
use OCA\CMSPico\Model\TemplateFile;
36
use OCA\CMSPico\Model\Website;
37
use OCP\Files\AlreadyExistsException;
38
use OCP\Files\NotFoundException;
39
40
class TemplatesService
41
{
42
	/** @var ConfigService */
43
	private $configService;
44
45
	/** @var FileService */
46
	private $fileService;
47
48
	/**
49
	 * TemplatesService constructor.
50
	 *
51
	 * @param ConfigService $configService
52
	 * @param FileService   $fileService
53
	 */
54 1
	public function __construct(ConfigService $configService, FileService $fileService)
55
	{
56 1
		$this->configService = $configService;
57 1
		$this->fileService = $fileService;
58 1
	}
59
60
	/**
61
	 * @param string $templateName
62
	 *
63
	 * @throws TemplateNotFoundException
64
	 * @throws TemplateNotCompatibleException
65
	 */
66 4
	public function assertValidTemplate(string $templateName): void
67
	{
68 4
		$templates = $this->getTemplates();
69
70 4
		if (!isset($templates[$templateName])) {
71
			throw new TemplateNotFoundException();
72
		}
73
74 4
		if (!$templates[$templateName]['compat']) {
75
			throw new TemplateNotCompatibleException(
76
				$templateName,
77
				$templates[$templateName]['compatReason'],
78
				$templates[$templateName]['compatReasonData']
79
			);
80
		}
81 4
	}
82
83
	/**
84
	 * @return array[]
85
	 */
86 9
	public function getTemplates(): array
87
	{
88 9
		return $this->getSystemTemplates() + $this->getCustomTemplates();
89
	}
90
91
	/**
92
	 * @return array[]
93
	 */
94 9
	public function getSystemTemplates(): array
95
	{
96 9
		$json = $this->configService->getAppValue(ConfigService::SYSTEM_TEMPLATES);
97 9
		return $json ? json_decode($json, true) : [];
98
	}
99
100
	/**
101
	 * @return array[]
102
	 */
103 9
	public function getCustomTemplates(): array
104
	{
105 9
		$json = $this->configService->getAppValue(ConfigService::CUSTOM_TEMPLATES);
106 9
		return $json ? json_decode($json, true) : [];
107
	}
108
109
	/**
110
	 * @return string[]
111
	 */
112 5
	public function getNewCustomTemplates(): array
113
	{
114 5
		$customTemplatesFolder = $this->fileService->getAppDataFolder(PicoService::DIR_TEMPLATES);
115 5
		$customTemplatesFolder->sync(FolderInterface::SYNC_SHALLOW);
116
117 5
		$currentTemplates = $this->getTemplates();
118
119 5
		$newCustomTemplates = [];
120 5
		foreach ($customTemplatesFolder as $templateFolder) {
121 4
			$templateName = $templateFolder->getName();
122 4
			if ($templateFolder->isFolder() && !isset($currentTemplates[$templateName])) {
123 2
				$newCustomTemplates[] = $templateName;
124
			}
125
		}
126
127 5
		return $newCustomTemplates;
128
	}
129
130
	/**
131
	 * @param string $templateName
132
	 *
133
	 * @return Template
134
	 * @throws TemplateNotFoundException
135
	 * @throws TemplateAlreadyExistsException
136
	 */
137
	public function registerSystemTemplate(string $templateName): Template
138
	{
139
		if (!$templateName) {
140
			throw new TemplateNotFoundException();
141
		}
142
143
		$systemTemplatesFolder = $this->fileService->getSystemFolder(PicoService::DIR_TEMPLATES);
144
		$systemTemplatesFolder->sync(FolderInterface::SYNC_SHALLOW);
145
146
		try {
147
			$templateFolder = $systemTemplatesFolder->getFolder($templateName);
148
		} catch (NotFoundException $e) {
149
			throw new TemplateNotFoundException();
150
		}
151
152
		$templates = $this->getSystemTemplates();
153
		$templates[$templateName] = new Template($templateFolder, Template::TYPE_SYSTEM);
154
		$this->configService->setAppValue(ConfigService::SYSTEM_TEMPLATES, json_encode($templates));
155
156
		return $templates[$templateName];
157
	}
158
159
	/**
160
	 * @param string $templateName
161
	 *
162
	 * @return Template
163
	 * @throws TemplateNotFoundException
164
	 * @throws TemplateAlreadyExistsException
165
	 */
166 2
	public function registerCustomTemplate(string $templateName): Template
167
	{
168 2
		if (!$templateName) {
169
			throw new TemplateNotFoundException();
170
		}
171
172 2
		$systemTemplates = $this->getSystemTemplates();
173 2
		if (isset($systemTemplates[$templateName])) {
174
			throw new TemplateAlreadyExistsException();
175
		}
176
177 2
		$appDataTemplatesFolder = $this->fileService->getAppDataFolder(PicoService::DIR_TEMPLATES);
178 2
		$appDataTemplatesFolder->sync(FolderInterface::SYNC_SHALLOW);
179
180
		try {
181 2
			$templateFolder = $appDataTemplatesFolder->getFolder($templateName);
182
		} catch (NotFoundException $e) {
183
			throw new TemplateNotFoundException();
184
		}
185
186 2
		$templates = $this->getCustomTemplates();
187 2
		$templates[$templateName] = new Template($templateFolder, Template::TYPE_CUSTOM);
188 2
		$this->configService->setAppValue(ConfigService::CUSTOM_TEMPLATES, json_encode($templates));
189
190 2
		return $templates[$templateName];
191
	}
192
193
	/**
194
	 * @param string $templateName
195
	 *
196
	 * @throws TemplateNotFoundException
197
	 */
198 1
	public function removeCustomTemplate(string $templateName): void
199
	{
200 1
		if (!$templateName) {
201
			throw new TemplateNotFoundException();
202
		}
203
204 1
		$customTemplates = $this->getCustomTemplates();
205 1
		unset($customTemplates[$templateName]);
206 1
		$this->configService->setAppValue(ConfigService::CUSTOM_TEMPLATES, json_encode($customTemplates));
207 1
	}
208
209
	/**
210
	 * @param string $baseTemplateName
211
	 * @param string $templateName
212
	 *
213
	 * @return Template
214
	 * @throws TemplateNotFoundException
215
	 * @throws TemplateAlreadyExistsException
216
	 */
217 1
	public function copyTemplate(string $baseTemplateName, string $templateName): Template
218
	{
219 1
		if (!$baseTemplateName || !$templateName) {
220
			throw new TemplateNotFoundException();
221
		}
222
223 1
		$systemTemplates = $this->getSystemTemplates();
224 1
		$customTemplates = $this->getCustomTemplates();
225
226 1
		if (isset($systemTemplates[$templateName]) || isset($customTemplates[$templateName])) {
227
			throw new TemplateAlreadyExistsException();
228
		}
229
230 1
		$baseTemplateFolder = $this->getTemplateFolder($baseTemplateName);
231 1
		$appDataTemplatesFolder = $this->fileService->getAppDataFolder(PicoService::DIR_TEMPLATES);
232
233
		try {
234 1
			$baseTemplateFolder->copy($appDataTemplatesFolder, $templateName);
235
		} catch (AlreadyExistsException $e) {
236
			throw new TemplateAlreadyExistsException();
237
		}
238
239 1
		return $this->registerCustomTemplate($templateName);
240
	}
241
242
	/**
243
	 * @param Website $website
244
	 * @param string  $templateName
245
	 *
246
	 * @throws TemplateNotFoundException
247
	 */
248 4
	public function installTemplate(Website $website, string $templateName): void
249
	{
250 4
		$userFolder = new StorageFolder(\OC::$server->getUserFolder($website->getUserId()));
0 ignored issues
show
Deprecated Code introduced by
The function OC\Server::getUserFolder() has been deprecated: 20.0.0 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

250
		$userFolder = new StorageFolder(/** @scrutinizer ignore-deprecated */ \OC::$server->getUserFolder($website->getUserId()));

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
251
252
		try {
253 4
			$userFolder->get($website->getPath());
254
255
			// website folder exists; since we don't want to
256
			// mess around with a user's files, bail out
257 1
			return;
258 3
		} catch (NotFoundException $e) {
259
			// proceed if the website folder doesn't exist yet
260
		}
261
262 3
		$websiteFolder = $userFolder->newFolder($website->getPath());
263
264 3
		$templateFolder = $this->getTemplateFolder($templateName);
265 3
		$templateFolder->sync();
266
267 3
		$templateData = $this->getTemplateData($website);
268 3
		foreach (new \RecursiveIteratorIterator($templateFolder) as $file) {
269
			/** @var FileInterface $file */
270 3
			$templateFile = new TemplateFile($file);
271
272
			try {
273 3
				$targetFolder = $websiteFolder->getFolder($templateFile->getParent());
274 3
			} catch (NotFoundException $e) {
275 3
				$targetFolder = $websiteFolder->newFolder($templateFile->getParent());
276
			}
277
278 3
			if ($templateFile->getName() === 'empty') {
279
				continue;
280
			}
281
282 3
			$templateFile->setTemplateData($templateData);
283 3
			$templateFile->copy($targetFolder);
284
		}
285 3
	}
286
287
	/**
288
	 * @param Website $website
289
	 *
290
	 * @return array<string,string>
291
	 */
292 3
	private function getTemplateData(Website $website): array
293
	{
294
		return [
295 3
			'site_title' => $website->getName()
296
		];
297
	}
298
299
	/**
300
	 * @param string $templateName
301
	 *
302
	 * @return FolderInterface
303
	 * @throws TemplateNotFoundException
304
	 */
305 4
	public function getTemplateFolder(string $templateName): FolderInterface
306
	{
307 4
		if (!$templateName) {
308
			throw new TemplateNotFoundException();
309
		}
310
311 4
		$systemTemplatesFolder = $this->fileService->getSystemFolder(PicoService::DIR_TEMPLATES);
312 4
		$systemTemplatesFolder->sync(FolderInterface::SYNC_SHALLOW);
313
314 4
		$customTemplatesFolder = $this->fileService->getAppDataFolder(PicoService::DIR_TEMPLATES);
315 4
		$customTemplatesFolder->sync(FolderInterface::SYNC_SHALLOW);
316
317
		try {
318 4
			$templateFolder = $systemTemplatesFolder->getFolder($templateName);
319
		} catch (NotFoundException $e) {
320
			try {
321
				$templateFolder = $customTemplatesFolder->getFolder($templateName);
322
			} catch (NotFoundException $e) {
323
				throw new TemplateNotFoundException();
324
			}
325
		}
326
327 4
		return $templateFolder->fakeRoot();
328
	}
329
}
330