Projet

Général

Profil

Paste
Télécharger (11,1 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / media / includes / MediaReadOnlyStreamWrapper.inc @ e4215af7

1
<?php
2

    
3
/**
4
 * @file
5
 * Implements a base class for Resource Stream Wrappers.
6
 */
7

    
8
/**
9
 * A base class for Resource Stream Wrappers.
10
 *
11
 * This class provides a complete stream wrapper implementation. It passes
12
 * incoming  URL's through an interpolation method then recursively calls
13
 * the invoking PHP filesystem function.
14
 *
15
 * MediaReadOnlyStreamWrapper implementations need to override at least the
16
 * interpolateUrl method to rewrite the URL before is it passed back into the
17
 * calling function.
18
 */
19
abstract class MediaReadOnlyStreamWrapper implements DrupalStreamWrapperInterface {
20
  protected $parameters = array();
21
  protected $base_url = NULL;
22
  private $_DEBUG_MODE = NULL;
23

    
24
  /**
25
   * Utility function to return paramenters.
26
   */
27
  public function get_parameters() {
28
    return $this->parameters;
29
  }
30

    
31
  // As part of the inode protection mode returned by stat(), identifies the
32
  // file as a regular file, as opposed to a directory, symbolic link, or other
33
  // type of "file".
34
  // @see http://linux.die.net/man/2/stat
35
  const S_IFREG = 0100000;
36

    
37
  /**
38
   * Template for stat calls.
39
   *
40
   * All elements must be initialized.
41
   */
42
  protected $_stat = array(
43
    0 => 0, // Device number
44
    'dev' => 0,
45
    1 => 0, // Inode number
46
    'ino' => 0,
47
    // Inode protection mode. file_unmanaged_delete() requires is_file() to
48
    // return TRUE.
49
    2 => self::S_IFREG,
50
    'mode' => self::S_IFREG,
51
    3 => 0, // Number of links.
52
    'nlink' => 0,
53
    4 => 0, // Userid of owner.
54
    'uid' => 0,
55
    5 => 0, // Groupid of owner.
56
    'gid' => 0,
57
    6 => -1, // Device type, if inode device *
58
    'rdev' => -1,
59
    7 => 0, // Size in bytes.
60
    'size' => 0,
61
    8 => 0, // Time of last access (Unix timestamp).
62
    'atime' => 0,
63
    9 => 0, // Time of last modification (Unix timestamp).
64
    'mtime' => 0,
65
    10 => 0, // Time of last inode change (Unix timestamp).
66
    'ctime' => 0,
67
    11 => -1, // Blocksize of filesystem IO.
68
    'blksize' => -1,
69
    12 => -1, // Number of blocks allocated.
70
    'blocks' => -1,
71
  );
72

    
73
  /**
74
   * Handles parameters on the URL string.
75
   */
76
  public function interpolateUrl() {
77
    if ($parameters = $this->get_parameters()) {
78
      return $this->base_url . '?' . http_build_query($parameters);
79
    }
80
  }
81

    
82
  /**
83
   * Returns a web accessible URL for the resource.
84
   *
85
   * This function should return a URL that can be embedded in a web page
86
   * and accessed from a browser. For example, the external URL of
87
   * "youtube://xIpLd0WQKCY" might be
88
   * "http://www.youtube.com/watch?v=xIpLd0WQKCY".
89
   *
90
   * @return string
91
   *   Returns a string containing a web accessible URL for the resource.
92
   */
93
  public function getExternalUrl() {
94
    return $this->interpolateUrl();
95
  }
96

    
97
  /**
98
   * Base implementation of getMimeType().
99
   */
100
  public static function getMimeType($uri, $mapping = NULL) {
101
    return 'application/octet-stream';
102
  }
103

    
104
  /**
105
   * Base implementation of realpath().
106
   */
107
  public function realpath() {
108
    return $this->getExternalUrl();
109
  }
110

    
111
  /**
112
   * Stream context resource.
113
   *
114
   * @var Resource
115
   */
116
  public $context;
117

    
118
  /**
119
   * A generic resource handle.
120
   *
121
   * @var Resource
122
   */
123
  public $handle = NULL;
124

    
125
  /**
126
   * Instance URI (stream).
127
   *
128
   * A stream is referenced as "scheme://target".
129
   *
130
   * @var String
131
   */
132
  protected $uri;
133

    
134
  /**
135
   * Base implementation of setUri().
136
   */
137
  public function setUri($uri) {
138
    $this->uri = $uri;
139
    $this->parameters = $this->_parse_url($uri);
140
  }
141

    
142
  /**
143
   * Base implementation of getUri().
144
   */
145
  public function getUri() {
146
    return $this->uri;
147
  }
148

    
149
  /**
150
   * Report an error.
151
   *
152
   * @param string $message
153
   *   The untranslated string to report.
154
   * @param array $options
155
   *   An optional array of options to send to t().
156
   * @param bool $display
157
   *   If TRUE, then we display the error to the user.
158
   *
159
   * @return bool
160
   *   We return FALSE, since we sometimes pass that back from the reporting
161
   *   function.
162
   */
163
  private function _report_error($message, $options = array(), $display = FALSE) {
164
    watchdog('resource', $message, $options, WATCHDOG_ERROR);
165
    if ($display) {
166
      drupal_set_message(t($message, $options), 'error');
167
    }
168
    return FALSE;
169
  }
170

    
171
  /**
172
   * Sets the debug mode.
173
   */
174
  private function _debug($message, $type = 'status') {
175
    if ($this->_DEBUG_MODE) {
176
      drupal_set_message($message, $type);
177
    }
178
  }
179

    
180
  /**
181
   * Returns an array of any parameters stored in the URL's path.
182
   *
183
   * @param string $url
184
   *   The URL to parse, such as youtube://v/[video-code]/t/[tags+more-tags].
185
   *
186
   * @return array
187
   *   An associative array of all the parameters in the path,
188
   *   or FALSE if the $url is ill-formed.
189
   */
190
  protected function _parse_url($url) {
191
    $path = explode('://', $url);
192
    $parts = explode('/', $path[1]);
193
    $params = array();
194
    $count = 0;
195
    $total = count($parts);
196
    if (!$total || ($total % 2)) {
197
      // If we have no parts, or an odd number of parts, it's malformed.
198
      return FALSE;
199
    }
200
    while ($count < $total) {
201
      // We iterate count for each step of the assignment to keep us honest.
202
      $params[$parts[$count++]] = $parts[$count++];
203
    }
204
    return $params;
205
  }
206

    
207
  /**
208
   * Support for fopen(), file_get_contents(), file_put_contents() etc.
209
   *
210
   * @param string $url
211
   *   A string containing the path to the file to open.
212
   * @param string $mode
213
   *   The file mode ("r", "wb" etc.).
214
   * @param bitmask $options
215
   *   A bit mask of STREAM_USE_PATH and STREAM_REPORT_ERRORS.
216
   * @param string &$opened_url
217
   *   A string containing the path actually opened.
218
   *
219
   * @return bool
220
   *   TRUE if file was opened successfully.
221
   */
222
  public function stream_open($url, $mode, $options, &$opened_url) {
223
    $this->_debug(t('Stream open: %url', array('%url' => $url)));
224

    
225
    // We only handle Read-Only mode by default.
226
    if ($mode != 'r' && $mode != 'rb') {
227
      return $this->_report_error('Attempted to open %url as mode: %mode.', array('%url' => $url, '%mode' => $mode), ($options & STREAM_REPORT_ERRORS));
228
    }
229

    
230
    // We parse a URL as youtube://v/dsyiufo34/t/cats+dogs to store
231
    // the relevant code(s) in our private array of parameters.
232
    $this->parameters = $this->_parse_url($url);
233

    
234
    if ($this->parameters === FALSE) {
235
      return $this->_report_error('Attempted to parse an ill-formed url: %url.', array('%url' => $url), ($options & STREAM_REPORT_ERRORS));
236
    }
237

    
238
    if ((bool) $this->parameters && ($options & STREAM_USE_PATH)) {
239
      $opened_url = $url;
240
    }
241

    
242
    $this->_debug(t('Stream opened: %parameters', array('%parameters' => print_r($this->parameters, TRUE))));
243

    
244
    return (bool) $this->parameters;
245
  }
246

    
247
  /**
248
   * Undocumented PHP stream wrapper method.
249
   */
250
  function stream_lock($operation) {
251
    return FALSE;
252
  }
253

    
254
  /**
255
   * Support for fread(), file_get_contents() etc.
256
   *
257
   * @param int $count
258
   *   Maximum number of bytes to be read.
259
   *
260
   * @return bool
261
   *   The string that was read, or FALSE in case of an error.
262
   */
263
  public function stream_read($count) {
264
    return FALSE;
265
  }
266

    
267
  /**
268
   * Support for fwrite(), file_put_contents() etc.
269
   *
270
   * Since this is a read only stream wrapper this always returns false.
271
   *
272
   * @param string $data
273
   *   The string to be written.
274
   *
275
   * @return bool
276
   *   Returns FALSE.
277
   */
278
  public function stream_write($data) {
279
    return FALSE;
280
  }
281

    
282
  /**
283
   * Support for feof().
284
   *
285
   * @return bool
286
   *   TRUE if end-of-file has been reached.
287
   */
288
  public function stream_eof() {
289
    return FALSE;
290
  }
291

    
292
  /**
293
   * Support for fseek().
294
   *
295
   * @todo document why this returns false.
296
   *
297
   * @param int $offset
298
   *   The byte offset to got to.
299
   * @param string $whence
300
   *   SEEK_SET, SEEK_CUR, or SEEK_END.
301
   *
302
   * @return bool
303
   *   TRUE on success
304
   */
305
  public function stream_seek($offset, $whence) {
306
    return FALSE;
307
  }
308

    
309
  /**
310
   * Support for fflush().
311
   *
312
   * @todo document why this returns false.
313
   *
314
   * @return bool
315
   *   TRUE if data was successfully stored (or there was no data to store).
316
   */
317
  public function stream_flush() {
318
    return FALSE;
319
  }
320

    
321
  /**
322
   * Support for ftell().
323
   *
324
   * @todo document why this returns false.
325
   *
326
   * @return bool
327
   *   The current offset in bytes from the beginning of file.
328
   */
329
  public function stream_tell() {
330
    return FALSE;
331
  }
332

    
333
  /**
334
   * Support for fstat().
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
  public function stream_stat() {
341
    return $this->_stat;
342
  }
343

    
344
  /**
345
   * Support for fclose().
346
   *
347
   * @todo document why this returns TRUE.
348
   *
349
   * @return bool
350
   *   TRUE if stream was successfully closed.
351
   */
352
  public function stream_close() {
353
    return TRUE;
354
  }
355

    
356
  /**
357
   * Support for stat().
358
   *
359
   * @param string $url
360
   *   A string containing the url to get information about.
361
   * @param bitmask $flags
362
   *   A bit mask of STREAM_URL_STAT_LINK and STREAM_URL_STAT_QUIET.
363
   *
364
   * @return array
365
   *   An array with file status, or FALSE in case of an error - see fstat()
366
   *   for a description of this array.
367
   */
368
  public function url_stat($url, $flags) {
369
    return $this->stream_stat();
370
  }
371

    
372
  /**
373
   * Support for opendir().
374
   *
375
   * @param string $url
376
   *   A string containing the url to the directory to open.
377
   * @param int $options
378
   *   Whether or not to enforce safe_mode (0x04).
379
   *
380
   * @return bool
381
   *   TRUE on success.
382
   */
383
  public function dir_opendir($url, $options) {
384
    return FALSE;
385
  }
386

    
387
  /**
388
   * Support for readdir().
389
   *
390
   * @return bool
391
   *   The next filename, or FALSE if there are no more files in the directory.
392
   */
393
  public function dir_readdir() {
394
    return FALSE;
395
  }
396

    
397
  /**
398
   * Support for rewinddir().
399
   *
400
   * @return bool
401
   *   TRUE on success.
402
   */
403
  public function dir_rewinddir() {
404
    return FALSE;
405
  }
406

    
407
  /**
408
   * Support for closedir().
409
   *
410
   * @return bool
411
   *   TRUE on success.
412
   */
413
  public function dir_closedir() {
414
    return FALSE;
415
  }
416

    
417
  /**
418
   * Undocumented.
419
   *
420
   * @todo document.
421
   */
422
  public function getDirectoryPath() {
423
    return '';
424
  }
425

    
426
  /**
427
   * DrupalStreamWrapperInterface requires that these methods be implemented,
428
   * but none of them apply to a read-only stream wrapper. On failure they
429
   * are expected to return FALSE.
430
   */
431

    
432
  /**
433
   * Implements DrupalStreamWrapperInterface::unlink().
434
   */
435
  public function unlink($uri) {
436
    // Although the remote file itself can't be deleted, return TRUE so that
437
    // file_delete() can remove the file record from the Drupal database.
438
    return TRUE;
439
  }
440

    
441
  /**
442
   * Implements DrupalStreamWrapperInterface::rename().
443
   */
444
  public function rename($from_uri, $to_uri) {
445
    return FALSE;
446
  }
447

    
448
  /**
449
   * Implements DrupalStreamWrapperInterface::mkdir().
450
   */
451
  public function mkdir($uri, $mode, $options) {
452
    return FALSE;
453
  }
454

    
455
  /**
456
   * Implements DrupalStreamWrapperInterface::rmdir().
457
   */
458
  public function rmdir($uri, $options) {
459
    return FALSE;
460
  }
461

    
462
  /**
463
   * Implements DrupalStreamWrapperInterface::chmod().
464
   */
465
  public function chmod($mode) {
466
    return FALSE;
467
  }
468

    
469
  /**
470
   * Implements DrupalStreamWrapperInterface::dirname().
471
   */
472
  public function dirname($uri = NULL) {
473
    return FALSE;
474
  }
475

    
476
}