Pressroom template verwijderd, website naar root van repo

This commit is contained in:
2020-03-22 15:30:52 +01:00
parent 2cb6a77425
commit f3d1c41e91
7620 changed files with 0 additions and 186900 deletions

View File

@@ -0,0 +1,71 @@
<?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 void
*/
public function setPathPrefix($prefix)
{
$prefix = (string) $prefix;
if ($prefix === '') {
$this->pathPrefix = null;
return;
}
$this->pathPrefix = rtrim($prefix, '\\/') . $this->pathSeparator;
}
/**
* 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)
{
return $this->getPathPrefix() . ltrim($path, '\\/');
}
/**
* Remove a path prefix.
*
* @param string $path
*
* @return string path without the prefix
*/
public function removePathPrefix($path)
{
return substr($path, strlen($this->getPathPrefix()));
}
}

View File

@@ -0,0 +1,630 @@
<?php
namespace League\Flysystem\Adapter;
use DateTime;
use League\Flysystem\AdapterInterface;
use League\Flysystem\Config;
use League\Flysystem\NotSupportedException;
use League\Flysystem\SafeStorage;
use RuntimeException;
abstract class AbstractFtpAdapter extends AbstractAdapter
{
/**
* @var mixed
*/
protected $connection;
/**
* @var string
*/
protected $host;
/**
* @var int
*/
protected $port = 21;
/**
* @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;
/**
* @var bool
*/
protected $alternativeRecursion = false;
/**
* @var SafeStorage
*/
protected $safeStorage;
/**
* Constructor.
*
* @param array $config
*/
public function __construct(array $config)
{
$this->safeStorage = new SafeStorage();
$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()
{
$username = $this->safeStorage->retrieveSafely('username');
return $username !== null ? $username : 'anonymous';
}
/**
* Set ftp username.
*
* @param string $username
*
* @return $this
*/
public function setUsername($username)
{
$this->safeStorage->storeSafely('username', $username);
return $this;
}
/**
* Returns the password.
*
* @return string password
*/
public function getPassword()
{
return $this->safeStorage->retrieveSafely('password');
}
/**
* Set the ftp password.
*
* @param string $password
*
* @return $this
*/
public function setPassword($password)
{
$this->safeStorage->storeSafely('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);
}
abstract protected function listDirectoryContents($directory, $recursive = false);
/**
* 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);
if (count(explode(' ', $item, 9)) !== 9) {
throw new RuntimeException("Metadata can't be parsed from item '$item' , not enough parts.");
}
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);
if (count(explode(' ', $item, 4)) !== 4) {
throw new RuntimeException("Metadata can't be parsed from item '$item' , not enough parts.");
}
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';
$dt = DateTime::createFromFormat($format, $date . $time);
$timestamp = $dt ? $dt->getTimestamp() : (int) strtotime("$date $time");
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)
{
return preg_match('/^[0-9]{2,4}-[0-9]{2}-[0-9]{2}/', $item) ? 'windows' : '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()
{
$tries = 0;
while ( ! $this->isConnected() && $tries < 3) {
$tries++;
$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,10 @@
<?php
namespace League\Flysystem\Adapter;
/**
* Adapters that implement this interface let the Filesystem know that it files can be overwritten using the write
* functions and don't need the update function to be called. This can help improve performance when asserts are disabled.
*/
interface CanOverwriteFiles {}

View File

@@ -0,0 +1,569 @@
<?php
namespace League\Flysystem\Adapter;
use ErrorException;
use League\Flysystem\Adapter\Polyfill\StreamedCopyTrait;
use League\Flysystem\AdapterInterface;
use League\Flysystem\Config;
use League\Flysystem\Util;
use League\Flysystem\Util\MimeType;
use RuntimeException;
class Ftp extends AbstractFtpAdapter
{
use StreamedCopyTrait;
/**
* @var int
*/
protected $transferMode = FTP_BINARY;
/**
* @var null|bool
*/
protected $ignorePassiveAddress = null;
/**
* @var bool
*/
protected $recurseManually = false;
/**
* @var bool
*/
protected $utf8 = false;
/**
* @var array
*/
protected $configurable = [
'host',
'port',
'username',
'password',
'ssl',
'timeout',
'root',
'permPrivate',
'permPublic',
'passive',
'transferMode',
'systemType',
'ignorePassiveAddress',
'recurseManually',
'utf8',
];
/**
* @var bool
*/
protected $isPureFtpd;
/**
* 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;
}
/**
* @param bool $recurseManually
*/
public function setRecurseManually($recurseManually)
{
$this->recurseManually = $recurseManually;
}
/**
* @param bool $utf8
*/
public function setUtf8($utf8)
{
$this->utf8 = (bool) $utf8;
}
/**
* 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->setUtf8Mode();
$this->setConnectionPassiveMode();
$this->setConnectionRoot();
$this->isPureFtpd = $this->isPureFtpdServer();
}
/**
* Set the connection to UTF-8 mode.
*/
protected function setUtf8Mode()
{
if ($this->utf8) {
$response = ftp_raw($this->connection, "OPTS UTF8 ON");
if (substr($response[0], 0, 3) !== '200') {
throw new RuntimeException(
'Could not set UTF-8 mode for connection: ' . $this->getHost() . '::' . $this->getPort()
);
}
}
}
/**
* 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 (is_resource($this->connection)) {
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);
}
$type = 'file';
return compact('type', '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 ['type' => 'dir', '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, true)) {
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 = $this->ftpRawlist('-A', str_replace('*', '\\*', $path));
if (empty($listing) || in_array('total 0', $listing, true)) {
return false;
}
if (preg_match('/.* not found/', $listing[0])) {
return false;
}
if (preg_match('/^total [0-9]*$/', $listing[0])) {
array_shift($listing);
}
return $this->normalizeObject($listing[0], '');
}
/**
* @inheritdoc
*/
public function getMimetype($path)
{
if ( ! $metadata = $this->getMetadata($path)) {
return false;
}
$metadata['mimetype'] = MimeType::detectByFilename($path);
return $metadata;
}
/**
* @inheritdoc
*/
public function getTimestamp($path)
{
$timestamp = ftp_mdtm($this->getConnection(), $path);
return ($timestamp !== -1) ? ['path' => $path, '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+b');
$result = ftp_fget($this->getConnection(), $stream, $path, $this->transferMode);
rewind($stream);
if ( ! $result) {
fclose($stream);
return false;
}
return ['type' => 'file', 'path' => $path, 'stream' => $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('path', 'visibility');
}
/**
* @inheritdoc
*
* @param string $directory
*/
protected function listDirectoryContents($directory, $recursive = true)
{
$directory = str_replace('*', '\\*', $directory);
if ($recursive && $this->recurseManually) {
return $this->listDirectoryContentsRecursive($directory);
}
$options = $recursive ? '-alnR' : '-aln';
$listing = $this->ftpRawlist($options, $directory);
return $listing ? $this->normalizeListing($listing, $directory) : [];
}
/**
* @inheritdoc
*
* @param string $directory
*/
protected function listDirectoryContentsRecursive($directory)
{
$listing = $this->normalizeListing($this->ftpRawlist('-aln', $directory) ?: []);
$output = [];
foreach ($listing as $directory) {
$output[] = $directory;
if ($directory['type'] !== 'dir') continue;
$output = array_merge($output, $this->listDirectoryContentsRecursive($directory['path']));
}
return $output;
}
/**
* Check if the connection is open.
*
* @return bool
* @throws ErrorException
*/
public function isConnected()
{
try {
return is_resource($this->connection) && ftp_rawlist($this->connection, '/') !== false;
} catch (ErrorException $e) {
if (strpos($e->getMessage(), 'ftp_rawlist') === false) {
throw $e;
}
return false;
}
}
/**
* @return null|string
*/
protected function isPureFtpdServer()
{
$response = ftp_raw($this->connection, 'HELP');
return stripos(implode(' ', $response), 'Pure-FTPd') !== false;
}
/**
* The ftp_rawlist function with optional escaping.
*
* @param string $options
* @param string $path
*
* @return array
*/
protected function ftpRawlist($options, $path)
{
$connection = $this->getConnection();
if ($this->isPureFtpd) {
$path = str_replace(' ', '\ ', $path);
}
return ftp_rawlist($connection, $options . ' ' . $path);
}
}

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,510 @@
<?php
namespace League\Flysystem\Adapter;
use DirectoryIterator;
use FilesystemIterator;
use finfo as Finfo;
use League\Flysystem\AdapterInterface;
use League\Flysystem\Config;
use League\Flysystem\Exception;
use League\Flysystem\NotSupportedException;
use League\Flysystem\UnreadableFileException;
use League\Flysystem\Util;
use LogicException;
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' => 0644,
'private' => 0600,
],
'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
*
* @throws LogicException
*/
public function __construct($root, $writeFlags = LOCK_EX, $linkHandling = self::DISALLOW_LINKS, array $permissions = [])
{
$root = is_link($root) ? realpath($root) : $root;
$this->permissionMap = array_replace_recursive(static::$permissions, $permissions);
$this->ensureDirectory($root);
if ( ! is_dir($root) || ! is_readable($root)) {
throw new LogicException('The root path ' . $root . ' is not readable.');
}
$this->setPathPrefix($root);
$this->writeFlags = $writeFlags;
$this->linkHandling = $linkHandling;
}
/**
* Ensure the root directory exists.
*
* @param string $root root directory path
*
* @return void
*
* @throws Exception in case the root directory can not be created
*/
protected function ensureDirectory($root)
{
if ( ! is_dir($root)) {
$umask = umask(0);
@mkdir($root, $this->permissionMap['dir']['public'], true);
umask($umask);
if ( ! is_dir($root)) {
throw new Exception(sprintf('Impossible to create the root directory "%s".', $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+b');
if ( ! $stream) {
return false;
}
stream_copy_to_stream($resource, $stream);
if ( ! fclose($stream)) {
return false;
}
if ($visibility = $config->get('visibility')) {
$this->setVisibility($path, $visibility);
}
$type = 'file';
return compact('type', 'path', 'visibility');
}
/**
* @inheritdoc
*/
public function readStream($path)
{
$location = $this->applyPathPrefix($path);
$stream = fopen($location, 'rb');
return ['type' => 'file', 'path' => $path, 'stream' => $stream];
}
/**
* @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;
}
$type = 'file';
return compact('type', 'path', 'size', 'contents', 'mimetype');
}
/**
* @inheritdoc
*/
public function read($path)
{
$location = $this->applyPathPrefix($path);
$contents = file_get_contents($location);
if ($contents === false) {
return false;
}
return ['type' => 'file', 'path' => $path, 'contents' => $contents];
}
/**
* @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);
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);
$mimetype = $finfo->file($location);
if (in_array($mimetype, ['application/octet-stream', 'inode/x-empty'])) {
$mimetype = Util\MimeType::detectByFilename($location);
}
return ['path' => $path, 'type' => 'file', 'mimetype' => $mimetype];
}
/**
* @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('path', '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('path', '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 SplFileInfo $file
*/
protected function deleteFileInfoObject(SplFileInfo $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|void
*
* @throws NotSupportedException
*/
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;
}
/**
* @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', '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,49 @@
<?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
* @return resource
*/
abstract public function readStream($path);
/**
* @param string $path
* @param resource $resource
* @param Config $config
* @return resource
*/
abstract public function writeStream($path, $resource, Config $config);
}

View File

@@ -0,0 +1,44 @@
<?php
namespace League\Flysystem\Adapter\Polyfill;
/**
* A helper for adapters that only handle strings to provide read streams.
*/
trait StreamedReadingTrait
{
/**
* Reads a file as a stream.
*
* @param string $path
*
* @return array|false
*
* @see League\Flysystem\ReadInterface::readStream()
*/
public function readStream($path)
{
if ( ! $data = $this->read($path)) {
return false;
}
$stream = fopen('php://temp', 'w+b');
fwrite($stream, $data['contents']);
rewind($stream);
$data['stream'] = $stream;
unset($data['contents']);
return $data;
}
/**
* Reads a file.
*
* @param string $path
*
* @return array|false
*
* @see League\Flysystem\ReadInterface::read()
*/
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.
}