Passed
Push — master ( b25e8a...7609fe )
by Maxence
07:16
created

TemplatesService::generateFile()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 13
rs 9.4285
cc 3
eloc 9
nc 2
nop 2
1
<?php
2
/**
3
 * CMS Pico - Integration of Pico within your files to create websites.
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Maxence Lange <[email protected]>
9
 * @copyright 2017
10
 * @license GNU AGPL version 3 or any later version
11
 *
12
 * This program is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License as
14
 * published by the Free Software Foundation, either version 3 of the
15
 * License, or (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24
 *
25
 */
26
27
namespace OCA\CMSPico\Service;
28
29
use DirectoryIterator;
30
use Exception;
31
use OCA\CMSPico\Exceptions\TemplateDoesNotExistException;
32
use OCA\CMSPico\Exceptions\WriteAccessException;
33
use OCA\CMSPico\Model\TemplateFile;
34
use OCA\CMSPico\Model\Website;
35
use OCP\Files\Folder;
36
use OCP\IL10N;
37
38
class TemplatesService {
39
40
	const TEMPLATES = ['sample_pico', 'empty'];
41
	const TEMPLATE_DIR = __DIR__ . '/../../Pico/templates/';
42
43
	/** @var IL10N */
44
	private $l10n;
45
46
	/** @var ConfigService */
47
	private $configService;
48
49
	/** @var MiscService */
50
	private $miscService;
51
52
	/** @var Folder */
53
	private $websiteFolder;
54
55
	/**
56
	 * TemplatesService constructor.
57
	 *
58
	 * @param IL10N $l10n
59
	 * @param ConfigService $configService
60
	 * @param MiscService $miscService
61
	 */
62
	function __construct(IL10N $l10n, ConfigService $configService, MiscService $miscService) {
63
		$this->l10n = $l10n;
64
		$this->configService = $configService;
65
		$this->miscService = $miscService;
66
	}
67
68
69
	/**
70
	 * check if template exist.
71
	 *
72
	 * @param string $template
73
	 *
74
	 * @throws TemplateDoesNotExistException
75
	 */
76
	public function templateHasToExist($template) {
77
		if (!in_array($template, $this->getTemplatesList())) {
78
			throw new TemplateDoesNotExistException($this->l10n->t('Template does not exist'));
79
		}
80
	}
81
82
83
	/**
84
	 * returns all templates available to users.
85
	 *
86
	 * @param bool $customOnly
87
	 *
88
	 * @return array
89
	 */
90 View Code Duplication
	public function getTemplatesList($customOnly = false) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
91
		$templates = [];
92
		if ($customOnly !== true) {
93
			$templates = self::TEMPLATES;
94
		}
95
96
		$customs = json_decode($this->configService->getAppValue(ConfigService::CUSTOM_TEMPLATES), true);
97
		if ($customs !== null) {
98
			$templates = array_merge($templates, $customs);
99
		}
100
101
		return $templates;
102
	}
103
104
105
	/**
106
	 * returns theme from the Pico/templates/ dir that are not available yet to users.
107
	 *
108
	 * @return array
109
	 */
110
	public function getNewTemplatesList() {
111
112
		$newTemplates = [];
113
		$currTemplates = $this->getTemplatesList();
114
		$allTemplates = $this->getDirectoriesFromTemplatesDir();
115
		foreach ($allTemplates as $template) {
116
			if (!in_array($template, $currTemplates)) {
117
				$newTemplates[] = $template;
118
			}
119
		}
120
121
		return $newTemplates;
122
	}
123
124
125
	/**
126
	 * returns custom templates from Pico/templates/
127
	 *
128
	 * @return array
129
	 */
130 View Code Duplication
	private function getDirectoriesFromTemplatesDir() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
131
132
		$allTemplates = [];
133
		foreach (new DirectoryIterator(self::TEMPLATE_DIR) as $file) {
134
135
			if (!$file->isDir() || substr($file->getFilename(), 0, 1) === '.') {
136
				continue;
137
			}
138
139
			$allTemplates[] = $file->getFilename();
140
		}
141
142
		return $allTemplates;
143
	}
144
145
146
	/**
147
	 * Install templates into a new website.
148
	 * Templates will be parsed and formatted in the process.
149
	 *
150
	 * @param Website $website
151
	 */
152
	public function installTemplates(Website $website) {
153
154
		$files = $this->getSourceFiles(self::TEMPLATE_DIR . $website->getTemplateSource() . '/');
155
156
		$this->initWebsiteFolder($website);
157
		$data = $this->generateData($website);
158
		foreach ($files as $file) {
159
			$file->applyData($data);
160
			$this->generateFile($file, $website);
161
		}
162
	}
163
164
165
	/**
166
	 * @param string $base
167
	 * @param string $dir
168
	 *
169
	 * @return TemplateFile[]
170
	 */
171
	private function getSourceFiles($base, $dir = '') {
172
173
		$base = MiscService::endSlash($base);
174
		$dir = MiscService::endSlash($dir);
175
176
		$files = [];
177
		foreach (new DirectoryIterator($base . $dir) as $file) {
178
179
			if (substr($file->getFilename(), 0, 1) === '.') {
180
				continue;
181
			}
182
183
			if ($file->isDir()) {
184
				$files = array_merge($files, $this->getSourceFiles($base, $dir . $file->getFilename()));
185
				continue;
186
			}
187
188
			$files[] = new TemplateFile($base, $dir . $file->getFilename());
189
		}
190
191
		return $files;
192
	}
193
194
195
	/**
196
	 * @param TemplateFile $file
197
	 * @param Website $website
198
	 *
199
	 * @throws WriteAccessException
200
	 */
201
	private function generateFile(TemplateFile $file, Website $website) {
202
		try {
203
			$this->initFolder(pathinfo($website->getPath() . $file->getFilename(), PATHINFO_DIRNAME));
204
205
			if (substr($file->getFilename(), -5) === 'empty') {
206
				return;
207
			}
208
209
			$new = $this->websiteFolder->newFile($website->getPath() . $file->getFilename());
210
			$new->putContent($file->getContent());
211
		} catch (Exception $e) {
212
			throw new WriteAccessException(
213
				$this->l10n->t('Cannot generate template file in this folder')
214
			);
215
		}
216
217
	}
218
219
220
	/**
221
	 * @param Website $website
222
	 */
223
	private function initWebsiteFolder(Website $website) {
224
		$this->websiteFolder = \OC::$server->getUserFolder($website->getUserId());
225
		$this->initFolder($website->getPath());
226
	}
227
228
229
	/**
230
	 * @param Website $website
231
	 *
232
	 * @return array
233
	 */
234
	private function generateData(Website $website) {
235
		return [
236
			'site_title' => $website->getName(),
237
			'base_url'   => \OC::$WEBROOT . $website->getSite()
238
		];
239
	}
240
241
242
	/**
243
	 * @param $path
244
	 */
245
	private function initFolder($path) {
246
247
		if (!$this->websiteFolder->nodeExists($path)) {
248
			$this->websiteFolder->newFolder($path);
249
		}
250
	}
251
252
253
}