PageRenderTime 82ms CodeModel.GetById 31ms RepoModel.GetById 3ms app.codeStats 0ms

/htdocs/symfony/2.0.0pr2/src/vendor/symfony/src/Symfony/Components/Finder/Finder.php

http://github.com/pmjones/php-framework-benchmarks
PHP | 389 lines | 150 code | 52 blank | 187 comment | 15 complexity | c54aa61dcc22c3b19a0d87138cd6f47c MD5 | raw file
Possible License(s): LGPL-3.0, Apache-2.0, BSD-3-Clause, ISC, AGPL-3.0, LGPL-2.1
  1. <?php
  2. namespace Symfony\Components\Finder;
  3. /*
  4. * This file is part of the Symfony framework.
  5. *
  6. * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
  7. *
  8. * This source file is subject to the MIT license that is bundled
  9. * with this source code in the file LICENSE.
  10. */
  11. /**
  12. * Finder allows to build rules to find files and directories.
  13. *
  14. * It is a thin wrapper around several specialized iterator classes.
  15. *
  16. * All rules may be invoked several times.
  17. *
  18. * All methods return the current Finder object to allow easy chaining:
  19. *
  20. * $finder = new Finder();
  21. * $finder = $finder->files()->name('*.php')->in(__DIR__);
  22. *
  23. * @package Symfony
  24. * @subpackage Components_Finder
  25. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  26. */
  27. class Finder implements \IteratorAggregate
  28. {
  29. protected $mode = 0;
  30. protected $names = array();
  31. protected $notNames = array();
  32. protected $exclude = array();
  33. protected $filters = array();
  34. protected $depths = array();
  35. protected $sizes = array();
  36. protected $followLinks = false;
  37. protected $sort = false;
  38. protected $ignoreVCS = true;
  39. protected $dirs = array();
  40. protected $dates = array();
  41. /**
  42. * Restricts the matching to directories only.
  43. *
  44. * @return Symfony\Components\Finder The current Finder instance
  45. */
  46. public function directories()
  47. {
  48. $this->mode = Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES;
  49. return $this;
  50. }
  51. /**
  52. * Restricts the matching to files only.
  53. *
  54. * @return Symfony\Components\Finder The current Finder instance
  55. */
  56. public function files()
  57. {
  58. $this->mode = Iterator\FileTypeFilterIterator::ONLY_FILES;
  59. return $this;
  60. }
  61. /**
  62. * Adds tests for the directory depth.
  63. *
  64. * Usage:
  65. *
  66. * $finder->depth('> 1') // the Finder will start matching at level 1.
  67. * $finder->depth('< 3') // the Finder will descend at most 3 levels of directories below the starting point.
  68. *
  69. * @param int $level The depth level expression
  70. *
  71. * @return Symfony\Components\Finder The current Finder instance
  72. *
  73. * @see Symfony\Components\Finder\Iterator\DepthRangeFilterIterator
  74. * @see Symfony\Components\Finder\Comparator\NumberComparator
  75. */
  76. public function depth($level)
  77. {
  78. $this->depths[] = new Comparator\NumberComparator($level);
  79. return $this;
  80. }
  81. /**
  82. * Adds tests for file dates (last modified).
  83. *
  84. * The date must be something that strtotime() is able to parse:
  85. *
  86. * $finder->date('since yesterday');
  87. * $finder->date('until 2 days ago');
  88. * $finder->date('> now - 2 hours');
  89. * $finder->date('>= 2005-10-15');
  90. *
  91. * @param string $date A date rage string
  92. *
  93. * @return Symfony\Components\Finder The current Finder instance
  94. *
  95. * @see strtotime
  96. * @see Symfony\Components\Finder\Iterator\DateRangeFilterIterator
  97. * @see Symfony\Components\Finder\Comparator\DateComparator
  98. */
  99. public function date($date)
  100. {
  101. $this->dates[] = new Comparator\DateComparator($date);
  102. return $this;
  103. }
  104. /**
  105. * Adds rules that files must match.
  106. *
  107. * You can use patterns (delimited with / sign), globs or simple strings.
  108. *
  109. * $finder->name('*.php')
  110. * $finder->name('/\.php$/') // same as above
  111. * $finder->name('test.php')
  112. *
  113. * @param string $pattern A pattern (a regexp, a glob, or a string)
  114. *
  115. * @return Symfony\Components\Finder The current Finder instance
  116. *
  117. * @see Symfony\Components\Finder\Iterator\FilenameFilterIterator
  118. */
  119. public function name($pattern)
  120. {
  121. $this->names[] = $pattern;
  122. return $this;
  123. }
  124. /**
  125. * Adds rules that files must not match.
  126. *
  127. * @param string $pattern A pattern (a regexp, a glob, or a string)
  128. *
  129. * @return Symfony\Components\Finder The current Finder instance
  130. *
  131. * @see Symfony\Components\Finder\Iterator\FilenameFilterIterator
  132. */
  133. public function notName($pattern)
  134. {
  135. $this->notNames[] = $pattern;
  136. return $this;
  137. }
  138. /**
  139. * Adds tests for file sizes.
  140. *
  141. * $finder->size('> 10K');
  142. * $finder->size('<= 1Ki');
  143. * $finder->size(4);
  144. *
  145. * @param string $size A size range string
  146. *
  147. * @return Symfony\Components\Finder The current Finder instance
  148. *
  149. * @see Symfony\Components\Finder\Iterator\SizeRangeFilterIterator
  150. * @see Symfony\Components\Finder\Comparator\NumberComparator
  151. */
  152. public function size($size)
  153. {
  154. $this->sizes[] = new Comparator\NumberComparator($size);
  155. return $this;
  156. }
  157. /**
  158. * Excludes directories.
  159. *
  160. * @param string $dir A directory to exclude
  161. *
  162. * @return Symfony\Components\Finder The current Finder instance
  163. *
  164. * @see Symfony\Components\Finder\Iterator\ExcludeDirectoryFilterIterator
  165. */
  166. public function exclude($dir)
  167. {
  168. $this->exclude[] = $dir;
  169. return $this;
  170. }
  171. /**
  172. * Forces the finder to ignore version control directories.
  173. *
  174. * @return Symfony\Components\Finder The current Finder instance
  175. *
  176. * @see Symfony\Components\Finder\Iterator\IgnoreVcsFilterIterator
  177. */
  178. public function ignoreVCS($ignoreVCS)
  179. {
  180. $this->ignoreVCS = (Boolean) $ignoreVCS;
  181. return $this;
  182. }
  183. /**
  184. * Sorts files and directories by an anonymous function.
  185. *
  186. * The anonymous function receives two \SplFileInfo instances to compare.
  187. *
  188. * This can be slow as all the matching files and directories must be retrieved for comparison.
  189. *
  190. * @param Closure $closure An anonymous function
  191. *
  192. * @return Symfony\Components\Finder The current Finder instance
  193. *
  194. * @see Symfony\Components\Finder\Iterator\SortableIterator
  195. */
  196. public function sort(\Closure $closure)
  197. {
  198. $this->sort = $closure;
  199. return $this;
  200. }
  201. /**
  202. * Sorts files and directories by name.
  203. *
  204. * This can be slow as all the matching files and directories must be retrieved for comparison.
  205. *
  206. * @return Symfony\Components\Finder The current Finder instance
  207. *
  208. * @see Symfony\Components\Finder\Iterator\SortableIterator
  209. */
  210. public function sortByName()
  211. {
  212. $this->sort = Iterator\SortableIterator::SORT_BY_NAME;
  213. return $this;
  214. }
  215. /**
  216. * Sorts files and directories by type (directories before files), then by name.
  217. *
  218. * This can be slow as all the matching files and directories must be retrieved for comparison.
  219. *
  220. * @return Symfony\Components\Finder The current Finder instance
  221. *
  222. * @see Symfony\Components\Finder\Iterator\SortableIterator
  223. */
  224. public function sortByType()
  225. {
  226. $this->sort = Iterator\SortableIterator::SORT_BY_TYPE;
  227. return $this;
  228. }
  229. /**
  230. * Filters the iterator with an anonymous function.
  231. *
  232. * The anonymous function receives a \SplFileInfo and must return false
  233. * to remove files.
  234. *
  235. * @param Closure $closure An anonymous function
  236. *
  237. * @return Symfony\Components\Finder The current Finder instance
  238. *
  239. * @see Symfony\Components\Finder\Iterator\CustomFilterIterator
  240. */
  241. public function filter(\Closure $closure)
  242. {
  243. $this->filters[] = $closure;
  244. return $this;
  245. }
  246. /**
  247. * Forces the following of symlinks.
  248. *
  249. * @return Symfony\Components\Finder The current Finder instance
  250. */
  251. public function followLinks()
  252. {
  253. $this->followLinks = true;
  254. return $this;
  255. }
  256. /**
  257. * Searches files and directories which match defined rules.
  258. *
  259. * @param string|array $dirs A directory path or an array of directories
  260. *
  261. * @return Symfony\Components\Finder The current Finder instance
  262. *
  263. * @throws \InvalidArgumentException if one of the directory does not exist
  264. */
  265. public function in($dirs)
  266. {
  267. if (!is_array($dirs)) {
  268. $dirs = array($dirs);
  269. }
  270. foreach ($dirs as $dir) {
  271. if (!is_dir($dir)) {
  272. throw new \InvalidArgumentException(sprintf('The "%s" directory does not exist.', $dir));
  273. }
  274. }
  275. $this->dirs = array_merge($this->dirs, $dirs);
  276. return $this;
  277. }
  278. /**
  279. * Returns an Iterator for the current Finder configuration.
  280. *
  281. * This method implements the IteratorAggregate interface.
  282. *
  283. * @return \Iterator An iterator
  284. *
  285. * @throws \LogicException if the in() method has not been called
  286. */
  287. public function getIterator()
  288. {
  289. if (0 === count($this->dirs)) {
  290. throw new \LogicException('You must call the in() method before iterating over a Finder.');
  291. }
  292. if (1 === count($this->dirs)) {
  293. return $this->searchInDirectory($this->dirs[0]);
  294. }
  295. $iterator = new \AppendIterator();
  296. foreach ($this->dirs as $dir) {
  297. $iterator->append($this->searchInDirectory($dir));
  298. }
  299. return $iterator;
  300. }
  301. protected function searchInDirectory($dir)
  302. {
  303. $flags = \FilesystemIterator::SKIP_DOTS;
  304. if ($this->followLinks) {
  305. $flags |= \FilesystemIterator::FOLLOW_SYMLINKS;
  306. }
  307. $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir, $flags), \RecursiveIteratorIterator::SELF_FIRST);
  308. if ($this->depths) {
  309. $iterator = new Iterator\DepthRangeFilterIterator($iterator, $this->depths);
  310. }
  311. if ($this->mode) {
  312. $iterator = new Iterator\FileTypeFilterIterator($iterator, $this->mode);
  313. }
  314. if ($this->exclude) {
  315. $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
  316. }
  317. if ($this->ignoreVCS) {
  318. $iterator = new Iterator\IgnoreVcsFilterIterator($iterator);
  319. }
  320. if ($this->names || $this->notNames) {
  321. $iterator = new Iterator\FilenameFilterIterator($iterator, $this->names, $this->notNames);
  322. }
  323. if ($this->sizes) {
  324. $iterator = new Iterator\SizeRangeFilterIterator($iterator, $this->sizes);
  325. }
  326. if ($this->dates) {
  327. $iterator = new Iterator\DateRangeFilterIterator($iterator, $this->dates);
  328. }
  329. if ($this->filters) {
  330. $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
  331. }
  332. if ($this->sort) {
  333. $iterator = new Iterator\SortableIterator($iterator, $this->sort);
  334. }
  335. return $iterator;
  336. }
  337. }