Update v1.0.6

This commit is contained in:
Bhanu Slathia
2016-02-16 23:24:52 +05:30
parent c710c20b9e
commit b1f62846ab
7662 changed files with 1361647 additions and 0 deletions

View File

@@ -0,0 +1,86 @@
<?php
namespace League\Flysystem\Adapter;
use League\Flysystem\AdapterInterface;
abstract class AbstractAdapter implements AdapterInterface
{
/**
* @var string path prefix
*/
protected $pathPrefix;
/**
* @var string
*/
protected $pathSeparator = '/';
/**
* Set the path prefix.
*
* @param string $prefix
*
* @return self
*/
public function setPathPrefix($prefix)
{
$is_empty = empty($prefix);
if ( ! $is_empty) {
$prefix = rtrim($prefix, $this->pathSeparator) . $this->pathSeparator;
}
$this->pathPrefix = $is_empty ? null : $prefix;
}
/**
* Get the path prefix.
*
* @return string path prefix
*/
public function getPathPrefix()
{
return $this->pathPrefix;
}
/**
* Prefix a path.
*
* @param string $path
*
* @return string prefixed path
*/
public function applyPathPrefix($path)
{
$path = ltrim($path, '\\/');
if (strlen($path) === 0) {
return $this->getPathPrefix() ?: '';
}
if ($prefix = $this->getPathPrefix()) {
$path = $prefix . $path;
}
return $path;
}
/**
* Remove a path prefix.
*
* @param string $path
*
* @return string path without the prefix
*/
public function removePathPrefix($path)
{
$pathPrefix = $this->getPathPrefix();
if ($pathPrefix === null) {
return $path;
}
return substr($path, strlen($pathPrefix));
}
}

View File

@@ -0,0 +1,613 @@
<?php
namespace League\Flysystem\Adapter;
use DateTime;
use League\Flysystem\AdapterInterface;
use League\Flysystem\Config;
use League\Flysystem\NotSupportedException;
abstract class AbstractFtpAdapter extends AbstractAdapter
{
/**
* @var mixed
*/
protected $connection;
/**
* @var string
*/
protected $host;
/**
* @var int
*/
protected $port = 21;
/**
* @var string|null
*/
protected $username;
/**
* @var string|null
*/
protected $password;
/**
* @var bool
*/
protected $ssl = false;
/**
* @var int
*/
protected $timeout = 90;
/**
* @var bool
*/
protected $passive = true;
/**
* @var string
*/
protected $separator = '/';
/**
* @var string|null
*/
protected $root;
/**
* @var int
*/
protected $permPublic = 0744;
/**
* @var int
*/
protected $permPrivate = 0700;
/**
* @var array
*/
protected $configurable = [];
/**
* @var string
*/
protected $systemType;
/**
* Constructor.
*
* @param array $config
*/
public function __construct(array $config)
{
$this->setConfig($config);
}
/**
* Set the config.
*
* @param array $config
*
* @return $this
*/
public function setConfig(array $config)
{
foreach ($this->configurable as $setting) {
if ( ! isset($config[$setting])) {
continue;
}
$method = 'set' . ucfirst($setting);
if (method_exists($this, $method)) {
$this->$method($config[$setting]);
}
}
return $this;
}
/**
* Returns the host.
*
* @return string
*/
public function getHost()
{
return $this->host;
}
/**
* Set the host.
*
* @param string $host
*
* @return $this
*/
public function setHost($host)
{
$this->host = $host;
return $this;
}
/**
* Set the public permission value.
*
* @param int $permPublic
*
* @return $this
*/
public function setPermPublic($permPublic)
{
$this->permPublic = $permPublic;
return $this;
}
/**
* Set the private permission value.
*
* @param int $permPrivate
*
* @return $this
*/
public function setPermPrivate($permPrivate)
{
$this->permPrivate = $permPrivate;
return $this;
}
/**
* Returns the ftp port.
*
* @return int
*/
public function getPort()
{
return $this->port;
}
/**
* Returns the root folder to work from.
*
* @return string
*/
public function getRoot()
{
return $this->root;
}
/**
* Set the ftp port.
*
* @param int|string $port
*
* @return $this
*/
public function setPort($port)
{
$this->port = (int) $port;
return $this;
}
/**
* Set the root folder to work from.
*
* @param string $root
*
* @return $this
*/
public function setRoot($root)
{
$this->root = rtrim($root, '\\/') . $this->separator;
return $this;
}
/**
* Returns the ftp username.
*
* @return string username
*/
public function getUsername()
{
return empty($this->username) ? 'anonymous' : $this->username;
}
/**
* Set ftp username.
*
* @param string $username
*
* @return $this
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Returns the password.
*
* @return string password
*/
public function getPassword()
{
return $this->password;
}
/**
* Set the ftp password.
*
* @param string $password
*
* @return $this
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Returns the amount of seconds before the connection will timeout.
*
* @return int
*/
public function getTimeout()
{
return $this->timeout;
}
/**
* Set the amount of seconds before the connection should timeout.
*
* @param int $timeout
*
* @return $this
*/
public function setTimeout($timeout)
{
$this->timeout = (int) $timeout;
return $this;
}
/**
* Return the FTP system type.
*
* @return string
*/
public function getSystemType()
{
return $this->systemType;
}
/**
* Set the FTP system type (windows or unix).
*
* @param string $systemType
*
* @return $this
*/
public function setSystemType($systemType)
{
$this->systemType = strtolower($systemType);
return $this;
}
/**
* @inheritdoc
*/
public function listContents($directory = '', $recursive = false)
{
return $this->listDirectoryContents($directory, $recursive);
}
/**
* Normalize a directory listing.
*
* @param array $listing
* @param string $prefix
*
* @return array directory listing
*/
protected function normalizeListing(array $listing, $prefix = '')
{
$base = $prefix;
$result = [];
$listing = $this->removeDotDirectories($listing);
while ($item = array_shift($listing)) {
if (preg_match('#^.*:$#', $item)) {
$base = trim($item, ':');
continue;
}
$result[] = $this->normalizeObject($item, $base);
}
return $this->sortListing($result);
}
/**
* Sort a directory listing.
*
* @param array $result
*
* @return array sorted listing
*/
protected function sortListing(array $result)
{
$compare = function ($one, $two) {
return strnatcmp($one['path'], $two['path']);
};
usort($result, $compare);
return $result;
}
/**
* Normalize a file entry.
*
* @param string $item
* @param string $base
*
* @return array normalized file array
*
* @throws NotSupportedException
*/
protected function normalizeObject($item, $base)
{
$systemType = $this->systemType ?: $this->detectSystemType($item);
if ($systemType === 'unix') {
return $this->normalizeUnixObject($item, $base);
} elseif ($systemType === 'windows') {
return $this->normalizeWindowsObject($item, $base);
}
throw NotSupportedException::forFtpSystemType($systemType);
}
/**
* Normalize a Unix file entry.
*
* @param string $item
* @param string $base
*
* @return array normalized file array
*/
protected function normalizeUnixObject($item, $base)
{
$item = preg_replace('#\s+#', ' ', trim($item), 7);
list($permissions, /* $number */, /* $owner */, /* $group */, $size, /* $month */, /* $day */, /* $time*/, $name) = explode(' ', $item, 9);
$type = $this->detectType($permissions);
$path = empty($base) ? $name : $base . $this->separator . $name;
if ($type === 'dir') {
return compact('type', 'path');
}
$permissions = $this->normalizePermissions($permissions);
$visibility = $permissions & 0044 ? AdapterInterface::VISIBILITY_PUBLIC : AdapterInterface::VISIBILITY_PRIVATE;
$size = (int) $size;
return compact('type', 'path', 'visibility', 'size');
}
/**
* Normalize a Windows/DOS file entry.
*
* @param string $item
* @param string $base
*
* @return array normalized file array
*/
protected function normalizeWindowsObject($item, $base)
{
$item = preg_replace('#\s+#', ' ', trim($item), 3);
list($date, $time, $size, $name) = explode(' ', $item, 4);
$path = empty($base) ? $name : $base . $this->separator . $name;
// Check for the correct date/time format
$format = strlen($date) === 8 ? 'm-d-yH:iA' : 'Y-m-dH:i';
$timestamp = DateTime::createFromFormat($format, $date . $time)->getTimestamp();
if ($size === '<DIR>') {
$type = 'dir';
return compact('type', 'path', 'timestamp');
}
$type = 'file';
$visibility = AdapterInterface::VISIBILITY_PUBLIC;
$size = (int) $size;
return compact('type', 'path', 'visibility', 'size', 'timestamp');
}
/**
* Get the system type from a listing item.
*
* @param string $item
*
* @return string the system type
*/
protected function detectSystemType($item)
{
if (preg_match('/^[0-9]{2,4}-[0-9]{2}-[0-9]{2}/', $item)) {
return $this->systemType = 'windows';
}
return $this->systemType = 'unix';
}
/**
* Get the file type from the permissions.
*
* @param string $permissions
*
* @return string file type
*/
protected function detectType($permissions)
{
return substr($permissions, 0, 1) === 'd' ? 'dir' : 'file';
}
/**
* Normalize a permissions string.
*
* @param string $permissions
*
* @return int
*/
protected function normalizePermissions($permissions)
{
// remove the type identifier
$permissions = substr($permissions, 1);
// map the string rights to the numeric counterparts
$map = ['-' => '0', 'r' => '4', 'w' => '2', 'x' => '1'];
$permissions = strtr($permissions, $map);
// split up the permission groups
$parts = str_split($permissions, 3);
// convert the groups
$mapper = function ($part) {
return array_sum(str_split($part));
};
// get the sum of the groups
return array_sum(array_map($mapper, $parts));
}
/**
* Filter out dot-directories.
*
* @param array $list
*
* @return array
*/
public function removeDotDirectories(array $list)
{
$filter = function ($line) {
if ( ! empty($line) && ! preg_match('#.* \.(\.)?$|^total#', $line)) {
return true;
}
return false;
};
return array_filter($list, $filter);
}
/**
* @inheritdoc
*/
public function has($path)
{
return $this->getMetadata($path);
}
/**
* @inheritdoc
*/
public function getSize($path)
{
return $this->getMetadata($path);
}
/**
* @inheritdoc
*/
public function getVisibility($path)
{
return $this->getMetadata($path);
}
/**
* Ensure a directory exists.
*
* @param string $dirname
*/
public function ensureDirectory($dirname)
{
if ( ! empty($dirname) && ! $this->has($dirname)) {
$this->createDir($dirname, new Config());
}
}
/**
* @return mixed
*/
public function getConnection()
{
if ( ! $this->isConnected()) {
$this->disconnect();
$this->connect();
}
return $this->connection;
}
/**
* Get the public permission value.
*
* @return int
*/
public function getPermPublic()
{
return $this->permPublic;
}
/**
* Get the private permission value.
*
* @return int
*/
public function getPermPrivate()
{
return $this->permPrivate;
}
/**
* Disconnect on destruction.
*/
public function __destruct()
{
$this->disconnect();
}
/**
* Establish a connection.
*/
abstract public function connect();
/**
* Close the connection.
*/
abstract public function disconnect();
/**
* Check if a connection is active.
*
* @return bool
*/
abstract public function isConnected();
}

View File

@@ -0,0 +1,448 @@
<?php
namespace League\Flysystem\Adapter;
use League\Flysystem\Adapter\Polyfill\StreamedCopyTrait;
use League\Flysystem\AdapterInterface;
use League\Flysystem\Config;
use League\Flysystem\Util;
use RuntimeException;
class Ftp extends AbstractFtpAdapter
{
use StreamedCopyTrait;
/**
* @var int
*/
protected $transferMode = FTP_BINARY;
/**
* @var null|bool
*/
protected $ignorePassiveAddress = null;
/**
* @var array
*/
protected $configurable = [
'host',
'port',
'username',
'password',
'ssl',
'timeout',
'root',
'permPrivate',
'permPublic',
'passive',
'transferMode',
'systemType',
'ignorePassiveAddress',
];
/**
* Set the transfer mode.
*
* @param int $mode
*
* @return $this
*/
public function setTransferMode($mode)
{
$this->transferMode = $mode;
return $this;
}
/**
* Set if Ssl is enabled.
*
* @param bool $ssl
*
* @return $this
*/
public function setSsl($ssl)
{
$this->ssl = (bool) $ssl;
return $this;
}
/**
* Set if passive mode should be used.
*
* @param bool $passive
*/
public function setPassive($passive = true)
{
$this->passive = $passive;
}
/**
* @param bool $ignorePassiveAddress
*/
public function setIgnorePassiveAddress($ignorePassiveAddress)
{
$this->ignorePassiveAddress = $ignorePassiveAddress;
}
/**
* Connect to the FTP server.
*/
public function connect()
{
if ($this->ssl) {
$this->connection = ftp_ssl_connect($this->getHost(), $this->getPort(), $this->getTimeout());
} else {
$this->connection = ftp_connect($this->getHost(), $this->getPort(), $this->getTimeout());
}
if ( ! $this->connection) {
throw new RuntimeException('Could not connect to host: ' . $this->getHost() . ', port:' . $this->getPort());
}
$this->login();
$this->setConnectionPassiveMode();
$this->setConnectionRoot();
}
/**
* Set the connections to passive mode.
*
* @throws RuntimeException
*/
protected function setConnectionPassiveMode()
{
if (is_bool($this->ignorePassiveAddress) && defined('FTP_USEPASVADDRESS')) {
ftp_set_option($this->connection, FTP_USEPASVADDRESS, ! $this->ignorePassiveAddress);
}
if ( ! ftp_pasv($this->connection, $this->passive)) {
throw new RuntimeException(
'Could not set passive mode for connection: ' . $this->getHost() . '::' . $this->getPort()
);
}
}
/**
* Set the connection root.
*/
protected function setConnectionRoot()
{
$root = $this->getRoot();
$connection = $this->connection;
if (empty($root) === false && ! ftp_chdir($connection, $root)) {
throw new RuntimeException('Root is invalid or does not exist: ' . $this->getRoot());
}
// Store absolute path for further reference.
// This is needed when creating directories and
// initial root was a relative path, else the root
// would be relative to the chdir'd path.
$this->root = ftp_pwd($connection);
}
/**
* Login.
*
* @throws RuntimeException
*/
protected function login()
{
set_error_handler(
function () {
}
);
$isLoggedIn = ftp_login($this->connection, $this->getUsername(), $this->getPassword());
restore_error_handler();
if ( ! $isLoggedIn) {
$this->disconnect();
throw new RuntimeException(
'Could not login with connection: ' . $this->getHost() . '::' . $this->getPort(
) . ', username: ' . $this->getUsername()
);
}
}
/**
* Disconnect from the FTP server.
*/
public function disconnect()
{
if ($this->isConnected()) {
ftp_close($this->connection);
}
$this->connection = null;
}
/**
* @inheritdoc
*/
public function write($path, $contents, Config $config)
{
$stream = fopen('php://temp', 'w+b');
fwrite($stream, $contents);
rewind($stream);
$result = $this->writeStream($path, $stream, $config);
fclose($stream);
if ($result === false) {
return false;
}
$result['contents'] = $contents;
$result['mimetype'] = Util::guessMimeType($path, $contents);
return $result;
}
/**
* @inheritdoc
*/
public function writeStream($path, $resource, Config $config)
{
$this->ensureDirectory(Util::dirname($path));
if ( ! ftp_fput($this->getConnection(), $path, $resource, $this->transferMode)) {
return false;
}
if ($visibility = $config->get('visibility')) {
$this->setVisibility($path, $visibility);
}
return compact('path', 'visibility');
}
/**
* @inheritdoc
*/
public function update($path, $contents, Config $config)
{
return $this->write($path, $contents, $config);
}
/**
* @inheritdoc
*/
public function updateStream($path, $resource, Config $config)
{
return $this->writeStream($path, $resource, $config);
}
/**
* @inheritdoc
*/
public function rename($path, $newpath)
{
return ftp_rename($this->getConnection(), $path, $newpath);
}
/**
* @inheritdoc
*/
public function delete($path)
{
return ftp_delete($this->getConnection(), $path);
}
/**
* @inheritdoc
*/
public function deleteDir($dirname)
{
$connection = $this->getConnection();
$contents = array_reverse($this->listDirectoryContents($dirname));
foreach ($contents as $object) {
if ($object['type'] === 'file') {
if ( ! ftp_delete($connection, $object['path'])) {
return false;
}
} elseif ( ! ftp_rmdir($connection, $object['path'])) {
return false;
}
}
return ftp_rmdir($connection, $dirname);
}
/**
* @inheritdoc
*/
public function createDir($dirname, Config $config)
{
$connection = $this->getConnection();
$directories = explode('/', $dirname);
foreach ($directories as $directory) {
if (false === $this->createActualDirectory($directory, $connection)) {
$this->setConnectionRoot();
return false;
}
ftp_chdir($connection, $directory);
}
$this->setConnectionRoot();
return ['path' => $dirname];
}
/**
* Create a directory.
*
* @param string $directory
* @param resource $connection
*
* @return bool
*/
protected function createActualDirectory($directory, $connection)
{
// List the current directory
$listing = ftp_nlist($connection, '.');
foreach ($listing as $key => $item) {
if (preg_match('~^\./.*~', $item)) {
$listing[$key] = substr($item, 2);
}
}
if (in_array($directory, $listing)) {
return true;
}
return (boolean) ftp_mkdir($connection, $directory);
}
/**
* @inheritdoc
*/
public function getMetadata($path)
{
$connection = $this->getConnection();
if ($path === '') {
return ['type' => 'dir', 'path' => ''];
}
if (@ftp_chdir($connection, $path) === true) {
$this->setConnectionRoot();
return ['type' => 'dir', 'path' => $path];
}
$listing = ftp_rawlist($connection, str_replace('*', '\\*', $path));
if (empty($listing)) {
return false;
}
if (preg_match('/.* not found/', $listing[0])) {
return false;
}
return $this->normalizeObject($listing[0], '');
}
/**
* @inheritdoc
*/
public function getMimetype($path)
{
if ( ! $metadata = $this->read($path)) {
return false;
}
$metadata['mimetype'] = Util::guessMimeType($path, $metadata['contents']);
return $metadata;
}
/**
* @inheritdoc
*/
public function getTimestamp($path)
{
$timestamp = ftp_mdtm($this->getConnection(), $path);
return ($timestamp !== -1) ? ['timestamp' => $timestamp] : false;
}
/**
* @inheritdoc
*/
public function read($path)
{
if ( ! $object = $this->readStream($path)) {
return false;
}
$object['contents'] = stream_get_contents($object['stream']);
fclose($object['stream']);
unset($object['stream']);
return $object;
}
/**
* @inheritdoc
*/
public function readStream($path)
{
$stream = fopen('php://temp', 'w+');
$result = ftp_fget($this->getConnection(), $stream, $path, $this->transferMode);
rewind($stream);
if ( ! $result) {
fclose($stream);
return false;
}
return compact('stream');
}
/**
* @inheritdoc
*/
public function setVisibility($path, $visibility)
{
$mode = $visibility === AdapterInterface::VISIBILITY_PUBLIC ? $this->getPermPublic() : $this->getPermPrivate();
if ( ! ftp_chmod($this->getConnection(), $mode, $path)) {
return false;
}
return compact('visibility');
}
/**
* @inheritdoc
*
* @param string $directory
*/
protected function listDirectoryContents($directory, $recursive = true)
{
$directory = str_replace('*', '\\*', $directory);
$options = $recursive ? '-alnR' : '-aln';
$listing = ftp_rawlist($this->getConnection(), $options . ' ' . $directory);
return $listing ? $this->normalizeListing($listing, $directory) : [];
}
/**
* Check if the connection is open.
*
* @return bool
*/
public function isConnected()
{
return is_resource($this->connection) && ftp_systype($this->connection) !== false;
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace League\Flysystem\Adapter;
class Ftpd extends Ftp
{
/**
* @inheritdoc
*/
public function getMetadata($path)
{
if (empty($path) || ! ($object = ftp_raw($this->getConnection(), 'STAT ' . $path)) || count($object) < 3) {
return false;
}
if (substr($object[1], 0, 5) === "ftpd:") {
return false;
}
return $this->normalizeObject($object[1], '');
}
/**
* @inheritdoc
*/
protected function listDirectoryContents($directory, $recursive = true)
{
$listing = ftp_rawlist($this->getConnection(), $directory, $recursive);
if ($listing === false || ( ! empty($listing) && substr($listing[0], 0, 5) === "ftpd:")) {
return [];
}
return $this->normalizeListing($listing, $directory);
}
}

View File

@@ -0,0 +1,501 @@
<?php
namespace League\Flysystem\Adapter;
use DirectoryIterator;
use FilesystemIterator;
use finfo as Finfo;
use League\Flysystem\AdapterInterface;
use League\Flysystem\Config;
use League\Flysystem\NotSupportedException;
use League\Flysystem\UnreadableFileException;
use League\Flysystem\Util;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use SplFileInfo;
class Local extends AbstractAdapter
{
/**
* @var int
*/
const SKIP_LINKS = 0001;
/**
* @var int
*/
const DISALLOW_LINKS = 0002;
/**
* @var array
*/
protected static $permissions = [
'file' => [
'public' => 0744,
'private' => 0700,
],
'dir' => [
'public' => 0755,
'private' => 0700,
]
];
/**
* @var string
*/
protected $pathSeparator = DIRECTORY_SEPARATOR;
/**
* @var array
*/
protected $permissionMap;
/**
* @var int
*/
protected $writeFlags;
/**
* @var int
*/
private $linkHandling;
/**
* Constructor.
*
* @param string $root
* @param int $writeFlags
* @param int $linkHandling
* @param array $permissions
*/
public function __construct($root, $writeFlags = LOCK_EX, $linkHandling = self::DISALLOW_LINKS, array $permissions = [])
{
// permissionMap needs to be set before ensureDirectory() is called.
$this->permissionMap = array_replace_recursive(static::$permissions, $permissions);
$realRoot = $this->ensureDirectory($root);
if ( ! is_dir($realRoot) || ! is_readable($realRoot)) {
throw new \LogicException('The root path ' . $root . ' is not readable.');
}
$this->setPathPrefix($realRoot);
$this->writeFlags = $writeFlags;
$this->linkHandling = $linkHandling;
}
/**
* Ensure the root directory exists.
*
* @param string $root root directory path
*
* @return string real path to root
*/
protected function ensureDirectory($root)
{
if ( ! is_dir($root)) {
$umask = umask(0);
mkdir($root, $this->permissionMap['dir']['public'], true);
umask($umask);
}
return realpath($root);
}
/**
* @inheritdoc
*/
public function has($path)
{
$location = $this->applyPathPrefix($path);
return file_exists($location);
}
/**
* @inheritdoc
*/
public function write($path, $contents, Config $config)
{
$location = $this->applyPathPrefix($path);
$this->ensureDirectory(dirname($location));
if (($size = file_put_contents($location, $contents, $this->writeFlags)) === false) {
return false;
}
$type = 'file';
$result = compact('contents', 'type', 'size', 'path');
if ($visibility = $config->get('visibility')) {
$result['visibility'] = $visibility;
$this->setVisibility($path, $visibility);
}
return $result;
}
/**
* @inheritdoc
*/
public function writeStream($path, $resource, Config $config)
{
$location = $this->applyPathPrefix($path);
$this->ensureDirectory(dirname($location));
$stream = fopen($location, 'w+');
if ( ! $stream) {
return false;
}
stream_copy_to_stream($resource, $stream);
if ( ! fclose($stream)) {
return false;
}
if ($visibility = $config->get('visibility')) {
$this->setVisibility($path, $visibility);
}
return compact('path', 'visibility');
}
/**
* @inheritdoc
*/
public function readStream($path)
{
$location = $this->applyPathPrefix($path);
$stream = fopen($location, 'r');
return compact('stream', 'path');
}
/**
* @inheritdoc
*/
public function updateStream($path, $resource, Config $config)
{
return $this->writeStream($path, $resource, $config);
}
/**
* @inheritdoc
*/
public function update($path, $contents, Config $config)
{
$location = $this->applyPathPrefix($path);
$mimetype = Util::guessMimeType($path, $contents);
$size = file_put_contents($location, $contents, $this->writeFlags);
if ($size === false) {
return false;
}
return compact('path', 'size', 'contents', 'mimetype');
}
/**
* @inheritdoc
*/
public function read($path)
{
$location = $this->applyPathPrefix($path);
$contents = file_get_contents($location);
if ($contents === false) {
return false;
}
return compact('contents', 'path');
}
/**
* @inheritdoc
*/
public function rename($path, $newpath)
{
$location = $this->applyPathPrefix($path);
$destination = $this->applyPathPrefix($newpath);
$parentDirectory = $this->applyPathPrefix(Util::dirname($newpath));
$this->ensureDirectory($parentDirectory);
return rename($location, $destination);
}
/**
* @inheritdoc
*/
public function copy($path, $newpath)
{
$location = $this->applyPathPrefix($path);
$destination = $this->applyPathPrefix($newpath);
$this->ensureDirectory(dirname($destination));
return copy($location, $destination);
}
/**
* @inheritdoc
*/
public function delete($path)
{
$location = $this->applyPathPrefix($path);
return unlink($location);
}
/**
* @inheritdoc
*/
public function listContents($directory = '', $recursive = false)
{
$result = [];
$location = $this->applyPathPrefix($directory) . $this->pathSeparator;
if ( ! is_dir($location)) {
return [];
}
$iterator = $recursive ? $this->getRecursiveDirectoryIterator($location) : $this->getDirectoryIterator($location);
foreach ($iterator as $file) {
$path = $this->getFilePath($file);
if (preg_match('#(^|/|\\\\)\.{1,2}$#', $path)) {
continue;
}
$result[] = $this->normalizeFileInfo($file);
}
return array_filter($result);
}
/**
* @inheritdoc
*/
public function getMetadata($path)
{
$location = $this->applyPathPrefix($path);
$info = new SplFileInfo($location);
return $this->normalizeFileInfo($info);
}
/**
* @inheritdoc
*/
public function getSize($path)
{
return $this->getMetadata($path);
}
/**
* @inheritdoc
*/
public function getMimetype($path)
{
$location = $this->applyPathPrefix($path);
$finfo = new Finfo(FILEINFO_MIME_TYPE);
return ['mimetype' => $finfo->file($location)];
}
/**
* @inheritdoc
*/
public function getTimestamp($path)
{
return $this->getMetadata($path);
}
/**
* @inheritdoc
*/
public function getVisibility($path)
{
$location = $this->applyPathPrefix($path);
clearstatcache(false, $location);
$permissions = octdec(substr(sprintf('%o', fileperms($location)), -4));
$visibility = $permissions & 0044 ? AdapterInterface::VISIBILITY_PUBLIC : AdapterInterface::VISIBILITY_PRIVATE;
return compact('visibility');
}
/**
* @inheritdoc
*/
public function setVisibility($path, $visibility)
{
$location = $this->applyPathPrefix($path);
$type = is_dir($location) ? 'dir' : 'file';
$success = chmod($location, $this->permissionMap[$type][$visibility]);
if ($success === false) {
return false;
}
return compact('visibility');
}
/**
* @inheritdoc
*/
public function createDir($dirname, Config $config)
{
$location = $this->applyPathPrefix($dirname);
$umask = umask(0);
$visibility = $config->get('visibility', 'public');
if ( ! is_dir($location) && ! mkdir($location, $this->permissionMap['dir'][$visibility], true)) {
$return = false;
} else {
$return = ['path' => $dirname, 'type' => 'dir'];
}
umask($umask);
return $return;
}
/**
* @inheritdoc
*/
public function deleteDir($dirname)
{
$location = $this->applyPathPrefix($dirname);
if ( ! is_dir($location)) {
return false;
}
$contents = $this->getRecursiveDirectoryIterator($location, RecursiveIteratorIterator::CHILD_FIRST);
/** @var SplFileInfo $file */
foreach ($contents as $file) {
$this->guardAgainstUnreadableFileInfo($file);
$this->deleteFileInfoObject($file);
}
return rmdir($location);
}
/**
* @param $file
*/
protected function deleteFileInfoObject($file)
{
switch ($file->getType()) {
case 'dir':
rmdir($file->getRealPath());
break;
case 'link':
unlink($file->getPathname());
break;
default:
unlink($file->getRealPath());
}
}
/**
* Normalize the file info.
*
* @param SplFileInfo $file
*
* @return array
*/
protected function normalizeFileInfo(SplFileInfo $file)
{
if ( ! $file->isLink()) {
return $this->mapFileInfo($file);
}
if ($this->linkHandling & self::DISALLOW_LINKS) {
throw NotSupportedException::forLink($file);
}
}
/**
* Get the normalized path from a SplFileInfo object.
*
* @param SplFileInfo $file
*
* @return string
*/
protected function getFilePath(SplFileInfo $file)
{
$location = $file->getPathname();
$path = $this->removePathPrefix($location);
return trim(str_replace('\\', '/', $path), '/');
}
/**
* @param string $path
* @param int $mode
*
* @return RecursiveIteratorIterator
*/
protected function getRecursiveDirectoryIterator($path, $mode = RecursiveIteratorIterator::SELF_FIRST)
{
return new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS),
$mode
);
}
/**
* @param string $path
*
* @return DirectoryIterator
*/
protected function getDirectoryIterator($path)
{
$iterator = new DirectoryIterator($path);
return $iterator;
}
/**
* @param SplFileInfo $file
*
* @return array
*/
protected function mapFileInfo(SplFileInfo $file)
{
$normalized = [
'type' => $file->getType(),
'path' => $this->getFilePath($file),
];
$normalized['timestamp'] = $file->getMTime();
if ($normalized['type'] === 'file') {
$normalized['size'] = $file->getSize();
}
return $normalized;
}
/**
* @inheritdoc
*/
public function applyPathPrefix($path)
{
$prefixedPath = parent::applyPathPrefix($path);
return str_replace('/', DIRECTORY_SEPARATOR, $prefixedPath);
}
/**
* @param SplFileInfo $file
*
* @throws UnreadableFileException
*/
protected function guardAgainstUnreadableFileInfo(SplFileInfo $file)
{
if ( ! $file->isReadable()) {
throw UnreadableFileException::forFileInfo($file);
}
}
}

View File

@@ -0,0 +1,144 @@
<?php
namespace League\Flysystem\Adapter;
use League\Flysystem\Adapter\Polyfill\StreamedCopyTrait;
use League\Flysystem\Adapter\Polyfill\StreamedTrait;
use League\Flysystem\Config;
class NullAdapter extends AbstractAdapter
{
use StreamedTrait;
use StreamedCopyTrait;
/**
* Check whether a file is present.
*
* @param string $path
*
* @return bool
*/
public function has($path)
{
return false;
}
/**
* @inheritdoc
*/
public function write($path, $contents, Config $config)
{
$type = 'file';
$result = compact('contents', 'type', 'size', 'path');
if ($visibility = $config->get('visibility')) {
$result['visibility'] = $visibility;
}
return $result;
}
/**
* @inheritdoc
*/
public function update($path, $contents, Config $config)
{
return false;
}
/**
* @inheritdoc
*/
public function read($path)
{
return false;
}
/**
* @inheritdoc
*/
public function rename($path, $newpath)
{
return false;
}
/**
* @inheritdoc
*/
public function delete($path)
{
return false;
}
/**
* @inheritdoc
*/
public function listContents($directory = '', $recursive = false)
{
return [];
}
/**
* @inheritdoc
*/
public function getMetadata($path)
{
return false;
}
/**
* @inheritdoc
*/
public function getSize($path)
{
return false;
}
/**
* @inheritdoc
*/
public function getMimetype($path)
{
return false;
}
/**
* @inheritdoc
*/
public function getTimestamp($path)
{
return false;
}
/**
* @inheritdoc
*/
public function getVisibility($path)
{
return false;
}
/**
* @inheritdoc
*/
public function setVisibility($path, $visibility)
{
return compact('visibility');
}
/**
* @inheritdoc
*/
public function createDir($dirname, Config $config)
{
return ['path' => $dirname, 'type' => 'dir'];
}
/**
* @inheritdoc
*/
public function deleteDir($dirname)
{
return false;
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace League\Flysystem\Adapter\Polyfill;
use LogicException;
trait NotSupportingVisibilityTrait
{
/**
* Get the visibility of a file.
*
* @param string $path
*
* @throws LogicException
*/
public function getVisibility($path)
{
throw new LogicException(get_class($this) . ' does not support visibility. Path: ' . $path);
}
/**
* Set the visibility for a file.
*
* @param string $path
* @param string $visibility
*
* @throws LogicException
*/
public function setVisibility($path, $visibility)
{
throw new LogicException(get_class($this) . ' does not support visibility. Path: ' . $path . ', visibility: ' . $visibility);
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace League\Flysystem\Adapter\Polyfill;
use League\Flysystem\Config;
trait StreamedCopyTrait
{
/**
* Copy a file.
*
* @param string $path
* @param string $newpath
*
* @return bool
*/
public function copy($path, $newpath)
{
$response = $this->readStream($path);
if ($response === false || ! is_resource($response['stream'])) {
return false;
}
$result = $this->writeStream($newpath, $response['stream'], new Config());
if ($result !== false && is_resource($response['stream'])) {
fclose($response['stream']);
}
return $result !== false;
}
// Required abstract method
/**
* @param string $path
*/
abstract public function readStream($path);
/**
* @param string $path
*/
abstract public function writeStream($path, $resource, Config $config);
}

View File

@@ -0,0 +1,37 @@
<?php
namespace League\Flysystem\Adapter\Polyfill;
trait StreamedReadingTrait
{
/**
* Get the contents of a file in a stream.
*
* @param string $path
*
* @return resource|false false when not found, or a resource
*/
public function readStream($path)
{
if ( ! $data = $this->read($path)) {
return false;
}
$stream = tmpfile();
fwrite($stream, $data['contents']);
rewind($stream);
$data['stream'] = $stream;
unset($data['contents']);
return $data;
}
// Required abstract method
/**
* @param string $path
*
* @return resource
*/
abstract public function read($path);
}

View File

@@ -0,0 +1,9 @@
<?php
namespace League\Flysystem\Adapter\Polyfill;
trait StreamedTrait
{
use StreamedReadingTrait;
use StreamedWritingTrait;
}

View File

@@ -0,0 +1,60 @@
<?php
namespace League\Flysystem\Adapter\Polyfill;
use League\Flysystem\Config;
use League\Flysystem\Util;
trait StreamedWritingTrait
{
/**
* Stream fallback delegator.
*
* @param string $path
* @param resource $resource
* @param Config $config
* @param string $fallback
*
* @return mixed fallback result
*/
protected function stream($path, $resource, Config $config, $fallback)
{
Util::rewindStream($resource);
$contents = stream_get_contents($resource);
$fallbackCall = [$this, $fallback];
return call_user_func($fallbackCall, $path, $contents, $config);
}
/**
* Write using a stream.
*
* @param string $path
* @param resource $resource
* @param Config $config
*
* @return mixed false or file metadata
*/
public function writeStream($path, $resource, Config $config)
{
return $this->stream($path, $resource, $config, 'write');
}
/**
* Update a file using a stream.
*
* @param string $path
* @param resource $resource
* @param Config $config Config object or visibility setting
*
* @return mixed false of file metadata
*/
public function updateStream($path, $resource, Config $config)
{
return $this->stream($path, $resource, $config, 'update');
}
// Required abstract methods
abstract public function write($pash, $contents, Config $config);
abstract public function update($pash, $contents, Config $config);
}

View File

@@ -0,0 +1,8 @@
<?php
namespace League\Flysystem\Adapter;
class SynologyFtp extends Ftpd
{
// This class merely exists because of BC.
}