Resources & Stream Wrappers

Last updated on
30 April 2025

An important element of the new Media module is the concept of Resources. Resources are anything your website can reference that has a properly implemented ResourceStreamWrapper.

Before we venture too deeply into Resources a quick explanation of StreamWrappers is due. Most standard file functions in PHP accept URL's as path parameters. PHP allows developers to write custom call backs to handle different URL schemes. The standard format for URLs is scheme://<authority>/path. You might not be familar with authority, but it is the user:pass@host:port portion of a URL.

The Resource system leverages PHP's stream wrapper system to abstract the interaction with local and remote media using standard functions for copying, moving, and deleting files. Streamwrappers are not limited to just manipulating files. Properly implemented they can be used to query remote APIs as directory listings or to post content to remote sites.

Currently there are basic stream wrappers implemented for public and private files, and the Resource system is under active development. Once the interfaces are stabilized developer specific documentation will be added here.

In order to add a resource to the Media module, a new ResourceExampleStreamWrapper.inc file needs to be created. This file will store a class with your chosen name (something like ResourceExampleStreamWrapper) that extends another stream-wrapper class (Most likely ResourceStreamWrapper).

A resource-stream-wrapper will typically override any or all of the following functions: htmlUrl, interpolateUrl, and mime.

For example, ResourcePublicStreamWrapper.inc is included with the Media module.

/**
 * public:// stream wrapper class.
 *
 * This class provides support for storing publicly
 * accessible files with the Drupal resource api.
 */
class ResourcePublicStreamWrapper extends ResourceStreamWrapper {

  // A handle to the file opened by stream_open().
  private $pathKey = 'stream_public_path';
  private $pathDefault = 'sites/default/files';

  /**
   * Return the HTML Url of a public file.
   */
  function htmlUrl($url) {
    $basepath = variable_get($this->pathKey, $this->pathDefault);
    $path = parse_url($url, PHP_URL_PATH);
    return $GLOBALS['base_url'] . '/' . $basepath . '/' . str_replace('\\', '/', $path);
  }

  /**
   * Interpolate the url path, adding the public files path.
   */
  function interpolateUrl($url) {
    $basepath = variable_get($this->pathKey, $this->pathDefault);

    // just in case stream_public_path is s3://, ftp://, etc. Don't call PHP's
    // realpath().
    if (parse_url($basepath, PHP_URL_SCHEME)) {
      $path =  $basepath . parse_url($url, PHP_URL_PATH);;
    }
    else {
      // interpolate relative paths for basepath, and strip relative paths from
      // url path.
      $path = realpath($basepath) . str_replace('/..','', parse_url($url, PHP_URL_PATH));
    }
    return $path;
  }

  /**
   * Return the mime type of a file.
   */
  function mime($url) {
    return file_get_mimetype(basename($url));
  }
}

Help improve this page

Page status: Not set

You can: