Iterator.php 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <?php declare(strict_types=1);
  2. /*
  3. * This file is part of phpunit/php-file-iterator.
  4. *
  5. * (c) Sebastian Bergmann <sebastian@phpunit.de>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace SebastianBergmann\FileIterator;
  11. use function array_filter;
  12. use function array_map;
  13. use function preg_match;
  14. use function realpath;
  15. use function str_replace;
  16. use function strlen;
  17. use function strpos;
  18. use function substr;
  19. use FilterIterator;
  20. class Iterator extends FilterIterator
  21. {
  22. public const PREFIX = 0;
  23. public const SUFFIX = 1;
  24. /**
  25. * @var string
  26. */
  27. private $basePath;
  28. /**
  29. * @var array
  30. */
  31. private $suffixes = [];
  32. /**
  33. * @var array
  34. */
  35. private $prefixes = [];
  36. /**
  37. * @var array
  38. */
  39. private $exclude = [];
  40. public function __construct(string $basePath, \Iterator $iterator, array $suffixes = [], array $prefixes = [], array $exclude = [])
  41. {
  42. $this->basePath = realpath($basePath);
  43. $this->prefixes = $prefixes;
  44. $this->suffixes = $suffixes;
  45. $this->exclude = array_filter(array_map('realpath', $exclude));
  46. parent::__construct($iterator);
  47. }
  48. public function accept(): bool
  49. {
  50. $current = $this->getInnerIterator()->current();
  51. $filename = $current->getFilename();
  52. $realPath = $current->getRealPath();
  53. if ($realPath === false) {
  54. return false;
  55. }
  56. return $this->acceptPath($realPath) &&
  57. $this->acceptPrefix($filename) &&
  58. $this->acceptSuffix($filename);
  59. }
  60. private function acceptPath(string $path): bool
  61. {
  62. // Filter files in hidden directories by checking path that is relative to the base path.
  63. if (preg_match('=/\.[^/]*/=', str_replace($this->basePath, '', $path))) {
  64. return false;
  65. }
  66. foreach ($this->exclude as $exclude) {
  67. if (strpos($path, $exclude) === 0) {
  68. return false;
  69. }
  70. }
  71. return true;
  72. }
  73. private function acceptPrefix(string $filename): bool
  74. {
  75. return $this->acceptSubString($filename, $this->prefixes, self::PREFIX);
  76. }
  77. private function acceptSuffix(string $filename): bool
  78. {
  79. return $this->acceptSubString($filename, $this->suffixes, self::SUFFIX);
  80. }
  81. private function acceptSubString(string $filename, array $subStrings, int $type): bool
  82. {
  83. if (empty($subStrings)) {
  84. return true;
  85. }
  86. $matched = false;
  87. foreach ($subStrings as $string) {
  88. if (($type === self::PREFIX && strpos($filename, $string) === 0) ||
  89. ($type === self::SUFFIX &&
  90. substr($filename, -1 * strlen($string)) === $string)) {
  91. $matched = true;
  92. break;
  93. }
  94. }
  95. return $matched;
  96. }
  97. }