1<?php 2 3/* 4 * This file is part of the Symfony package. 5 * 6 * (c) Fabien Potencier <fabien@symfony.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Symfony\Component\Finder\Iterator; 13 14/** 15 * ExcludeDirectoryFilterIterator filters out directories. 16 * 17 * @author Fabien Potencier <fabien@symfony.com> 18 */ 19class ExcludeDirectoryFilterIterator extends \FilterIterator implements \RecursiveIterator 20{ 21 private $iterator; 22 private $isRecursive; 23 private $excludedDirs = []; 24 private $excludedPattern; 25 26 /** 27 * @param \Iterator $iterator The Iterator to filter 28 * @param string[] $directories An array of directories to exclude 29 */ 30 public function __construct(\Iterator $iterator, array $directories) 31 { 32 $this->iterator = $iterator; 33 $this->isRecursive = $iterator instanceof \RecursiveIterator; 34 $patterns = []; 35 foreach ($directories as $directory) { 36 $directory = rtrim($directory, '/'); 37 if (!$this->isRecursive || false !== strpos($directory, '/')) { 38 $patterns[] = preg_quote($directory, '#'); 39 } else { 40 $this->excludedDirs[$directory] = true; 41 } 42 } 43 if ($patterns) { 44 $this->excludedPattern = '#(?:^|/)(?:'.implode('|', $patterns).')(?:/|$)#'; 45 } 46 47 parent::__construct($iterator); 48 } 49 50 /** 51 * Filters the iterator values. 52 * 53 * @return bool True if the value should be kept, false otherwise 54 */ 55 public function accept() 56 { 57 if ($this->isRecursive && isset($this->excludedDirs[$this->getFilename()]) && $this->isDir()) { 58 return false; 59 } 60 61 if ($this->excludedPattern) { 62 $path = $this->isDir() ? $this->current()->getRelativePathname() : $this->current()->getRelativePath(); 63 $path = str_replace('\\', '/', $path); 64 65 return !preg_match($this->excludedPattern, $path); 66 } 67 68 return true; 69 } 70 71 /** 72 * @return bool 73 */ 74 public function hasChildren() 75 { 76 return $this->isRecursive && $this->iterator->hasChildren(); 77 } 78 79 public function getChildren() 80 { 81 $children = new self($this->iterator->getChildren(), []); 82 $children->excludedDirs = $this->excludedDirs; 83 $children->excludedPattern = $this->excludedPattern; 84 85 return $children; 86 } 87} 88