Completed
Push — master ( ab4fd5...664d98 )
by Victor
20:52 queued 01:47
created

ThemeService::makeTheme()   C

Complexity

Conditions 7
Paths 8

Size

Total Lines 39
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 26
nc 8
nop 2
dl 0
loc 39
rs 6.7272
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Philipp Schaffrath <[email protected]>
4
 *
5
 * @copyright Copyright (c) 2018, ownCloud GmbH
6
 * @license AGPL-3.0
7
 *
8
 * This code is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License, version 3,
10
 * as published by the Free Software Foundation.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
 * GNU Affero General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License, version 3,
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
19
 */
20
namespace OC\Theme;
21
22
use OCP\Theme\IThemeService;
23
24
class ThemeService implements IThemeService {
25
26
	const DEFAULT_THEME_PATH = '/themes/default';
27
28
	/**
29
	 * @var Theme
30
	 */
31
	private $theme;
32
	
33
	/** @var string */
34
	private $serverRoot;
35
36
	/** @var string */
37
	private $defaultThemeDirectory;
38
39
	/**
40
	 * ThemeService constructor.
41
	 *
42
	 * @param string $themeName
43
	 * @param string $serverRoot
44
	 */
45
	public function __construct($themeName, $serverRoot) {
46
		$this->serverRoot = $serverRoot;
47
		$this->defaultThemeDirectory = $this->serverRoot . self::DEFAULT_THEME_PATH;
48
49
		if ($themeName === '' && $this->defaultThemeExists()) {
50
			$themeName = 'default';
51
		}
52
53
		$this->theme = $this->makeTheme($themeName, false);
54
	}
55
56
	/**
57
	 * @return bool
58
	 */
59
	public function defaultThemeExists() {
60
		return is_dir($this->defaultThemeDirectory);
61
	}
62
63
	/**
64
	 * @return Theme
65
	 */
66
	public function getTheme() {
67
		return $this->theme;
68
	}
69
70
	/**
71
	 * @param string $themeName
72
	 */
73
	public function setAppTheme($themeName = '') {
74
		$this->theme = $this->makeTheme($themeName, true);
75
	}
76
77
	/**
78
	 * @param string $themeName
79
	 * @param bool $appTheme
80
	 * @return Theme
81
	 */
82
	private function makeTheme($themeName, $appTheme = true) {
83
		$baseDirectory = $this->serverRoot;
84
		$directory = '';
85
		$webPath = '';
86
		if ($themeName !== '') {
87
			if ($appTheme) {
88
				$themeDirectory = \OC_App::getAppPath($themeName);
89
				// Use OC server root as a theme base directory if theme is located below it
90
				// Use path to an app root as a theme base directory otherwise
91
				// in any case theme directory is relative to theme base directory
92
				if (strpos($themeDirectory, $this->serverRoot)===0) {
93
					$directory = substr($themeDirectory, strlen($this->serverRoot) + 1);
94
				} else {
95
					foreach (\OC::$APPSROOTS as $appRoot) {
96
						if (strpos($themeDirectory, $appRoot['path'])===0) {
97
							$baseDirectory = $appRoot['path'];
98
							$directory = substr($themeDirectory, strlen($appRoot['path']) + 1);
99
						}
100
					}
101
				}
102
103
				$webPath = \OC_App::getAppWebPath($themeName);
104
			} else {
105
				$directory = 'themes/' . $themeName;
106
				$webPath = '/themes/' . $themeName;
107
			}
108
		}
109
110
		if (is_null($this->theme)) {
111
			$this->theme = new Theme($themeName, $directory, $webPath);
0 ignored issues
show
Security Bug introduced by
It seems like $webPath defined by \OC_App::getAppWebPath($themeName) on line 103 can also be of type false; however, OC\Theme\Theme::__construct() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
112
		} else {
113
			$this->theme->setName($themeName);
114
			$this->theme->setDirectory($directory);
115
			$this->theme->setWebPath($webPath);
0 ignored issues
show
Security Bug introduced by
It seems like $webPath defined by \OC_App::getAppWebPath($themeName) on line 103 can also be of type false; however, OC\Theme\Theme::setWebPath() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
116
		}
117
		$this->theme->setBaseDirectory($baseDirectory);
118
119
		return $this->theme;
120
	}
121
122
	/**
123
	 * @return Theme[]
124
	 */
125
	public function getAllThemes() {
126
		return array_merge($this->getAllAppThemes(), $this->getAllLegacyThemes());
127
	}
128
129
	/**
130
	 * @return Theme[]
131
	 */
132
	private function getAllAppThemes() {
133
		$themes = [];
134
		foreach (\OC::$server->getAppManager()->getAllApps() as $app) {
135
			if (\OC_App::isType($app, 'theme')) {
136
				$themes[$app] = $this->makeTheme($app);
137
			}
138
		}
139
		return $themes;
140
	}
141
142
	/**
143
	 * @return Theme[]
144
	 */
145
	private function getAllLegacyThemes() {
146
		$themes = [];
147
		if (is_dir($this->serverRoot . '/themes')) {
148
			if ($handle = opendir($this->serverRoot . '/themes')) {
149
				while (false !== ($entry = readdir($handle))) {
150
					if ($entry === '.' || $entry === '..') {
151
						continue;
152
					}
153
					if (is_dir($this->serverRoot . '/themes/' . $entry)) {
154
						$themes[$entry] = $this->makeTheme($entry, false);
155
					}
156
				}
157
				closedir($handle);
158
				return $themes;
159
			}
160
		}
161
		return $themes;
162
	}
163
164
	/**
165
	 * @param string $themeName
166
	 * @return Theme|false
167
	 */
168
	public function findTheme($themeName) {
169
		$allThemes = $this->getAllThemes();
170
		if (array_key_exists($themeName, $allThemes)) {
171
			return $allThemes[$themeName];
172
		}
173
		return false;
174
	}
175
}
176