Test Failed
Push — master ( dc798f...d76e2d )
by Daniel
48:22
created

TemplatesService::installTemplate()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 36
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 5.5359

Importance

Changes 0
Metric Value
eloc 19
c 0
b 0
f 0
dl 0
loc 36
ccs 13
cts 18
cp 0.7221
rs 9.3222
cc 5
nc 6
nop 1
crap 5.5359
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 1
			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 4
	public function getTemplates(): array
87
	{
88 4
		return $this->getSystemTemplates() + $this->getCustomTemplates();
89
	}
90
91
	/**
92
	 * @return array[]
93
	 */
94 4
	public function getSystemTemplates(): array
95
	{
96 4
		$json = $this->configService->getAppValue(ConfigService::SYSTEM_TEMPLATES);
97 4
		return $json ? json_decode($json, true) : [];
98
	}
99
100
	/**
101
	 * @return array[]
102
	 */
103 4
	public function getCustomTemplates(): array
104
	{
105 4
		$json = $this->configService->getAppValue(ConfigService::CUSTOM_TEMPLATES);
106 4
		return $json ? json_decode($json, true) : [];
107
	}
108
109
	/**
110
	 * @return string[]
111
	 */
112 1
	public function getNewCustomTemplates(): array
113
	{
114 1
		$customTemplatesFolder = $this->fileService->getAppDataFolder(PicoService::DIR_TEMPLATES);
115 1
		$customTemplatesFolder->sync(FolderInterface::SYNC_SHALLOW);
116
117 1
		$currentTemplates = $this->getTemplates();
118
119 1
		$newCustomTemplates = [];
120 1
		foreach ($customTemplatesFolder as $templateFolder) {
121 1
			$templateName = $templateFolder->getName();
122 1
			if ($templateFolder->isFolder() && !isset($currentTemplates[$templateName])) {
123 1
				$newCustomTemplates[] = $templateName;
124
			}
125
		}
126
127 1
		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 1
	public function registerCustomTemplate(string $templateName): Template
167
	{
168 1
		if (!$templateName) {
169
			throw new TemplateNotFoundException();
170
		}
171
172 1
		$systemTemplates = $this->getSystemTemplates();
173 1
		if (isset($systemTemplates[$templateName])) {
174
			throw new TemplateAlreadyExistsException();
175
		}
176
177 1
		$appDataTemplatesFolder = $this->fileService->getAppDataFolder(PicoService::DIR_TEMPLATES);
178 1
		$appDataTemplatesFolder->sync(FolderInterface::SYNC_SHALLOW);
179
180
		try {
181 1
			$templateFolder = $appDataTemplatesFolder->getFolder($templateName);
182
		} catch (NotFoundException $e) {
183
			throw new TemplateNotFoundException();
184
		}
185
186 1
		$templates = $this->getCustomTemplates();
187 1
		$templates[$templateName] = new Template($templateFolder, Template::TYPE_CUSTOM);
188 1
		$this->configService->setAppValue(ConfigService::CUSTOM_TEMPLATES, json_encode($templates));
189
190 1
		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
	public function copyTemplate(string $baseTemplateName, string $templateName): Template
218
	{
219
		if (!$baseTemplateName || !$templateName) {
220
			throw new TemplateNotFoundException();
221
		}
222
223
		$systemTemplates = $this->getSystemTemplates();
224
		$customTemplates = $this->getCustomTemplates();
225
226
		if (isset($systemTemplates[$templateName]) || isset($customTemplates[$templateName])) {
227
			throw new TemplateAlreadyExistsException();
228
		}
229
230
		$baseTemplateFolder = $this->getTemplateFolder($baseTemplateName);
231
		$appDataTemplatesFolder = $this->fileService->getAppDataFolder(PicoService::DIR_TEMPLATES);
232
233
		try {
234
			$baseTemplateFolder->copy($appDataTemplatesFolder, $templateName);
235
		} catch (AlreadyExistsException $e) {
236
			throw new TemplateAlreadyExistsException();
237
		}
238
239
		return $this->registerCustomTemplate($templateName);
240
	}
241
242
	/**
243
	 * @param Website $website
244
	 *
245
	 * @throws TemplateNotFoundException
246
	 */
247 3
	public function installTemplate(Website $website): void
248
	{
249 3
		$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

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