first commit

This commit is contained in:
root
2020-02-19 16:42:35 +01:00
commit d668d90f82
2224 changed files with 334338 additions and 0 deletions

View File

@ -0,0 +1,94 @@
<?php
namespace RocketTheme\Toolbox\StreamWrapper;
use RocketTheme\Toolbox\ResourceLocator\ResourceLocatorInterface;
/**
* Implements Read Only Streams.
*
* @package RocketTheme\Toolbox\StreamWrapper
* @author RocketTheme
* @license MIT
*/
class ReadOnlyStream extends Stream implements StreamInterface
{
/**
* @var ResourceLocatorInterface
*/
protected static $locator;
public function stream_open($uri, $mode, $options, &$opened_url)
{
if (!\in_array($mode, ['r', 'rb', 'rt'], true)) {
if ($options & STREAM_REPORT_ERRORS) {
trigger_error(sprintf('stream_open() write modes not allowed for %s', $uri), E_USER_WARNING);
}
return false;
}
$path = $this->getPath($uri);
if (!$path) {
if ($options & STREAM_REPORT_ERRORS) {
trigger_error(sprintf('stream_open(): path for %s does not exist', $uri), E_USER_WARNING);
}
return false;
}
$this->uri = $uri;
$this->handle = ($options & STREAM_REPORT_ERRORS) ? fopen($path, $mode) : @fopen($path, $mode);
return (bool) $this->handle;
}
public function stream_lock($operation)
{
// Disallow exclusive lock or non-blocking lock requests
if (!\in_array($operation, [LOCK_SH, LOCK_UN, LOCK_SH | LOCK_NB], true)) {
trigger_error(
sprintf('stream_lock() exclusive lock operations not allowed for %s', $this->uri),
E_USER_WARNING
);
return false;
}
return flock($this->handle, $operation);
}
public function stream_metadata($uri, $option, $value)
{
if ($option !== STREAM_META_TOUCH) {
throw new \BadMethodCallException(sprintf('stream_metadata() not allowed for %s', $uri));
}
return parent::stream_metadata($uri, $option, $value);
}
public function stream_write($data)
{
throw new \BadMethodCallException(sprintf('stream_write() not allowed for %s', $this->uri));
}
public function unlink($uri)
{
throw new \BadMethodCallException(sprintf('unlink() not allowed for %s', $uri));
}
public function rename($from_uri, $to_uri)
{
throw new \BadMethodCallException(sprintf('rename() not allowed for %s', $from_uri));
}
public function mkdir($uri, $mode, $options)
{
throw new \BadMethodCallException(sprintf('mkdir() not allowed for %s', $uri));
}
public function rmdir($uri, $options)
{
throw new \BadMethodCallException(sprintf('rmdir() not allowed for %s', $uri));
}
}

View File

@ -0,0 +1,293 @@
<?php
namespace RocketTheme\Toolbox\StreamWrapper;
use RocketTheme\Toolbox\ResourceLocator\ResourceLocatorInterface;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
/**
* Implements Read/Write Streams.
*
* @package RocketTheme\Toolbox\StreamWrapper
* @author RocketTheme
* @license MIT
*/
class Stream implements StreamInterface
{
/**
* @var string
*/
protected $uri;
/**
* A generic resource handle.
*
* @var Resource
*/
protected $handle = null;
/**
* @var ResourceLocatorInterface|UniformResourceLocator
*/
protected static $locator;
/**
* @param ResourceLocatorInterface $locator
*/
public static function setLocator(ResourceLocatorInterface $locator)
{
static::$locator = $locator;
}
public function stream_open($uri, $mode, $options, &$opened_url)
{
$path = $this->getPath($uri, $mode);
if (!$path) {
if ($options & STREAM_REPORT_ERRORS) {
trigger_error(sprintf('stream_open(): path for %s does not exist', $uri), E_USER_WARNING);
}
return false;
}
$this->uri = $uri;
$this->handle = ($options & STREAM_REPORT_ERRORS) ? fopen($path, $mode) : @fopen($path, $mode);
if (static::$locator instanceof UniformResourceLocator && !\in_array($mode, ['r', 'rb', 'rt'], true)) {
static::$locator->clearCache($this->uri);
}
return (bool) $this->handle;
}
public function stream_close()
{
return fclose($this->handle);
}
public function stream_lock($operation)
{
if (\in_array($operation, [LOCK_SH, LOCK_EX, LOCK_UN, LOCK_NB], true)) {
return flock($this->handle, $operation);
}
return false;
}
public function stream_metadata($uri, $option, $value)
{
$path = $this->findPath($uri);
if ($path) {
switch ($option) {
case STREAM_META_TOUCH:
list ($time, $atime) = $value;
return touch($path, $time, $atime);
case STREAM_META_OWNER_NAME:
case STREAM_META_OWNER:
return chown($path, $value);
case STREAM_META_GROUP_NAME:
case STREAM_META_GROUP:
return chgrp($path, $value);
case STREAM_META_ACCESS:
return chmod($path, $value);
}
}
return false;
}
public function stream_read($count)
{
return fread($this->handle, $count);
}
public function stream_write($data)
{
return fwrite($this->handle, $data);
}
public function stream_eof()
{
return feof($this->handle);
}
public function stream_seek($offset, $whence)
{
// fseek returns 0 on success and -1 on a failure.
return !fseek($this->handle, $offset, $whence);
}
public function stream_flush()
{
return fflush($this->handle);
}
public function stream_tell()
{
return ftell($this->handle);
}
public function stream_stat()
{
return fstat($this->handle);
}
public function unlink($uri)
{
$path = $this->getPath($uri);
if (!$path) {
return false;
}
return unlink($path);
}
public function rename($fromUri, $toUri)
{
$fromPath = $this->getPath($fromUri);
$toPath = $this->getPath($toUri, 'w');
if (!$fromPath || !$toPath) {
return false;
}
if (static::$locator instanceof UniformResourceLocator) {
static::$locator->clearCache($fromUri);
static::$locator->clearCache($toUri);
}
return rename($fromPath, $toPath);
}
public function mkdir($uri, $mode, $options)
{
$recursive = (bool) ($options & STREAM_MKDIR_RECURSIVE);
$path = $this->getPath($uri, $recursive ? 'd' : 'w');
if (!$path) {
if ($options & STREAM_REPORT_ERRORS) {
trigger_error(sprintf('mkdir(): Could not create directory for %s', $uri), E_USER_WARNING);
}
return false;
}
if (static::$locator instanceof UniformResourceLocator) {
static::$locator->clearCache($uri);
}
return ($options & STREAM_REPORT_ERRORS) ? mkdir($path, $mode, $recursive) : @mkdir($path, $mode, $recursive);
}
public function rmdir($uri, $options)
{
$path = $this->getPath($uri);
if (!$path) {
if ($options & STREAM_REPORT_ERRORS) {
trigger_error(sprintf('rmdir(): Directory not found for %s', $uri), E_USER_WARNING);
}
return false;
}
if (static::$locator instanceof UniformResourceLocator) {
static::$locator->clearCache($uri);
}
return ($options & STREAM_REPORT_ERRORS) ? rmdir($path) : @rmdir($path);
}
public function url_stat($uri, $flags)
{
$path = $this->getPath($uri);
if (!$path) {
return false;
}
// Suppress warnings if requested or if the file or directory does not
// exist. This is consistent with PHPs plain filesystem stream wrapper.
return ($flags & STREAM_URL_STAT_QUIET || !file_exists($path)) ? @stat($path) : stat($path);
}
public function dir_opendir($uri, $options)
{
$path = $this->getPath($uri);
if (!$path) {
return false;
}
$this->uri = $uri;
$this->handle = opendir($path);
return (bool) $this->handle;
}
public function dir_readdir()
{
return readdir($this->handle);
}
public function dir_rewinddir()
{
rewinddir($this->handle);
return true;
}
public function dir_closedir()
{
closedir($this->handle);
return true;
}
protected function getPath($uri, $mode = null)
{
if ($mode === null) {
$mode = 'r';
}
$path = $this->findPath($uri);
if ($path && file_exists($path)) {
return $path;
}
if (strpos($mode[0], 'r') === 0) {
return false;
}
// We are either opening a file or creating directory.
list($scheme, $target) = explode('://', $uri, 2);
if ($target === '') {
return false;
}
$target = explode('/', $target);
$filename = [];
do {
$filename[] = array_pop($target);
$path = $this->findPath($scheme . '://' . implode('/', $target));
} while ($target && !$path);
if (!$path) {
return false;
}
return $path . '/' . implode('/', array_reverse($filename));
}
protected function findPath($uri)
{
return static::$locator && static::$locator->isStream($uri) ? static::$locator->findResource($uri) : false;
}
}

View File

@ -0,0 +1,94 @@
<?php
namespace RocketTheme\Toolbox\StreamWrapper;
/**
* Class StreamBuilder
* @package RocketTheme\Toolbox\StreamWrapper
*/
class StreamBuilder
{
/**
* @var array
*/
protected $items = [];
/**
* StreamBuilder constructor.
* @param StreamInterface[] $items
* @throws \InvalidArgumentException
*/
public function __construct(array $items = [])
{
foreach ($items as $scheme => $handler) {
$this->add($scheme, $handler);
}
}
/**
* @param string $scheme
* @param StreamInterface $handler
* @return $this
* @throws \InvalidArgumentException
*/
public function add($scheme, $handler)
{
if (isset($this->items[$scheme])) {
if ($handler === $this->items[$scheme]) {
return $this;
}
throw new \InvalidArgumentException("Stream '{$scheme}' has already been initialized.");
}
if (!is_subclass_of($handler, 'RocketTheme\Toolbox\StreamWrapper\StreamInterface')) {
throw new \InvalidArgumentException("Stream '{$scheme}' has unknown or invalid type.");
}
if (!@stream_wrapper_register($scheme, $handler)) {
throw new \InvalidArgumentException("Stream '{$scheme}' could not be initialized.");
}
$this->items[$scheme] = $handler;
return $this;
}
/**
* @param string $scheme
* @return $this
*/
public function remove($scheme)
{
if (isset($this->items[$scheme])) {
stream_wrapper_unregister($scheme);
unset($this->items[$scheme]);
}
return $this;
}
/**
* @return array
*/
public function getStreams()
{
return $this->items;
}
/**
* @param string $scheme
* @return bool
*/
public function isStream($scheme)
{
return isset($this->items[$scheme]);
}
/**
* @param string $scheme
* @return StreamInterface|null
*/
public function getStreamType($scheme)
{
return isset($this->items[$scheme]) ? $this->items[$scheme] : null;
}
}

View File

@ -0,0 +1,255 @@
<?php
namespace RocketTheme\Toolbox\StreamWrapper;
/**
* Defines Generic PHP stream wrapper interface.
*
* @package RocketTheme\Toolbox\StreamWrapper
* @author RocketTheme
* @license MIT
*
* @see http://www.php.net/manual/class.streamwrapper.php
*/
interface StreamInterface
{
/**
* Support for fopen(), file_get_contents(), file_put_contents() etc.
*
* @param string $uri A string containing the URI to the file to open.
* @param string $mode The file mode ("r", "wb" etc.).
* @param int $options A bit mask of STREAM_USE_PATH and STREAM_REPORT_ERRORS.
* @param string $opened_url A string containing the path actually opened.
*
* @return bool Returns TRUE if file was opened successfully.
* @see http://php.net/manual/streamwrapper.stream-open.php
*/
public function stream_open($uri, $mode, $options, &$opened_url);
/**
* Support for fclose().
*
* @return bool TRUE if stream was successfully closed.
* @see http://php.net/manual/streamwrapper.stream-close.php
*/
public function stream_close();
/**
* Support for flock().
*
* @param $operation
* One of the following:
* - LOCK_SH to acquire a shared lock (reader).
* - LOCK_EX to acquire an exclusive lock (writer).
* - LOCK_UN to release a lock (shared or exclusive).
* - LOCK_NB if you don't want flock() to block while locking (not
* supported on Windows).
*
* @return bool Always returns TRUE at the present time.
* @see http://php.net/manual/streamwrapper.stream-lock.php
*/
public function stream_lock($operation);
/**
* Support for touch(), chmod(), chown(), chgrp().
*
* @param $path
* The file path or URL to set metadata. Note that in the case of a URL, it must be a :// delimited URL.
* Other URL forms are not supported.
*
* @param $option
* One of:
* - STREAM_META_TOUCH The method was called in response to touch()
* - STREAM_META_OWNER_NAME The method was called in response to chown() with string parameter
* - STREAM_META_OWNER The method was called in response to chown()
* - STREAM_META_GROUP_NAME The method was called in response to chgrp()
* - STREAM_META_GROUP The method was called in response to chgrp()
* - STREAM_META_ACCESS The method was called in response to chmod()
*
* @param $value
* If option is
* - STREAM_META_TOUCH: Array consisting of two arguments of the touch() function.
* - STREAM_META_OWNER_NAME or
* STREAM_META_GROUP_NAME: The name of the owner user/group as string.
* - STREAM_META_OWNER or
* STREAM_META_GROUP: The value owner user/group argument as integer.
* - STREAM_META_ACCESS: The argument of the chmod() as integer.
*
* @return bool
* @see http://php.net/manual/en/streamwrapper.stream-metadata.php
*/
public function stream_metadata($path, $option, $value);
/**
* Support for fread(), file_get_contents() etc.
*
* @param $count
* Maximum number of bytes to be read.
*
* @return string|bool The string that was read, or FALSE in case of an error.
* @see http://php.net/manual/streamwrapper.stream-read.php
*/
public function stream_read($count);
/**
* Support for fwrite(), file_put_contents() etc.
*
* @param $data
* The string to be written.
*
* @return int The number of bytes written (integer).
* @see http://php.net/manual/streamwrapper.stream-write.php
*/
public function stream_write($data);
/**
* Support for feof().
*
* @return bool TRUE if end-of-file has been reached.
* @see http://php.net/manual/streamwrapper.stream-eof.php
*/
public function stream_eof();
/**
* Support for fseek().
*
* @param $offset
* The byte offset to got to.
* @param $whence
* SEEK_SET, SEEK_CUR, or SEEK_END.
*
* @return bool TRUE on success.
* @see http://php.net/manual/streamwrapper.stream-seek.php
*/
public function stream_seek($offset, $whence);
/**
* Support for fflush().
*
* @return bool TRUE if data was successfully stored (or there was no data to store).
* @see http://php.net/manual/streamwrapper.stream-flush.php
*/
public function stream_flush();
/**
* Support for ftell().
*
* @return int The current offset in bytes from the beginning of file.
* @see http://php.net/manual/streamwrapper.stream-tell.php
*/
public function stream_tell();
/**
* Support for fstat().
*
* @return array An array with file status, or FALSE in case of an error - see fstat()
* @see http://php.net/manual/streamwrapper.stream-stat.php
*/
public function stream_stat();
/**
* Support for unlink().
*
* @param $uri
* A string containing the URI to the resource to delete.
*
* @return
* TRUE if resource was successfully deleted.
* @see http://php.net/manual/streamwrapper.unlink.php
*/
public function unlink($uri);
/**
* Support for rename().
*
* @param $from_uri ,
* The URI to the file to rename.
* @param $to_uri
* The new URI for file.
*
* @return bool TRUE if file was successfully renamed.
* @see http://php.net/manual/streamwrapper.rename.php
*/
public function rename($from_uri, $to_uri);
/**
* Support for mkdir().
*
* @param $uri
* A string containing the URI to the directory to create.
* @param $mode
* Permission flags - see mkdir().
* @param $options
* A bit mask of STREAM_REPORT_ERRORS and STREAM_MKDIR_RECURSIVE.
*
* @return bool TRUE if directory was successfully created.
* @see http://php.net/manual/streamwrapper.mkdir.php
*/
public function mkdir($uri, $mode, $options);
/**
* Support for rmdir().
*
* @param $uri
* A string containing the URI to the directory to delete.
* @param $options
* A bit mask of STREAM_REPORT_ERRORS.
*
* @return
* TRUE if directory was successfully removed.
*
* @see http://php.net/manual/streamwrapper.rmdir.php
*/
public function rmdir($uri, $options);
/**
* Support for stat().
*
* @param $uri
* A string containing the URI to get information about.
* @param $flags
* A bit mask of STREAM_URL_STAT_LINK and STREAM_URL_STAT_QUIET.
*
* @return array An array with file status, or FALSE in case of an error - see fstat()
* @see http://php.net/manual/streamwrapper.url-stat.php
*/
public function url_stat($uri, $flags);
/**
* Support for opendir().
*
* @param $uri
* A string containing the URI to the directory to open.
* @param $options
* Unknown (parameter is not documented in PHP Manual).
*
* @return bool TRUE on success.
* @see http://php.net/manual/streamwrapper.dir-opendir.php
*/
public function dir_opendir($uri, $options);
/**
* Support for readdir().
*
* @return string The next filename, or FALSE if there are no more files in the directory.
* @see http://php.net/manual/streamwrapper.dir-readdir.php
*/
public function dir_readdir();
/**
* Support for rewinddir().
*
* @return bool TRUE on success.
* @see http://php.net/manual/streamwrapper.dir-rewinddir.php
*/
public function dir_rewinddir();
/**
* Support for closedir().
*
* @return bool TRUE on success.
* @see http://php.net/manual/streamwrapper.dir-closedir.php
*/
public function dir_closedir();
}