Completed
Push — master ( 381850...a5ad6d )
by Jan-Christoph
16:02
created

URLGenerator::getBaseUrl()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Bart Visscher <[email protected]>
6
 * @author Felix Anand Epp <[email protected]>
7
 * @author Joas Schilling <[email protected]>
8
 * @author Jörn Friedrich Dreyer <[email protected]>
9
 * @author Lukas Reschke <[email protected]>
10
 * @author mmccarn <[email protected]>
11
 * @author Morris Jobke <[email protected]>
12
 * @author Robin Appelman <[email protected]>
13
 * @author Robin McCorkell <[email protected]>
14
 * @author Thomas Müller <[email protected]>
15
 * @author Thomas Tanghus <[email protected]>
16
 *
17
 * @license AGPL-3.0
18
 *
19
 * This code is free software: you can redistribute it and/or modify
20
 * it under the terms of the GNU Affero General Public License, version 3,
21
 * as published by the Free Software Foundation.
22
 *
23
 * This program is distributed in the hope that it will be useful,
24
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26
 * GNU Affero General Public License for more details.
27
 *
28
 * You should have received a copy of the GNU Affero General Public License, version 3,
29
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
30
 *
31
 */
32
33
namespace OC;
34
35
36
use OCP\ICacheFactory;
37
use OCP\IConfig;
38
use OCP\IRequest;
39
use OCP\IURLGenerator;
40
use OCP\Route\IRoute;
41
use RuntimeException;
42
43
/**
44
 * Class to generate URLs
45
 */
46
class URLGenerator implements IURLGenerator {
47
	/** @var IConfig */
48
	private $config;
49
	/** @var ICacheFactory */
50
	private $cacheFactory;
51
	/** @var IRequest */
52
	private $request;
53
54
	/**
55
	 * @param IConfig $config
56
	 * @param ICacheFactory $cacheFactory
57
	 * @param IRequest $request
58
	 */
59
	public function __construct(IConfig $config,
60
								ICacheFactory $cacheFactory,
61
								IRequest $request) {
62
		$this->config = $config;
63
		$this->cacheFactory = $cacheFactory;
64
		$this->request = $request;
65
	}
66
67
	/**
68
	 * Creates an url using a defined route
69
	 * @param string $route
70
	 * @param array $parameters args with param=>value, will be appended to the returned url
71
	 * @return string the url
72
	 *
73
	 * Returns a url to the given route.
74
	 */
75
	public function linkToRoute($route, $parameters = array()) {
76
		// TODO: mock router
77
		$urlLinkTo = \OC::$server->getRouter()->generate($route, $parameters);
0 ignored issues
show
Deprecated Code introduced by
The method OCP\Route\IRouter::generate() has been deprecated with message: 9.0.0

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
78
		return $urlLinkTo;
79
	}
80
81
	/**
82
	 * Creates an absolute url using a defined route
83
	 * @param string $routeName
84
	 * @param array $arguments args with param=>value, will be appended to the returned url
85
	 * @return string the url
86
	 *
87
	 * Returns an absolute url to the given route.
88
	 */
89
	public function linkToRouteAbsolute($routeName, $arguments = array()) {
90
		return $this->getAbsoluteURL($this->linkToRoute($routeName, $arguments));
91
	}
92
93
	/**
94
	 * Creates an url
95
	 * @param string $app app
96
	 * @param string $file file
97
	 * @param array $args array with param=>value, will be appended to the returned url
98
	 *    The value of $args will be urlencoded
99
	 * @return string the url
100
	 *
101
	 * Returns a url to the given app and file.
102
	 */
103
	public function linkTo( $app, $file, $args = array() ) {
104
		$frontControllerActive = ($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true');
105
106
		if( $app != '' ) {
107
			$app_path = \OC_App::getAppPath($app);
108
			// Check if the app is in the app folder
109
			if ($app_path && file_exists($app_path . '/' . $file)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $app_path of type false|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false 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...
110
				if (substr($file, -3) == 'php') {
111
112
					$urlLinkTo = \OC::$WEBROOT . '/index.php/apps/' . $app;
113
					if ($frontControllerActive) {
114
						$urlLinkTo = \OC::$WEBROOT . '/apps/' . $app;
115
					}
116
					$urlLinkTo .= ($file != 'index.php') ? '/' . $file : '';
117
				} else {
118
					$urlLinkTo = \OC_App::getAppWebPath($app) . '/' . $file;
119
				}
120
			} else {
121
				$urlLinkTo = \OC::$WEBROOT . '/' . $app . '/' . $file;
122
			}
123
		} else {
124
			if (file_exists(\OC::$SERVERROOT . '/core/' . $file)) {
125
				$urlLinkTo = \OC::$WEBROOT . '/core/' . $file;
126
			} else {
127
				if ($frontControllerActive && $file === 'index.php') {
128
					$urlLinkTo = \OC::$WEBROOT . '/';
129
				} else {
130
					$urlLinkTo = \OC::$WEBROOT . '/' . $file;
131
				}
132
			}
133
		}
134
135
		if ($args && $query = http_build_query($args, '', '&')) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $args of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
136
			$urlLinkTo .= '?' . $query;
137
		}
138
139
		return $urlLinkTo;
140
	}
141
142
	/**
143
	 * Creates path to an image
144
	 * @param string $app app
145
	 * @param string $image image name
146
	 * @throws \RuntimeException If the image does not exist
147
	 * @return string the url
148
	 *
149
	 * Returns the path to the image.
150
	 */
151
	public function imagePath($app, $image) {
152
		$cache = $this->cacheFactory->create('imagePath-'.md5($this->getBaseUrl()).'-');
153
		$cacheKey = $app.'-'.$image;
154
		if($key = $cache->get($cacheKey)) {
155
			return $key;
156
		}
157
158
		// Read the selected theme from the config file
159
		$theme = \OC_Util::getTheme();
160
161
		//if a theme has a png but not an svg always use the png
162
		$basename = substr(basename($image),0,-4);
163
164
		$appPath = \OC_App::getAppPath($app);
165
166
		// Check if the app is in the app folder
167
		$path = '';
168
		$themingEnabled = $this->config->getSystemValue('installed', false) && \OCP\App::isEnabled('theming') && \OC_App::isAppLoaded('theming');
169
		if($themingEnabled && $image === 'favicon.ico' && \OC::$server->getThemingDefaults()->shouldReplaceIcons()) {
170
			$cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
171
			if($app === '') { $app = 'core'; }
172
			$path = $this->linkToRoute('theming.Icon.getFavicon', [ 'app' => $app ]) . '?v='. $cacheBusterValue;
173
		} elseif($themingEnabled && $image === 'favicon-touch.png' && \OC::$server->getThemingDefaults()->shouldReplaceIcons()) {
174
			$cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
175
			if($app === '') { $app = 'core'; }
176
			$path = $this->linkToRoute('theming.Icon.getTouchIcon', [ 'app' => $app ]) . '?v='. $cacheBusterValue;
177
		} elseif($themingEnabled && $image === 'favicon-fb.png' && \OC::$server->getThemingDefaults()->shouldReplaceIcons()) {
178
			$cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
179
			if($app === '') { $app = 'core'; }
180
			$path = $this->linkToRoute('theming.Icon.getTouchIcon', [ 'app' => $app ]) . '?v='. $cacheBusterValue;
181
		} elseif (file_exists(\OC::$SERVERROOT . "/themes/$theme/apps/$app/img/$image")) {
182
			$path = \OC::$WEBROOT . "/themes/$theme/apps/$app/img/$image";
183
		} elseif (!file_exists(\OC::$SERVERROOT . "/themes/$theme/apps/$app/img/$basename.svg")
184
			&& file_exists(\OC::$SERVERROOT . "/themes/$theme/apps/$app/img/$basename.png")) {
185
			$path =  \OC::$WEBROOT . "/themes/$theme/apps/$app/img/$basename.png";
186
		} elseif (!empty($app) and file_exists(\OC::$SERVERROOT . "/themes/$theme/$app/img/$image")) {
187
			$path =  \OC::$WEBROOT . "/themes/$theme/$app/img/$image";
188 View Code Duplication
		} elseif (!empty($app) and (!file_exists(\OC::$SERVERROOT . "/themes/$theme/$app/img/$basename.svg")
189
			&& file_exists(\OC::$SERVERROOT . "/themes/$theme/$app/img/$basename.png"))) {
190
			$path =  \OC::$WEBROOT . "/themes/$theme/$app/img/$basename.png";
191
		} elseif (file_exists(\OC::$SERVERROOT . "/themes/$theme/core/img/$image")) {
192
			$path =  \OC::$WEBROOT . "/themes/$theme/core/img/$image";
193 View Code Duplication
		} elseif (!file_exists(\OC::$SERVERROOT . "/themes/$theme/core/img/$basename.svg")
194
			&& file_exists(\OC::$SERVERROOT . "/themes/$theme/core/img/$basename.png")) {
195
			$path =  \OC::$WEBROOT . "/themes/$theme/core/img/$basename.png";
196
		} elseif ($appPath && file_exists($appPath . "/img/$image")) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $appPath of type false|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false 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...
197
			$path =  \OC_App::getAppWebPath($app) . "/img/$image";
198
		} elseif ($appPath && !file_exists($appPath . "/img/$basename.svg")
0 ignored issues
show
Bug Best Practice introduced by
The expression $appPath of type false|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false 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...
199
			&& file_exists($appPath . "/img/$basename.png")) {
200
			$path =  \OC_App::getAppWebPath($app) . "/img/$basename.png";
201
		} elseif (!empty($app) and file_exists(\OC::$SERVERROOT . "/$app/img/$image")) {
202
			$path =  \OC::$WEBROOT . "/$app/img/$image";
203 View Code Duplication
		} elseif (!empty($app) and (!file_exists(\OC::$SERVERROOT . "/$app/img/$basename.svg")
204
				&& file_exists(\OC::$SERVERROOT . "/$app/img/$basename.png"))) {
205
			$path =  \OC::$WEBROOT . "/$app/img/$basename.png";
206
		} elseif (file_exists(\OC::$SERVERROOT . "/core/img/$image")) {
207
			$path =  \OC::$WEBROOT . "/core/img/$image";
208 View Code Duplication
		} elseif (!file_exists(\OC::$SERVERROOT . "/core/img/$basename.svg")
209
			&& file_exists(\OC::$SERVERROOT . "/core/img/$basename.png")) {
210
			$path =  \OC::$WEBROOT . "/themes/$theme/core/img/$basename.png";
211
		}
212
213
		if($path !== '') {
214
			$cache->set($cacheKey, $path);
215
			return $path;
216
		} else {
217
			throw new RuntimeException('image not found: image:' . $image . ' webroot:' . \OC::$WEBROOT . ' serverroot:' . \OC::$SERVERROOT);
218
		}
219
	}
220
221
222
	/**
223
	 * Makes an URL absolute
224
	 * @param string $url the url in the ownCloud host
225
	 * @return string the absolute version of the url
226
	 */
227
	public function getAbsoluteURL($url) {
228
		$separator = $url[0] === '/' ? '' : '/';
229
230
		if (\OC::$CLI && !defined('PHPUNIT_RUN')) {
231
			return rtrim($this->config->getSystemValue('overwrite.cli.url'), '/') . '/' . ltrim($url, '/');
232
		}
233
		// The ownCloud web root can already be prepended.
234
		if(substr($url, 0, strlen(\OC::$WEBROOT)) === \OC::$WEBROOT) {
235
			$url = substr($url, strlen(\OC::$WEBROOT));
236
		}
237
238
		return $this->getBaseUrl() . $separator . $url;
239
	}
240
241
	/**
242
	 * @param string $key
243
	 * @return string url to the online documentation
244
	 */
245
	public function linkToDocs($key) {
246
		$theme = \OC::$server->getThemingDefaults();
247
		return $theme->buildDocLinkToKey($key);
248
	}
249
250
	/**
251
	 * @return string base url of the current request
252
	 */
253
	public function getBaseUrl() {
254
		return $this->request->getServerProtocol() . '://' . $this->request->getServerHost() . \OC::$WEBROOT;
255
	}
256
}
257