Passed
Push — master ( 41eab8...e6b4c7 )
by Maxence
08:18 queued 03:31
created

PicoService::generateConfig()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 9
rs 9.6666
cc 1
eloc 7
nc 1
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 Exception;
30
use HTMLPurifier;
31
use HTMLPurifier_Config;
32
use OC\App\AppManager;
33
use OCA\CMSPico\AppInfo\Application;
34
use OCA\CMSPico\Exceptions\AssetDoesNotExistException;
35
use OCA\CMSPico\Exceptions\PicoRuntimeException;
36
use OCA\CMSPico\Exceptions\PluginNextcloudNotLoadedException;
37
use OCA\CMSPico\Model\Website;
38
use OCP\Files;
0 ignored issues
show
Bug introduced by
The type OCP\Files was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
39
use OCP\Files\File;
0 ignored issues
show
Bug introduced by
The type OCP\Files\File was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
40
use OCP\Files\IRootFolder;
41
use Pico;
42
43
class PicoService {
44
45
	const DIR_CONFIG = 'Pico/config/';
46
	const DIR_PLUGINS = 'Pico/plugins/';
47
	const DIR_THEMES = 'Pico/themes/';
48
49
	const DIR_ASSETS = 'assets/';
50
51
	const NC_PLUGIN = 'Nextcloud';
52
53
	private $userId;
54
55
	/** @var AppManager */
56
	private $appManager;
57
58
	/** @var IRootFolder */
59
	private $rootFolder;
60
61
	/** @var ThemesService */
62
	private $themesService;
63
64
	/** @var MiscService */
65
	private $miscService;
66
67
	/**
68
	 * PicoService constructor.
69
	 *
70
	 * @param string $userId
71
	 * @param AppManager $appManager
72
	 * @param IRootFolder $rootFolder
73
	 * @param ThemesService $themesService
74
	 * @param MiscService $miscService
75
	 */
76
	function __construct(
77
		$userId, AppManager $appManager, IRootFolder $rootFolder, ThemesService $themesService,
78
		MiscService $miscService
79
	) {
80
		$this->userId = $userId;
81
		$this->appManager = $appManager;
82
		$this->rootFolder = $rootFolder;
83
		$this->themesService = $themesService;
84
		$this->miscService = $miscService;
85
	}
86
87
88
	/**
89
	 * getContent();
90
	 *
91
	 * @param Website $website
92
	 *
93
	 * @return string
94
	 */
95
	public function getContent(Website $website) {
96
97
		if (strpos($website->getPage(), self::DIR_ASSETS) === 0) {
98
			return $this->getContentFromAssets(
99
				$website, substr($website->getPage(), strlen(self::DIR_ASSETS))
100
			);
101
		} else {
102
			return $this->getContentFromPico($website);
103
		}
104
	}
105
106
107
	/**
108
	 * @param Website $website
109
	 * @param $asset
110
	 *
111
	 * @return string
112
	 * @throws AssetDoesNotExistException
113
	 */
114
	public function getContentFromAssets(Website $website, $asset) {
115
		$website->pathCantContainSpecificFolders($asset);
116
		$relativePath = $website->getPath() . self::DIR_ASSETS . $asset;
117
118
		try {
119
120
			$userFolder = $this->rootFolder->getUserFolder($website->getUserId());
121
122
			/** @var File $file */
123
			$file = $userFolder->get($relativePath);
124
125
			header('Content-type: ' . $file->getMimeType());
126
127
			return $file->getContent();
128
		} catch (Exception $e) {
129
			throw new AssetDoesNotExistException("404");
130
		}
131
	}
132
133
134
	/**
135
	 * getContentFromPico();
136
	 *
137
	 * main method that will create a Pico object, feed it with settings and get the content to be
138
	 * displayed.
139
	 * We check that the Nextcloud plugin is loaded, that the content location is a valid directory.
140
	 * In case of a private page, we check the viewer have a read access to the source files.
141
	 *
142
	 * @param Website $website
143
	 *
144
	 * @return string
145
	 * @throws PicoRuntimeException
146
	 */
147
	public function getContentFromPico(Website $website) {
148
149
		$appPath = MiscService::endSlash($this->appManager->getAppPath(Application::APP_NAME));
150
		$pico = new Pico(
151
			$website->getAbsolutePath(), $appPath . self::DIR_CONFIG,
152
			$appPath . self::DIR_PLUGINS, $appPath . self::DIR_THEMES
153
		);
154
155
		$this->generateConfig($pico, $website);
156
		try {
157
			$content = $pico->run();
158
		} catch (\Exception $e) {
159
			throw new PicoRuntimeException($e->getMessage());
160
		}
161
162
		$this->pluginNextcloudMustBeLoaded($pico);
163
		$absolutePath = $this->getAbsolutePathFromPico($pico);
164
		$website->contentMustBeLocal($absolutePath);
165
		$website->viewerMustHaveAccess($absolutePath, $pico->getFileMeta());
166
167
		return $content;
168
	}
169
170
171
	/**
172
	 * @param Pico $pico
173
	 * @param Website $website
174
	 */
175
	private function generateConfig(Pico &$pico, Website $website) {
176
		$this->themesService->hasToBeAValidTheme($website->getTheme());
177
		$pico->setConfig(
178
			[
179
				'content_dir' => 'content/',
180
				'content_ext' => '.md',
181
				'theme'       => $website->getTheme(),
182
				'site_title'  => $website->getName(),
183
				'base_url'    => \OC::$WEBROOT . '/index.php/apps/cms_pico/pico/' . $website->getSite()
184
			]
185
		);
186
	}
187
188
189
	/**
190
	 * @param Pico $pico ][p
191
	 *
192
	 * @return string
193
	 */
194
	private function getAbsolutePathFromPico(Pico $pico) {
195
		return $pico->getConfig()['content_dir'] . $pico->getCurrentPage()['id'] . '.md';
196
	}
197
198
199
	/**
200
	 * @param Pico $pico
201
	 *
202
	 * @throws PluginNextcloudNotLoadedException
203
	 */
204
	private function pluginNextcloudMustBeLoaded(Pico $pico) {
205
		try {
206
			$pico->getPlugin(self::NC_PLUGIN);
207
		} catch (Exception $e) {
208
			throw new PluginNextcloudNotLoadedException($e->getMessage());
209
		}
210
	}
211
}