You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

202 lines
5.4 KiB

3 years ago
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Bart Visscher <bartv@thisnet.nl>
  6. * @author Christoph Wurst <christoph@winzerhof-wurst.at>
  7. * @author Joas Schilling <coding@schilljs.com>
  8. * @author John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
  9. * @author Jörn Friedrich Dreyer <jfd@butonic.de>
  10. * @author Morris Jobke <hey@morrisjobke.de>
  11. * @author Robin Appelman <robin@icewind.nl>
  12. * @author Robin McCorkell <robin@mccorkell.me.uk>
  13. * @author tux-rampage <tux-rampage@users.noreply.github.com>
  14. *
  15. * @license AGPL-3.0
  16. *
  17. * This code is free software: you can redistribute it and/or modify
  18. * it under the terms of the GNU Affero General Public License, version 3,
  19. * as published by the Free Software Foundation.
  20. *
  21. * This program is distributed in the hope that it will be useful,
  22. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24. * GNU Affero General Public License for more details.
  25. *
  26. * You should have received a copy of the GNU Affero General Public License, version 3,
  27. * along with this program. If not, see <http://www.gnu.org/licenses/>
  28. *
  29. */
  30. namespace OC\Template;
  31. abstract class ResourceLocator {
  32. protected $theme;
  33. protected $mapping;
  34. protected $serverroot;
  35. protected $thirdpartyroot;
  36. protected $webroot;
  37. protected $resources = [];
  38. /** @var \OCP\ILogger */
  39. protected $logger;
  40. /**
  41. * @param \OCP\ILogger $logger
  42. * @param string $theme
  43. * @param array $core_map
  44. * @param array $party_map
  45. */
  46. public function __construct(\OCP\ILogger $logger, $theme, $core_map, $party_map) {
  47. $this->logger = $logger;
  48. $this->theme = $theme;
  49. $this->mapping = $core_map + $party_map;
  50. $this->serverroot = key($core_map);
  51. $this->thirdpartyroot = key($party_map);
  52. $this->webroot = $this->mapping[$this->serverroot];
  53. }
  54. /**
  55. * @param string $resource
  56. */
  57. abstract public function doFind($resource);
  58. /**
  59. * @param string $resource
  60. */
  61. abstract public function doFindTheme($resource);
  62. /**
  63. * Finds the resources and adds them to the list
  64. *
  65. * @param array $resources
  66. */
  67. public function find($resources) {
  68. foreach ($resources as $resource) {
  69. try {
  70. $this->doFind($resource);
  71. } catch (ResourceNotFoundException $e) {
  72. $resourceApp = substr($resource, 0, strpos($resource, '/'));
  73. $this->logger->debug('Could not find resource file "' . $e->getResourcePath() . '"', ['app' => $resourceApp]);
  74. }
  75. }
  76. if (!empty($this->theme)) {
  77. foreach ($resources as $resource) {
  78. try {
  79. $this->doFindTheme($resource);
  80. } catch (ResourceNotFoundException $e) {
  81. $resourceApp = substr($resource, 0, strpos($resource, '/'));
  82. $this->logger->debug('Could not find resource file in theme "' . $e->getResourcePath() . '"', ['app' => $resourceApp]);
  83. }
  84. }
  85. }
  86. }
  87. /**
  88. * append the $file resource if exist at $root
  89. *
  90. * @param string $root path to check
  91. * @param string $file the filename
  92. * @param string|null $webRoot base for path, default map $root to $webRoot
  93. * @return bool True if the resource was found, false otherwise
  94. */
  95. protected function appendIfExist($root, $file, $webRoot = null) {
  96. if (is_file($root.'/'.$file)) {
  97. $this->append($root, $file, $webRoot, false);
  98. return true;
  99. }
  100. return false;
  101. }
  102. /**
  103. * Attempt to find the webRoot
  104. *
  105. * traverse the potential web roots upwards in the path
  106. *
  107. * example:
  108. * - root: /srv/www/apps/myapp
  109. * - available mappings: ['/srv/www']
  110. *
  111. * First we check if a mapping for /srv/www/apps/myapp is available,
  112. * then /srv/www/apps, /srv/www/apps, /srv/www, ... until we find a
  113. * valid web root
  114. *
  115. * @param string $root
  116. * @return string|null The web root or null on failure
  117. */
  118. protected function findWebRoot($root) {
  119. $webRoot = null;
  120. $tmpRoot = $root;
  121. while ($webRoot === null) {
  122. if (isset($this->mapping[$tmpRoot])) {
  123. $webRoot = $this->mapping[$tmpRoot];
  124. break;
  125. }
  126. if ($tmpRoot === '/') {
  127. break;
  128. }
  129. $tmpRoot = dirname($tmpRoot);
  130. }
  131. if ($webRoot === null) {
  132. $realpath = realpath($root);
  133. if ($realpath && ($realpath !== $root)) {
  134. return $this->findWebRoot($realpath);
  135. }
  136. }
  137. return $webRoot;
  138. }
  139. /**
  140. * append the $file resource at $root
  141. *
  142. * @param string $root path to check
  143. * @param string $file the filename
  144. * @param string|null $webRoot base for path, default map $root to $webRoot
  145. * @param bool $throw Throw an exception, when the route does not exist
  146. * @throws ResourceNotFoundException Only thrown when $throw is true and the resource is missing
  147. */
  148. protected function append($root, $file, $webRoot = null, $throw = true) {
  149. if (!is_string($root)) {
  150. if ($throw) {
  151. throw new ResourceNotFoundException($file, $webRoot);
  152. }
  153. return;
  154. }
  155. if (!$webRoot) {
  156. $webRoot = $this->findWebRoot($root);
  157. if ($webRoot === null) {
  158. $webRoot = '';
  159. $this->logger->error('ResourceLocator can not find a web root (root: {root}, file: {file}, webRoot: {webRoot}, throw: {throw})', [
  160. 'app' => 'lib',
  161. 'root' => $root,
  162. 'file' => $file,
  163. 'webRoot' => $webRoot,
  164. 'throw' => $throw ? 'true' : 'false'
  165. ]);
  166. }
  167. }
  168. $this->resources[] = [$root, $webRoot, $file];
  169. if ($throw && !is_file($root . '/' . $file)) {
  170. throw new ResourceNotFoundException($file, $webRoot);
  171. }
  172. }
  173. /**
  174. * Returns the list of all resources that should be loaded
  175. * @return array
  176. */
  177. public function getResources() {
  178. return $this->resources;
  179. }
  180. }