You are here

class SessionStreamWrapper in Examples for Developers 8

Same name and namespace in other branches
  1. 3.x modules/stream_wrapper_example/src/StreamWrapper/SessionStreamWrapper.php \Drupal\stream_wrapper_example\StreamWrapper\SessionStreamWrapper

Example stream wrapper class to handle session:// streams.

This is just an example, as it could have horrible results if much information were placed in the session object. However, it does demonstrate both the read and write implementation of a stream wrapper. You should *never* do this on any website accessable on the open Internet.

A "stream" is an important Unix concept for the reading and writing of files and other devices. Reading or writing a "stream" just means that you open some device, file, internet site, or whatever, and you don't have to know at all what it is. All the functions that deal with it are the same. You can read/write more from/to the stream, seek a position in the stream, or anything else without the code that does it even knowing what kind of device it is talking to. This Unix idea is extended into PHP's mindset.

The idea of "stream wrapper" is that this can be extended indefinitely. The classic example is HTTP: With PHP you can do a file_get_contents("http://drupal.org/projects") as if it were a file, because the scheme "http" is supported natively in PHP. So Drupal adds the public:// and private:// schemes, and contrib modules can add any scheme they want to. This example adds the session:// scheme, which allows reading and writing the 'stream_wrapper_example' key of the session object as if it were a file.

Drupal makes use of this concept to implement custom URI types like "private://" and "public://". To implement a stream wrapper, reading the implementation of these stream wrappers is a very good way to get started.

To implement a stream wrapper in Drupal, you should do the following:

1. Create a class that implements the StreamWrapperInterface (Drupal\Core\StreamWrapper\StreamWrapperInterface).

2. Register the class with Drupal. The best way to do this is to define a service in your MY_MODULE.services.yml file. The service needs to be "tagged" with the scheme you want to implement, and, as so:


        tags:
          - { name: stream_wrapper, scheme: session }

See stream_wrapper_example.services.yml for an example.

3. (Optional) If you want to be able to access your files over the web, you need to add a route that handles, and implement hook_file_download(). See stream_wrapper_example.routing.yml for an example of this, and file.module for the hook implementation.

Note that because this implementation uses simple PHP arrays it is limited to string values, so binary files will not work correctly. Only text files can be used.

Also, experienced Drupal coders will notice that we are violating one of Drupal's coding standards here: normally, you should use "camelCase" for the names of your public functions. We cannot do this here, since PHP itself defines the interface used to interact with stream wrappers. Since PHP uses names_like_this we are required to do the same here. We've turned off PHPCS for those method names in our implementation using the 'codingStandardsIgnore' annotation.

Hierarchy

Expanded class hierarchy of SessionStreamWrapper

Related topics

1 string reference to 'SessionStreamWrapper'
stream_wrapper_example.services.yml in stream_wrapper_example/stream_wrapper_example.services.yml
stream_wrapper_example/stream_wrapper_example.services.yml
1 service uses SessionStreamWrapper
stream_wrapper_example.stream_wrapper in stream_wrapper_example/stream_wrapper_example.services.yml
Drupal\stream_wrapper_example\StreamWrapper\SessionStreamWrapper

File

stream_wrapper_example/src/StreamWrapper/SessionStreamWrapper.php, line 77

Namespace

Drupal\stream_wrapper_example\StreamWrapper
View source
class SessionStreamWrapper implements StreamWrapperInterface {
  use StringTranslationTrait;

  /**
   * The session helper service.
   *
   * @var \Drupal\stream_wrapper_example\SessionHelper
   */
  protected $sessionHelper;

  /**
   * Instance URI (stream).
   *
   * These streams will be references as 'session://example_target'
   *
   * @var string
   */
  protected $uri;

  /**
   * The content of the stream.
   *
   * Since this trivial example uses the session object, this is a reference to
   * the the session object's 'stream_wrapper_example' key.
   *
   * @var array
   */
  protected $sessionContent;

  /**
   * Pointer to where we are in a directory read.
   *
   * @var int
   */
  protected $directoryPointer;

  /**
   * List of keys in a given directory.
   *
   * @var string[]
   */
  protected $directoryKeys;

  /**
   * The pointer to the next read or write within the session variable.
   *
   * @var int
   */
  protected $streamPointer;

  /**
   * The mode we are currently in.
   *
   * Possible values are FALSE, 'r', 'w'.
   *
   * @var mixed
   */
  protected $streamMode;

  /**
   * Returns the type of stream wrapper.
   *
   * @return int
   *   See StreamWrapperInterface for permissible values.
   */
  public static function getType() {
    return StreamWrapperInterface::NORMAL;
  }

  /**
   * Constructor method.
   *
   * Note this cannot take any arguments; PHP's stream wrapper users
   * do not know how to supply them.
   *
   * @todo Refactor helper injection after https://www.drupal.org/node/3048126
   */
  public function __construct() {

    // Dependency injection will not work here, since PHP doesn't give us a
    // chance to perform the injection. PHP creates the stream wrapper objects
    // automatically when certain file functions are called. Therefore we'll use
    // the \Drupal service locator.
    // phpcs:ignore
    $this->sessionHelper = \Drupal::service('stream_wrapper_example.session_helper');
    $this->sessionHelper
      ->setPath('.isadir.txt', TRUE);
    $this->streamMode = FALSE;
  }

  /**
   * Returns the name of the stream wrapper for use in the UI.
   *
   * @return string
   *   The stream wrapper name.
   */
  public function getName() {
    return $this
      ->t('Session stream wrapper example files');
  }

  /**
   * {@inheritdoc}
   */
  public function getDescription() {
    return $this
      ->t('Simulated file system using your session storage. Not for real use!');
  }

  /**
   * Implements setUri().
   */
  public function setUri($uri) {
    $this->uri = $uri;
  }

  /**
   * Implements getUri().
   */
  public function getUri() {
    return $this->uri;
  }

  /**
   * Overrides getExternalUrl().
   *
   * We have set up a helper function and menu entry to provide access to this
   * key via HTTP; normally it would be accessible some other way.
   */
  public function getExternalUrl() {
    $path = str_replace('\\', '/', $this
      ->getLocalPath());
    return Url::fromRoute('stream_wrapper_example.files.session', [
      'filepath' => $path,
      'scheme' => 'session',
    ], [
      'absolute' => TRUE,
    ])
      ->toString(FALSE);
  }

  /**
   * Returns canonical, absolute path of the resource.
   *
   * Implementation placeholder. PHP's realpath() does not support stream
   * wrappers. We provide this as a default so that individual wrappers may
   * implement their own solutions.
   *
   * @return string
   *   Returns a string with absolute pathname on success (implemented
   *   by core wrappers), or FALSE on failure or if the registered
   *   wrapper does not provide an implementation.
   */
  public function realpath() {
    return 'session://' . $this
      ->getLocalPath();
  }

  /**
   * Returns the local path.
   *
   * In our case, the local path is the URI minus the wrapper type. So a URI
   * like 'session://one/two/three.txt' becomes 'one/two/three.txt'.
   *
   * @param string $uri
   *   Optional URI, supplied when doing a move or rename.
   *
   * @return string
   *   The local path.
   */
  protected function getLocalPath($uri = NULL) {
    if (!isset($uri)) {
      $uri = $this->uri;
    }
    $path = str_replace('session://', '', $uri);
    $path = trim($path, '/');
    return $path;
  }

  /**
   * Opens a stream, as for fopen(), file_get_contents(), file_put_contents().
   *
   * @param string $uri
   *   A string containing the URI to the file to open.
   * @param string $mode
   *   The file mode ("r", "wb" etc.).
   * @param int $options
   *   A bit mask of STREAM_USE_PATH and STREAM_REPORT_ERRORS.
   * @param string &$opened_path
   *   A string containing the path actually opened.
   *
   * @return bool
   *   Returns TRUE if file was opened successfully. (Always returns TRUE).
   *
   * @see http://php.net/manual/en/streamwrapper.stream-open.php
   */

  // @codingStandardsIgnoreStart
  public function stream_open($uri, $mode, $options, &$opened_path) {

    // @codingStandardsIgnoreEnd
    $this->uri = $uri;
    $path = $this
      ->getLocalPath($uri);

    // We will support two modes only, 'r' and 'w'.  If the key is 'r',
    // check to make sure the file is there.
    if (stristr($mode, 'r') !== FALSE) {
      if (!$this->sessionHelper
        ->checkPath($path)) {
        return FALSE;
      }
      else {
        $buffer = $this->sessionHelper
          ->getPath($path);
        if (!is_string($buffer)) {
          return FALSE;
        }
        $this->sessionContent = $buffer;
      }
      $this->streamMode = 'r';
    }
    else {
      $this->sessionContent = '';
      $this->streamMode = 'w';
    }

    // Reset the stream pointer since this is an open.
    $this->streamPointer = 0;
    return TRUE;
  }

  /**
   * Retrieve the underlying stream resource.
   *
   * This method is called in response to stream_select().
   *
   * @param int $cast_as
   *   Can be STREAM_CAST_FOR_SELECT when stream_select() is calling
   *   stream_cast() or STREAM_CAST_AS_STREAM when stream_cast() is called for
   *   other uses.
   *
   * @return resource|false
   *   The underlying stream resource or FALSE if stream_select() is not
   *   supported.
   *
   * @see stream_select()
   * @see http://php.net/manual/streamwrapper.stream-cast.php
   */

  // @codingStandardsIgnoreStart
  public function stream_cast($cast_as) {

    // @codingStandardsIgnoreEnd
    return FALSE;
  }

  /**
   * Sets metadata on the stream.
   *
   * @param string $path
   *   A string containing the URI to the file to set metadata on.
   * @param int $option
   *   One of:
   *   - STREAM_META_TOUCH: The method was called in response to touch().
   *   - STREAM_META_OWNER_NAME: The method was called in response to chown()
   *     with string parameter.
   *   - STREAM_META_OWNER: The method was called in response to chown().
   *   - STREAM_META_GROUP_NAME: The method was called in response to chgrp().
   *   - STREAM_META_GROUP: The method was called in response to chgrp().
   *   - STREAM_META_ACCESS: The method was called in response to chmod().
   * @param mixed $value
   *   If option is:
   *   - STREAM_META_TOUCH: Array consisting of two arguments of the touch()
   *     function.
   *   - STREAM_META_OWNER_NAME or STREAM_META_GROUP_NAME: The name of the owner
   *     user/group as string.
   *   - STREAM_META_OWNER or STREAM_META_GROUP: The value of the owner
   *     user/group as integer.
   *   - STREAM_META_ACCESS: The argument of the chmod() as integer.
   *
   * @return bool
   *   Returns TRUE on success or FALSE on failure. If $option is not
   *   implemented, FALSE should be returned.
   *
   * @see http://www.php.net/manual/streamwrapper.stream-metadata.php
   */

  // @codingStandardsIgnoreStart
  public function stream_metadata($path, $option, $value) {

    // @codingStandardsIgnoreEnd
    // We don't really do any of these, but we want to reassure the calling code
    // that there is no problem with chown or chgrp, even though we do not
    // actually support these.
    return TRUE;
  }

  /**
   * Change stream options.
   *
   * This method is called to set options on the stream.
   *
   * @param int $option
   *   One of:
   *   - STREAM_OPTION_BLOCKING: The method was called in response to
   *     stream_set_blocking().
   *   - STREAM_OPTION_READ_TIMEOUT: The method was called in response to
   *     stream_set_timeout().
   *   - STREAM_OPTION_WRITE_BUFFER: The method was called in response to
   *     stream_set_write_buffer().
   * @param int $arg1
   *   If option is:
   *   - STREAM_OPTION_BLOCKING: The requested blocking mode:
   *     - 1 means blocking.
   *     - 0 means not blocking.
   *   - STREAM_OPTION_READ_TIMEOUT: The timeout in seconds.
   *   - STREAM_OPTION_WRITE_BUFFER: The buffer mode, STREAM_BUFFER_NONE or
   *     STREAM_BUFFER_FULL.
   * @param int $arg2
   *   If option is:
   *   - STREAM_OPTION_BLOCKING: This option is not set.
   *   - STREAM_OPTION_READ_TIMEOUT: The timeout in microseconds.
   *   - STREAM_OPTION_WRITE_BUFFER: The requested buffer size.
   *
   * @return bool
   *   TRUE on success, FALSE otherwise. If $option is not implemented, FALSE
   *   should be returned.
   */

  // @codingStandardsIgnoreStart
  public function stream_set_option($option, $arg1, $arg2) {

    // @codingStandardsIgnoreEnd
    return FALSE;
  }

  /**
   * Truncate stream.
   *
   * Will respond to truncation; e.g., through ftruncate().
   *
   * @param int $new_size
   *   The new size.
   *
   * @return bool
   *   TRUE on success, FALSE otherwise.
   *
   * @todo
   *   Allow truncating the stream.
   *   https://www.drupal.org/project/examples/issues/2992398
   */

  // @codingStandardsIgnoreStart
  public function stream_truncate($new_size) {

    // @codingStandardsIgnoreEnd
    return FALSE;
  }

  /**
   * Support for flock().
   *
   * The session object has no locking capability, so return TRUE.
   *
   * @param int $operation
   *   One of the following:
   *   - LOCK_SH to acquire a shared lock (reader).
   *   - LOCK_EX to acquire an exclusive lock (writer).
   *   - LOCK_UN to release a lock (shared or exclusive).
   *   - LOCK_NB if you don't want flock() to block while locking (not
   *     supported on Windows).
   *
   * @return bool
   *   Always returns TRUE at the present time. (no support)
   *
   * @see http://php.net/manual/en/streamwrapper.stream-lock.php
   */

  // @codingStandardsIgnoreStart
  public function stream_lock($operation) {

    // @codingStandardsIgnoreEnd
    return TRUE;
  }

  /**
   * Support for fread(), file_get_contents() etc.
   *
   * @param int $count
   *   Maximum number of bytes to be read.
   *
   * @return string
   *   The string that was read, or FALSE in case of an error.
   *
   * @see http://php.net/manual/en/streamwrapper.stream-read.php
   */

  // @codingStandardsIgnoreStart
  public function stream_read($count) {

    // @codingStandardsIgnoreEnd
    if (is_string($this->sessionContent)) {
      $remaining_chars = strlen($this->sessionContent) - $this->streamPointer;
      $number_to_read = min($count, $remaining_chars);
      if ($remaining_chars > 0) {
        $buffer = substr($this->sessionContent, $this->streamPointer, $number_to_read);
        $this->streamPointer += $number_to_read;
        return $buffer;
      }
    }
    return FALSE;
  }

  /**
   * Support for fwrite(), file_put_contents() etc.
   *
   * @param string $data
   *   The string to be written.
   *
   * @return int
   *   The number of bytes written (integer).
   *
   * @see http://php.net/manual/en/streamwrapper.stream-write.php
   */

  // @codingStandardsIgnoreStart
  public function stream_write($data) {

    // @codingStandardsIgnoreEnd
    // Sanitize the data in a simple way since we're putting it into the
    // session variable.
    $data = Html::escape($data);
    $this->sessionContent = substr_replace($this->sessionContent, $data, $this->streamPointer);
    $this->streamPointer += strlen($data);
    return strlen($data);
  }

  /**
   * Support for feof().
   *
   * @return bool
   *   TRUE if end-of-file has been reached.
   *
   * @see http://php.net/manual/en/streamwrapper.stream-eof.php
   */

  // @codingStandardsIgnoreStart
  public function stream_eof() {

    // @codingStandardsIgnoreEnd
    return FALSE;
  }

  /**
   * Support for fseek().
   *
   * @param int $offset
   *   The byte offset to got to.
   * @param int $whence
   *   SEEK_SET, SEEK_CUR, or SEEK_END.
   *
   * @return bool
   *   TRUE on success.
   *
   * @see http://php.net/manual/en/streamwrapper.stream-seek.php
   */

  // @codingStandardsIgnoreStart
  public function stream_seek($offset, $whence = SEEK_SET) {

    // @codingStandardsIgnoreEnd
    if (strlen($this->sessionContent) >= $offset) {
      $this->streamPointer = $offset;
      return TRUE;
    }
    return FALSE;
  }

  /**
   * Support for fflush().
   *
   * @return bool
   *   TRUE if data was successfully stored (or there was no data to store).
   *   This always returns TRUE, as this example provides and needs no
   *   flush support.
   *
   * @see http://php.net/manual/en/streamwrapper.stream-flush.php
   */

  // @codingStandardsIgnoreStart
  public function stream_flush() {

    // @codingStandardsIgnoreEnd
    if ($this->streamMode == 'w') {

      // Since we aren't writing directly to the session, we need to send
      // the bytes on to the store.
      $path = $this
        ->getLocalPath($this->uri);
      $this->sessionHelper
        ->setPath($path, $this->sessionContent);
      $this->sessionContent = '';
      $this->streamPointer = 0;
    }
    return TRUE;
  }

  /**
   * Support for ftell().
   *
   * @return int
   *   The current offset in bytes from the beginning of file.
   *
   * @see http://php.net/manual/en/streamwrapper.stream-tell.php
   */

  // @codingStandardsIgnoreStart
  public function stream_tell() {

    // @codingStandardsIgnoreEnd
    return $this->streamPointer;
  }

  /**
   * Support for fstat().
   *
   * @return array
   *   An array with file status, or FALSE in case of an error - see fstat()
   *   for a description of this array.
   *
   * @see http://php.net/manual/en/streamwrapper.stream-stat.php
   */

  // @codingStandardsIgnoreStart
  public function stream_stat() {

    // @codingStandardsIgnoreEnd
    return [
      'size' => strlen($this->sessionContent),
    ];
  }

  /**
   * Support for fclose().
   *
   * @return bool
   *   TRUE if stream was successfully closed.
   *
   * @see http://php.net/manual/en/streamwrapper.stream-close.php
   */

  // @codingStandardsIgnoreStart
  public function stream_close() {

    // @codingStandardsIgnoreEnd
    $this->streamPointer = 0;

    // Unassign the reference.
    unset($this->sessionContent);
    return TRUE;
  }

  /**
   * Support for unlink().
   *
   * @param string $uri
   *   A string containing the uri to the resource to delete.
   *
   * @return bool
   *   TRUE if resource was successfully deleted.
   *
   * @see http://php.net/manual/en/streamwrapper.unlink.php
   */
  public function unlink($uri) {
    $path = $this
      ->getLocalPath($uri);
    $this->sessionHelper
      ->clearPath($path);
    return TRUE;
  }

  /**
   * Support for rename().
   *
   * @param string $from_uri
   *   The uri to the file to rename.
   * @param string $to_uri
   *   The new uri for file.
   *
   * @return bool
   *   TRUE if file was successfully renamed.
   *
   * @see http://php.net/manual/en/streamwrapper.rename.php
   */
  public function rename($from_uri, $to_uri) {

    // We get the old key contents, write it
    // to a new key, erase the old key.
    $from_path = $this
      ->getLocalPath($from_uri);
    $to_path = $this
      ->getLocalPath($to_uri);
    if (!$this->sessionHelper
      ->checkPath($from_path)) {
      return FALSE;
    }
    $from_key = $this->sessionHelper
      ->getPath($from_path);
    $path_info = $this->sessionHelper
      ->getParentPath($to_path);
    $parent_path = $path_info['dirname'];

    // We will only allow writing to a non-existent file
    // in an existing directory.
    if ($this->sessionHelper
      ->checkPath($parent_path) && !$this->sessionHelper
      ->checkPath($to_path)) {
      $this->sessionHelper
        ->setPath($to_path, $from_key);
      $this->sessionHelper
        ->clearPath($from_path);
      return TRUE;
    }
    return FALSE;
  }

  /**
   * Gets the name of the directory from a given path.
   *
   * @param string $uri
   *   A URI.
   *
   * @return string
   *   A string containing the directory name.
   *
   * @see drupal_dirname()
   */
  public function dirname($uri = NULL) {
    list($scheme, ) = explode('://', $uri, 2);
    $target = $this
      ->getLocalPath($uri);
    if (strpos($target, '/')) {
      $dirname = preg_replace('@/[^/]*$@', '', $target);
    }
    else {
      $dirname = '';
    }
    return $scheme . '://' . $dirname;
  }

  /**
   * Support for mkdir().
   *
   * @param string $uri
   *   A string containing the URI to the directory to create.
   * @param int $mode
   *   Permission flags - see mkdir().
   * @param int $options
   *   A bit mask of STREAM_REPORT_ERRORS and STREAM_MKDIR_RECURSIVE.
   *
   * @return bool
   *   TRUE if directory was successfully created.
   *
   * @see http://php.net/manual/en/streamwrapper.mkdir.php
   */
  public function mkdir($uri, $mode, $options) {

    // If this already exists, then we can't mkdir.
    if (is_dir($uri) || is_file($uri)) {
      return FALSE;
    }
    $path = $this
      ->getLocalPath($uri);
    $new_dir = [
      'isadir.txt' => TRUE,
    ];
    $this->sessionHelper
      ->setPath($path, $new_dir);
    return TRUE;
  }

  /**
   * Support for rmdir().
   *
   * @param string $uri
   *   A string containing the URI to the directory to delete.
   * @param int $options
   *   A bit mask of STREAM_REPORT_ERRORS.
   *
   * @return bool
   *   TRUE if directory was successfully removed.
   *
   * @see http://php.net/manual/en/streamwrapper.rmdir.php
   */
  public function rmdir($uri, $options) {
    $path = $this
      ->getLocalPath($uri);
    if (!$this->sessionHelper
      ->checkPath($path) or !is_array($this->sessionHelper
      ->getPath($path))) {
      return FALSE;
    }
    $this->sessionHelper
      ->clearPath($path);
    return TRUE;
  }

  /**
   * Support for stat().
   *
   * This important function goes back to the Unix way of doing things.
   * In this example almost the entire stat array is irrelevant, but the
   * mode is very important. It tells PHP whether we have a file or a
   * directory and what the permissions are. All that is packed up in a
   * bitmask. This is not normal PHP fodder.
   *
   * @param string $uri
   *   A string containing the URI to get information about.
   * @param int $flags
   *   A bit mask of STREAM_URL_STAT_LINK and STREAM_URL_STAT_QUIET.
   *
   * @return array|bool
   *   An array with file status, or FALSE in case of an error - see fstat()
   *   for a description of this array.
   *
   * @see http://php.net/manual/en/streamwrapper.url-stat.php
   */

  // @codingStandardsIgnoreStart
  public function url_stat($uri, $flags) {

    // @codingStandardsIgnoreEnd
    $path = $this
      ->getLocalPath($uri);
    if (!$this->sessionHelper
      ->checkPath($path)) {
      return FALSE;

      // No file.
    }

    // Default to fail.
    $return = FALSE;
    $mode = 0;
    $key = $this->sessionHelper
      ->getPath($path);

    // We will call an array a directory and the root is always an array.
    if (is_array($key)) {

      // S_IFDIR means it's a directory.
      $mode = 040000;
    }
    elseif ($key !== FALSE) {

      // S_IFREG, means it's a file.
      $mode = 0100000;
    }
    if ($mode) {
      $size = 0;
      if ($mode == 0100000) {
        $size = strlen($key);
      }

      // There are no protections on this, so all writable.
      $mode |= 0777;
      $return = [
        'dev' => 0,
        'ino' => 0,
        'mode' => $mode,
        'nlink' => 0,
        'uid' => 0,
        'gid' => 0,
        'rdev' => 0,
        'size' => $size,
        'atime' => 0,
        'mtime' => 0,
        'ctime' => 0,
        'blksize' => 0,
        'blocks' => 0,
      ];
    }
    return $return;
  }

  /**
   * Support for opendir().
   *
   * @param string $uri
   *   A string containing the URI to the directory to open.
   * @param int $options
   *   Whether or not to enforce safe_mode (0x04).
   *
   * @return bool
   *   TRUE on success.
   *
   * @see http://php.net/manual/en/streamwrapper.dir-opendir.php
   */

  // @codingStandardsIgnoreStart
  public function dir_opendir($uri, $options) {

    // @codingStandardsIgnoreEnd
    $path = $this
      ->getLocalPath($uri);
    if (!$this->sessionHelper
      ->checkPath($path)) {
      return FALSE;
    }
    $var = $this->sessionHelper
      ->getPath($path);
    if (!is_array($var)) {
      return FALSE;
    }

    // We grab the list of key names, flip it so that .isadir.txt can easily
    // be removed, then flip it back so we can easily walk it as a list.
    $this->directoryKeys = array_flip(array_keys($var));
    unset($this->directoryKeys['.isadir.txt']);
    $this->directoryKeys = array_keys($this->directoryKeys);
    $this->directoryPointer = 0;
    return TRUE;
  }

  /**
   * Support for readdir().
   *
   * @return string|bool
   *   The next filename, or FALSE if there are no more files in the directory.
   *
   * @see http://php.net/manual/en/streamwrapper.dir-readdir.php
   */

  // @codingStandardsIgnoreStart
  public function dir_readdir() {

    // @codingStandardsIgnoreEnd
    if ($this->directoryPointer < count($this->directoryKeys)) {
      $next = $this->directoryKeys[$this->directoryPointer];
      $this->directoryPointer++;
      return $next;
    }
    return FALSE;
  }

  /**
   * Support for rewinddir().
   *
   * @return bool
   *   TRUE on success.
   *
   * @see http://php.net/manual/en/streamwrapper.dir-rewinddir.php
   */

  // @codingStandardsIgnoreStart
  public function dir_rewinddir() {

    // @codingStandardsIgnoreEnd
    $this->directoryPointer = 0;
    return TRUE;
  }

  /**
   * Support for closedir().
   *
   * @return bool
   *   TRUE on success.
   *
   * @see http://php.net/manual/en/streamwrapper.dir-closedir.php
   */

  // @codingStandardsIgnoreStart
  public function dir_closedir() {

    // @codingStandardsIgnoreEnd
    $this->directoryPointer = 0;
    unset($this->directoryKeys);
    return TRUE;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
SessionStreamWrapper::$directoryKeys protected property List of keys in a given directory.
SessionStreamWrapper::$directoryPointer protected property Pointer to where we are in a directory read.
SessionStreamWrapper::$sessionContent protected property The content of the stream.
SessionStreamWrapper::$sessionHelper protected property The session helper service.
SessionStreamWrapper::$streamMode protected property The mode we are currently in.
SessionStreamWrapper::$streamPointer protected property The pointer to the next read or write within the session variable.
SessionStreamWrapper::$uri protected property Instance URI (stream).
SessionStreamWrapper::dirname public function Gets the name of the directory from a given path. Overrides StreamWrapperInterface::dirname
SessionStreamWrapper::dir_closedir public function Overrides PhpStreamWrapperInterface::dir_closedir
SessionStreamWrapper::dir_opendir public function Overrides PhpStreamWrapperInterface::dir_opendir
SessionStreamWrapper::dir_readdir public function Overrides PhpStreamWrapperInterface::dir_readdir
SessionStreamWrapper::dir_rewinddir public function Overrides PhpStreamWrapperInterface::dir_rewinddir
SessionStreamWrapper::getDescription public function Returns the description of the stream wrapper for use in the UI. Overrides StreamWrapperInterface::getDescription
SessionStreamWrapper::getExternalUrl public function Overrides getExternalUrl(). Overrides StreamWrapperInterface::getExternalUrl
SessionStreamWrapper::getLocalPath protected function Returns the local path.
SessionStreamWrapper::getName public function Returns the name of the stream wrapper for use in the UI. Overrides StreamWrapperInterface::getName
SessionStreamWrapper::getType public static function Returns the type of stream wrapper. Overrides StreamWrapperInterface::getType
SessionStreamWrapper::getUri public function Implements getUri(). Overrides StreamWrapperInterface::getUri
SessionStreamWrapper::mkdir public function Support for mkdir(). Overrides PhpStreamWrapperInterface::mkdir
SessionStreamWrapper::realpath public function Returns canonical, absolute path of the resource. Overrides StreamWrapperInterface::realpath
SessionStreamWrapper::rename public function Support for rename(). Overrides PhpStreamWrapperInterface::rename
SessionStreamWrapper::rmdir public function Support for rmdir(). Overrides PhpStreamWrapperInterface::rmdir
SessionStreamWrapper::setUri public function Implements setUri(). Overrides StreamWrapperInterface::setUri
SessionStreamWrapper::stream_cast public function Retrieve the underlying stream resource. Overrides PhpStreamWrapperInterface::stream_cast
SessionStreamWrapper::stream_close public function Closes stream. Overrides PhpStreamWrapperInterface::stream_close
SessionStreamWrapper::stream_eof public function Overrides PhpStreamWrapperInterface::stream_eof
SessionStreamWrapper::stream_flush public function Overrides PhpStreamWrapperInterface::stream_flush
SessionStreamWrapper::stream_lock public function Overrides PhpStreamWrapperInterface::stream_lock
SessionStreamWrapper::stream_metadata public function Sets metadata on the stream. Overrides PhpStreamWrapperInterface::stream_metadata
SessionStreamWrapper::stream_open public function Overrides PhpStreamWrapperInterface::stream_open
SessionStreamWrapper::stream_read public function Overrides PhpStreamWrapperInterface::stream_read
SessionStreamWrapper::stream_seek public function Seeks to specific location in a stream. Overrides PhpStreamWrapperInterface::stream_seek
SessionStreamWrapper::stream_set_option public function Change stream options. Overrides PhpStreamWrapperInterface::stream_set_option
SessionStreamWrapper::stream_stat public function Overrides PhpStreamWrapperInterface::stream_stat
SessionStreamWrapper::stream_tell public function Overrides PhpStreamWrapperInterface::stream_tell
SessionStreamWrapper::stream_truncate public function Truncate stream. Overrides PhpStreamWrapperInterface::stream_truncate
SessionStreamWrapper::stream_write public function Overrides PhpStreamWrapperInterface::stream_write
SessionStreamWrapper::unlink public function Support for unlink(). Overrides PhpStreamWrapperInterface::unlink
SessionStreamWrapper::url_stat public function Overrides PhpStreamWrapperInterface::url_stat
SessionStreamWrapper::__construct public function Constructor method.
StreamWrapperInterface::ALL constant A filter that matches all wrappers.
StreamWrapperInterface::HIDDEN constant Defines the stream wrapper bit flag for a hidden file.
StreamWrapperInterface::LOCAL constant Refers to a local file system location.
StreamWrapperInterface::LOCAL_HIDDEN constant Hidden, readable and writable using local files.
StreamWrapperInterface::LOCAL_NORMAL constant Visible, readable and writable using local files.
StreamWrapperInterface::NORMAL constant This is the default 'type' flag. This does not include StreamWrapperInterface::LOCAL, because PHP grants a greater trust level to local files (for example, they can be used in an "include" statement, regardless of the…
StreamWrapperInterface::READ constant Wrapper is readable (almost always true).
StreamWrapperInterface::READ_VISIBLE constant Visible and read-only.
StreamWrapperInterface::VISIBLE constant Exposed in the UI and potentially web accessible.
StreamWrapperInterface::WRITE constant Wrapper is writable.
StreamWrapperInterface::WRITE_VISIBLE constant Visible, readable and writable.
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.