Factory.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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 const GLOB_ONLYDIR;
  12. use function array_filter;
  13. use function array_map;
  14. use function array_merge;
  15. use function array_values;
  16. use function glob;
  17. use function is_dir;
  18. use function is_string;
  19. use function realpath;
  20. use AppendIterator;
  21. use FilesystemIterator;
  22. use RecursiveDirectoryIterator;
  23. use RecursiveIteratorIterator;
  24. /**
  25. * @internal This class is not covered by the backward compatibility promise for phpunit/php-file-iterator
  26. */
  27. final class Factory
  28. {
  29. /**
  30. * @psalm-param list<non-empty-string>|non-empty-string $paths
  31. * @psalm-param list<non-empty-string>|string $suffixes
  32. * @psalm-param list<non-empty-string>|string $prefixes
  33. * @psalm-param list<non-empty-string> $exclude
  34. */
  35. public function getFileIterator(array|string $paths, array|string $suffixes = '', array|string $prefixes = '', array $exclude = []): AppendIterator
  36. {
  37. if (is_string($paths)) {
  38. $paths = [$paths];
  39. }
  40. $paths = $this->resolveWildcards($paths);
  41. $exclude = $this->resolveWildcards($exclude);
  42. if (is_string($prefixes)) {
  43. if ($prefixes !== '') {
  44. $prefixes = [$prefixes];
  45. } else {
  46. $prefixes = [];
  47. }
  48. }
  49. if (is_string($suffixes)) {
  50. if ($suffixes !== '') {
  51. $suffixes = [$suffixes];
  52. } else {
  53. $suffixes = [];
  54. }
  55. }
  56. $iterator = new AppendIterator;
  57. foreach ($paths as $path) {
  58. if (is_dir($path)) {
  59. $iterator->append(
  60. new Iterator(
  61. $path,
  62. new RecursiveIteratorIterator(
  63. new ExcludeIterator(
  64. new RecursiveDirectoryIterator($path, FilesystemIterator::FOLLOW_SYMLINKS | FilesystemIterator::SKIP_DOTS),
  65. $exclude,
  66. ),
  67. ),
  68. $suffixes,
  69. $prefixes,
  70. )
  71. );
  72. }
  73. }
  74. return $iterator;
  75. }
  76. /**
  77. * @psalm-param list<non-empty-string> $paths
  78. *
  79. * @psalm-return list<non-empty-string>
  80. */
  81. private function resolveWildcards(array $paths): array
  82. {
  83. $_paths = [[]];
  84. foreach ($paths as $path) {
  85. if ($locals = glob($path, GLOB_ONLYDIR)) {
  86. $_paths[] = array_map('\realpath', $locals);
  87. } else {
  88. // @codeCoverageIgnoreStart
  89. $_paths[] = [realpath($path)];
  90. // @codeCoverageIgnoreEnd
  91. }
  92. }
  93. return array_values(array_filter(array_merge(...$_paths)));
  94. }
  95. }