--- /dev/null
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\video\StreamWrapper\VideoRemoteStreamWrapper.
+ */
+
+namespace Drupal\video\StreamWrapper;
+
+use Drupal\Core\StreamWrapper\ReadOnlyStream;
+use Drupal\Core\StreamWrapper\StreamWrapperInterface;
+use Drupal\Component\Utility\UrlHelper;
+
+/**
+ * Defines a video read only stream wrapper class.
+ *
+ * Provides support for reading remotely accessible files with the Drupal file
+ * interface.
+ */
+abstract class VideoRemoteStreamWrapper extends ReadOnlyStream {
+
+ protected static $base_url = NULL;
+ protected $parameters = array();
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function getType() {
+ return StreamWrapperInterface::READ;
+ }
+
+ /**
+ * Finds and returns the base URL for read only stream.
+ * @return string
+ * The external base URL
+ */
+ public static function baseUrl() {
+ return self::$base_url;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getDirectoryPath() {
+ return static::basePath();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getExternalUrl() {
+ $path = str_replace('\\', '/', $this->getTarget());
+ return static::baseUrl() . '/' . UrlHelper::encodePath($path);
+ }
+
+ /**
+ * Returns the base path for stream wrapper.
+ */
+ public static function basePath(\SplString $site_path = NULL) {
+ return static::baseUrl();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ function setUri($uri) {
+ $this->uri = $uri;
+ }
+
+ /**
+ * Returns the local writable target of the resource within the stream.
+ *
+ * This function should be used in place of calls to realpath() or similar
+ * functions when attempting to determine the location of a file. While
+ * functions like realpath() may return the location of a read-only file, this
+ * method may return a URI or path suitable for writing that is completely
+ * separate from the URI used for reading.
+ *
+ * @param string $uri
+ * Optional URI.
+ *
+ * @return string|bool
+ * Returns a string representing a location suitable for writing of a file,
+ * or FALSE if unable to write to the file such as with read-only streams.
+ */
+ protected function getTarget($uri = NULL) {
+ if (!isset($uri)) {
+ $uri = $this->uri;
+ }
+
+ list(, $target) = explode('://', $uri, 2);
+
+ // Remove erroneous leading or trailing, forward-slashes and backslashes.
+ return trim($target, '\/');
+ }
+
+ /**
+ * Returns the canonical absolute path of the URI, if possible.
+ *
+ * @param string $uri
+ * (optional) The stream wrapper URI to be converted to a canonical
+ * absolute path. This may point to a directory or another type of file.
+ *
+ * @return string|bool
+ * If $uri is not set, returns the canonical absolute path of the URI
+ * previously set by the
+ * Drupal\Core\StreamWrapper\StreamWrapperInterface::setUri() function.
+ * If $uri is set and valid for this class, returns its canonical absolute
+ * path, as determined by the realpath() function. If $uri is set but not
+ * valid, returns FALSE.
+ */
+ protected function getLocalPath($uri = NULL) {
+ if (!isset($uri)) {
+ $uri = $this->uri;
+ }
+ $path = $this->getDirectoryPath() . '/' . $this->getTarget($uri);
+
+ // In PHPUnit tests, the base path for local streams may be a virtual
+ // filesystem stream wrapper URI, in which case this local stream acts like
+ // a proxy. realpath() is not supported by vfsStream, because a virtual
+ // file system does not have a real filepath.
+ if (strpos($path, 'vfs://') === 0) {
+ return $path;
+ }
+
+ $realpath = realpath($path);
+ if (!$realpath) {
+ // This file does not yet exist.
+ $realpath = realpath(dirname($path)) . '/' . drupal_basename($path);
+ }
+ $directory = realpath($this->getDirectoryPath());
+ if (!$realpath || !$directory || strpos($realpath, $directory) !== 0) {
+ return FALSE;
+ }
+ return $realpath;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ function realpath() {
+ return $this->getLocalPath();
+ }
+
+ /**
+ * Gets the name of the directory from a given path.
+ *
+ * This method is usually accessed through drupal_dirname(), which wraps
+ * around the PHP dirname() function because it does not support stream
+ * wrappers.
+ *
+ * @param string $uri
+ * A URI or path.
+ *
+ * @return string
+ * A string containing the directory name.
+ *
+ * @see drupal_dirname()
+ */
+ public function dirname($uri = NULL) {
+ list($scheme) = explode('://', $uri, 2);
+ $target = $this->getTarget($uri);
+ $dirname = dirname($target);
+
+ if ($dirname == '.') {
+ $dirname = '';
+ }
+
+ return $scheme . '://' . $dirname;
+ }
+
+ /**
+ * Support for closedir().
+ *
+ * @return bool
+ * TRUE on success.
+ *
+ * @see http://php.net/manual/streamwrapper.dir-closedir.php
+ */
+ public function dir_closedir() {
+ closedir($this->handle);
+ // We do not really have a way to signal a failure as closedir() does not
+ // have a return value.
+ return TRUE;
+ }
+
+ /**
+ * Support for opendir().
+ *
+ * @param string $uri
+ * A string containing the URI to the directory to open.
+ * @param int $options
+ * Unknown (parameter is not documented in PHP Manual).
+ *
+ * @return bool
+ * TRUE on success.
+ *
+ * @see http://php.net/manual/streamwrapper.dir-opendir.php
+ */
+ public function dir_opendir($uri, $options) {
+ $this->uri = $uri;
+ $this->handle = opendir($this->getLocalPath());
+
+ return (bool) $this->handle;
+ }
+
+ /**
+ * Support for readdir().
+ *
+ * @return string
+ * The next filename, or FALSE if there are no more files in the directory.
+ *
+ * @see http://php.net/manual/streamwrapper.dir-readdir.php
+ */
+ public function dir_readdir() {
+ return readdir($this->handle);
+ }
+
+ /**
+ * Support for rewinddir().
+ *
+ * @return bool
+ * TRUE on success.
+ *
+ * @see http://php.net/manual/streamwrapper.dir-rewinddir.php
+ */
+ public function dir_rewinddir() {
+ rewinddir($this->handle);
+ // We do not really have a way to signal a failure as rewinddir() does not
+ // have a return value and there is no way to read a directory handler
+ // without advancing to the next file.
+ return TRUE;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function stream_cast($cast_as) {
+ return $this->handle ? $this->handle : FALSE;
+ }
+
+ /**
+ * Support for fclose().
+ *
+ * @return bool
+ * TRUE if stream was successfully closed.
+ *
+ * @see http://php.net/manual/streamwrapper.stream-close.php
+ */
+ public function stream_close() {
+ return fclose($this->handle);
+ }
+
+ /**
+ * Support for feof().
+ *
+ * @return bool
+ * TRUE if end-of-file has been reached.
+ *
+ * @see http://php.net/manual/streamwrapper.stream-eof.php
+ */
+ public function stream_eof() {
+ return feof($this->handle);
+ }
+
+ /**
+ * Support for fread(), file_get_contents() etc.
+ *
+ * @param int $count
+ * Maximum number of bytes to be read.
+ *
+ * @return string|bool
+ * The string that was read, or FALSE in case of an error.
+ *
+ * @see http://php.net/manual/streamwrapper.stream-read.php
+ */
+ public function stream_read($count) {
+ return fread($this->handle, $count);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function stream_seek($offset, $whence = SEEK_SET) {
+ // fseek returns 0 on success and -1 on a failure.
+ // stream_seek 1 on success and 0 on a failure.
+ return !fseek($this->handle, $offset, $whence);
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * Since Windows systems do not allow it and it is not needed for most use
+ * cases anyway, this method is not supported on local files and will trigger
+ * an error and return false. If needed, custom subclasses can provide
+ * OS-specific implementations for advanced use cases.
+ */
+ public function stream_set_option($option, $arg1, $arg2) {
+ trigger_error('stream_set_option() not supported for local file based stream wrappers', E_USER_WARNING);
+ return FALSE;
+ }
+
+ /**
+ * Support for fstat().
+ *
+ * @return 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/streamwrapper.stream-stat.php
+ */
+ public function stream_stat() {
+ return fstat($this->handle);
+ }
+
+ /**
+ * Support for ftell().
+ *
+ * @return bool
+ * The current offset in bytes from the beginning of file.
+ *
+ * @see http://php.net/manual/streamwrapper.stream-tell.php
+ */
+ public function stream_tell() {
+ return ftell($this->handle);
+ }
+
+ /**
+ * Support for stat().
+ *
+ * @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
+ * 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/streamwrapper.url-stat.php
+ */
+ public function url_stat($uri, $flags) {
+ $this->uri = $uri;
+ $path = $this->getLocalPath();
+ // Suppress warnings if requested or if the file or directory does not
+ // exist. This is consistent with PHP's plain filesystem stream wrapper.
+ if ($flags & STREAM_URL_STAT_QUIET || !file_exists($path)) {
+ return @stat($path);
+ }
+ else {
+ return stat($path);
+ }
+ }
+}