/** * Opens stream in selected mode. * * @see http://php.net/streamwrapper.stream-open * * @param string $path * @param int $mode * @param int $options * @param string $opened_path * * @return bool */ public function stream_open($path, $mode, $options, &$opened_path) { $container = $this->getContainerFromContext($path); $path = $this->stripScheme($path); $mode = str_split(str_replace('b', '', $mode)); $permissionDeniedError = function () use($path, $options) { if ($options & STREAM_REPORT_ERRORS) { trigger_error(sprintf('fopen(%s): failed to open stream: Permission denied', $path), E_USER_WARNING); } return false; }; $appendMode = in_array('a', $mode); $readMode = in_array('r', $mode); $writeMode = in_array('w', $mode); $extended = in_array('+', $mode); if (!$container->hasFileAt($path)) { if ($readMode or !$container->hasFileAt(dirname($path))) { if ($options & STREAM_REPORT_ERRORS) { trigger_error(sprintf('%s: failed to open stream.', $path), E_USER_WARNING); } return false; } $parent = $container->fileAt(dirname($path)); $ph = $container->getPermissionHelper($parent); if (!$ph->isWritable()) { return $permissionDeniedError(); } $parent->addFile($container->factory()->getFile(basename($path))); } $file = $container->fileAt($path); if (($extended || $writeMode || $appendMode) && $file instanceof Directory) { if ($options & STREAM_REPORT_ERRORS) { trigger_error(sprintf('fopen(%s): failed to open stream: Is a directory', $path), E_USER_WARNING); } return false; } if ($file instanceof Directory) { $dir = $file; $file = $container->factory()->getFile('tmp'); $file->chmod($dir->mode()); $file->chown($dir->user()); $file->chgrp($dir->group()); } $permissionHelper = $container->getPermissionHelper($file); $this->currently_opened = new FileHandler(); $this->currently_opened->setFile($file); if ($extended) { if (!$permissionHelper->isReadable() or !$permissionHelper->isWritable()) { return $permissionDeniedError(); } $this->currently_opened->setReadWriteMode(); } elseif ($readMode) { if (!$permissionHelper->isReadable()) { return $permissionDeniedError(); } $this->currently_opened->setReadOnlyMode(); } else { // a or w are for write only if (!$permissionHelper->isWritable()) { return $permissionDeniedError(); } $this->currently_opened->setWriteOnlyMode(); } if ($appendMode) { $this->currently_opened->seekToEnd(); } elseif ($writeMode) { $this->currently_opened->truncate(); clearstatcache(); } return true; }