URLGenerator.php 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Bart Visscher <bartv@thisnet.nl>
  6. * @author Felix Anand Epp <work@felixepp.de>
  7. * @author Joas Schilling <coding@schilljs.com>
  8. * @author Jörn Friedrich Dreyer <jfd@butonic.de>
  9. * @author Lukas Reschke <lukas@statuscode.ch>
  10. * @author mmccarn <mmccarn-github@mmsionline.us>
  11. * @author Morris Jobke <hey@morrisjobke.de>
  12. * @author Robin Appelman <robin@icewind.nl>
  13. * @author Robin McCorkell <robin@mccorkell.me.uk>
  14. * @author Thomas Müller <thomas.mueller@tmit.eu>
  15. * @author Thomas Tanghus <thomas@tanghus.net>
  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. namespace OC;
  33. use OCP\ICacheFactory;
  34. use OCP\IConfig;
  35. use OCP\IRequest;
  36. use OCP\IURLGenerator;
  37. use OCP\Route\IRoute;
  38. use RuntimeException;
  39. /**
  40. * Class to generate URLs
  41. */
  42. class URLGenerator implements IURLGenerator {
  43. /** @var IConfig */
  44. private $config;
  45. /** @var ICacheFactory */
  46. private $cacheFactory;
  47. /** @var IRequest */
  48. private $request;
  49. /**
  50. * @param IConfig $config
  51. * @param ICacheFactory $cacheFactory
  52. * @param IRequest $request
  53. */
  54. public function __construct(IConfig $config,
  55. ICacheFactory $cacheFactory,
  56. IRequest $request) {
  57. $this->config = $config;
  58. $this->cacheFactory = $cacheFactory;
  59. $this->request = $request;
  60. }
  61. /**
  62. * Creates an url using a defined route
  63. * @param string $route
  64. * @param array $parameters args with param=>value, will be appended to the returned url
  65. * @return string the url
  66. *
  67. * Returns a url to the given route.
  68. */
  69. public function linkToRoute($route, $parameters = array()) {
  70. // TODO: mock router
  71. $urlLinkTo = \OC::$server->getRouter()->generate($route, $parameters);
  72. return $urlLinkTo;
  73. }
  74. /**
  75. * Creates an absolute url using a defined route
  76. * @param string $routeName
  77. * @param array $arguments args with param=>value, will be appended to the returned url
  78. * @return string the url
  79. *
  80. * Returns an absolute url to the given route.
  81. */
  82. public function linkToRouteAbsolute($routeName, $arguments = array()) {
  83. return $this->getAbsoluteURL($this->linkToRoute($routeName, $arguments));
  84. }
  85. /**
  86. * Creates an url
  87. * @param string $app app
  88. * @param string $file file
  89. * @param array $args array with param=>value, will be appended to the returned url
  90. * The value of $args will be urlencoded
  91. * @return string the url
  92. *
  93. * Returns a url to the given app and file.
  94. */
  95. public function linkTo( $app, $file, $args = array() ) {
  96. $frontControllerActive = ($this->config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true');
  97. if( $app != '' ) {
  98. $app_path = \OC_App::getAppPath($app);
  99. // Check if the app is in the app folder
  100. if ($app_path && file_exists($app_path . '/' . $file)) {
  101. if (substr($file, -3) == 'php') {
  102. $urlLinkTo = \OC::$WEBROOT . '/index.php/apps/' . $app;
  103. if ($frontControllerActive) {
  104. $urlLinkTo = \OC::$WEBROOT . '/apps/' . $app;
  105. }
  106. $urlLinkTo .= ($file != 'index.php') ? '/' . $file : '';
  107. } else {
  108. $urlLinkTo = \OC_App::getAppWebPath($app) . '/' . $file;
  109. }
  110. } else {
  111. $urlLinkTo = \OC::$WEBROOT . '/' . $app . '/' . $file;
  112. }
  113. } else {
  114. if (file_exists(\OC::$SERVERROOT . '/core/' . $file)) {
  115. $urlLinkTo = \OC::$WEBROOT . '/core/' . $file;
  116. } else {
  117. if ($frontControllerActive && $file === 'index.php') {
  118. $urlLinkTo = \OC::$WEBROOT . '/';
  119. } else {
  120. $urlLinkTo = \OC::$WEBROOT . '/' . $file;
  121. }
  122. }
  123. }
  124. if ($args && $query = http_build_query($args, '', '&')) {
  125. $urlLinkTo .= '?' . $query;
  126. }
  127. return $urlLinkTo;
  128. }
  129. /**
  130. * Creates path to an image
  131. * @param string $app app
  132. * @param string $image image name
  133. * @throws \RuntimeException If the image does not exist
  134. * @return string the url
  135. *
  136. * Returns the path to the image.
  137. */
  138. public function imagePath($app, $image) {
  139. $cache = $this->cacheFactory->create('imagePath-'.md5($this->getBaseUrl()).'-');
  140. $cacheKey = $app.'-'.$image;
  141. if($key = $cache->get($cacheKey)) {
  142. return $key;
  143. }
  144. // Read the selected theme from the config file
  145. $theme = \OC_Util::getTheme();
  146. //if a theme has a png but not an svg always use the png
  147. $basename = substr(basename($image),0,-4);
  148. $appPath = \OC_App::getAppPath($app);
  149. // Check if the app is in the app folder
  150. $path = '';
  151. $themingEnabled = $this->config->getSystemValue('installed', false) && \OCP\App::isEnabled('theming') && \OC_App::isAppLoaded('theming');
  152. if($themingEnabled && $image === 'favicon.ico' && \OC::$server->getThemingDefaults()->shouldReplaceIcons()) {
  153. $cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
  154. if($app === '') { $app = 'core'; }
  155. $path = $this->linkToRoute('theming.Icon.getFavicon', [ 'app' => $app ]) . '?v='. $cacheBusterValue;
  156. } elseif($themingEnabled && $image === 'favicon-touch.png' && \OC::$server->getThemingDefaults()->shouldReplaceIcons()) {
  157. $cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
  158. if($app === '') { $app = 'core'; }
  159. $path = $this->linkToRoute('theming.Icon.getTouchIcon', [ 'app' => $app ]) . '?v='. $cacheBusterValue;
  160. } elseif($themingEnabled && $image === 'favicon-fb.png' && \OC::$server->getThemingDefaults()->shouldReplaceIcons()) {
  161. $cacheBusterValue = $this->config->getAppValue('theming', 'cachebuster', '0');
  162. if($app === '') { $app = 'core'; }
  163. $path = $this->linkToRoute('theming.Icon.getTouchIcon', [ 'app' => $app ]) . '?v='. $cacheBusterValue;
  164. } elseif (file_exists(\OC::$SERVERROOT . "/themes/$theme/apps/$app/img/$image")) {
  165. $path = \OC::$WEBROOT . "/themes/$theme/apps/$app/img/$image";
  166. } elseif (!file_exists(\OC::$SERVERROOT . "/themes/$theme/apps/$app/img/$basename.svg")
  167. && file_exists(\OC::$SERVERROOT . "/themes/$theme/apps/$app/img/$basename.png")) {
  168. $path = \OC::$WEBROOT . "/themes/$theme/apps/$app/img/$basename.png";
  169. } elseif (!empty($app) and file_exists(\OC::$SERVERROOT . "/themes/$theme/$app/img/$image")) {
  170. $path = \OC::$WEBROOT . "/themes/$theme/$app/img/$image";
  171. } elseif (!empty($app) and (!file_exists(\OC::$SERVERROOT . "/themes/$theme/$app/img/$basename.svg")
  172. && file_exists(\OC::$SERVERROOT . "/themes/$theme/$app/img/$basename.png"))) {
  173. $path = \OC::$WEBROOT . "/themes/$theme/$app/img/$basename.png";
  174. } elseif (file_exists(\OC::$SERVERROOT . "/themes/$theme/core/img/$image")) {
  175. $path = \OC::$WEBROOT . "/themes/$theme/core/img/$image";
  176. } elseif (!file_exists(\OC::$SERVERROOT . "/themes/$theme/core/img/$basename.svg")
  177. && file_exists(\OC::$SERVERROOT . "/themes/$theme/core/img/$basename.png")) {
  178. $path = \OC::$WEBROOT . "/themes/$theme/core/img/$basename.png";
  179. } elseif ($appPath && file_exists($appPath . "/img/$image")) {
  180. $path = \OC_App::getAppWebPath($app) . "/img/$image";
  181. } elseif ($appPath && !file_exists($appPath . "/img/$basename.svg")
  182. && file_exists($appPath . "/img/$basename.png")) {
  183. $path = \OC_App::getAppWebPath($app) . "/img/$basename.png";
  184. } elseif (!empty($app) and file_exists(\OC::$SERVERROOT . "/$app/img/$image")) {
  185. $path = \OC::$WEBROOT . "/$app/img/$image";
  186. } elseif (!empty($app) and (!file_exists(\OC::$SERVERROOT . "/$app/img/$basename.svg")
  187. && file_exists(\OC::$SERVERROOT . "/$app/img/$basename.png"))) {
  188. $path = \OC::$WEBROOT . "/$app/img/$basename.png";
  189. } elseif (file_exists(\OC::$SERVERROOT . "/core/img/$image")) {
  190. $path = \OC::$WEBROOT . "/core/img/$image";
  191. } elseif (!file_exists(\OC::$SERVERROOT . "/core/img/$basename.svg")
  192. && file_exists(\OC::$SERVERROOT . "/core/img/$basename.png")) {
  193. $path = \OC::$WEBROOT . "/themes/$theme/core/img/$basename.png";
  194. }
  195. if($path !== '') {
  196. $cache->set($cacheKey, $path);
  197. return $path;
  198. } else {
  199. throw new RuntimeException('image not found: image:' . $image . ' webroot:' . \OC::$WEBROOT . ' serverroot:' . \OC::$SERVERROOT);
  200. }
  201. }
  202. /**
  203. * Makes an URL absolute
  204. * @param string $url the url in the ownCloud host
  205. * @return string the absolute version of the url
  206. */
  207. public function getAbsoluteURL($url) {
  208. $separator = $url[0] === '/' ? '' : '/';
  209. if (\OC::$CLI && !defined('PHPUNIT_RUN')) {
  210. return rtrim($this->config->getSystemValue('overwrite.cli.url'), '/') . '/' . ltrim($url, '/');
  211. }
  212. // The ownCloud web root can already be prepended.
  213. if(substr($url, 0, strlen(\OC::$WEBROOT)) === \OC::$WEBROOT) {
  214. $url = substr($url, strlen(\OC::$WEBROOT));
  215. }
  216. return $this->getBaseUrl() . $separator . $url;
  217. }
  218. /**
  219. * @param string $key
  220. * @return string url to the online documentation
  221. */
  222. public function linkToDocs($key) {
  223. $theme = \OC::$server->getThemingDefaults();
  224. return $theme->buildDocLinkToKey($key);
  225. }
  226. /**
  227. * @return string base url of the current request
  228. */
  229. public function getBaseUrl() {
  230. return $this->request->getServerProtocol() . '://' . $this->request->getServerHost() . \OC::$WEBROOT;
  231. }
  232. }