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())); |
|
|
|
|
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
|
|
|
|
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.