add directory wrapper base

This commit is contained in:
Robin Appelman 2015-10-16 15:36:02 +02:00
commit 91176a6bf5
2 changed files with 143 additions and 0 deletions

103
src/DirectoryWrapper.php Normal file
View file

@ -0,0 +1,103 @@
<?php
/**
* Copyright (c) 2015 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Licensed under the MIT license:
* http://opensource.org/licenses/MIT
*/
namespace Icewind\Streams;
class DirectoryWrapper implements Directory {
/**
* @var resource
*/
public $context;
/**
* @var resource
*/
protected $source;
/**
* Load the source from the stream context and return the context options
*
* @param string $name
* @return array
* @throws \Exception
*/
protected function loadContext($name) {
$context = stream_context_get_options($this->context);
if (isset($context[$name])) {
$context = $context[$name];
} else {
throw new \BadMethodCallException('Invalid context, "' . $name . '" options not set');
}
if (isset($context['source']) and is_resource($context['source'])) {
$this->source = $context['source'];
} else {
throw new \BadMethodCallException('Invalid context, source not set');
}
return $context;
}
/**
* @param string $path
* @param array $options
* @return bool
*/
public function dir_opendir($path, $options) {
$this->loadContext('dir');
return true;
}
/**
* @return string
*/
public function dir_readdir() {
return readdir($this->source);
}
/**
* @return bool
*/
public function dir_closedir() {
closedir($this->source);
return true;
}
/**
* @return bool
*/
public function dir_rewinddir() {
rewinddir($this->source);
return true;
}
/**
* Creates a directory handle from the provided array or iterator
*
* @param resource $source
* @return resource
*
* @throws \BadMethodCallException
*/
public static function wrap($source) {
$options = array(
'dir' => array(
'source' => $source)
);
return self::wrapWithOptions($options);
}
/**
* @param string $options the options for the context to wrap the stream with
* @return resource
*/
protected static function wrapWithOptions($options) {
$context = stream_context_create($options);
stream_wrapper_register('dirwrapper', static::class);
$wrapped = opendir('dirwrapper://', $context);
stream_wrapper_unregister('dirwrapper');
return $wrapped;
}
}

View file

@ -0,0 +1,40 @@
<?php
/**
* Copyright (c) 2015 Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Licensed under the MIT license:
* http://opensource.org/licenses/MIT
*/
namespace Icewind\Streams\Tests;
class DirectoryWrapperDummy extends \Icewind\Streams\DirectoryWrapper {
public function dir_readdir() {
$file = parent::dir_readdir();
if ($file !== false) {
$file .= '_';
}
return $file;
}
}
class DirectoryWrapper extends IteratorDirectory {
/**
* @param \Iterator | array $source
* @return resource
*/
protected function wrapSource($source) {
$dir = \Icewind\Streams\IteratorDirectory::wrap($source);
return \Icewind\Streams\DirectoryWrapper::wrap($dir);
}
public function testManipulateContent() {
$source = \Icewind\Streams\IteratorDirectory::wrap(['asd', 'bar']);
$wrapped = DirectoryWrapperDummy::wrap($source);
$result = [];
while (($file = readdir($wrapped)) !== false) {
$result[] = $file;
}
$this->assertEquals(['asd_', 'bar_'], $result);
}
}