mirror of
https://codeberg.org/icewind/streams.git
synced 2026-06-03 16:44:07 +02:00
Add UrlCallBack wrapper that provides callbacks for fopen, unlink, rename, etc
This commit is contained in:
parent
53cfe7f4f1
commit
e5854bfd06
4 changed files with 421 additions and 0 deletions
104
src/Path.php
Normal file
104
src/Path.php
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
|
||||
* This file is licensed under the Licensed under the MIT license:
|
||||
* http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
namespace Icewind\Streams;
|
||||
|
||||
/**
|
||||
* A string-like object that automatically registers a stream wrapper when used and removes the stream wrapper when no longer used
|
||||
*
|
||||
* Can optionally pass context options to the stream wrapper
|
||||
*/
|
||||
class Path {
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $registered = false;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $protocol;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $class;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $contextOptions;
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @param array $contextOptions
|
||||
*/
|
||||
public function __construct($class, $contextOptions = array()) {
|
||||
$this->class = $class;
|
||||
$this->contextOptions = $contextOptions;
|
||||
}
|
||||
|
||||
public function getProtocol() {
|
||||
if (!$this->protocol) {
|
||||
$this->protocol = 'auto' . uniqid();
|
||||
}
|
||||
return $this->protocol;
|
||||
}
|
||||
|
||||
public function wrapPath($path) {
|
||||
return $this->getProtocol() . '://' . $path;
|
||||
}
|
||||
|
||||
protected function register() {
|
||||
if (!$this->registered) {
|
||||
$this->appendDefaultContent($this->getProtocol(), $this->contextOptions);
|
||||
stream_wrapper_register($this->getProtocol(), $this->class);
|
||||
$this->registered = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected function unregister() {
|
||||
stream_wrapper_unregister($this->getProtocol());
|
||||
$this->unsetDefaultContent($this->getProtocol());
|
||||
$this->registered = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add values to the default stream context
|
||||
*
|
||||
* @param string $key
|
||||
* @param array $values
|
||||
*/
|
||||
protected function appendDefaultContent($key, $values) {
|
||||
$context = stream_context_get_default();
|
||||
$defaults = stream_context_get_options($context);
|
||||
$defaults[$key] = $values;
|
||||
stream_context_set_default($defaults);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove values from the default stream context
|
||||
*
|
||||
* @param string $key
|
||||
*/
|
||||
protected function unsetDefaultContent($key) {
|
||||
$context = stream_context_get_default();
|
||||
$defaults = stream_context_get_options($context);
|
||||
unset($defaults[$key]);
|
||||
stream_context_set_default($defaults);
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
$this->register();
|
||||
return $this->protocol . '://';
|
||||
}
|
||||
|
||||
public function __destruct() {
|
||||
$this->unregister();
|
||||
}
|
||||
}
|
||||
64
src/Url.php
Normal file
64
src/Url.php
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
|
||||
* This file is licensed under the Licensed under the MIT license:
|
||||
* http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
namespace Icewind\Streams;
|
||||
|
||||
/**
|
||||
* Interface for stream wrappers that implement url functions such as unlink, stat
|
||||
*/
|
||||
interface Url {
|
||||
/**
|
||||
* @param string $path
|
||||
* @param array $options
|
||||
* @return bool
|
||||
*/
|
||||
public function dir_opendir($path, $options);
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param string $mode
|
||||
* @param int $options
|
||||
* @param string &$opened_path
|
||||
* @return bool
|
||||
*/
|
||||
public function stream_open($path, $mode, $options, &$opened_path);
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param int $mode
|
||||
* @param int $options
|
||||
* @return bool
|
||||
*/
|
||||
public function mkdir($path, $mode, $options);
|
||||
|
||||
/**
|
||||
* @param string $source
|
||||
* @param string $target
|
||||
* @return bool
|
||||
*/
|
||||
public function rename($source, $target);
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param int $options
|
||||
* @return bool
|
||||
*/
|
||||
public function rmdir($path, $options);
|
||||
|
||||
/**
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
public function unlink($path);
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param int $flags
|
||||
* @return array
|
||||
*/
|
||||
public function url_stat($path, $flags);
|
||||
}
|
||||
121
src/UrlCallBack.php
Normal file
121
src/UrlCallBack.php
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
|
||||
* This file is licensed under the Licensed under the MIT license:
|
||||
* http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
namespace Icewind\Streams;
|
||||
|
||||
/**
|
||||
* Wrapper that provides callbacks for url actions such as fopen, unlink, rename
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* $path = UrlCallBack('/path/so/source', function(){
|
||||
* echo 'fopen';
|
||||
* }, function(){
|
||||
* echo 'opendir';
|
||||
* }, function(){
|
||||
* echo 'mkdir';
|
||||
* }, function(){
|
||||
* echo 'rename';
|
||||
* }, function(){
|
||||
* echo 'rmdir';
|
||||
* }, function(){
|
||||
* echo 'unlink';
|
||||
* }, function(){
|
||||
* echo 'stat';
|
||||
* });
|
||||
*
|
||||
* mkdir($path);
|
||||
* ...
|
||||
*
|
||||
* All callbacks are called after the operation is executed on the source stream
|
||||
*/
|
||||
class UrlCallback extends Wrapper implements Url {
|
||||
|
||||
/**
|
||||
* @param string $source
|
||||
* @param callable $fopen
|
||||
* @param callable $opendir
|
||||
* @param callable $mkdir
|
||||
* @param callable $rename
|
||||
* @param callable $rmdir
|
||||
* @param callable $unlink
|
||||
* @param callable $stat
|
||||
* @return \Icewind\Streams\Path
|
||||
*
|
||||
* @throws \BadMethodCallException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function wrap($source, $fopen = null, $opendir = null, $mkdir = null, $rename = null, $rmdir = null,
|
||||
$unlink = null, $stat = null) {
|
||||
$options = array(
|
||||
'source' => $source,
|
||||
'fopen' => $fopen,
|
||||
'opendir' => $opendir,
|
||||
'mkdir' => $mkdir,
|
||||
'rename' => $rename,
|
||||
'rmdir' => $rmdir,
|
||||
'unlink' => $unlink,
|
||||
'stat' => $stat
|
||||
);
|
||||
return new Path('\Icewind\Streams\UrlCallBack', $options);
|
||||
}
|
||||
|
||||
protected function loadContext($url) {
|
||||
list($protocol) = explode('://', $url);
|
||||
$options = stream_context_get_options($this->context);
|
||||
return $options[$protocol];
|
||||
}
|
||||
|
||||
protected function callCallBack($context, $callback) {
|
||||
if (is_callable($context[$callback])) {
|
||||
call_user_func($context[$callback]);
|
||||
}
|
||||
}
|
||||
|
||||
public function stream_open($path, $mode, $options, &$opened_path) {
|
||||
$context = $this->loadContext($path);
|
||||
$this->callCallBack($context, 'fopen');
|
||||
$this->setSourceStream(fopen($context['source'], $mode));
|
||||
return true;
|
||||
}
|
||||
|
||||
public function dir_opendir($path, $options) {
|
||||
$context = $this->loadContext($path);
|
||||
$this->callCallBack($context, 'opendir');
|
||||
$this->setSourceStream(opendir($context['source']));
|
||||
return true;
|
||||
}
|
||||
|
||||
public function mkdir($path, $mode, $options) {
|
||||
$context = $this->loadContext($path);
|
||||
$this->callCallBack($context, 'mkdir');
|
||||
return mkdir($context['source'], $mode, $options);
|
||||
}
|
||||
|
||||
public function rmdir($path, $options) {
|
||||
$context = $this->loadContext($path);
|
||||
$this->callCallBack($context, 'rmdir');
|
||||
return rmdir($context['source']);
|
||||
}
|
||||
|
||||
public function rename($source, $target) {
|
||||
$context = $this->loadContext($source);
|
||||
$this->callCallBack($context, 'rename');
|
||||
list(, $target) = explode('://', $target);
|
||||
return rename($context['source'], $target);
|
||||
}
|
||||
|
||||
public function unlink($path) {
|
||||
$context = $this->loadContext($path);
|
||||
$this->callCallBack($context, 'unlink');
|
||||
return unlink($context['source']);
|
||||
}
|
||||
|
||||
public function url_stat($path, $flags) {
|
||||
throw new \Exception('stat is not supported due to php bug 50526');
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue