View source
<?php
namespace TYPO3\PharStreamWrapper;
use TYPO3\PharStreamWrapper\Resolver\PharInvocation;
class PharStreamWrapper {
const STREAM_OPEN_FOR_INCLUDE = 128;
public $context;
protected $internalResource;
protected $invocation;
public function dir_closedir() {
if (!is_resource($this->internalResource)) {
return false;
}
$this
->invokeInternalStreamWrapper('closedir', $this->internalResource);
return !is_resource($this->internalResource);
}
public function dir_opendir($path, $options) {
$this
->assert($path, Behavior::COMMAND_DIR_OPENDIR);
$this->internalResource = $this
->invokeInternalStreamWrapper('opendir', $path, $this->context);
return is_resource($this->internalResource);
}
public function dir_readdir() {
return $this
->invokeInternalStreamWrapper('readdir', $this->internalResource);
}
public function dir_rewinddir() {
if (!is_resource($this->internalResource)) {
return false;
}
$this
->invokeInternalStreamWrapper('rewinddir', $this->internalResource);
return is_resource($this->internalResource);
}
public function mkdir($path, $mode, $options) {
$this
->assert($path, Behavior::COMMAND_MKDIR);
return $this
->invokeInternalStreamWrapper('mkdir', $path, $mode, (bool) ($options & STREAM_MKDIR_RECURSIVE), $this->context);
}
public function rename($path_from, $path_to) {
$this
->assert($path_from, Behavior::COMMAND_RENAME);
$this
->assert($path_to, Behavior::COMMAND_RENAME);
return $this
->invokeInternalStreamWrapper('rename', $path_from, $path_to, $this->context);
}
public function rmdir($path, $options) {
$this
->assert($path, Behavior::COMMAND_RMDIR);
return $this
->invokeInternalStreamWrapper('rmdir', $path, $this->context);
}
public function stream_cast($cast_as) {
throw new Exception('Method stream_select() cannot be used', 1530103999);
}
public function stream_close() {
$this
->invokeInternalStreamWrapper('fclose', $this->internalResource);
}
public function stream_eof() {
return $this
->invokeInternalStreamWrapper('feof', $this->internalResource);
}
public function stream_flush() {
return $this
->invokeInternalStreamWrapper('fflush', $this->internalResource);
}
public function stream_lock($operation) {
return $this
->invokeInternalStreamWrapper('flock', $this->internalResource, $operation);
}
public function stream_metadata($path, $option, $value) {
$this
->assert($path, Behavior::COMMAND_STEAM_METADATA);
if ($option === STREAM_META_TOUCH) {
return call_user_func_array(array(
$this,
'invokeInternalStreamWrapper',
), array_merge(array(
'touch',
$path,
), (array) $value));
}
if ($option === STREAM_META_OWNER_NAME || $option === STREAM_META_OWNER) {
return $this
->invokeInternalStreamWrapper('chown', $path, $value);
}
if ($option === STREAM_META_GROUP_NAME || $option === STREAM_META_GROUP) {
return $this
->invokeInternalStreamWrapper('chgrp', $path, $value);
}
if ($option === STREAM_META_ACCESS) {
return $this
->invokeInternalStreamWrapper('chmod', $path, $value);
}
return false;
}
public function stream_open($path, $mode, $options, &$opened_path = null) {
$this
->assert($path, Behavior::COMMAND_STREAM_OPEN);
$arguments = array(
$path,
$mode,
(bool) ($options & STREAM_USE_PATH),
);
if (!($options & static::STREAM_OPEN_FOR_INCLUDE)) {
$arguments[] = $this->context;
}
else {
Helper::resetOpCache();
}
$this->internalResource = call_user_func_array(array(
$this,
'invokeInternalStreamWrapper',
), array_merge(array(
'fopen',
), $arguments));
if (!is_resource($this->internalResource)) {
return false;
}
if ($opened_path !== null) {
$metaData = stream_get_meta_data($this->internalResource);
$opened_path = $metaData['uri'];
}
return true;
}
public function stream_read($count) {
return $this
->invokeInternalStreamWrapper('fread', $this->internalResource, $count);
}
public function stream_seek($offset, $whence = SEEK_SET) {
return $this
->invokeInternalStreamWrapper('fseek', $this->internalResource, $offset, $whence) !== -1;
}
public function stream_set_option($option, $arg1, $arg2) {
if ($option === STREAM_OPTION_BLOCKING) {
return $this
->invokeInternalStreamWrapper('stream_set_blocking', $this->internalResource, $arg1);
}
if ($option === STREAM_OPTION_READ_TIMEOUT) {
return $this
->invokeInternalStreamWrapper('stream_set_timeout', $this->internalResource, $arg1, $arg2);
}
if ($option === STREAM_OPTION_WRITE_BUFFER) {
return $this
->invokeInternalStreamWrapper('stream_set_write_buffer', $this->internalResource, $arg2) === 0;
}
return false;
}
public function stream_stat() {
return $this
->invokeInternalStreamWrapper('fstat', $this->internalResource);
}
public function stream_tell() {
return $this
->invokeInternalStreamWrapper('ftell', $this->internalResource);
}
public function stream_truncate($new_size) {
return $this
->invokeInternalStreamWrapper('ftruncate', $this->internalResource, $new_size);
}
public function stream_write($data) {
return $this
->invokeInternalStreamWrapper('fwrite', $this->internalResource, $data);
}
public function unlink($path) {
$this
->assert($path, Behavior::COMMAND_UNLINK);
return $this
->invokeInternalStreamWrapper('unlink', $path, $this->context);
}
public function url_stat($path, $flags) {
$this
->assert($path, Behavior::COMMAND_URL_STAT);
$functionName = $flags & STREAM_URL_STAT_QUIET ? '@stat' : 'stat';
return $this
->invokeInternalStreamWrapper($functionName, $path);
}
protected function assert($path, $command) {
if (Manager::instance()
->assert($path, $command) === true) {
$this
->collectInvocation($path);
return;
}
throw new Exception(sprintf('Denied invocation of "%s" for command "%s"', $path, $command), 1535189880);
}
protected function collectInvocation($path) {
if (isset($this->invocation)) {
return;
}
$manager = Manager::instance();
$this->invocation = $manager
->resolve($path);
if ($this->invocation === null) {
throw new Exception('Expected invocation could not be resolved', 1556389591);
}
$this->invocation
->confirm();
$collection = $manager
->getCollection();
if (!$collection
->has($this->invocation)) {
$collection
->collect($this->invocation);
}
}
protected function resolveAssertable() {
return Manager::instance();
}
private function invokeInternalStreamWrapper($functionName) {
$arguments = func_get_args();
array_shift($arguments);
$silentExecution = $functionName[0] === '@';
$functionName = ltrim($functionName, '@');
$this
->restoreInternalSteamWrapper();
try {
if ($silentExecution) {
$result = @call_user_func_array($functionName, $arguments);
}
else {
$result = call_user_func_array($functionName, $arguments);
}
} catch (\Exception $exception) {
$this
->registerStreamWrapper();
throw $exception;
} catch (\Throwable $throwable) {
$this
->registerStreamWrapper();
throw $throwable;
}
$this
->registerStreamWrapper();
return $result;
}
private function restoreInternalSteamWrapper() {
stream_wrapper_restore('phar');
}
private function registerStreamWrapper() {
stream_wrapper_unregister('phar');
stream_wrapper_register('phar', get_class($this));
}
}