From b6852c3b6e5de85613665572272c4d4ca6b54a41 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 14 May 2010 09:29:04 +0200 Subject: [PATCH] [Finder] added a data range filter --- src/Symfony/Components/Finder/Finder.php | 63 ++++++++++++++++-- .../Iterator/DateRangeFilterIterator.php | 66 +++++++++++++++++++ 2 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 src/Symfony/Components/Finder/Iterator/DateRangeFilterIterator.php diff --git a/src/Symfony/Components/Finder/Finder.php b/src/Symfony/Components/Finder/Finder.php index e20ac335cb..9db0515b47 100644 --- a/src/Symfony/Components/Finder/Finder.php +++ b/src/Symfony/Components/Finder/Finder.php @@ -36,13 +36,15 @@ class Finder implements \IteratorAggregate protected $notNames = array(); protected $exclude = array(); protected $filters = array(); - protected $mindepth = 0; - protected $maxdepth = INF; + protected $minDepth = 0; + protected $maxDepth = INF; protected $sizes = array(); protected $followLinks = false; protected $sort = false; protected $ignoreVCS = true; protected $dirs = array(); + protected $minDate = false; + protected $maxDate = false; /** * Restricts the matching to directories only. @@ -81,7 +83,7 @@ class Finder implements \IteratorAggregate */ public function maxDepth($level) { - $this->maxdepth = (double) $level; + $this->maxDepth = (double) $level; return $this; } @@ -99,7 +101,52 @@ class Finder implements \IteratorAggregate */ public function minDepth($level) { - $this->mindepth = (integer) $level; + $this->minDepth = (integer) $level; + + return $this; + } + + /** + * Sets the maximum date (last modified) for a file or directory. + * + * The date must be something that strtotime() is able to parse: + * + * $finder->maxDate('yesterday'); + * $finder->maxDate('2 days ago'); + * $finder->maxDate('now - 2 hours'); + * $finder->maxDate('2005-10-15'); + * + * @param string $date A date + * + * @return Symfony\Components\Finder The current Finder instance + * + * @see Symfony\Components\Finder\Iterator\DateRangeFilterIterator + */ + public function maxDate($date) + { + if (false === $this->maxDate = @strtotime($date)) { + throw new \InvalidArgumentException(sprintf('"%s" is not a valid date')); + } + + return $this; + } + + /** + * Sets the minimum date (last modified) for a file or a directory. + * + * The date must be something that strtotime() is able to parse (@see maxDate()). + * + * @param string $date A date + * + * @return Symfony\Components\Finder The current Finder instance + * + * @see Symfony\Components\Finder\Iterator\DateRangeFilterIterator + */ + public function minDate($date) + { + if (false === $this->minDate = @strtotime($date)) { + throw new \InvalidArgumentException(sprintf('"%s" is not a valid date')); + } return $this; } @@ -339,8 +386,8 @@ class Finder implements \IteratorAggregate $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir, $flags), \RecursiveIteratorIterator::SELF_FIRST); - if ($this->mindepth > 0 || $this->maxdepth < INF) { - $iterator = new Iterator\LimitDepthFilterIterator($iterator, $this->mindepth, $this->maxdepth); + if ($this->minDepth > 0 || $this->maxDepth < INF) { + $iterator = new Iterator\LimitDepthFilterIterator($iterator, $this->minDepth, $this->maxDepth); } if ($this->mode) { @@ -363,6 +410,10 @@ class Finder implements \IteratorAggregate $iterator = new Iterator\SizeRangeFilterIterator($iterator, $this->sizes); } + if (false !== $this->minDate || false !== $this->maxDate) { + $iterator = new Iterator\DateRangeFilterIterator($iterator, $this->minDate, $this->maxDate); + } + if ($this->filters) { $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters); } diff --git a/src/Symfony/Components/Finder/Iterator/DateRangeFilterIterator.php b/src/Symfony/Components/Finder/Iterator/DateRangeFilterIterator.php new file mode 100644 index 0000000000..fdf6d5f057 --- /dev/null +++ b/src/Symfony/Components/Finder/Iterator/DateRangeFilterIterator.php @@ -0,0 +1,66 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * DateRangeFilterIterator filters out files that are not in the given date range (last modified dates). + * + * @package Symfony + * @subpackage Components_Finder + * @author Fabien Potencier + */ +class DateRangeFilterIterator extends \FilterIterator +{ + protected $minDate = false; + protected $maxDate = false; + + /** + * Constructor. + * + * @param \Iterator $iterator The Iterator to filter + * @param integer $minDate The minimum date + * @param integer $maxDate The maximum date + */ + public function __construct(\Iterator $iterator, $minDate = false, $maxDate = false) + { + $this->minDate = $minDate; + $this->maxDate = $maxDate; + + parent::__construct($iterator); + } + + /** + * Filters the iterator values. + * + * @return Boolean true if the value should be kept, false otherwise + */ + public function accept() + { + $fileinfo = $this->getInnerIterator()->current(); + + if (!$fileinfo->isFile()) { + return true; + } + + $filedate = $fileinfo->getMTime(); + + if ( + (false !== $this->minDate && $filedate < $this->minDate) + || + (false !== $this->maxDate && $filedate > $this->maxDate) + ) { + return false; + } + + return true; + } +}