Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

RecursiveDirectoryFtpIterator #4354

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions 17 src/Symfony/Component/Finder/Finder.php
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}
Expand Down Expand Up @@ -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);
Expand Down
137 changes: 137 additions & 0 deletions 137 src/Symfony/Component/Finder/FtpSplFileInfo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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 <gajdaw@gajdaw.pl>
*/
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;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* 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 <gajdaw@gajdaw.pl>
*/
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;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
18 changes: 18 additions & 0 deletions 18 src/Symfony/Component/Finder/SplFileInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.