From 45df2e681e5f30ea5e2068d8ac5afd37a84815bd Mon Sep 17 00:00:00 2001 From: everzet Date: Sat, 19 Nov 2011 08:58:54 +0100 Subject: [PATCH 01/11] [Config] updated resources API to be more explicit --- .../Config/Resource/DirectoryResource.php | 39 ++++++++++++++++--- .../Config/Resource/FileResource.php | 26 ++++++++++++- .../Config/Resource/ResourceInterface.php | 14 +++++++ .../Tests/Resource/DirectoryResourceTest.php | 12 ++++++ .../Tests/Resource/FileResourceTest.php | 19 +++++++++ 5 files changed, 102 insertions(+), 8 deletions(-) diff --git a/src/Symfony/Component/Config/Resource/DirectoryResource.php b/src/Symfony/Component/Config/Resource/DirectoryResource.php index 5ccd204ef9..021523963e 100644 --- a/src/Symfony/Component/Config/Resource/DirectoryResource.php +++ b/src/Symfony/Component/Config/Resource/DirectoryResource.php @@ -59,14 +59,14 @@ class DirectoryResource implements ResourceInterface, \Serializable } /** - * Returns true if the resource has not been updated since the given timestamp. + * Returns resource mtime. * - * @param integer $timestamp The last time the resource was loaded - * - * @return Boolean true if the resource has not been updated, false otherwise + * @return integer */ - public function isFresh($timestamp) + public function getModificationTime() { + clearstatcache(true, $this->resource); + if (!is_dir($this->resource)) { return false; } @@ -84,10 +84,37 @@ class DirectoryResource implements ResourceInterface, \Serializable continue; } + clearstatcache(true, (string) $file); $newestMTime = max($file->getMTime(), $newestMTime); } - return $newestMTime < $timestamp; + return $newestMTime; + } + + /** + * Returns true if the resource has not been updated since the given timestamp. + * + * @param integer $timestamp The last time the resource was loaded + * + * @return Boolean true if the resource has not been updated, false otherwise + */ + public function isFresh($timestamp) + { + if (!$this->exists()) { + return false; + } + + return $this->getModificationTime() <= $timestamp; + } + + /** + * Returns true if the resource exists in the filesystem. + * + * @return Boolean + */ + public function exists() + { + return file_exists($this->resource); } public function serialize() diff --git a/src/Symfony/Component/Config/Resource/FileResource.php b/src/Symfony/Component/Config/Resource/FileResource.php index 619f84bcef..2499de68e5 100644 --- a/src/Symfony/Component/Config/Resource/FileResource.php +++ b/src/Symfony/Component/Config/Resource/FileResource.php @@ -52,6 +52,18 @@ class FileResource implements ResourceInterface, \Serializable return $this->resource; } + /** + * Returns resource mtime. + * + * @return integer + */ + public function getModificationTime() + { + clearstatcache(true, $this->resource); + + return filemtime($this->resource); + } + /** * Returns true if the resource has not been updated since the given timestamp. * @@ -61,11 +73,21 @@ class FileResource implements ResourceInterface, \Serializable */ public function isFresh($timestamp) { - if (!file_exists($this->resource)) { + if (!$this->exists()) { return false; } - return filemtime($this->resource) < $timestamp; + return $this->getModificationTime() <= $timestamp; + } + + /** + * Returns true if the resource exists in the filesystem. + * + * @return Boolean + */ + public function exists() + { + return file_exists($this->resource); } public function serialize() diff --git a/src/Symfony/Component/Config/Resource/ResourceInterface.php b/src/Symfony/Component/Config/Resource/ResourceInterface.php index 024f2e95f9..e684fd6b09 100644 --- a/src/Symfony/Component/Config/Resource/ResourceInterface.php +++ b/src/Symfony/Component/Config/Resource/ResourceInterface.php @@ -34,6 +34,20 @@ interface ResourceInterface */ function isFresh($timestamp); + /** + * Returns resource mtime. + * + * @return integer + */ + function getModificationTime(); + + /** + * Returns true if the resource exists in the filesystem. + * + * @return Boolean + */ + function exists(); + /** * Returns the resource tied to this Resource. * diff --git a/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php index c626ec62ad..98714289a1 100644 --- a/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php @@ -118,8 +118,20 @@ class DirectoryResourceTest extends \PHPUnit_Framework_TestCase $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the whole resource is removed'); } + /** + * @covers Symfony\Component\Config\Resource\DirectoryResource::exists + */ + public function testExists() + { + $this->assertTrue($this->resource->exists(), '->exists() returns true if the directory still exist'); + + $this->removeDirectory($this->directory); + $this->assertFalse($this->resource->exists(), '->exists() returns false if the directory does not exist'); + } + /** * @covers Symfony\Component\Config\Resource\DirectoryResource::isFresh + * @covers Symfony\Component\Config\Resource\DirectoryResource::getModificationTime */ public function testIsFreshCreateFileInSubdirectory() { diff --git a/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php index 83c403bbe7..1c5fa4253b 100644 --- a/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php @@ -49,4 +49,23 @@ class FileResourceTest extends \PHPUnit_Framework_TestCase $resource = new FileResource('/____foo/foobar'.rand(1, 999999)); $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the resource does not exist'); } + + /** + * @covers Symfony\Component\Config\Resource\FileResource::exists + */ + public function testExists() + { + $this->assertTrue($this->resource->exists(), '->exists() returns true if the resource does exist'); + + $resource = new FileResource('/____foo/foobar'.rand(1, 999999)); + $this->assertFalse($resource->exists(), '->exists() returns false if the resource does not exist'); + } + + /** + * @covers Symfony\Component\Config\Resource\FileResource::getModificationTime + */ + public function testGetModificationTime() + { + $this->assertSame(filemtime($this->resource->getResource()), $this->resource->getModificationTime()); + } } From 6b396885861cd1836d1031e157170b3bd54fb150 Mon Sep 17 00:00:00 2001 From: everzet Date: Sat, 19 Nov 2011 10:50:13 +0100 Subject: [PATCH 02/11] [Config] moved DirectoryResource childs retrieving to the special getFilteredChilds method --- .../Config/Resource/DirectoryResource.php | 57 +++++++++++++------ .../Tests/Resource/DirectoryResourceTest.php | 1 + 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/src/Symfony/Component/Config/Resource/DirectoryResource.php b/src/Symfony/Component/Config/Resource/DirectoryResource.php index 021523963e..1818f6da9f 100644 --- a/src/Symfony/Component/Config/Resource/DirectoryResource.php +++ b/src/Symfony/Component/Config/Resource/DirectoryResource.php @@ -33,6 +33,46 @@ class DirectoryResource implements ResourceInterface, \Serializable $this->pattern = $pattern; } + /** + * Returns the list of filtered file and directory childs of directory resource. + * + * @param Boolean $recursive search for files recursive + * + * @return array An array of files + */ + public function getFilteredChilds($recursive = true) + { + $iterator = $recursive + ? new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->resource), \RecursiveIteratorIterator::SELF_FIRST) + : new \DirectoryIterator($this->resource); + + $childs = array(); + foreach ($iterator as $file) { + // if regex filtering is enabled only return matching files + if (isset($this->filterRegexList) && $file->isFile()) { + $regexMatched = false; + foreach ($this->filterRegexList as $regex) { + if (preg_match($regex, (string) $file)) { + $regexMatched = true; + } + } + if (!$regexMatched) { + continue; + } + } + + // always monitor directories for changes, except the .. entries + // (otherwise deleted files wouldn't get detected) + if ($file->isDir() && '/..' === substr($file, -3)) { + continue; + } + + $childs[] = $file; + } + + return $childs; + } + /** * Returns a string representation of the Resource. * @@ -66,24 +106,9 @@ class DirectoryResource implements ResourceInterface, \Serializable public function getModificationTime() { clearstatcache(true, $this->resource); - - if (!is_dir($this->resource)) { - return false; - } - $newestMTime = filemtime($this->resource); - foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->resource), \RecursiveIteratorIterator::SELF_FIRST) as $file) { - // if regex filtering is enabled only check matching files - if ($this->pattern && $file->isFile() && !preg_match($this->pattern, $file->getBasename())) { - continue; - } - - // always monitor directories for changes, except the .. entries - // (otherwise deleted files wouldn't get detected) - if ($file->isDir() && '/..' === substr($file, -3)) { - continue; - } + foreach ($this->getFilteredChilds() as $file) { clearstatcache(true, (string) $file); $newestMTime = max($file->getMTime(), $newestMTime); } diff --git a/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php index 98714289a1..3345b451a3 100644 --- a/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php @@ -161,6 +161,7 @@ class DirectoryResourceTest extends \PHPUnit_Framework_TestCase /** * @covers Symfony\Component\Config\Resource\DirectoryResource::isFresh + * @covers Symfony\Component\Config\Resource\DirectoryResource::getFilteredChilds */ public function testFilterRegexListNoMatch() { From 1f9ba382eebcde54db80859df79bc607648f1126 Mon Sep 17 00:00:00 2001 From: everzet Date: Sat, 19 Nov 2011 23:31:59 +0100 Subject: [PATCH 03/11] [Config] getFilteredChildResources() method added to DirectoryResource --- .../Config/Resource/DirectoryResource.php | 76 ++++++++++++++----- 1 file changed, 58 insertions(+), 18 deletions(-) diff --git a/src/Symfony/Component/Config/Resource/DirectoryResource.php b/src/Symfony/Component/Config/Resource/DirectoryResource.php index 1818f6da9f..10424c3c6b 100644 --- a/src/Symfony/Component/Config/Resource/DirectoryResource.php +++ b/src/Symfony/Component/Config/Resource/DirectoryResource.php @@ -36,29 +36,15 @@ class DirectoryResource implements ResourceInterface, \Serializable /** * Returns the list of filtered file and directory childs of directory resource. * - * @param Boolean $recursive search for files recursive - * * @return array An array of files */ - public function getFilteredChilds($recursive = true) + public function getFilteredChilds() { - $iterator = $recursive - ? new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->resource), \RecursiveIteratorIterator::SELF_FIRST) - : new \DirectoryIterator($this->resource); - $childs = array(); - foreach ($iterator as $file) { + foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->resource), \RecursiveIteratorIterator::SELF_FIRST) as $file) { // if regex filtering is enabled only return matching files - if (isset($this->filterRegexList) && $file->isFile()) { - $regexMatched = false; - foreach ($this->filterRegexList as $regex) { - if (preg_match($regex, (string) $file)) { - $regexMatched = true; - } - } - if (!$regexMatched) { - continue; - } + if (!$this->isFileMatchesFilters($file)) { + continue; } // always monitor directories for changes, except the .. entries @@ -73,6 +59,36 @@ class DirectoryResource implements ResourceInterface, \Serializable return $childs; } + /** + * Returns child resources that matches directory filters. + * + * @return array + */ + public function getFilteredChildResources() + { + $iterator = new \DirectoryIterator($this->resource); + + $resources = array(); + foreach ($iterator as $file) { + // if regex filtering is enabled only return matching files + if (!$this->isFileMatchesFilters($file)) { + continue; + } + + // always monitor directories for changes, except the .. entries + // (otherwise deleted files wouldn't get detected) + if ($file->isDir() && '/..' === substr($file, -3)) { + continue; + } + + $resources[] = $file->isDir() + ? new DirectoryResource((string) $file) + : new FileResource((string) $file); + } + + return $resources; + } + /** * Returns a string representation of the Resource. * @@ -151,4 +167,28 @@ class DirectoryResource implements ResourceInterface, \Serializable { list($this->resource, $this->pattern) = unserialize($serialized); } + + /** + * Checks that passed file matches specified in resource filters. + * + * @param \SplFileInfo $file + * + * @return Boolean + */ + private function isFileMatchesFilters(\SplFileInfo $file) + { + if (isset($this->filterRegexList) && $file->isFile()) { + $regexMatched = false; + foreach ($this->filterRegexList as $regex) { + if (preg_match($regex, (string) $file)) { + $regexMatched = true; + } + } + if (!$regexMatched) { + return false; + } + } + + return true; + } } From 45a45baf2f0cd4eb052640ed394a45385d3b4a8b Mon Sep 17 00:00:00 2001 From: everzet Date: Fri, 25 Nov 2011 12:11:24 +0100 Subject: [PATCH 04/11] [Config] updated DirectoryResource tests --- .../Config/Resource/DirectoryResource.php | 27 +++++------ .../Tests/Resource/DirectoryResourceTest.php | 45 +++++++++++++------ 2 files changed, 44 insertions(+), 28 deletions(-) diff --git a/src/Symfony/Component/Config/Resource/DirectoryResource.php b/src/Symfony/Component/Config/Resource/DirectoryResource.php index 10424c3c6b..b36e0372db 100644 --- a/src/Symfony/Component/Config/Resource/DirectoryResource.php +++ b/src/Symfony/Component/Config/Resource/DirectoryResource.php @@ -43,7 +43,7 @@ class DirectoryResource implements ResourceInterface, \Serializable $childs = array(); foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->resource), \RecursiveIteratorIterator::SELF_FIRST) as $file) { // if regex filtering is enabled only return matching files - if (!$this->isFileMatchesFilters($file)) { + if ($file->isFile() && !$this->isFileMatchesPattern($file)) { continue; } @@ -71,7 +71,7 @@ class DirectoryResource implements ResourceInterface, \Serializable $resources = array(); foreach ($iterator as $file) { // if regex filtering is enabled only return matching files - if (!$this->isFileMatchesFilters($file)) { + if ($file->isFile() && !$this->isFileMatchesPattern($file)) { continue; } @@ -109,6 +109,11 @@ class DirectoryResource implements ResourceInterface, \Serializable return $this->resource; } + /** + * Returns check pattern. + * + * @return mixed + */ public function getPattern() { return $this->pattern; @@ -145,7 +150,7 @@ class DirectoryResource implements ResourceInterface, \Serializable return false; } - return $this->getModificationTime() <= $timestamp; + return $this->getModificationTime() < $timestamp; } /** @@ -155,7 +160,7 @@ class DirectoryResource implements ResourceInterface, \Serializable */ public function exists() { - return file_exists($this->resource); + return is_dir($this->resource); } public function serialize() @@ -175,18 +180,10 @@ class DirectoryResource implements ResourceInterface, \Serializable * * @return Boolean */ - private function isFileMatchesFilters(\SplFileInfo $file) + private function isFileMatchesPattern(\SplFileInfo $file) { - if (isset($this->filterRegexList) && $file->isFile()) { - $regexMatched = false; - foreach ($this->filterRegexList as $regex) { - if (preg_match($regex, (string) $file)) { - $regexMatched = true; - } - } - if (!$regexMatched) { - return false; - } + if ($this->pattern) { + return preg_match($this->pattern, $file->getBasename()); } return true; diff --git a/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php index 3345b451a3..77967f94d2 100644 --- a/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php @@ -118,20 +118,8 @@ class DirectoryResourceTest extends \PHPUnit_Framework_TestCase $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the whole resource is removed'); } - /** - * @covers Symfony\Component\Config\Resource\DirectoryResource::exists - */ - public function testExists() - { - $this->assertTrue($this->resource->exists(), '->exists() returns true if the directory still exist'); - - $this->removeDirectory($this->directory); - $this->assertFalse($this->resource->exists(), '->exists() returns false if the directory does not exist'); - } - /** * @covers Symfony\Component\Config\Resource\DirectoryResource::isFresh - * @covers Symfony\Component\Config\Resource\DirectoryResource::getModificationTime */ public function testIsFreshCreateFileInSubdirectory() { @@ -161,7 +149,6 @@ class DirectoryResourceTest extends \PHPUnit_Framework_TestCase /** * @covers Symfony\Component\Config\Resource\DirectoryResource::isFresh - * @covers Symfony\Component\Config\Resource\DirectoryResource::getFilteredChilds */ public function testFilterRegexListNoMatch() { @@ -181,4 +168,36 @@ class DirectoryResourceTest extends \PHPUnit_Framework_TestCase touch($this->directory.'/new.xml', time() + 20); $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if an new file matching the filter regex is created '); } + + /** + * @covers Symfony\Component\Config\Resource\DirectoryResource::exists + */ + public function testDirectoryExists() + { + $resource = new DirectoryResource($this->directory); + + $this->assertTrue($resource->exists(), '->exists() returns true if directory exists '); + + unlink($this->directory.'/tmp.xml'); + rmdir($this->directory); + + $this->assertFalse($resource->exists(), '->exists() returns false if directory does not exists'); + } + + /** + * @covers Symfony\Component\Config\Resource\DirectoryResource::getModificationTime + */ + public function testGetModificationTime() + { + $resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/'); + + touch($this->directory.'/new.xml', $time = time() + 20); + $this->assertSame($time, $resource->getModificationTime(), '->getModificationTime() returns time of the last modificated resource'); + + touch($this->directory.'/some', time() + 60); + $this->assertSame($time, $resource->getModificationTime(), '->getModificationTime() returns time of last modificated resource, that only matches pattern'); + + touch($this->directory, $time2 = time() + 90); + $this->assertSame($time2, $resource->getModificationTime(), '->getModificationTime() returns modification time of the directory itself'); + } } From 9fe0d00735b737fb391f3b2b6a365674569e0b63 Mon Sep 17 00:00:00 2001 From: everzet Date: Fri, 25 Nov 2011 14:48:15 +0100 Subject: [PATCH 05/11] [Config] update FileResourceTest --- .../Tests/Resource/FileResourceTest.php | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php index 1c5fa4253b..236dfabf8f 100644 --- a/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php @@ -27,7 +27,9 @@ class FileResourceTest extends \PHPUnit_Framework_TestCase protected function tearDown() { - unlink($this->file); + if ($this->file) { + unlink($this->file); + } } /** @@ -50,22 +52,25 @@ class FileResourceTest extends \PHPUnit_Framework_TestCase $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the resource does not exist'); } - /** - * @covers Symfony\Component\Config\Resource\FileResource::exists - */ - public function testExists() - { - $this->assertTrue($this->resource->exists(), '->exists() returns true if the resource does exist'); - - $resource = new FileResource('/____foo/foobar'.rand(1, 999999)); - $this->assertFalse($resource->exists(), '->exists() returns false if the resource does not exist'); - } - /** * @covers Symfony\Component\Config\Resource\FileResource::getModificationTime */ public function testGetModificationTime() { - $this->assertSame(filemtime($this->resource->getResource()), $this->resource->getModificationTime()); + touch($this->file, $time = time() + 100); + $this->assertSame($time, $this->resource->getModificationTime()); + } + + /** + * @covers Symfony\Component\Config\Resource\FileResource::exists + */ + public function testExists() + { + $this->assertTrue($this->resource->exists(), '->exists() returns true if the resource exists'); + + unlink($this->file); + $this->file = null; + + $this->assertFalse($this->resource->exists(), '->exists() returns false if the resource does not exists'); } } From d7c24eb88ab384e3992245d7cf1e7ef075b69283 Mon Sep 17 00:00:00 2001 From: everzet Date: Tue, 29 Nov 2011 22:51:48 +0100 Subject: [PATCH 06/11] [Config] added new methods and their tests to File and Directory resources --- .../Config/Resource/DirectoryResource.php | 69 +++++++++++----- .../Config/Resource/FileResource.php | 10 +++ .../Config/Resource/ResourceInterface.php | 7 ++ .../Tests/Resource/DirectoryResourceTest.php | 80 +++++++++++++++++++ .../Tests/Resource/FileResourceTest.php | 12 +++ 5 files changed, 156 insertions(+), 22 deletions(-) diff --git a/src/Symfony/Component/Config/Resource/DirectoryResource.php b/src/Symfony/Component/Config/Resource/DirectoryResource.php index b36e0372db..c2c1e58959 100644 --- a/src/Symfony/Component/Config/Resource/DirectoryResource.php +++ b/src/Symfony/Component/Config/Resource/DirectoryResource.php @@ -43,7 +43,7 @@ class DirectoryResource implements ResourceInterface, \Serializable $childs = array(); foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->resource), \RecursiveIteratorIterator::SELF_FIRST) as $file) { // if regex filtering is enabled only return matching files - if ($file->isFile() && !$this->isFileMatchesPattern($file)) { + if ($file->isFile() && !$this->hasFile($file)) { continue; } @@ -64,14 +64,14 @@ class DirectoryResource implements ResourceInterface, \Serializable * * @return array */ - public function getFilteredChildResources() + public function getFilteredResources() { $iterator = new \DirectoryIterator($this->resource); $resources = array(); foreach ($iterator as $file) { // if regex filtering is enabled only return matching files - if ($file->isFile() && !$this->isFileMatchesPattern($file)) { + if ($file->isFile() && !$this->hasFile($file)) { continue; } @@ -81,9 +81,16 @@ class DirectoryResource implements ResourceInterface, \Serializable continue; } - $resources[] = $file->isDir() - ? new DirectoryResource((string) $file) - : new FileResource((string) $file); + // if file is dot - continue + if ($file->isDot()) { + continue; + } + + if ($file->isFile()) { + $resources[] = new FileResource($file->getRealPath()); + } elseif ($file->isDir()) { + $resources[] = new DirectoryResource($file->getRealPath()); + } } return $resources; @@ -119,6 +126,30 @@ class DirectoryResource implements ResourceInterface, \Serializable return $this->pattern; } + /** + * Checks that passed file exists in resource and matches resource filters. + * + * @param SplFileInfo|string $file + * + * @return Boolean + */ + public function hasFile($file) + { + if (!$file instanceof \SplFileInfo) { + $file = new \SplFileInfo($file); + } + + if (0 !== strpos($file->getRealPath(), realpath($this->resource))) { + return false; + } + + if ($this->pattern) { + return (bool) preg_match($this->pattern, $file->getBasename()); + } + + return true; + } + /** * Returns resource mtime. * @@ -163,6 +194,16 @@ class DirectoryResource implements ResourceInterface, \Serializable return is_dir($this->resource); } + /** + * Returns unique resource ID. + * + * @return string + */ + public function getId() + { + return md5($this->resource.$this->pattern); + } + public function serialize() { return serialize(array($this->resource, $this->pattern)); @@ -172,20 +213,4 @@ class DirectoryResource implements ResourceInterface, \Serializable { list($this->resource, $this->pattern) = unserialize($serialized); } - - /** - * Checks that passed file matches specified in resource filters. - * - * @param \SplFileInfo $file - * - * @return Boolean - */ - private function isFileMatchesPattern(\SplFileInfo $file) - { - if ($this->pattern) { - return preg_match($this->pattern, $file->getBasename()); - } - - return true; - } } diff --git a/src/Symfony/Component/Config/Resource/FileResource.php b/src/Symfony/Component/Config/Resource/FileResource.php index 2499de68e5..9d699dae00 100644 --- a/src/Symfony/Component/Config/Resource/FileResource.php +++ b/src/Symfony/Component/Config/Resource/FileResource.php @@ -90,6 +90,16 @@ class FileResource implements ResourceInterface, \Serializable return file_exists($this->resource); } + /** + * Returns unique resource ID. + * + * @return string + */ + public function getId() + { + return md5($this->resource); + } + public function serialize() { return serialize($this->resource); diff --git a/src/Symfony/Component/Config/Resource/ResourceInterface.php b/src/Symfony/Component/Config/Resource/ResourceInterface.php index e684fd6b09..b4529e8de6 100644 --- a/src/Symfony/Component/Config/Resource/ResourceInterface.php +++ b/src/Symfony/Component/Config/Resource/ResourceInterface.php @@ -54,4 +54,11 @@ interface ResourceInterface * @return mixed The resource */ function getResource(); + + /** + * Returns unique resource ID. + * + * @return string + */ + function getId(); } diff --git a/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php index 77967f94d2..d702a5bc55 100644 --- a/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php @@ -50,6 +50,20 @@ class DirectoryResourceTest extends \PHPUnit_Framework_TestCase rmdir($directory); } + /** + * @covers Symfony\Component\Config\Resource\DirectoryResource::getId + */ + public function testGetId() + { + $resource1 = new DirectoryResource($this->directory); + $resource2 = new DirectoryResource($this->directory); + $resource3 = new DirectoryResource($this->directory, '/\.(foo|xml)$/'); + + $this->assertNotNull($resource1->getId()); + $this->assertEquals($resource1->getId(), $resource2->getId()); + $this->assertNotEquals($resource1->getId(), $resource3->getId()); + } + /** * @covers Symfony\Component\Config\Resource\DirectoryResource::getResource */ @@ -169,6 +183,72 @@ class DirectoryResourceTest extends \PHPUnit_Framework_TestCase $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if an new file matching the filter regex is created '); } + /** + * @covers Symfony\Component\Config\Resource\DirectoryResource::hasFile + */ + public function testHasFile() + { + $resource = new DirectoryResource($this->directory, '/\.foo$/'); + + touch($this->directory.'/new.foo', time() + 20); + + $this->assertFalse($resource->hasFile($this->directory.'/tmp.xml')); + $this->assertTrue($resource->hasFile($this->directory.'/new.foo')); + } + + /** + * @covers Symfony\Component\Config\Resource\DirectoryResource::getFilteredChilds + */ + public function testGetFilteredChilds() + { + $resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/'); + + touch($file1 = $this->directory.'/new.xml', time() + 20); + touch($file2 = $this->directory.'/old.foo', time() + 20); + touch($this->directory.'/old', time() + 20); + mkdir($dir = $this->directory.'/sub'); + touch($file3 = $this->directory.'/sub/file.foo', time() + 20); + + $childs = $resource->getFilteredChilds(); + $this->assertSame(5, count($childs)); + + $childs = array_map(function($item) { + return (string) $item; + }, $childs); + + $this->assertContains($file1, $childs); + $this->assertContains($file2, $childs); + $this->assertContains($dir, $childs); + $this->assertContains($this->directory.'/tmp.xml', $childs); + $this->assertContains($file3, $childs); + } + + /** + * @covers Symfony\Component\Config\Resource\DirectoryResource::getFilteredResources + */ + public function testGetFilteredResources() + { + $resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/'); + + touch($file1 = $this->directory.'/new.xml', time() + 20); + touch($file2 = $this->directory.'/old.foo', time() + 20); + touch($this->directory.'/old', time() + 20); + mkdir($dir = $this->directory.'/sub'); + touch($file3 = $this->directory.'/sub/file.foo', time() + 20); + + $resources = $resource->getFilteredResources(); + $this->assertSame(4, count($resources)); + + $childs = array_map(function($item) { + return realpath($item->getResource()); + }, $resources); + + $this->assertContains(realpath($file1), $childs); + $this->assertContains(realpath($file2), $childs); + $this->assertContains(realpath($dir), $childs); + $this->assertContains(realpath($this->directory.'/tmp.xml'), $childs); + } + /** * @covers Symfony\Component\Config\Resource\DirectoryResource::exists */ diff --git a/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php b/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php index 236dfabf8f..5413c7ed70 100644 --- a/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php +++ b/src/Symfony/Component/Config/Tests/Resource/FileResourceTest.php @@ -32,6 +32,18 @@ class FileResourceTest extends \PHPUnit_Framework_TestCase } } + /** + * @covers Symfony\Component\Config\Resource\DirectoryResource::getId + */ + public function testGetId() + { + $resource1 = new FileResource($this->file); + $resource2 = new FileResource($this->file); + + $this->assertNotNull($resource1->getId()); + $this->assertEquals($resource1->getId(), $resource2->getId()); + } + /** * @covers Symfony\Component\Config\Resource\FileResource::getResource */ From c9eaa72e2f7e0945eb9f90a6da8f397a1a0fe974 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 5 Dec 2011 13:58:28 +0100 Subject: [PATCH 07/11] [Config] made ResourceInterface extends Serializable --- src/Symfony/Component/Config/Resource/DirectoryResource.php | 2 +- src/Symfony/Component/Config/Resource/FileResource.php | 2 +- src/Symfony/Component/Config/Resource/ResourceInterface.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Config/Resource/DirectoryResource.php b/src/Symfony/Component/Config/Resource/DirectoryResource.php index c2c1e58959..0a4c39d151 100644 --- a/src/Symfony/Component/Config/Resource/DirectoryResource.php +++ b/src/Symfony/Component/Config/Resource/DirectoryResource.php @@ -16,7 +16,7 @@ namespace Symfony\Component\Config\Resource; * * @author Fabien Potencier */ -class DirectoryResource implements ResourceInterface, \Serializable +class DirectoryResource implements ResourceInterface { private $resource; private $pattern; diff --git a/src/Symfony/Component/Config/Resource/FileResource.php b/src/Symfony/Component/Config/Resource/FileResource.php index 9d699dae00..2ebc39f2da 100644 --- a/src/Symfony/Component/Config/Resource/FileResource.php +++ b/src/Symfony/Component/Config/Resource/FileResource.php @@ -18,7 +18,7 @@ namespace Symfony\Component\Config\Resource; * * @author Fabien Potencier */ -class FileResource implements ResourceInterface, \Serializable +class FileResource implements ResourceInterface { private $resource; diff --git a/src/Symfony/Component/Config/Resource/ResourceInterface.php b/src/Symfony/Component/Config/Resource/ResourceInterface.php index b4529e8de6..7febbd8139 100644 --- a/src/Symfony/Component/Config/Resource/ResourceInterface.php +++ b/src/Symfony/Component/Config/Resource/ResourceInterface.php @@ -16,7 +16,7 @@ namespace Symfony\Component\Config\Resource; * * @author Fabien Potencier */ -interface ResourceInterface +interface ResourceInterface extends \Serializable { /** * Returns a string representation of the Resource. From ece489f4b952d7961fcbd14837ca55576dc2ada3 Mon Sep 17 00:00:00 2001 From: everzet Date: Fri, 20 Apr 2012 13:17:55 +0200 Subject: [PATCH 08/11] [Config] skip dots in getFilteredChilds() (fixes test suite on Linux) --- .../Component/Config/Resource/DirectoryResource.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Config/Resource/DirectoryResource.php b/src/Symfony/Component/Config/Resource/DirectoryResource.php index 0a4c39d151..7d31cd3f5c 100644 --- a/src/Symfony/Component/Config/Resource/DirectoryResource.php +++ b/src/Symfony/Component/Config/Resource/DirectoryResource.php @@ -40,8 +40,17 @@ class DirectoryResource implements ResourceInterface */ public function getFilteredChilds() { + if (!$this->exists()) { + return array(); + } + + $iterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($this->resource, \FilesystemIterator::SKIP_DOTS), + \RecursiveIteratorIterator::SELF_FIRST + ); + $childs = array(); - foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->resource), \RecursiveIteratorIterator::SELF_FIRST) as $file) { + foreach ($iterator as $file) { // if regex filtering is enabled only return matching files if ($file->isFile() && !$this->hasFile($file)) { continue; From ff9c1321dc2d7014d7a516a7d939e8e0e66bf1ed Mon Sep 17 00:00:00 2001 From: everzet Date: Sat, 9 Jun 2012 13:25:01 +0200 Subject: [PATCH 09/11] [Config] added type prefixes to resource ids Makes sure that directory and the file resources with the same name will have different ids --- src/Symfony/Component/Config/Resource/DirectoryResource.php | 2 +- src/Symfony/Component/Config/Resource/FileResource.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Config/Resource/DirectoryResource.php b/src/Symfony/Component/Config/Resource/DirectoryResource.php index 7d31cd3f5c..13ef5d10da 100644 --- a/src/Symfony/Component/Config/Resource/DirectoryResource.php +++ b/src/Symfony/Component/Config/Resource/DirectoryResource.php @@ -210,7 +210,7 @@ class DirectoryResource implements ResourceInterface */ public function getId() { - return md5($this->resource.$this->pattern); + return md5('d'.$this->resource.$this->pattern); } public function serialize() diff --git a/src/Symfony/Component/Config/Resource/FileResource.php b/src/Symfony/Component/Config/Resource/FileResource.php index 2ebc39f2da..86618f63d1 100644 --- a/src/Symfony/Component/Config/Resource/FileResource.php +++ b/src/Symfony/Component/Config/Resource/FileResource.php @@ -97,7 +97,7 @@ class FileResource implements ResourceInterface */ public function getId() { - return md5($this->resource); + return md5('f'.$this->resource); } public function serialize() From 56b60c8d460d2de1a82c2890c538531bf5aa6fdc Mon Sep 17 00:00:00 2001 From: everzet Date: Sat, 9 Jun 2012 13:31:14 +0200 Subject: [PATCH 10/11] [Config] use is_file in FileResource::exists() file resource existence check shouldn't return true if there's directory with same name instead of file. --- src/Symfony/Component/Config/Resource/FileResource.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Config/Resource/FileResource.php b/src/Symfony/Component/Config/Resource/FileResource.php index 86618f63d1..07564a3470 100644 --- a/src/Symfony/Component/Config/Resource/FileResource.php +++ b/src/Symfony/Component/Config/Resource/FileResource.php @@ -87,7 +87,7 @@ class FileResource implements ResourceInterface */ public function exists() { - return file_exists($this->resource); + return is_file($this->resource); } /** From 241aa92cc5db32b7d4125e47b04bb67466ef6150 Mon Sep 17 00:00:00 2001 From: everzet Date: Wed, 20 Jun 2012 10:19:09 +0200 Subject: [PATCH 11/11] [Config] added existence check to some resource methods * fixed DELETED event when starting to watch a file that does not exist yet * fixed files that are deleted and then re-created Conflicts: src/Symfony/Component/ResourceWatcher/StateChecker/ResourceStateChecker.php tests/Symfony/Tests/Component/ResourceWatcher/StateChecker/DirectoryStateCheckerTest.php tests/Symfony/Tests/Component/ResourceWatcher/StateChecker/FileStateCheckerTest.php --- .../Component/Config/Resource/DirectoryResource.php | 8 ++++++++ src/Symfony/Component/Config/Resource/FileResource.php | 6 +++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Config/Resource/DirectoryResource.php b/src/Symfony/Component/Config/Resource/DirectoryResource.php index 13ef5d10da..474fbb3078 100644 --- a/src/Symfony/Component/Config/Resource/DirectoryResource.php +++ b/src/Symfony/Component/Config/Resource/DirectoryResource.php @@ -75,6 +75,10 @@ class DirectoryResource implements ResourceInterface */ public function getFilteredResources() { + if (!$this->exists()) { + return array(); + } + $iterator = new \DirectoryIterator($this->resource); $resources = array(); @@ -166,6 +170,10 @@ class DirectoryResource implements ResourceInterface */ public function getModificationTime() { + if (!$this->exists()) { + return -1; + } + clearstatcache(true, $this->resource); $newestMTime = filemtime($this->resource); diff --git a/src/Symfony/Component/Config/Resource/FileResource.php b/src/Symfony/Component/Config/Resource/FileResource.php index 07564a3470..259db3c75d 100644 --- a/src/Symfony/Component/Config/Resource/FileResource.php +++ b/src/Symfony/Component/Config/Resource/FileResource.php @@ -29,7 +29,7 @@ class FileResource implements ResourceInterface */ public function __construct($resource) { - $this->resource = realpath($resource); + $this->resource = file_exists($resource) ? realpath($resource) : $resource; } /** @@ -59,6 +59,10 @@ class FileResource implements ResourceInterface */ public function getModificationTime() { + if (!$this->exists()) { + return -1; + } + clearstatcache(true, $this->resource); return filemtime($this->resource);