예제 #1
0
파일: Wrapper.php 프로젝트: mathroc/php-vfs
 /**
  * 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;
 }