diff --git a/src/Symfony/Component/Finder/Finder.php b/src/Symfony/Component/Finder/Finder.php index f4b3c7d8c31d9..7e50bd44914ce 100644 --- a/src/Symfony/Component/Finder/Finder.php +++ b/src/Symfony/Component/Finder/Finder.php @@ -494,7 +494,7 @@ public function in($dirs) $dirs = (array) $dirs; foreach ($dirs as $dir) { - if (!is_dir($dir)) { + if (!is_dir($dir) && !Iterator\FtpRecursiveDirectoryIterator::isValidFtpUrl($dir)) { throw new \InvalidArgumentException(sprintf('The "%s" directory does not exist.', $dir)); } } @@ -577,10 +577,17 @@ private function searchInDirectory($dir) $flags |= \RecursiveDirectoryIterator::FOLLOW_SYMLINKS; } - $iterator = new \RecursiveIteratorIterator( - new Iterator\RecursiveDirectoryIterator($dir, $flags), - \RecursiveIteratorIterator::SELF_FIRST - ); + if (Iterator\FtpRecursiveDirectoryIterator::isValidFtpUrl($dir)) { + $iterator = new \RecursiveIteratorIterator( + new Iterator\FtpRecursiveDirectoryIterator($dir), + \RecursiveIteratorIterator::SELF_FIRST + ); + } else { + $iterator = new \RecursiveIteratorIterator( + new Iterator\RecursiveDirectoryIterator($dir, $flags), + \RecursiveIteratorIterator::SELF_FIRST + ); + } if ($this->depths) { $iterator = new Iterator\DepthRangeFilterIterator($iterator, $this->depths); diff --git a/src/Symfony/Component/Finder/FtpSplFileInfo.php b/src/Symfony/Component/Finder/FtpSplFileInfo.php new file mode 100644 index 0000000000000..0cdaa7db312a4 --- /dev/null +++ b/src/Symfony/Component/Finder/FtpSplFileInfo.php @@ -0,0 +1,137 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder; + +/** + * FtpSplFileInfo implements \SplFileInfo + * for files/directories accesible via ftp connection. + * + * @author Włodzimierz Gajda + */ +class FtpSplFileInfo extends SplFileInfo +{ + + const TYPE_UNKNOWN = 1; + const TYPE_DIRECTORY = 2; + const TYPE_FILE = 3; + const TYPE_LINK = 4; + + private $type = self::TYPE_FILE; + private $basePath = ''; + + public function __construct($file, $relativePath, $relativePathname, $basePath) + { + parent::__construct($file, $relativePath, $relativePathname); + $this->setBasePath($basePath); + } + + public function setBasePath($basePath) + { + $this->basePath = $basePath; + } + + public function getBasePath() + { + return $this->basePath; + } + + public function getRealpath() + { + return $this->getPathname(); + } + + public function getItemname($item) + { + if (0 === strpos($item, '/')) { + throw new \InvalidArgumentException(sprintf('Item can not be absolute path: "%s".', $item)); + } + $result = $this->getRealpath(); + $len = strlen($result); + if ($result[$len - 1] != '/') { + $result .= '/'; + } + + return $result . $item; + } + + /** + * Sets the type. + * + * @param integer $type + */ + public function setType($type) + { + $this->type = $type; + } + + /** + * Returns the type. + * + * @return integer the type of the current object. + */ + public function getType() + { + return $this->type; + } + + /** + * Checks if the current object is a directory. + * + * @return Boolean true if the current object represents a directory + * + */ + public function isDir() + { + return self::TYPE_DIRECTORY === $this->type; + } + + /** + * Checks if the current object is a file. + * + * @return Boolean true if the current object represents a file + * + */ + public function isFile() + { + return self::TYPE_FILE === $this->type; + } + + /** + * Parses the output of ftp_rawlist to get the type: + * d (directory), - (file), l (link) + * + * @param string $item the output of ftp raw list + * + * @return type + */ + public static function parseRawListItem($item) + { + if ($item === '') { + return self::TYPE_UNKNOWN; + } + switch ($item[0]) { + + case 'd': + return self::TYPE_DIRECTORY; + + case '-': + return self::TYPE_FILE; + + case 'l': + return self::TYPE_LINK; + + default: + return self::TYPE_UNKNOWN; + } + } + +} diff --git a/src/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php b/src/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php index cff773d3e77f1..40759c04f59e7 100644 --- a/src/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php +++ b/src/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php @@ -43,7 +43,7 @@ public function __construct(\Iterator $iterator, array $directories) */ public function accept() { - $path = $this->isDir() ? $this->getSubPathname() : $this->getSubPath(); + $path = $this->isDir() ? $this->current()->getRelativePathname() : $this->current()->getRelativePath(); $path = strtr($path, '\\', '/'); foreach ($this->patterns as $pattern) { if (preg_match($pattern, $path)) { diff --git a/src/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php b/src/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php index 96b6867a3042c..da62ecf4a9426 100644 --- a/src/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php +++ b/src/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php @@ -43,9 +43,10 @@ public function __construct(\Iterator $iterator, $mode) */ public function accept() { - if (self::ONLY_DIRECTORIES === (self::ONLY_DIRECTORIES & $this->mode) && $this->isFile()) { + $fileinfo = $this->current(); + if (self::ONLY_DIRECTORIES === (self::ONLY_DIRECTORIES & $this->mode) && $fileinfo->isFile()) { return false; - } elseif (self::ONLY_FILES === (self::ONLY_FILES & $this->mode) && $this->isDir()) { + } elseif (self::ONLY_FILES === (self::ONLY_FILES & $this->mode) && $fileinfo->isDir()) { return false; } diff --git a/src/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php b/src/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php index ffe3ddb7a8edb..953f9c373386b 100644 --- a/src/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php +++ b/src/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php @@ -30,13 +30,15 @@ public function accept() return true; } - if ($this->isDir() || !$this->isReadable()) { + $fileinfo = $this->current(); + + if ($fileinfo->isDir() || !$fileinfo->isReadable()) { return false; } - $content = @file_get_contents($filename = $this->getRealpath()); - if (false === $content) { - throw new \RuntimeException(sprintf('Error reading file "%s".', $this->getRealpath())); + $content = $fileinfo->getContents(); + if (!$content) { + return false; } // should at least not match one rule to exclude diff --git a/src/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php b/src/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php index 03189e3a8a1d1..109b5f00294bc 100644 --- a/src/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php +++ b/src/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php @@ -28,7 +28,7 @@ class FilenameFilterIterator extends MultiplePcreFilterIterator */ public function accept() { - $filename = $this->getFilename(); + $filename = $this->current()->getFilename(); // should at least not match one rule to exclude foreach ($this->noMatchRegexps as $regex) { diff --git a/src/Symfony/Component/Finder/Iterator/FtpRecursiveDirectoryIterator.php b/src/Symfony/Component/Finder/Iterator/FtpRecursiveDirectoryIterator.php new file mode 100644 index 0000000000000..30b955ee5860a --- /dev/null +++ b/src/Symfony/Component/Finder/Iterator/FtpRecursiveDirectoryIterator.php @@ -0,0 +1,138 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Iterator; + +use Symfony\Component\Finder\FtpSplFileInfo; +use Symfony\Component\Finder\Util\Ftp; + +/** + * RecursiveDirectoryFtpIterator implements \RecursiveDirectoryIterator + * over ftp stream. + * + * @author Włodzimierz Gajda + */ +class FtpRecursiveDirectoryIterator extends FtpSplFileInfo implements \RecursiveIterator +{ + + private $contents = array(); + private $ftp = false; + + public function __construct($file) + { + if (0 === strpos($file, 'ftp://')) { + $parsedUrl = parse_url($file); + if (isset($parsedUrl['scheme']) && $parsedUrl['scheme'] != 'ftp') { + throw new \InvalidArgumentException(sprintf('Ftp url expected. Incorrect value: "%s"', $item)); + } + $defaults = array( + 'user' => 'anonymous', + 'pass' => '', + 'path' => '/' + ); + $defaults = array_merge($defaults, $parsedUrl); + $this->ftp = new Ftp($defaults); + $this->ftp->connectAndLogin(); + parent::__construct($defaults['path'], '', '', ''); + } else { + parent::__construct($file, '', '', ''); + } + $this->setType(self::TYPE_DIRECTORY); + } + + public function isConnected() + { + return $this->ftp->isConnected(); + } + + public function getConnection() + { + return $this->ftp; + } + + public function setConnection($ftp) + { + $this->ftp = $ftp; + } + + public function getChildren() + { + $iterator = new FtpRecursiveDirectoryIterator($this->current()->getRealPath()); + $iterator->setConnection($this->getConnection()); + + return $iterator; + } + + public function hasChildren() + { + return $this->current()->isDir(); + } + + public function current() + { + return current($this->contents); + } + + public function key() + { + return $this->current()->getRealPath(); + } + + public function next() + { + next($this->contents); + } + + public function rewind() + { + $this->refresh(); + } + + /** + * + * Destroy $this->contents and generate is once again? + * + */ + public function refresh() + { + $this->ftp->chDir($this->getPathname()); + + $names = $this->ftp->nList($this->getPathname()); + $types = $this->ftp->rawList($this->getPathname()); + + $this->contents = array(); + foreach ($names as $k => $name) { + $parsedType = self::parseRawListItem($types[$k]); + $item = new FtpSplFileInfo($name, '', '', ''); + $item->setType($parsedType); + $this->contents[] = $item; + } + } + + public function valid() + { + return $this->isConnected() && (current($this->contents) instanceof FtpSplFileInfo); + } + + public static function isValidFtpUrl($url) + { + if (0 !== strpos($url, 'ftp://')) { + return false; + } + $parsedUrl = parse_url($url); + if ($parsedUrl['scheme'] === 'ftp') { + return true; + } + + return false; + } + +} \ No newline at end of file diff --git a/src/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php b/src/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php index 0b672c1062345..b9b80441beb17 100644 --- a/src/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php +++ b/src/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php @@ -40,11 +40,12 @@ public function __construct(\Iterator $iterator, array $comparators) */ public function accept() { - if (!$this->isFile()) { + $fileinfo = $this->current(); + if (!$fileinfo->isFile()) { return true; } - $filesize = $this->getSize(); + $filesize = $fileinfo->getSize(); foreach ($this->comparators as $compare) { if (!$compare->test($filesize)) { return false; diff --git a/src/Symfony/Component/Finder/SplFileInfo.php b/src/Symfony/Component/Finder/SplFileInfo.php index 6fe003a79c6b0..e9d4f7b72f1d4 100644 --- a/src/Symfony/Component/Finder/SplFileInfo.php +++ b/src/Symfony/Component/Finder/SplFileInfo.php @@ -54,4 +54,22 @@ public function getRelativePathname() { return $this->relativePathname; } + + /** + * Returns the contents of the file + * + * @return string the contents of the file + */ + public function getContents() + { + $level = error_reporting(0); + $content = file_get_contents($this->getRealpath()); + error_reporting($level); + if (false === $content) { + $error = error_get_last(); + throw new \RuntimeException($error['message']); + } + + return $content; + } } diff --git a/src/Symfony/Component/Finder/Tests/FinderTest.php b/src/Symfony/Component/Finder/Tests/FinderTest.php index fda06079cae79..e2b88d822af27 100644 --- a/src/Symfony/Component/Finder/Tests/FinderTest.php +++ b/src/Symfony/Component/Finder/Tests/FinderTest.php @@ -232,7 +232,7 @@ public function testIn() $finder = new Finder(); $iterator = $finder->files()->name('*.php')->depth('< 1')->in(array(self::$tmpDir, __DIR__))->getIterator(); - $this->assertIterator(array(self::$tmpDir.DIRECTORY_SEPARATOR.'test.php', __DIR__.DIRECTORY_SEPARATOR.'FinderTest.php', __DIR__.DIRECTORY_SEPARATOR.'bootstrap.php', __DIR__.DIRECTORY_SEPARATOR.'GlobTest.php'), $iterator); + $this->assertIterator(array(self::$tmpDir.DIRECTORY_SEPARATOR.'test.php', __DIR__.DIRECTORY_SEPARATOR.'FinderTest.php', __DIR__.DIRECTORY_SEPARATOR.'bootstrap.php', __DIR__.DIRECTORY_SEPARATOR.'GlobTest.php', __DIR__.DIRECTORY_SEPARATOR.'FtpSplFileInfoTest.php'), $iterator); } public function testGetIterator() diff --git a/src/Symfony/Component/Finder/Tests/FtpSplFileInfoTest.php b/src/Symfony/Component/Finder/Tests/FtpSplFileInfoTest.php new file mode 100644 index 0000000000000..d8b1d8792a17a --- /dev/null +++ b/src/Symfony/Component/Finder/Tests/FtpSplFileInfoTest.php @@ -0,0 +1,149 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Tests; + +use Symfony\Component\Finder\FtpSplFileInfo; + +class FtpSplFileInfoTest extends Iterator\RealIteratorTestCase +{ + /** + * + * @dataProvider getTestParseRawListItemData + */ + public function testParseRawListItem($string, $type) + { + $this->assertEquals($type, FtpSplFileInfo::parseRawListItem($string)); + } + + public function getTestParseRawListItemData() + { + return array( + array('d ', FtpSplFileInfo::TYPE_DIRECTORY), + array('d', FtpSplFileInfo::TYPE_DIRECTORY), + array('drwxrwxrwx', FtpSplFileInfo::TYPE_DIRECTORY), + array('-', FtpSplFileInfo::TYPE_FILE), + array('-rwxrwxrwx', FtpSplFileInfo::TYPE_FILE), + array('a', FtpSplFileInfo::TYPE_UNKNOWN), + array('?fdsaf', FtpSplFileInfo::TYPE_UNKNOWN), + array('link', FtpSplFileInfo::TYPE_LINK), + array('', FtpSplFileInfo::TYPE_UNKNOWN), + array(123, FtpSplFileInfo::TYPE_UNKNOWN), + ); + } + + /** + * + * @dataProvider getTestConstructorData + */ + public function testConstructor($data, $expected) + { + $f = new FtpSplFileInfo($data['file'], $data['relativePath'], $data['relativePathname'], $data['basePath']); + $result = array( + 'baseneme' => $f->getBasename(), + 'filename' => $f->getFilename(), + 'path' => $f->getPath(), + 'pathname' => $f->getPathname(), + 'realPath' => $f->getRealPath(), + 'relativepath' => $f->getRelativePath(), + 'relativePathname' => $f->getRelativePathname(), + 'itemName' => $f->getItemname($data['item']), + ); + $this->assertEquals($expected, $result); + } + + public function getTestConstructorData() + { + return array( + + array( + 'data' => array( + 'file' => '/', + 'relativePath' => '', + 'relativePathname' => '', + 'basePath' => '', + 'item' => 'pub', + ), + 'result' => array( + 'baseneme' => '', + 'filename' => '/', + 'path' => '', + 'pathname' => '/', + 'realPath' => '/', + 'relativepath' => '', + 'relativePathname' => '', + 'itemName' => '/pub', + ) + ), + + array( + 'data' => array( + 'file' => '/pub', + 'relativePath' => '', + 'relativePathname' => '', + 'basePath' => '', + 'item' => 'file.txt', + ), + 'result' => array( + 'baseneme' => 'pub', + 'filename' => '/pub', + 'path' => '', + 'pathname' => '/pub', + 'realPath' => '/pub', + 'relativepath' => '', + 'relativePathname' => '', + 'itemName' => '/pub/file.txt', + ) + ), + array( + 'data' => array( + 'file' => '/tmp/my/dir/', + 'relativePath' => '', + 'relativePathname' => '', + 'basePath' => '', + 'item' => 'nextFile.yml', + ), + 'result' => array( + 'baseneme' => 'dir', + 'filename' => 'dir', + 'path' => '/tmp/my', + 'pathname' => '/tmp/my/dir', + 'realPath' => '/tmp/my/dir', + 'relativepath' => '', + 'relativePathname' => '', + 'itemName' => '/tmp/my/dir/nextFile.yml', + ) + ), + ); + } + + + /** + * + * @dataProvider getTestGetItemnameData + */ + public function testGetItemname($directory, $item, $result) + { + $ftp = new FtpSplFileInfo($directory, '', '', ''); + $this->assertEquals($result, $ftp->getItemname($item)); + } + + public function getTestGetItemnameData() + { + return array( + array('/', 'file', '/file'), + array('/pub', 'file', '/pub/file'), + array('/lorem/ipsum/dolor', 'new', '/lorem/ipsum/dolor/new'), + ); + } + + +} diff --git a/src/Symfony/Component/Finder/Tests/Iterator/ExcludeDirectoryFileIteratorTest.php b/src/Symfony/Component/Finder/Tests/Iterator/ExcludeDirectoryFileIteratorTest.php index cd8b2155d93f6..a0c522bfe5336 100644 --- a/src/Symfony/Component/Finder/Tests/Iterator/ExcludeDirectoryFileIteratorTest.php +++ b/src/Symfony/Component/Finder/Tests/Iterator/ExcludeDirectoryFileIteratorTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Finder\Tests\Iterator; use Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator; +use Symfony\Component\Finder\Iterator\RecursiveDirectoryIterator; class ExcludeDirectoryFilterIteratorTest extends RealIteratorTestCase { @@ -20,7 +21,7 @@ class ExcludeDirectoryFilterIteratorTest extends RealIteratorTestCase */ public function testAccept($directories, $expected) { - $inner = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator(sys_get_temp_dir().'/symfony2_finder', \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST); + $inner = new \RecursiveIteratorIterator(new RecursiveDirectoryIterator(sys_get_temp_dir().'/symfony2_finder', \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST); $iterator = new ExcludeDirectoryFilterIterator($inner, $directories); diff --git a/src/Symfony/Component/Finder/Tests/Iterator/FilecontentFilterIteratorTest.php b/src/Symfony/Component/Finder/Tests/Iterator/FilecontentFilterIteratorTest.php index 38bc6c9e3a16a..f80e6a57aad8a 100644 --- a/src/Symfony/Component/Finder/Tests/Iterator/FilecontentFilterIteratorTest.php +++ b/src/Symfony/Component/Finder/Tests/Iterator/FilecontentFilterIteratorTest.php @@ -18,73 +18,176 @@ class FilecontentFilterIteratorTest extends IteratorTestCase public function testAccept() { - $inner = new ContentInnerNameIterator(array('test.txt')); + $inner = new MockFileListIterator(array('test.txt')); $iterator = new FilecontentFilterIterator($inner, array(), array()); $this->assertIterator(array('test.txt'), $iterator); } public function testDirectory() { - $inner = new ContentInnerNameIterator(array('directory')); + $inner = new MockFileListIterator(array('directory')); $iterator = new FilecontentFilterIterator($inner, array('directory'), array()); $this->assertIterator(array(), $iterator); } public function testUnreadableFile() { - $inner = new ContentInnerNameIterator(array('file r-')); + $inner = new MockFileListIterator(array('file r-')); $iterator = new FilecontentFilterIterator($inner, array('file r-'), array()); $this->assertIterator(array(), $iterator); } /** - * @expectedException RuntimeException + * @dataProvider getTestFilterData */ - public function testFileGetContents() + public function testFilter(\Iterator $inner, array $matchPatterns, array $noMatchPatterns, array $resultArray) { - $inner = new ContentInnerNameIterator(array('file r+')); - $iterator = new FilecontentFilterIterator($inner, array('file r+'), array()); - $array = iterator_to_array($iterator); + $iterator = new FilecontentFilterIterator($inner, $matchPatterns, $noMatchPatterns); + $this->assertIterator($resultArray, $iterator); } + public function getTestFilterData() + { + $inner = new MockFileListIterator(); + + $inner[] = new MockSplFileInfo(array( + 'name' => 'a.txt', + 'contents' => 'Lorem ipsum...', + 'type' => 'file', + 'mode' => 'r+') + ); + + $inner[] = new MockSplFileInfo(array( + 'name' => 'b.yml', + 'contents' => 'dolor sit...', + 'type' => 'file', + 'mode' => 'r+') + ); + + $inner[] = new MockSplFileInfo(array( + 'name' => 'some/other/dir/third.php', + 'contents' => 'amet...', + 'type' => 'file', + 'mode' => 'r+') + ); + + $inner[] = new MockSplFileInfo(array( + 'name' => 'unreadable-file.txt', + 'contents' => false, + 'type' => 'file', + 'mode' => 'r+') + ); + + return array( + array($inner, array('.'), array(), array('a.txt', 'b.yml', 'some/other/dir/third.php')), + array($inner, array('ipsum'), array(), array('a.txt')), + array($inner, array('i', 'amet'), array('Lorem', 'amet'), array('b.yml')), + ); + } } -class ContentInnerNameIterator extends \ArrayIterator +class MockSplFileInfo extends \SplFileInfo { - public function current() - { - return new \SplFileInfo(parent::current()); - } + const TYPE_DIRECTORY = 1; + const TYPE_FILE = 2; + const TYPE_UNKNOWN = 3; + + private $contents = null; + private $mode = null; + private $type = null; - public function getFilename() + public function __construct($param) { - return parent::current(); + if (is_string($param)) { + parent::__construct($param); + } elseif (is_array($param)) { + + $defaults = array( + 'name' => 'file.txt', + 'contents' => null, + 'mode' => null, + 'type' => null + ); + $defaults = array_merge($defaults, $param); + parent::__construct($defaults['name']); + $this->setContents($defaults['contents']); + $this->setMode($defaults['mode']); + $this->setType($defaults['type']); + } else { + throw new \RuntimeException(sprintf('Incorrect parameter "%s"', $param)); + } } public function isFile() { - $name = parent::current(); + if ($this->type === null) { + return preg_match('/file/', $this->getFilename()); + }; - return preg_match('/file/', $name); + return self::TYPE_FILE === $this->type; } public function isDir() { - $name = parent::current(); + if ($this->type === null) { + return preg_match('/directory/', $this->getFilename()); + } - return preg_match('/directory/', $name); + return self::TYPE_DIRECTORY === $this->type; } - public function getRealpath() + public function isReadable() { - return parent::current(); + if ($this->mode === null) { + return preg_match('/r\+/', $this->getFilename()); + } + + return preg_match('/r\+/', $this->mode); } - public function isReadable() + public function getContents() + { + return $this->contents; + } + + public function setContents($contents) { - $name = parent::current(); + $this->contents = $contents; + } + + public function setMode($mode) + { + $this->mode = $mode; + } - return preg_match('/r\+/', $name); + public function setType($type) + { + if (is_string($type)) { + switch ($type) { + case 'directory': + $this->type = self::TYPE_DIRECTORY; + case 'd': + $this->type = self::TYPE_DIRECTORY; + break; + case 'file': + $this->type = self::TYPE_FILE; + case 'f': + $this->type = self::TYPE_FILE; + break; + default: + $this->type = self::TYPE_UNKNOWN; + } + } else { + $this->type = $type; + } } +} +class MockFileListIterator extends \ArrayIterator +{ + public function __construct(array $filesArray = array()) + { + $files = array_map(function($file){ return new MockSplFileInfo($file); }, $filesArray); + parent::__construct($files); + } } diff --git a/src/Symfony/Component/Finder/Util/Ftp.php b/src/Symfony/Component/Finder/Util/Ftp.php new file mode 100644 index 0000000000000..062865fb5ff4d --- /dev/null +++ b/src/Symfony/Component/Finder/Util/Ftp.php @@ -0,0 +1,134 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Finder\Util; + +/** + * Ftp client using ftp extension. + * + * @author Włodzimierz Gajda + * + */ +class Ftp +{ + private $ftpParameters = array(); + private $ftpResource = null; + + public function __construct(array $parameters = array()) + { + $this->setFtpParameters($parameters); + } + + public function setFtpParameters(array $ftpParameters) + { + $this->ftpParameters = $ftpParameters; + } + + public function getFtpParameters() + { + return $this->ftpParameters; + } + + public function connectAndLogin() + { + if (!$this->isConnected()) { + $ftpConnId = ftp_connect($this->getFtpHost()); + $loginResult = ftp_login($ftpConnId, $this->getFtpUser(), $this->getFtpPass()); + + if ((!$ftpConnId) || (!$loginResult)) { + throw new \RuntimeException('Cannnot ftp_connect() or ftp_login()'); + } + $this->ftpResource = $ftpConnId; + ftp_pasv($this->ftpResource, true); + } + } + + public function isConnected() + { + return is_resource($this->ftpResource); + } + + public function getFtpResource() + { + return $this->ftpResource; + } + + public function getFtpHost() + { + if (isset($this->ftpParameters['host'])) { + return $this->ftpParameters['host']; + } else { + return ''; + } + } + + public function setFtpHost($host) + { + $this->ftpParameters['host'] = $host; + } + + public function getFtpUser() + { + if (isset($this->ftpParameters['user'])) { + return $this->ftpParameters['user']; + } else { + return ''; + } + } + + public function setFtpUser($user) + { + $this->ftpParameters['user'] = $user; + } + + public function getFtpPass() + { + if (isset($this->ftpParameters['pass'])) { + return $this->ftpParameters['pass']; + } else { + return ''; + } + } + + public function setFtpPass($pass) + { + $this->ftpParameters['pass'] = $pass; + } + + public static function isValidFtpUrl($url) + { + if (0 !== strpos($url, 'ftp://')) { + return false; + } + $parsedUrl = parse_url($url); + if ($parsedUrl['scheme'] === 'ftp') { + return true; + } + + return false; + } + + public function chDir($dir) + { + ftp_chdir($this->getFtpResource(), $dir); + } + + public function nList($dir) + { + return ftp_nlist($this->getFtpResource(), $dir); + } + + public function rawList($dir) + { + return ftp_rawlist($this->getFtpResource(), $dir); + } + +}