Interim commit.
[yaffs-website] / web / modules / contrib / video / src / StreamWrapper / VideoRemoteStreamWrapper.php
1 <?php
2
3 /**
4  * @file
5  * Contains \Drupal\video\StreamWrapper\VideoRemoteStreamWrapper.
6  */
7
8 namespace Drupal\video\StreamWrapper;
9
10 use Drupal\Core\StreamWrapper\ReadOnlyStream;
11 use Drupal\Core\StreamWrapper\StreamWrapperInterface;
12 use Drupal\Component\Utility\UrlHelper;
13
14 /**
15  * Defines a video read only stream wrapper class.
16  *
17  * Provides support for reading remotely accessible files with the Drupal file
18  * interface.
19  */
20 abstract class VideoRemoteStreamWrapper extends ReadOnlyStream {
21   
22   protected static $base_url = NULL;
23   protected $parameters = array();
24   
25   /**
26    * {@inheritdoc}
27    */
28   public static function getType() {
29     return StreamWrapperInterface::READ;
30   }
31   
32   /**
33    * Finds and returns the base URL for read only stream.
34    * @return string
35    *   The external base URL
36    */
37   public static function baseUrl() {
38     return self::$base_url;
39   }
40   
41   /**
42    * {@inheritdoc}
43    */
44   public function getDirectoryPath() {
45     return static::basePath();
46   }
47
48   /**
49    * {@inheritdoc}
50    */
51   public function getExternalUrl() {
52     $path = str_replace('\\', '/', $this->getTarget());
53     return static::baseUrl() . '/' . UrlHelper::encodePath($path);
54   }
55   
56   /**
57    * Returns the base path for stream wrapper.
58    */
59   public static function basePath(\SplString $site_path = NULL) {
60     return static::baseUrl();
61   }
62   
63   /**
64    * {@inheritdoc}
65    */
66   function setUri($uri) {
67     $this->uri = $uri;
68   }
69   
70   /**
71    * Returns the local writable target of the resource within the stream.
72    *
73    * This function should be used in place of calls to realpath() or similar
74    * functions when attempting to determine the location of a file. While
75    * functions like realpath() may return the location of a read-only file, this
76    * method may return a URI or path suitable for writing that is completely
77    * separate from the URI used for reading.
78    *
79    * @param string $uri
80    *   Optional URI.
81    *
82    * @return string|bool
83    *   Returns a string representing a location suitable for writing of a file,
84    *   or FALSE if unable to write to the file such as with read-only streams.
85    */
86   protected function getTarget($uri = NULL) {
87     if (!isset($uri)) {
88       $uri = $this->uri;
89     }
90
91     list(, $target) = explode('://', $uri, 2);
92
93     // Remove erroneous leading or trailing, forward-slashes and backslashes.
94     return trim($target, '\/');
95   }
96   
97   /**
98    * Returns the canonical absolute path of the URI, if possible.
99    *
100    * @param string $uri
101    *   (optional) The stream wrapper URI to be converted to a canonical
102    *   absolute path. This may point to a directory or another type of file.
103    *
104    * @return string|bool
105    *   If $uri is not set, returns the canonical absolute path of the URI
106    *   previously set by the
107    *   Drupal\Core\StreamWrapper\StreamWrapperInterface::setUri() function.
108    *   If $uri is set and valid for this class, returns its canonical absolute
109    *   path, as determined by the realpath() function. If $uri is set but not
110    *   valid, returns FALSE.
111    */
112   protected function getLocalPath($uri = NULL) {
113     if (!isset($uri)) {
114       $uri = $this->uri;
115     }
116     $path = $this->getDirectoryPath() . '/' . $this->getTarget($uri);
117
118     // In PHPUnit tests, the base path for local streams may be a virtual
119     // filesystem stream wrapper URI, in which case this local stream acts like
120     // a proxy. realpath() is not supported by vfsStream, because a virtual
121     // file system does not have a real filepath.
122     if (strpos($path, 'vfs://') === 0) {
123       return $path;
124     }
125
126     $realpath = realpath($path);
127     if (!$realpath) {
128       // This file does not yet exist.
129       $realpath = realpath(dirname($path)) . '/' . drupal_basename($path);
130     }
131     $directory = realpath($this->getDirectoryPath());
132     if (!$realpath || !$directory || strpos($realpath, $directory) !== 0) {
133       return FALSE;
134     }
135     return $realpath;
136   }
137   
138   /**
139    * {@inheritdoc}
140    */
141   function realpath() {
142     return $this->getLocalPath();
143   }
144
145   /**
146    * Gets the name of the directory from a given path.
147    *
148    * This method is usually accessed through drupal_dirname(), which wraps
149    * around the PHP dirname() function because it does not support stream
150    * wrappers.
151    *
152    * @param string $uri
153    *   A URI or path.
154    *
155    * @return string
156    *   A string containing the directory name.
157    *
158    * @see drupal_dirname()
159    */
160   public function dirname($uri = NULL) {
161     list($scheme) = explode('://', $uri, 2);
162     $target = $this->getTarget($uri);
163     $dirname = dirname($target);
164
165     if ($dirname == '.') {
166       $dirname = '';
167     }
168
169     return $scheme . '://' . $dirname;
170   }
171   
172   /**
173    * Support for closedir().
174    *
175    * @return bool
176    *   TRUE on success.
177    *
178    * @see http://php.net/manual/streamwrapper.dir-closedir.php
179    */
180   public function dir_closedir() {
181     closedir($this->handle);
182     // We do not really have a way to signal a failure as closedir() does not
183     // have a return value.
184     return TRUE;
185   }
186
187   /**
188    * Support for opendir().
189    *
190    * @param string $uri
191    *   A string containing the URI to the directory to open.
192    * @param int $options
193    *   Unknown (parameter is not documented in PHP Manual).
194    *
195    * @return bool
196    *   TRUE on success.
197    *
198    * @see http://php.net/manual/streamwrapper.dir-opendir.php
199    */
200   public function dir_opendir($uri, $options) {
201     $this->uri = $uri;
202     $this->handle = opendir($this->getLocalPath());
203
204     return (bool) $this->handle;
205   }
206
207   /**
208    * Support for readdir().
209    *
210    * @return string
211    *   The next filename, or FALSE if there are no more files in the directory.
212    *
213    * @see http://php.net/manual/streamwrapper.dir-readdir.php
214    */
215   public function dir_readdir() {
216     return readdir($this->handle);
217   }
218
219   /**
220    * Support for rewinddir().
221    *
222    * @return bool
223    *   TRUE on success.
224    *
225    * @see http://php.net/manual/streamwrapper.dir-rewinddir.php
226    */
227   public function dir_rewinddir() {
228     rewinddir($this->handle);
229     // We do not really have a way to signal a failure as rewinddir() does not
230     // have a return value and there is no way to read a directory handler
231     // without advancing to the next file.
232     return TRUE;
233   }
234
235   /**
236    * {@inheritdoc}
237    */
238   public function stream_cast($cast_as) {
239     return $this->handle ? $this->handle : FALSE;
240   }
241
242   /**
243    * Support for fclose().
244    *
245    * @return bool
246    *   TRUE if stream was successfully closed.
247    *
248    * @see http://php.net/manual/streamwrapper.stream-close.php
249    */
250   public function stream_close() {
251     return fclose($this->handle);
252   }
253
254   /**
255    * Support for feof().
256    *
257    * @return bool
258    *   TRUE if end-of-file has been reached.
259    *
260    * @see http://php.net/manual/streamwrapper.stream-eof.php
261    */
262   public function stream_eof() {
263     return feof($this->handle);
264   }
265
266   /**
267    * Support for fread(), file_get_contents() etc.
268    *
269    * @param int $count
270    *   Maximum number of bytes to be read.
271    *
272    * @return string|bool
273    *   The string that was read, or FALSE in case of an error.
274    *
275    * @see http://php.net/manual/streamwrapper.stream-read.php
276    */
277   public function stream_read($count) {
278     return fread($this->handle, $count);
279   }
280
281   /**
282    * {@inheritdoc}
283    */
284   public function stream_seek($offset, $whence = SEEK_SET) {
285     // fseek returns 0 on success and -1 on a failure.
286     // stream_seek   1 on success and  0 on a failure.
287     return !fseek($this->handle, $offset, $whence);
288   }
289
290   /**
291    * {@inheritdoc}
292    *
293    * Since Windows systems do not allow it and it is not needed for most use
294    * cases anyway, this method is not supported on local files and will trigger
295    * an error and return false. If needed, custom subclasses can provide
296    * OS-specific implementations for advanced use cases.
297    */
298   public function stream_set_option($option, $arg1, $arg2) {
299     trigger_error('stream_set_option() not supported for local file based stream wrappers', E_USER_WARNING);
300     return FALSE;
301   }
302
303   /**
304    * Support for fstat().
305    *
306    * @return bool
307    *   An array with file status, or FALSE in case of an error - see fstat()
308    *   for a description of this array.
309    *
310    * @see http://php.net/manual/streamwrapper.stream-stat.php
311    */
312   public function stream_stat() {
313     return fstat($this->handle);
314   }
315
316   /**
317    * Support for ftell().
318    *
319    * @return bool
320    *   The current offset in bytes from the beginning of file.
321    *
322    * @see http://php.net/manual/streamwrapper.stream-tell.php
323    */
324   public function stream_tell() {
325     return ftell($this->handle);
326   }
327   
328   /**
329    * Support for stat().
330    *
331    * @param string $uri
332    *   A string containing the URI to get information about.
333    * @param int $flags
334    *   A bit mask of STREAM_URL_STAT_LINK and STREAM_URL_STAT_QUIET.
335    *
336    * @return array
337    *   An array with file status, or FALSE in case of an error - see fstat()
338    *   for a description of this array.
339    *
340    * @see http://php.net/manual/streamwrapper.url-stat.php
341    */
342   public function url_stat($uri, $flags) {
343     $this->uri = $uri;
344     $path = $this->getLocalPath();
345     // Suppress warnings if requested or if the file or directory does not
346     // exist. This is consistent with PHP's plain filesystem stream wrapper.
347     if ($flags & STREAM_URL_STAT_QUIET || !file_exists($path)) {
348       return @stat($path);
349     }
350     else {
351       return stat($path);
352     }
353   }
354 }