PageRenderTime 23ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/intromagang/blog/system/src/Grav/Common/Config/ConfigFileFinder.php

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