Passed
Pull Request — master (#77)
by Daniel
33:27
created

AppDataRepairStep::syncAppDataFolder()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 0
cts 3
cp 0
rs 10
cc 1
nc 1
nop 0
crap 2
1
<?php
2
/**
3
 * CMS Pico - Create websites using Pico CMS for Nextcloud.
4
 *
5
 * @copyright Copyright (c) 2019, Daniel Rudolf (<[email protected]>)
6
 *
7
 * @license GNU AGPL version 3 or any later version
8
 *
9
 * This program is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Affero General Public License as
11
 * published by the Free Software Foundation, either version 3 of the
12
 * License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU Affero General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Affero General Public License
20
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 */
22
23
declare(strict_types=1);
24
25
namespace OCA\CMSPico\Migration;
26
27
use OCA\CMSPico\AppInfo\Application;
28
use OCA\CMSPico\Service\ConfigService;
29
use OCA\CMSPico\Service\FileService;
30
use OCA\CMSPico\Service\PicoService;
31
use OCA\CMSPico\Service\PluginsService;
32
use OCA\CMSPico\Service\TemplatesService;
33
use OCA\CMSPico\Service\ThemesService;
34
use OCP\Files\NotFoundException;
35
use OCP\ILogger;
36
use OCP\Migration\IOutput;
37
use OCP\Migration\IRepairStep;
38
39
class AppDataRepairStep implements IRepairStep
40
{
41
	/** @var ILogger */
42
	private $logger;
43
44
	/** @var ConfigService */
45
	private $configService;
46
47
	/** @var TemplatesService */
48
	private $templatesService;
49
50
	/** @var ThemesService */
51
	private $themesService;
52
53
	/** @var PluginsService */
54
	private $pluginsService;
55
56
	/** @var FileService */
57
	private $fileService;
58
59
	/**
60
	 * AppDataRepairStep constructor.
61
	 *
62
	 * @param ILogger          $logger
63
	 * @param ConfigService    $configService
64
	 * @param TemplatesService $templatesService
65
	 * @param ThemesService    $themesService
66
	 * @param PluginsService   $pluginsService
67
	 * @param FileService      $fileService
68
	 */
69
	public function __construct(
70
		ILogger $logger,
71
		ConfigService $configService,
72
		TemplatesService $templatesService,
73
		ThemesService $themesService,
74
		PluginsService $pluginsService,
75
		FileService $fileService
76
	) {
77
		$this->logger = $logger;
78
		$this->configService = $configService;
79
		$this->templatesService = $templatesService;
80
		$this->themesService = $themesService;
81
		$this->pluginsService = $pluginsService;
82
		$this->fileService = $fileService;
83
	}
84
85
	/**
86
	 * @return string
87
	 */
88
	public function getName(): string
89
	{
90
		return 'Preparing app data of Pico CMS for Nextcloud';
91
	}
92
93
	/**
94
	 * @param IOutput $output
95
	 */
96
	public function run(IOutput $output)
97
	{
98
		$this->log('Syncing Pico CMS app data folder …');
99
		$this->syncAppDataFolder();
100
101
		$this->log('Copying Pico CMS config …');
102
		$this->copyConfig();
103
104
		$this->log('Registering Pico CMS templates …');
105
		$this->registerTemplates();
106
107
		$this->log('Publishing Pico CMS themes …');
108
		$this->publishThemes();
109
110
		$this->log('Publishing Pico CMS plugins …');
111
		$this->publishPlugins();
112
	}
113
114
	/**
115
	 * @return void
116
	 */
117
	private function syncAppDataFolder()
118
	{
119
		$this->fileService->syncAppDataFolder();
120
	}
121
122
	/**
123
	 * @return void
124
	 */
125
	private function copyConfig()
126
	{
127
		$appDataConfigFolder = $this->fileService->getAppDataFolder(PicoService::DIR_CONFIG);
128
		$systemConfigFolder = $this->fileService->getSystemFolder(PicoService::DIR_CONFIG);
129
130
		foreach ($systemConfigFolder as $configFile) {
131
			$configFileName = $configFile->getName();
132
133
			if (!$configFile->isFile()) {
134
				continue;
135
			}
136
137
			try {
138
				$appDataConfigFolder->getFile($configFileName)->delete();
139
				$this->log(sprintf('Replacing %s "%s"', 'config file', $configFileName), ILogger::WARN);
140
			} catch (NotFoundException $e) {
141
				$this->log(sprintf('Adding %s "%s"', 'config file', $configFileName));
142
			} catch (\Exception $e) {
143
				$this->log(sprintf('Unable to create %s "%s"', 'config file', $configFileName), ILogger::ERROR);
144
			}
145
146
			$configFile->copy($appDataConfigFolder);
147
		}
148
	}
149
150
	/**
151
	 * @return void
152
	 */
153
	private function registerTemplates()
154
	{
155
		$this->registerSystemTemplates();
156
		$this->registerCustomTemplates();
157
	}
158
159
	/**
160
	 * @return void
161
	 */
162
	private function registerSystemTemplates()
163
	{
164
		$systemTemplatesFolder = $this->fileService->getSystemFolder(PicoService::DIR_TEMPLATES);
165
166
		$oldSystemTemplates = $this->templatesService->getSystemTemplates();
167
		$this->configService->deleteAppValue(ConfigService::SYSTEM_TEMPLATES);
168
169
		foreach ($systemTemplatesFolder as $templateFolder) {
170
			$templateName = $templateFolder->getName();
171
			if ($templateFolder->isFolder()) {
172
				$this->templatesService->registerSystemTemplate($templateName);
173
			}
174
		}
175
176
		$newSystemTemplates = $this->templatesService->getSystemTemplates();
177
		$this->logChanges('system template', array_keys($newSystemTemplates), array_keys($oldSystemTemplates));
178
	}
179
180
	/**
181
	 * @return void
182
	 */
183
	private function registerCustomTemplates()
184
	{
185
		$appDataTemplatesFolder = $this->fileService->getAppDataFolder(PicoService::DIR_TEMPLATES);
186
187
		$oldCustomTemplates = $this->templatesService->getCustomTemplates();
188
		$this->configService->deleteAppValue(ConfigService::CUSTOM_TEMPLATES);
189
190
		$systemTemplates = $this->templatesService->getSystemTemplates();
191
		foreach ($appDataTemplatesFolder as $templateFolder) {
192
			$templateName = $templateFolder->getName();
193
			if ($templateFolder->isFolder()) {
194
				if (isset($oldCustomTemplates[$templateName]) && !isset($systemTemplates[$templateName])) {
195
					$this->templatesService->registerCustomTemplate($templateName);
196
				}
197
			}
198
		}
199
200
		$newCustomTemplates = $this->templatesService->getCustomTemplates();
201
		$this->logChanges('custom template', array_keys($newCustomTemplates), array_keys($oldCustomTemplates));
202
	}
203
204
	/**
205
	 * @return void
206
	 */
207
	private function publishThemes()
208
	{
209
		$publicThemesFolder = $this->fileService->getPublicFolder(PicoService::DIR_THEMES);
210
		$publicThemesFolder->truncate();
211
212
		$this->configService->deleteAppValue(ConfigService::THEMES_ETAG);
213
214
		$this->publishSystemThemes();
215
		$this->publishCustomThemes();
216
	}
217
218
	/**
219
	 * @return void
220
	 */
221
	private function publishSystemThemes()
222
	{
223
		$systemThemesFolder = $this->fileService->getSystemFolder(PicoService::DIR_THEMES);
224
225
		$oldSystemThemes = $this->themesService->getSystemThemes();
226
		$this->configService->deleteAppValue(ConfigService::SYSTEM_THEMES);
227
228
		foreach ($systemThemesFolder as $themeFolder) {
229
			$themeName = $themeFolder->getName();
230
			if ($themeFolder->isFolder()) {
231
				$this->themesService->publishSystemTheme($themeName);
232
			}
233
		}
234
235
		$newSystemThemes = $this->themesService->getSystemThemes();
236
		$this->logChanges('system theme', array_keys($newSystemThemes), array_keys($oldSystemThemes));
237
	}
238
239
	/**
240
	 * @return void
241
	 */
242
	private function publishCustomThemes()
243
	{
244
		$appDataThemesFolder = $this->fileService->getAppDataFolder(PicoService::DIR_THEMES);
245
246
		$oldCustomThemes = $this->themesService->getCustomThemes();
247
		$this->configService->deleteAppValue(ConfigService::CUSTOM_THEMES);
248
249
		$systemThemes = $this->themesService->getSystemThemes();
250
		foreach ($appDataThemesFolder as $themeFolder) {
251
			$themeName = $themeFolder->getName();
252
			if ($themeFolder->isFolder()) {
253
				if (isset($oldCustomThemes[$themeName]) && !isset($systemThemes[$themeName])) {
254
					$this->themesService->publishCustomTheme($themeName);
255
				}
256
			}
257
		}
258
259
		$newCustomThemes = $this->themesService->getCustomThemes();
260
		$this->logChanges('custom theme', array_keys($newCustomThemes), array_keys($oldCustomThemes));
261
	}
262
263
	/**
264
	 * @return void
265
	 */
266
	private function publishPlugins()
267
	{
268
		$publicPluginsFolder = $this->fileService->getPublicFolder(PicoService::DIR_PLUGINS);
269
		$publicPluginsFolder->truncate();
270
271
		$this->configService->deleteAppValue(ConfigService::PLUGINS_ETAG);
272
273
		$this->publishSystemPlugins();
274
		$this->publishCustomPlugins();
275
	}
276
277
	/**
278
	 * @return void
279
	 */
280
	private function publishSystemPlugins()
281
	{
282
		$systemPluginsFolder = $this->fileService->getSystemFolder(PicoService::DIR_PLUGINS);
283
284
		$oldSystemPlugins = $this->pluginsService->getSystemPlugins();
285
		$this->configService->deleteAppValue(ConfigService::SYSTEM_PLUGINS);
286
287
		foreach ($systemPluginsFolder as $pluginFolder) {
288
			$pluginName = $pluginFolder->getName();
289
			if ($pluginFolder->isFolder()) {
290
				$this->pluginsService->publishSystemPlugin($pluginName);
291
			}
292
		}
293
294
		$newSystemPlugins = $this->pluginsService->getSystemPlugins();
295
		$this->logChanges('system plugin', array_keys($newSystemPlugins), array_keys($oldSystemPlugins));
296
	}
297
298
	/**
299
	 * @return void
300
	 */
301
	private function publishCustomPlugins()
302
	{
303
		$appDataPluginsFolder = $this->fileService->getAppDataFolder(PicoService::DIR_PLUGINS);
304
305
		$oldCustomPlugins = $this->pluginsService->getCustomPlugins();
306
		$this->configService->deleteAppValue(ConfigService::CUSTOM_PLUGINS);
307
308
		$systemPlugins = $this->pluginsService->getSystemPlugins();
309
		foreach ($appDataPluginsFolder as $pluginFolder) {
310
			$pluginName = $pluginFolder->getName();
311
			if ($pluginFolder->isFolder()) {
312
				if (isset($oldCustomPlugins[$pluginName]) && !isset($systemPlugins[$pluginName])) {
313
					$this->pluginsService->publishCustomPlugin($pluginName);
314
				}
315
			}
316
		}
317
318
		$newCustomPlugins = $this->pluginsService->getCustomPlugins();
319
		$this->logChanges('custom plugin', array_keys($newCustomPlugins), array_keys($oldCustomPlugins));
320
	}
321
322
	/**
323
	 * @param string $message
324
	 * @param int    $level
325
	 */
326
	private function log(string $message, int $level = ILogger::DEBUG)
327
	{
328
		$this->logger->log($level, $message, [ 'app' => Application::APP_NAME ]);
329
	}
330
331
	/**
332
	 * @param string $title
333
	 * @param array  $newItems
334
	 * @param array  $oldItems
335
	 */
336
	private function logChanges(string $title, array $newItems, array $oldItems)
337
	{
338
		$addedItems = array_diff($newItems, $oldItems);
339
		foreach ($addedItems as $item) {
340
			$this->log(sprintf('Adding %s "%s"', $title, $item));
341
		}
342
343
		$updatedItems = array_intersect($newItems, $oldItems);
344
		foreach ($updatedItems as $item) {
345
			$this->log(sprintf('Replacing %s "%s"', $title, $item), ILogger::WARN);
346
		}
347
348
		$removedItems = array_diff($oldItems, $newItems);
349
		foreach ($removedItems as $item) {
350
			$this->log(sprintf('Removing %s "%s"', $title, $item), ILogger::WARN);
351
		}
352
	}
353
}
354