Completed
Push — master ( 485e22...5184f3 )
by Morris
15:17
created

ResourceLocator   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 171
Duplicated Lines 8.19 %

Coupling/Cohesion

Components 2
Dependencies 2

Importance

Changes 0
Metric Value
dl 14
loc 171
rs 10
c 0
b 0
f 0
wmc 25
lcom 2
cbo 2

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
doFind() 0 1 ?
doFindTheme() 0 1 ?
A appendIfExist() 0 7 2
B find() 0 20 6
C findWebRoot() 0 27 7
C append() 14 29 8
A getResources() 0 3 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Bart Visscher <[email protected]>
6
 * @author Joas Schilling <[email protected]>
7
 * @author Jörn Friedrich Dreyer <[email protected]>
8
 * @author Morris Jobke <[email protected]>
9
 * @author Robin McCorkell <[email protected]>
10
 *
11
 * @license AGPL-3.0
12
 *
13
 * This code is free software: you can redistribute it and/or modify
14
 * it under the terms of the GNU Affero General Public License, version 3,
15
 * as published by the Free Software Foundation.
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, version 3,
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
24
 *
25
 */
26
27
namespace OC\Template;
28
29
abstract class ResourceLocator {
30
	protected $theme;
31
32
	protected $mapping;
33
	protected $serverroot;
34
	protected $thirdpartyroot;
35
	protected $webroot;
36
37
	protected $resources = array();
38
39
	/** @var \OCP\ILogger */
40
	protected $logger;
41
42
	/**
43
	 * @param \OCP\ILogger $logger
44
	 * @param string $theme
45
	 * @param array $core_map
46
	 * @param array $party_map
47
	 */
48
	public function __construct(\OCP\ILogger $logger, $theme, $core_map, $party_map) {
49
		$this->logger = $logger;
50
		$this->theme = $theme;
51
		$this->mapping = $core_map + $party_map;
52
		$this->serverroot = key($core_map);
53
		$this->thirdpartyroot = key($party_map);
54
		$this->webroot = $this->mapping[$this->serverroot];
55
	}
56
57
	/**
58
	 * @param string $resource
59
	 */
60
	abstract public function doFind($resource);
61
62
	/**
63
	 * @param string $resource
64
	 */
65
	abstract public function doFindTheme($resource);
66
67
	/**
68
	 * Finds the resources and adds them to the list
69
	 *
70
	 * @param array $resources
71
	 */
72
	public function find($resources) {
73
		foreach ($resources as $resource) {
74
			try {
75
				$this->doFind($resource);
76
			} catch (ResourceNotFoundException $e) {
77
				$resourceApp = substr($resource, 0, strpos($resource, '/'));
78
				$this->logger->debug('Could not find resource file "' . $e->getResourcePath() . '"', ['app' => $resourceApp]);
79
			}
80
		}
81
		if (!empty($this->theme)) {
82
			foreach ($resources as $resource) {
83
				try {
84
					$this->doFindTheme($resource);
85
				} catch (ResourceNotFoundException $e) {
86
					$resourceApp = substr($resource, 0, strpos($resource, '/'));
87
					$this->logger->debug('Could not find resource file in theme "' . $e->getResourcePath() . '"', ['app' => $resourceApp]);
88
				}
89
			}
90
		}
91
	}
92
93
	/**
94
	 * append the $file resource if exist at $root
95
	 *
96
	 * @param string $root path to check
97
	 * @param string $file the filename
98
	 * @param string|null $webRoot base for path, default map $root to $webRoot
99
	 * @return bool True if the resource was found, false otherwise
100
	 */
101
	protected function appendIfExist($root, $file, $webRoot = null) {
102
		if (is_file($root.'/'.$file)) {
103
			$this->append($root, $file, $webRoot, false);
104
			return true;
105
		}
106
		return false;
107
	}
108
109
	/**
110
	 * Attempt to find the webRoot
111
	 *
112
	 * traverse the potential web roots upwards in the path
113
	 *
114
	 * example:
115
	 *   - root: /srv/www/apps/myapp
116
	 *   - available mappings: ['/srv/www']
117
	 *
118
	 * First we check if a mapping for /srv/www/apps/myapp is available,
119
	 * then /srv/www/apps, /srv/www/apps, /srv/www, ... until we find a
120
	 * valid web root
121
	 *
122
	 * @param string $root
123
	 * @return string|null The web root or null on failure
124
	 */
125
	protected function findWebRoot($root) {
126
		$webRoot = null;
127
		$tmpRoot = $root;
128
129
		while ($webRoot === null) {
130
			if (isset($this->mapping[$tmpRoot])) {
131
				$webRoot = $this->mapping[$tmpRoot];
132
				break;
133
			}
134
135
			if ($tmpRoot === '/') {
136
				break;
137
			}
138
139
			$tmpRoot = dirname($tmpRoot);
140
		}
141
142
		if (!$webRoot) {
143
			$realpath = realpath($root);
144
145
			if ($realpath && ($realpath !== $root)) {
146
				return $this->findWebRoot($realpath);
147
			}
148
		}
149
150
		return $webRoot;
151
	}
152
153
	/**
154
	 * append the $file resource at $root
155
	 *
156
	 * @param string $root path to check
157
	 * @param string $file the filename
158
	 * @param string|null $webRoot base for path, default map $root to $webRoot
159
	 * @param bool $throw Throw an exception, when the route does not exist
160
	 * @throws ResourceNotFoundException Only thrown when $throw is true and the resource is missing
161
	 */
162
	protected function append($root, $file, $webRoot = null, $throw = true) {
163
164
		if (!is_string($root)) {
165
			if ($throw) {
166
				throw new ResourceNotFoundException($file, $webRoot);
167
			}
168
			return;
169
		}
170
171 View Code Duplication
		if (!$webRoot) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $webRoot of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
172
			$webRoot = $this->findWebRoot($root);
173
174
			if (!$webRoot) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $webRoot of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
175
				$webRoot = '';
176
				$this->logger->error('ResourceLocator can not find a web root (root: {root}, file: {file}, webRoot: {webRoot}, throw: {throw})', [
177
					'app' => 'lib',
178
					'root' => $root,
179
					'file' => $file,
180
					'webRoot' => $webRoot,
181
					'throw' => $throw ? 'true' : 'false'
182
				]);
183
			}
184
		}
185
		$this->resources[] = array($root, $webRoot, $file);
186
187
		if ($throw && !is_file($root . '/' . $file)) {
188
			throw new ResourceNotFoundException($file, $webRoot);
189
		}
190
	}
191
192
	/**
193
	 * Returns the list of all resources that should be loaded
194
	 * @return array
195
	 */
196
	public function getResources() {
197
		return $this->resources;
198
	}
199
}
200