Passed
Push — master ( c2190f...d26a14 )
by Maxence
02:26
created

PicoService::pluginNextcloudMustBeLoaded()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 5
rs 9.4285
cc 2
eloc 4
nc 1
nop 1
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;
33
use OC\App\AppManager;
34
use OCA\CMSPico\AppInfo\Application;
35
use OCA\CMSPico\Exceptions\AssetDoesNotExistException;
36
use OCA\CMSPico\Exceptions\PicoRuntimeException;
37
use OCA\CMSPico\Exceptions\PluginNextcloudNotLoadedException;
38
use OCA\CMSPico\Exceptions\WebsiteIsPrivateException;
39
use OCA\CMSPico\Model\Website;
40
use OCA\CMSPico\Pico;
41
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...
42
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...
43
use OCP\Files\IRootFolder;
44
45
class PicoService {
46
47
	const DIR_CONFIG = 'Pico/config/';
48
	const DIR_PLUGINS = 'Pico/plugins/';
49
	const DIR_THEMES = 'Pico/themes/';
50
51
	const DIR_ASSETS = 'assets/';
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
	 * @throws WebsiteIsPrivateException
114
	 */
115
	public function getContentFromAssets(Website $website, $asset) {
116
		$website->pathCantContainSpecificFolders($asset);
117
118
		try {
119
			$website->viewerMustHaveAccess(self::DIR_ASSETS . $asset);
120
			$userFolder = $this->rootFolder->getUserFolder($website->getUserId());
121
122
			/** @var File $file */
123
			$file = $userFolder->get($website->getPath() . self::DIR_ASSETS . $asset);
124
			$content = $file->getContent();
125
126
			header('Content-type: ' . $file->getMimeType());
127
128
			return $content;
129
		} catch (WebsiteIsPrivateException $e) {
130
			throw $e;
131
		} catch (Exception $e) {
132
			throw new AssetDoesNotExistException("404");
133
		}
134
	}
135
136
137
	/**
138
	 * getContentFromPico();
139
	 *
140
	 * main method that will create a Pico object, feed it with settings and get the content to be
141
	 * displayed.
142
	 * We check that the Nextcloud plugin is loaded, that the content location is a valid directory.
143
	 * In case of a private page, we check the viewer have a read access to the source files.
144
	 *
145
	 * @param Website $website
146
	 *
147
	 * @return string
148
	 * @throws PicoRuntimeException
149
	 */
150
	public function getContentFromPico(Website $website) {
151
152
		$appPath = MiscService::endSlash($this->appManager->getAppPath(Application::APP_NAME));
153
		$pico = new Pico(
154
			$website->getAbsolutePath(),
155
			$appPath . self::DIR_CONFIG,
156
			$appPath . self::DIR_PLUGINS,
157
			$appPath . self::DIR_THEMES
158
		);
159
160
		$this->generateConfig($pico, $website);
161
		try {
162
			$content = $pico->run();
163
		} catch (Exception $e) {
164
			throw new PicoRuntimeException($e->getMessage());
165
		}
166
167
		$absolutePath = $this->getAbsolutePathFromPico($pico);
168
		$website->contentMustBeLocal($absolutePath);
169
170
		$website->viewerMustHaveAccess($website->getRelativePath($absolutePath), $pico->getFileMeta());
171
172
		return $content;
173
	}
174
175
176
	/**
177
	 * @param Pico $pico
178
	 * @param Website $website
179
	 */
180
	private function generateConfig(Pico $pico, Website $website) {
181
		$appBaseUrl = OC::$WEBROOT . '/index.php/apps/' . Application::APP_NAME;
182
		$this->themesService->hasToBeAValidTheme($website->getTheme());
183
184
		$pico->setConfig(
185
			[
186
				'site_title'     => $website->getName(),
187
				'base_url'       => $appBaseUrl . '/pico/' . $website->getSite(),
188
				'theme'          => $website->getTheme(),
189
				'content_dir'    => 'content/',
190
				'content_ext'    => '.md',
191
				'nextcloud_site' => $website->getSite()
192
			]
193
		);
194
	}
195
196
197
	/**
198
	 * @param Pico $pico
199
	 *
200
	 * @return string
201
	 */
202
	private function getAbsolutePathFromPico(Pico $pico) {
203
		return $pico->getRequestFile() ?: '';
204
	}
205
}
206