/joomla/libraries/gantry5/classes/Gantry/Component/Config/ConfigFileFinder.php

https://gitlab.com/ricardosanchez/prueba · PHP · 270 lines · 142 code · 33 blank · 95 comment · 10 complexity · d1bd20d8f4801913a527d4ba6087bf20 MD5 · raw file

  1. <?php
  2. /**
  3. * @package Gantry5
  4. * @author RocketTheme http://www.rockettheme.com
  5. * @copyright Copyright (C) 2007 - 2016 RocketTheme, LLC
  6. * @license Dual License: MIT or GNU/GPLv2 and later
  7. *
  8. * http://opensource.org/licenses/MIT
  9. * http://www.gnu.org/licenses/gpl-2.0.html
  10. *
  11. * Gantry Framework code that extends GPL code is considered GNU/GPLv2 and later
  12. */
  13. namespace Gantry\Component\Config;
  14. use Gantry\Component\Filesystem\Folder;
  15. /**
  16. * The Configuration & Blueprints Finder class.
  17. */
  18. class ConfigFileFinder
  19. {
  20. protected $base = '';
  21. /**
  22. * @param string $base
  23. * @return $this
  24. */
  25. public function setBase($base)
  26. {
  27. $this->base = $base ? "{$base}/" : '';
  28. return $this;
  29. }
  30. /**
  31. * Return all locations for all the files with a timestamp.
  32. *
  33. * @param array $paths List of folders to look from.
  34. * @param string $pattern Pattern to match the file. Pattern will also be removed from the key.
  35. * @param int $levels Maximum number of recursive directories.
  36. * @return array
  37. */
  38. public function locateFiles(array $paths, $pattern = '|\.yaml$|', $levels = -1)
  39. {
  40. $list = [];
  41. foreach ($paths as $folder) {
  42. $list += $this->detectRecursive($folder, $pattern, $levels);
  43. }
  44. return $list;
  45. }
  46. /**
  47. * Return all locations for all the files with a timestamp.
  48. *
  49. * @param array $paths List of folders to look from.
  50. * @param string $pattern Pattern to match the file. Pattern will also be removed from the key.
  51. * @param int $levels Maximum number of recursive directories.
  52. * @return array
  53. */
  54. public function getFiles(array $paths, $pattern = '|\.yaml$|', $levels = -1)
  55. {
  56. $list = [];
  57. foreach ($paths as $folder) {
  58. $path = trim(Folder::getRelativePath($folder), '/');
  59. $files = $this->detectRecursive($folder, $pattern, $levels);
  60. $list += $files[trim($path, '/')];
  61. }
  62. return $list;
  63. }
  64. /**
  65. * Return all paths for all the files with a timestamp.
  66. *
  67. * @param array $paths List of folders to look from.
  68. * @param string $pattern Pattern to match the file. Pattern will also be removed from the key.
  69. * @param int $levels Maximum number of recursive directories.
  70. * @return array
  71. */
  72. public function listFiles(array $paths, $pattern = '|\.yaml$|', $levels = -1)
  73. {
  74. $list = [];
  75. foreach ($paths as $folder) {
  76. $list = array_merge_recursive($list, $this->detectAll($folder, $pattern, $levels));
  77. }
  78. return $list;
  79. }
  80. /**
  81. * Find filename from a list of folders.
  82. *
  83. * Note: Only finds the last override.
  84. *
  85. * @param string $filename
  86. * @param array $folders
  87. * @return array
  88. */
  89. public function locateFileInFolder($filename, array $folders)
  90. {
  91. $list = [];
  92. foreach ($folders as $folder) {
  93. $list += $this->detectInFolder($folder, $filename);
  94. }
  95. return $list;
  96. }
  97. /**
  98. * Find filename from a list of folders.
  99. *
  100. * @param array $folders
  101. * @param string $filename
  102. * @return array
  103. */
  104. public function locateInFolders(array $folders, $filename = null)
  105. {
  106. $list = [];
  107. foreach ($folders as $folder) {
  108. $path = trim(Folder::getRelativePath($folder), '/');
  109. $list[$path] = $this->detectInFolder($folder, $filename);
  110. }
  111. return $list;
  112. }
  113. /**
  114. * Return all existing locations for a single file with a timestamp.
  115. *
  116. * @param array $paths Filesystem paths to look up from.
  117. * @param string $name Configuration file to be located.
  118. * @param string $ext File extension (optional, defaults to .yaml).
  119. * @return array
  120. */
  121. public function locateFile(array $paths, $name, $ext = '.yaml')
  122. {
  123. $filename = preg_replace('|[.\/]+|', '/', $name) . $ext;
  124. $list = [];
  125. foreach ($paths as $folder) {
  126. $path = trim(Folder::getRelativePath($folder), '/');
  127. if (is_file("{$folder}/{$filename}")) {
  128. $modified = filemtime("{$folder}/{$filename}");
  129. } else {
  130. $modified = 0;
  131. }
  132. $basename = $this->base . $name;
  133. $list[$path] = [$basename => ['file' => "{$path}/{$filename}", 'modified' => $modified]];
  134. }
  135. return $list;
  136. }
  137. /**
  138. * Detects all directories with a configuration file and returns them with last modification time.
  139. *
  140. * @param string $folder Location to look up from.
  141. * @param string $pattern Pattern to match the file. Pattern will also be removed from the key.
  142. * @param int $levels Maximum number of recursive directories.
  143. * @return array
  144. * @internal
  145. */
  146. protected function detectRecursive($folder, $pattern, $levels)
  147. {
  148. $path = trim(Folder::getRelativePath($folder), '/');
  149. if (is_dir($folder)) {
  150. // Find all system and user configuration files.
  151. $options = [
  152. 'levels' => $levels,
  153. 'compare' => 'Filename',
  154. 'pattern' => $pattern,
  155. 'filters' => [
  156. 'pre-key' => $this->base,
  157. 'key' => $pattern,
  158. 'value' => function (\RecursiveDirectoryIterator $file) use ($path) {
  159. return ['file' => "{$path}/{$file->getSubPathname()}", 'modified' => $file->getMTime()];
  160. }
  161. ],
  162. 'key' => 'SubPathname'
  163. ];
  164. $list = Folder::all($folder, $options);
  165. ksort($list);
  166. } else {
  167. $list = [];
  168. }
  169. return [$path => $list];
  170. }
  171. /**
  172. * Detects all directories with the lookup file and returns them with last modification time.
  173. *
  174. * @param string $folder Location to look up from.
  175. * @param string $lookup Filename to be located (defaults to directory name).
  176. * @return array
  177. * @internal
  178. */
  179. protected function detectInFolder($folder, $lookup = null)
  180. {
  181. $folder = rtrim($folder, '/');
  182. $path = trim(Folder::getRelativePath($folder), '/');
  183. $base = $path === $folder ? '' : ($path ? substr($folder, 0, -strlen($path)) : $folder . '/');
  184. $list = [];
  185. if (is_dir($folder)) {
  186. $iterator = new \DirectoryIterator($folder);
  187. /** @var \DirectoryIterator $directory */
  188. foreach ($iterator as $directory) {
  189. if (!$directory->isDir() || $directory->isDot()) {
  190. continue;
  191. }
  192. $name = $directory->getBasename();
  193. $find = ($lookup ?: $name) . '.yaml';
  194. $filename = "{$path}/{$name}/{$find}";
  195. if (file_exists($base . $filename)) {
  196. $basename = $this->base . $name;
  197. $list[$basename] = ['file' => $filename, 'modified' => filemtime($base . $filename)];
  198. }
  199. }
  200. }
  201. return $list;
  202. }
  203. /**
  204. * Detects all plugins with a configuration file and returns them with last modification time.
  205. *
  206. * @param string $folder Location to look up from.
  207. * @param string $pattern Pattern to match the file. Pattern will also be removed from the key.
  208. * @param int $levels Maximum number of recursive directories.
  209. * @return array
  210. * @internal
  211. */
  212. protected function detectAll($folder, $pattern, $levels)
  213. {
  214. $path = trim(Folder::getRelativePath($folder), '/');
  215. if (is_dir($folder)) {
  216. // Find all system and user configuration files.
  217. $options = [
  218. 'levels' => $levels,
  219. 'compare' => 'Filename',
  220. 'pattern' => $pattern,
  221. 'filters' => [
  222. 'pre-key' => $this->base,
  223. 'key' => $pattern,
  224. 'value' => function (\RecursiveDirectoryIterator $file) use ($path) {
  225. return ["{$path}/{$file->getSubPathname()}" => $file->getMTime()];
  226. }
  227. ],
  228. 'key' => 'SubPathname'
  229. ];
  230. $list = Folder::all($folder, $options);
  231. ksort($list);
  232. } else {
  233. $list = [];
  234. }
  235. return $list;
  236. }
  237. }