DirectoryScanner.php 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. <?php
  2. /*
  3. * $Id: DirectoryScanner.php 905 2010-10-05 16:28:03Z mrook $
  4. *
  5. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  6. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  7. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  8. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  9. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  10. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  11. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  13. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  14. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  15. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16. *
  17. * This software consists of voluntary contributions made by many individuals
  18. * and is licensed under the LGPL. For more information please see
  19. * <http://phing.info>.
  20. */
  21. require_once 'phing/types/selectors/SelectorScanner.php';
  22. include_once 'phing/util/StringHelper.php';
  23. include_once 'phing/types/selectors/SelectorUtils.php';
  24. /**
  25. * Class for scanning a directory for files/directories that match a certain
  26. * criteria.
  27. *
  28. * These criteria consist of a set of include and exclude patterns. With these
  29. * patterns, you can select which files you want to have included, and which
  30. * files you want to have excluded.
  31. *
  32. * The idea is simple. A given directory is recursively scanned for all files
  33. * and directories. Each file/directory is matched against a set of include
  34. * and exclude patterns. Only files/directories that match at least one
  35. * pattern of the include pattern list, and don't match a pattern of the
  36. * exclude pattern list will be placed in the list of files/directories found.
  37. *
  38. * When no list of include patterns is supplied, "**" will be used, which
  39. * means that everything will be matched. When no list of exclude patterns is
  40. * supplied, an empty list is used, such that nothing will be excluded.
  41. *
  42. * The pattern matching is done as follows:
  43. * The name to be matched is split up in path segments. A path segment is the
  44. * name of a directory or file, which is bounded by DIRECTORY_SEPARATOR
  45. * ('/' under UNIX, '\' under Windows).
  46. * E.g. "abc/def/ghi/xyz.php" is split up in the segments "abc", "def", "ghi"
  47. * and "xyz.php".
  48. * The same is done for the pattern against which should be matched.
  49. *
  50. * Then the segments of the name and the pattern will be matched against each
  51. * other. When '**' is used for a path segment in the pattern, then it matches
  52. * zero or more path segments of the name.
  53. *
  54. * There are special case regarding the use of DIRECTORY_SEPARATOR at
  55. * the beginning of the pattern and the string to match:
  56. * When a pattern starts with a DIRECTORY_SEPARATOR, the string
  57. * to match must also start with a DIRECTORY_SEPARATOR.
  58. * When a pattern does not start with a DIRECTORY_SEPARATOR, the
  59. * string to match may not start with a DIRECTORY_SEPARATOR.
  60. * When one of these rules is not obeyed, the string will not
  61. * match.
  62. *
  63. * When a name path segment is matched against a pattern path segment, the
  64. * following special characters can be used:
  65. * '*' matches zero or more characters,
  66. * '?' matches one character.
  67. *
  68. * Examples:
  69. *
  70. * "**\*.php" matches all .php files/dirs in a directory tree.
  71. *
  72. * "test\a??.php" matches all files/dirs which start with an 'a', then two
  73. * more characters and then ".php", in a directory called test.
  74. *
  75. * "**" matches everything in a directory tree.
  76. *
  77. * "**\test\**\XYZ*" matches all files/dirs that start with "XYZ" and where
  78. * there is a parent directory called test (e.g. "abc\test\def\ghi\XYZ123").
  79. *
  80. * Case sensitivity may be turned off if necessary. By default, it is
  81. * turned on.
  82. *
  83. * Example of usage:
  84. * $ds = new DirectroyScanner();
  85. * $includes = array("**\*.php");
  86. * $excludes = array("modules\*\**");
  87. * $ds->SetIncludes($includes);
  88. * $ds->SetExcludes($excludes);
  89. * $ds->SetBasedir("test");
  90. * $ds->SetCaseSensitive(true);
  91. * $ds->Scan();
  92. *
  93. * print("FILES:");
  94. * $files = ds->GetIncludedFiles();
  95. * for ($i = 0; $i < count($files);$i++) {
  96. * println("$files[$i]\n");
  97. * }
  98. *
  99. * This will scan a directory called test for .php files, but excludes all
  100. * .php files in all directories under a directory called "modules"
  101. *
  102. * This class is complete preg/ereg free port of the Java class
  103. * org.apache.tools.ant.DirectoryScanner. Even functions that use preg/ereg
  104. * internally (like split()) are not used. Only the _fast_ string functions
  105. * and comparison operators (=== !=== etc) are used for matching and tokenizing.
  106. *
  107. * @author Arnout J. Kuiper, ajkuiper@wxs.nl
  108. * @author Magesh Umasankar, umagesh@rediffmail.com
  109. * @author Andreas Aderhold, andi@binarycloud.com
  110. *
  111. * @version $Revision: 905 $
  112. * @package phing.util
  113. */
  114. class DirectoryScanner implements SelectorScanner {
  115. /** default set of excludes */
  116. protected $DEFAULTEXCLUDES = array(
  117. "**/*~",
  118. "**/#*#",
  119. "**/.#*",
  120. "**/%*%",
  121. "**/CVS",
  122. "**/CVS/**",
  123. "**/.cvsignore",
  124. "**/SCCS",
  125. "**/SCCS/**",
  126. "**/vssver.scc",
  127. "**/.svn",
  128. "**/.svn/**",
  129. "**/._*",
  130. "**/.DS_Store",
  131. );
  132. /** The base directory which should be scanned. */
  133. protected $basedir;
  134. /** The patterns for the files that should be included. */
  135. protected $includes = null;
  136. /** The patterns for the files that should be excluded. */
  137. protected $excludes = null;
  138. /** Whether to expand/dereference symbolic links, default is false */
  139. protected $expandSymbolicLinks = false;
  140. /**
  141. * The files that where found and matched at least one includes, and matched
  142. * no excludes.
  143. */
  144. protected $filesIncluded;
  145. /** The files that where found and did not match any includes. Trie */
  146. protected $filesNotIncluded;
  147. /**
  148. * The files that where found and matched at least one includes, and also
  149. * matched at least one excludes. Trie object.
  150. */
  151. protected $filesExcluded;
  152. /**
  153. * The directories that where found and matched at least one includes, and
  154. * matched no excludes.
  155. */
  156. protected $dirsIncluded;
  157. /** The directories that where found and did not match any includes. */
  158. protected $dirsNotIncluded;
  159. /**
  160. * The files that where found and matched at least one includes, and also
  161. * matched at least one excludes.
  162. */
  163. protected $dirsExcluded;
  164. /** Have the vars holding our results been built by a slow scan? */
  165. protected $haveSlowResults = false;
  166. /** Should the file system be treated as a case sensitive one? */
  167. protected $isCaseSensitive = true;
  168. /** Selectors */
  169. protected $selectors = null;
  170. protected $filesDeselected;
  171. protected $dirsDeselected;
  172. /** if there are no deselected files */
  173. protected $everythingIncluded = true;
  174. /**
  175. * Does the path match the start of this pattern up to the first "**".
  176. * This is a static mehtod and should always be called static
  177. *
  178. * This is not a general purpose test and should only be used if you
  179. * can live with false positives.
  180. *
  181. * pattern=**\a and str=b will yield true.
  182. *
  183. * @param pattern the (non-null) pattern to match against
  184. * @param str the (non-null) string (path) to match
  185. * @param isCaseSensitive must matches be case sensitive?
  186. * @return boolean true if matches, otherwise false
  187. */
  188. function matchPatternStart($pattern, $str, $isCaseSensitive = true) {
  189. return SelectorUtils::matchPatternStart($pattern, $str, $isCaseSensitive);
  190. }
  191. /**
  192. * Matches a path against a pattern. Static
  193. *
  194. * @param pattern the (non-null) pattern to match against
  195. * @param str the (non-null) string (path) to match
  196. * @param isCaseSensitive must a case sensitive match be done?
  197. *
  198. * @return true when the pattern matches against the string.
  199. * false otherwise.
  200. */
  201. function matchPath($pattern, $str, $isCaseSensitive = true) {
  202. return SelectorUtils::matchPath($pattern, $str, $isCaseSensitive);
  203. }
  204. /**
  205. * Matches a string against a pattern. The pattern contains two special
  206. * characters:
  207. * '*' which means zero or more characters,
  208. * '?' which means one and only one character.
  209. *
  210. * @param pattern the (non-null) pattern to match against
  211. * @param str the (non-null) string that must be matched against the
  212. * pattern
  213. *
  214. * @return boolean true when the string matches against the pattern,
  215. * false otherwise.
  216. * @access public
  217. */
  218. function match($pattern, $str, $isCaseSensitive = true) {
  219. return SelectorUtils::match($pattern, $str, $isCaseSensitive);
  220. }
  221. /**
  222. * Sets the basedir for scanning. This is the directory that is scanned
  223. * recursively. All '/' and '\' characters are replaced by
  224. * DIRECTORY_SEPARATOR
  225. *
  226. * @param basedir the (non-null) basedir for scanning
  227. */
  228. function setBasedir($_basedir) {
  229. $_basedir = str_replace('\\', DIRECTORY_SEPARATOR, $_basedir);
  230. $_basedir = str_replace('/', DIRECTORY_SEPARATOR, $_basedir);
  231. $this->basedir = $_basedir;
  232. }
  233. /**
  234. * Gets the basedir that is used for scanning. This is the directory that
  235. * is scanned recursively.
  236. *
  237. * @return the basedir that is used for scanning
  238. */
  239. function getBasedir() {
  240. return $this->basedir;
  241. }
  242. /**
  243. * Sets the case sensitivity of the file system
  244. *
  245. * @param specifies if the filesystem is case sensitive
  246. */
  247. function setCaseSensitive($_isCaseSensitive) {
  248. $this->isCaseSensitive = ($_isCaseSensitive) ? true : false;
  249. }
  250. /**
  251. * Sets the set of include patterns to use. All '/' and '\' characters are
  252. * replaced by DIRECTORY_SEPARATOR. So the separator used need
  253. * not match DIRECTORY_SEPARATOR.
  254. *
  255. * When a pattern ends with a '/' or '\', "**" is appended.
  256. *
  257. * @param includes list of include patterns
  258. */
  259. function setIncludes($_includes = array()) {
  260. if (empty($_includes) || is_null($_includes)) {
  261. $this->includes = null;
  262. } else {
  263. for ($i = 0; $i < count($_includes); $i++) {
  264. $pattern = null;
  265. $pattern = str_replace('\\', DIRECTORY_SEPARATOR, $_includes[$i]);
  266. $pattern = str_replace('/', DIRECTORY_SEPARATOR, $pattern);
  267. if (StringHelper::endsWith(DIRECTORY_SEPARATOR, $pattern)) {
  268. $pattern .= "**";
  269. }
  270. $this->includes[] = $pattern;
  271. }
  272. }
  273. }
  274. /**
  275. * Sets the set of exclude patterns to use. All '/' and '\' characters are
  276. * replaced by <code>File.separatorChar</code>. So the separator used need
  277. * not match <code>File.separatorChar</code>.
  278. *
  279. * When a pattern ends with a '/' or '\', "**" is appended.
  280. *
  281. * @param excludes list of exclude patterns
  282. */
  283. function setExcludes($_excludes = array()) {
  284. if (empty($_excludes) || is_null($_excludes)) {
  285. $this->excludes = null;
  286. } else {
  287. for ($i = 0; $i < count($_excludes); $i++) {
  288. $pattern = null;
  289. $pattern = str_replace('\\', DIRECTORY_SEPARATOR, $_excludes[$i]);
  290. $pattern = str_replace('/', DIRECTORY_SEPARATOR, $pattern);
  291. if (StringHelper::endsWith(DIRECTORY_SEPARATOR, $pattern)) {
  292. $pattern .= "**";
  293. }
  294. $this->excludes[] = $pattern;
  295. }
  296. }
  297. }
  298. /**
  299. * Sets whether to expand/dereference symbolic links
  300. *
  301. * @param expandSymbolicLinks boolean value
  302. */
  303. function setExpandSymbolicLinks($expandSymbolicLinks)
  304. {
  305. $this->expandSymbolicLinks = $expandSymbolicLinks;
  306. }
  307. /**
  308. * Scans the base directory for files that match at least one include
  309. * pattern, and don't match any exclude patterns.
  310. *
  311. */
  312. function scan() {
  313. if ((empty($this->basedir)) || (!@is_dir($this->basedir))) {
  314. return false;
  315. }
  316. if ($this->includes === null) {
  317. // No includes supplied, so set it to 'matches all'
  318. $this->includes = array("**");
  319. }
  320. if (is_null($this->excludes)) {
  321. $this->excludes = array();
  322. }
  323. $this->filesIncluded = array();
  324. $this->filesNotIncluded = array();
  325. $this->filesExcluded = array();
  326. $this->dirsIncluded = array();
  327. $this->dirsNotIncluded = array();
  328. $this->dirsExcluded = array();
  329. $this->dirsDeselected = array();
  330. $this->filesDeselected = array();
  331. if ($this->isIncluded("")) {
  332. if (!$this->isExcluded("")) {
  333. if ($this->isSelected("", $this->basedir)) {
  334. $this->dirsIncluded[] = "";
  335. } else {
  336. $this->dirsDeselected[] = "";
  337. }
  338. } else {
  339. $this->dirsExcluded[] = "";
  340. }
  341. } else {
  342. $this->dirsNotIncluded[] = "";
  343. }
  344. $this->scandir($this->basedir, "", true);
  345. return true;
  346. }
  347. /**
  348. * Toplevel invocation for the scan.
  349. *
  350. * Returns immediately if a slow scan has already been requested.
  351. */
  352. protected function slowScan() {
  353. if ($this->haveSlowResults) {
  354. return;
  355. }
  356. // copy trie object add CopyInto() method
  357. $excl = $this->dirsExcluded;
  358. $notIncl = $this->dirsNotIncluded;
  359. for ($i=0, $_i=count($excl); $i < $_i; $i++) {
  360. if (!$this->couldHoldIncluded($excl[$i])) {
  361. $this->scandir($this->basedir.$excl[$i], $excl[$i].DIRECTORY_SEPARATOR, false);
  362. }
  363. }
  364. for ($i=0, $_i=count($notIncl); $i < $_i; $i++) {
  365. if (!$this->couldHoldIncluded($notIncl[$i])) {
  366. $this->scandir($this->basedir.$notIncl[$i], $notIncl[$i].DIRECTORY_SEPARATOR, false);
  367. }
  368. }
  369. $this->haveSlowResults = true;
  370. }
  371. /**
  372. * Lists contens of a given directory and returns array with entries
  373. *
  374. * @param src String. Source path and name file to copy.
  375. *
  376. * @access public
  377. * @return array directory entries
  378. * @author Albert Lash, alash@plateauinnovation.com
  379. */
  380. function listDir($_dir) {
  381. $d = dir($_dir);
  382. $list = array();
  383. while(($entry = $d->read()) !== false) {
  384. if ($entry != "." && $entry != "..") {
  385. $list[] = $entry;
  386. }
  387. }
  388. $d->close();
  389. return $list;
  390. }
  391. /**
  392. * Scans the passed dir for files and directories. Found files and
  393. * directories are placed in their respective collections, based on the
  394. * matching of includes and excludes. When a directory is found, it is
  395. * scanned recursively.
  396. *
  397. * @param dir the directory to scan
  398. * @param vpath the path relative to the basedir (needed to prevent
  399. * problems with an absolute path when using dir)
  400. *
  401. * @access private
  402. * @see #filesIncluded
  403. * @see #filesNotIncluded
  404. * @see #filesExcluded
  405. * @see #dirsIncluded
  406. * @see #dirsNotIncluded
  407. * @see #dirsExcluded
  408. */
  409. private function scandir($_rootdir, $_vpath, $_fast) {
  410. if (!is_readable($_rootdir)) {
  411. return;
  412. }
  413. $newfiles = self::listDir($_rootdir);
  414. for ($i=0,$_i=count($newfiles); $i < $_i; $i++) {
  415. $file = $_rootdir . DIRECTORY_SEPARATOR . $newfiles[$i];
  416. $name = $_vpath . $newfiles[$i];
  417. if (@is_link($file) && !$this->expandSymbolicLinks)
  418. {
  419. if ($this->isIncluded($name)) {
  420. if (!$this->isExcluded($name)) {
  421. if ($this->isSelected($name, $file)) {
  422. $this->filesIncluded[] = $name;
  423. } else {
  424. $this->everythingIncluded = false;
  425. $this->filesDeselected[] = $name;
  426. }
  427. } else {
  428. $this->everythingIncluded = false;
  429. $this->filesExcluded[] = $name;
  430. }
  431. } else {
  432. $this->everythingIncluded = false;
  433. $this->filesNotIncluded[] = $name;
  434. }
  435. }
  436. else
  437. if (@is_dir($file)) {
  438. if ($this->isIncluded($name)) {
  439. if (!$this->isExcluded($name)) {
  440. if ($this->isSelected($name, $file)) {
  441. $this->dirsIncluded[] = $name;
  442. if ($_fast) {
  443. $this->scandir($file, $name.DIRECTORY_SEPARATOR, $_fast);
  444. }
  445. } else {
  446. $this->everythingIncluded = false;
  447. $this->dirsDeselected[] = $name;
  448. if ($_fast && $this->couldHoldIncluded($name)) {
  449. $this->scandir($file, $name.DIRECTORY_SEPARATOR, $_fast);
  450. }
  451. }
  452. } else {
  453. $this->everythingIncluded = false;
  454. $this->dirsExcluded[] = $name;
  455. if ($_fast && $this->couldHoldIncluded($name)) {
  456. $this->scandir($file, $name.DIRECTORY_SEPARATOR, $_fast);
  457. }
  458. }
  459. } else {
  460. $this->everythingIncluded = false;
  461. $this->dirsNotIncluded[] = $name;
  462. if ($_fast && $this->couldHoldIncluded($name)) {
  463. $this->scandir($file, $name.DIRECTORY_SEPARATOR, $_fast);
  464. }
  465. }
  466. if (!$_fast) {
  467. $this->scandir($file, $name.DIRECTORY_SEPARATOR, $_fast);
  468. }
  469. } elseif (@is_file($file)) {
  470. if ($this->isIncluded($name)) {
  471. if (!$this->isExcluded($name)) {
  472. if ($this->isSelected($name, $file)) {
  473. $this->filesIncluded[] = $name;
  474. } else {
  475. $this->everythingIncluded = false;
  476. $this->filesDeselected[] = $name;
  477. }
  478. } else {
  479. $this->everythingIncluded = false;
  480. $this->filesExcluded[] = $name;
  481. }
  482. } else {
  483. $this->everythingIncluded = false;
  484. $this->filesNotIncluded[] = $name;
  485. }
  486. }
  487. }
  488. }
  489. /**
  490. * Tests whether a name matches against at least one include pattern.
  491. *
  492. * @param name the name to match
  493. * @return <code>true</code> when the name matches against at least one
  494. * include pattern, <code>false</code> otherwise.
  495. */
  496. protected function isIncluded($_name) {
  497. for ($i=0, $_i=count($this->includes); $i < $_i; $i++) {
  498. if (DirectoryScanner::matchPath($this->includes[$i], $_name, $this->isCaseSensitive)) {
  499. return true;
  500. }
  501. }
  502. return false;
  503. }
  504. /**
  505. * Tests whether a name matches the start of at least one include pattern.
  506. *
  507. * @param name the name to match
  508. * @return <code>true</code> when the name matches against at least one
  509. * include pattern, <code>false</code> otherwise.
  510. */
  511. protected function couldHoldIncluded($_name) {
  512. for ($i = 0; $i < count($this->includes); $i++) {
  513. if (DirectoryScanner::matchPatternStart($this->includes[$i], $_name, $this->isCaseSensitive)) {
  514. return true;
  515. }
  516. }
  517. return false;
  518. }
  519. /**
  520. * Tests whether a name matches against at least one exclude pattern.
  521. *
  522. * @param name the name to match
  523. * @return <code>true</code> when the name matches against at least one
  524. * exclude pattern, <code>false</code> otherwise.
  525. */
  526. protected function isExcluded($_name) {
  527. for ($i = 0; $i < count($this->excludes); $i++) {
  528. if (DirectoryScanner::matchPath($this->excludes[$i], $_name, $this->isCaseSensitive)) {
  529. return true;
  530. }
  531. }
  532. return false;
  533. }
  534. /**
  535. * Get the names of the files that matched at least one of the include
  536. * patterns, and matched none of the exclude patterns.
  537. * The names are relative to the basedir.
  538. *
  539. * @return the names of the files
  540. */
  541. function getIncludedFiles() {
  542. return $this->filesIncluded;
  543. }
  544. /**
  545. * Get the names of the files that matched at none of the include patterns.
  546. * The names are relative to the basedir.
  547. *
  548. * @return the names of the files
  549. */
  550. function getNotIncludedFiles() {
  551. $this->slowScan();
  552. return $this->filesNotIncluded;
  553. }
  554. /**
  555. * Get the names of the files that matched at least one of the include
  556. * patterns, an matched also at least one of the exclude patterns.
  557. * The names are relative to the basedir.
  558. *
  559. * @return the names of the files
  560. */
  561. function getExcludedFiles() {
  562. $this->slowScan();
  563. return $this->filesExcluded;
  564. }
  565. /**
  566. * <p>Returns the names of the files which were selected out and
  567. * therefore not ultimately included.</p>
  568. *
  569. * <p>The names are relative to the base directory. This involves
  570. * performing a slow scan if one has not already been completed.</p>
  571. *
  572. * @return the names of the files which were deselected.
  573. *
  574. * @see #slowScan
  575. */
  576. public function getDeselectedFiles() {
  577. $this->slowScan();
  578. return $this->filesDeselected;
  579. }
  580. /**
  581. * Get the names of the directories that matched at least one of the include
  582. * patterns, an matched none of the exclude patterns.
  583. * The names are relative to the basedir.
  584. *
  585. * @return the names of the directories
  586. */
  587. function getIncludedDirectories() {
  588. return $this->dirsIncluded;
  589. }
  590. /**
  591. * Get the names of the directories that matched at none of the include
  592. * patterns.
  593. * The names are relative to the basedir.
  594. *
  595. * @return the names of the directories
  596. */
  597. function getNotIncludedDirectories() {
  598. $this->slowScan();
  599. return $this->dirsNotIncluded;
  600. }
  601. /**
  602. * <p>Returns the names of the directories which were selected out and
  603. * therefore not ultimately included.</p>
  604. *
  605. * <p>The names are relative to the base directory. This involves
  606. * performing a slow scan if one has not already been completed.</p>
  607. *
  608. * @return the names of the directories which were deselected.
  609. *
  610. * @see #slowScan
  611. */
  612. public function getDeselectedDirectories() {
  613. $this->slowScan();
  614. return $this->dirsDeselected;
  615. }
  616. /**
  617. * Get the names of the directories that matched at least one of the include
  618. * patterns, an matched also at least one of the exclude patterns.
  619. * The names are relative to the basedir.
  620. *
  621. * @return the names of the directories
  622. */
  623. function getExcludedDirectories() {
  624. $this->slowScan();
  625. return $this->dirsExcluded;
  626. }
  627. /**
  628. * Adds the array with default exclusions to the current exclusions set.
  629. *
  630. */
  631. function addDefaultExcludes() {
  632. //$excludesLength = ($this->excludes == null) ? 0 : count($this->excludes);
  633. foreach($this->DEFAULTEXCLUDES as $pattern) {
  634. $pattern = str_replace('\\', DIRECTORY_SEPARATOR, $pattern);
  635. $pattern = str_replace('/', DIRECTORY_SEPARATOR, $pattern);
  636. $this->excludes[] = $pattern;
  637. }
  638. }
  639. /**
  640. * Sets the selectors that will select the filelist.
  641. *
  642. * @param selectors specifies the selectors to be invoked on a scan
  643. */
  644. public function setSelectors($selectors) {
  645. $this->selectors = $selectors;
  646. }
  647. /**
  648. * Returns whether or not the scanner has included all the files or
  649. * directories it has come across so far.
  650. *
  651. * @return <code>true</code> if all files and directories which have
  652. * been found so far have been included.
  653. */
  654. public function isEverythingIncluded() {
  655. return $this->everythingIncluded;
  656. }
  657. /**
  658. * Tests whether a name should be selected.
  659. *
  660. * @param string $name The filename to check for selecting.
  661. * @param string $file The full file path.
  662. * @return boolean False when the selectors says that the file
  663. * should not be selected, True otherwise.
  664. */
  665. protected function isSelected($name, $file) {
  666. if ($this->selectors !== null) {
  667. $basedir = new PhingFile($this->basedir);
  668. $file = new PhingFile($file);
  669. if (!$file->canRead())
  670. return false;
  671. foreach($this->selectors as $selector) {
  672. if (!$selector->isSelected($basedir, $name, $file)) {
  673. return false;
  674. }
  675. }
  676. }
  677. return true;
  678. }
  679. }