Project

General

Profile

Paste
Download (22.6 KB) Statistics
| Branch: | Revision:

root / drupal7 / includes / stream_wrappers.inc @ 582db59d

1
<?php
2

    
3
/**
4
 * @file
5
 * Drupal stream wrapper interface.
6
 *
7
 * Provides a Drupal interface and classes to implement PHP stream wrappers for
8
 * public, private, and temporary files.
9
 *
10
 * A stream wrapper is an abstraction of a file system that allows Drupal to
11
 * use the same set of methods to access both local files and remote resources.
12
 *
13
 * Note that PHP 5.2 fopen() only supports URIs of the form "scheme://target"
14
 * despite the fact that according to RFC 3986 a URI's scheme component
15
 * delimiter is in general just ":", not "://".  Because of this PHP limitation
16
 * and for consistency Drupal will only accept URIs of form "scheme://target".
17
 *
18
 * @see http://www.faqs.org/rfcs/rfc3986.html
19
 * @see http://bugs.php.net/bug.php?id=47070
20
 */
21

    
22
/**
23
 * Stream wrapper bit flags that are the basis for composite types.
24
 *
25
 * Note that 0x0002 is skipped, because it was the value of a constant that has
26
 * since been removed.
27
 */
28

    
29
/**
30
 * Stream wrapper bit flag -- a filter that matches all wrappers.
31
 */
32
define('STREAM_WRAPPERS_ALL', 0x0000);
33

    
34
/**
35
 * Stream wrapper bit flag -- refers to a local file system location.
36
 */
37
define('STREAM_WRAPPERS_LOCAL', 0x0001);
38

    
39
/**
40
 * Stream wrapper bit flag -- wrapper is readable (almost always true).
41
 */
42
define('STREAM_WRAPPERS_READ', 0x0004);
43

    
44
/**
45
 * Stream wrapper bit flag -- wrapper is writeable.
46
 */
47
define('STREAM_WRAPPERS_WRITE', 0x0008);
48

    
49
/**
50
 * Stream wrapper bit flag -- exposed in the UI and potentially web accessible.
51
 */
52
define('STREAM_WRAPPERS_VISIBLE', 0x0010);
53

    
54
/**
55
 * Composite stream wrapper bit flags that are usually used as the types.
56
 */
57

    
58
/**
59
 * Stream wrapper type flag -- not visible in the UI or accessible via web,
60
 * but readable and writable. E.g. the temporary directory for uploads.
61
 */
62
define('STREAM_WRAPPERS_HIDDEN', STREAM_WRAPPERS_READ | STREAM_WRAPPERS_WRITE);
63

    
64
/**
65
 * Stream wrapper type flag -- hidden, readable and writeable using local files.
66
 */
67
define('STREAM_WRAPPERS_LOCAL_HIDDEN', STREAM_WRAPPERS_LOCAL | STREAM_WRAPPERS_HIDDEN);
68

    
69
/**
70
 * Stream wrapper type flag -- visible, readable and writeable.
71
 */
72
define('STREAM_WRAPPERS_WRITE_VISIBLE', STREAM_WRAPPERS_READ | STREAM_WRAPPERS_WRITE | STREAM_WRAPPERS_VISIBLE);
73

    
74
/**
75
 * Stream wrapper type flag -- visible and read-only.
76
 */
77
define('STREAM_WRAPPERS_READ_VISIBLE', STREAM_WRAPPERS_READ | STREAM_WRAPPERS_VISIBLE);
78

    
79
/**
80
 * Stream wrapper type flag -- the default when 'type' is omitted from
81
 * hook_stream_wrappers(). This does not include STREAM_WRAPPERS_LOCAL,
82
 * because PHP grants a greater trust level to local files (for example, they
83
 * can be used in an "include" statement, regardless of the "allow_url_include"
84
 * setting), so stream wrappers need to explicitly opt-in to this.
85
 */
86
define('STREAM_WRAPPERS_NORMAL', STREAM_WRAPPERS_WRITE_VISIBLE);
87

    
88
/**
89
 * Stream wrapper type flag -- visible, readable and writeable using local files.
90
 */
91
define('STREAM_WRAPPERS_LOCAL_NORMAL', STREAM_WRAPPERS_LOCAL | STREAM_WRAPPERS_NORMAL);
92

    
93
/**
94
 * Generic PHP stream wrapper interface.
95
 *
96
 * @see http://www.php.net/manual/class.streamwrapper.php
97
 */
98
interface StreamWrapperInterface {
99
  public function stream_open($uri, $mode, $options, &$opened_url);
100
  public function stream_close();
101
  public function stream_lock($operation);
102
  public function stream_read($count);
103
  public function stream_write($data);
104
  public function stream_eof();
105
  public function stream_seek($offset, $whence);
106
  public function stream_flush();
107
  public function stream_tell();
108
  public function stream_stat();
109
  public function unlink($uri);
110
  public function rename($from_uri, $to_uri);
111
  public function mkdir($uri, $mode, $options);
112
  public function rmdir($uri, $options);
113
  public function url_stat($uri, $flags);
114
  public function dir_opendir($uri, $options);
115
  public function dir_readdir();
116
  public function dir_rewinddir();
117
  public function dir_closedir();
118
}
119

    
120
/**
121
 * Drupal stream wrapper extension.
122
 *
123
 * Extend the StreamWrapperInterface with methods expected by Drupal stream
124
 * wrapper classes.
125
 */
126
interface DrupalStreamWrapperInterface extends StreamWrapperInterface {
127
  /**
128
   * Set the absolute stream resource URI.
129
   *
130
   * This allows you to set the URI. Generally is only called by the factory
131
   * method.
132
   *
133
   * @param $uri
134
   *   A string containing the URI that should be used for this instance.
135
   */
136
  function setUri($uri);
137

    
138
  /**
139
   * Returns the stream resource URI.
140
   *
141
   * @return
142
   *   Returns the current URI of the instance.
143
   */
144
  public function getUri();
145

    
146
  /**
147
   * Returns a web accessible URL for the resource.
148
   *
149
   * This function should return a URL that can be embedded in a web page
150
   * and accessed from a browser. For example, the external URL of
151
   * "youtube://xIpLd0WQKCY" might be
152
   * "http://www.youtube.com/watch?v=xIpLd0WQKCY".
153
   *
154
   * @return
155
   *   Returns a string containing a web accessible URL for the resource.
156
   */
157
  public function getExternalUrl();
158

    
159
  /**
160
   * Returns the MIME type of the resource.
161
   *
162
   * @param $uri
163
   *   The URI, path, or filename.
164
   * @param $mapping
165
   *   An optional map of extensions to their mimetypes, in the form:
166
   *    - 'mimetypes': a list of mimetypes, keyed by an identifier,
167
   *    - 'extensions': the mapping itself, an associative array in which
168
   *      the key is the extension and the value is the mimetype identifier.
169
   *
170
   * @return
171
   *   Returns a string containing the MIME type of the resource.
172
   */
173
  public static function getMimeType($uri, $mapping = NULL);
174

    
175
  /**
176
   * Changes permissions of the resource.
177
   *
178
   * PHP lacks this functionality and it is not part of the official stream
179
   * wrapper interface. This is a custom implementation for Drupal.
180
   *
181
   * @param $mode
182
   *   Integer value for the permissions. Consult PHP chmod() documentation
183
   *   for more information.
184
   *
185
   * @return
186
   *   Returns TRUE on success or FALSE on failure.
187
   */
188
  public function chmod($mode);
189

    
190
  /**
191
   * Returns canonical, absolute path of the resource.
192
   *
193
   * Implementation placeholder. PHP's realpath() does not support stream
194
   * wrappers. We provide this as a default so that individual wrappers may
195
   * implement their own solutions.
196
   *
197
   * @return
198
   *   Returns a string with absolute pathname on success (implemented
199
   *   by core wrappers), or FALSE on failure or if the registered
200
   *   wrapper does not provide an implementation.
201
   */
202
  public function realpath();
203

    
204
  /**
205
   * Gets the name of the directory from a given path.
206
   *
207
   * This method is usually accessed through drupal_dirname(), which wraps
208
   * around the normal PHP dirname() function, which does not support stream
209
   * wrappers.
210
   *
211
   * @param $uri
212
   *   An optional URI.
213
   *
214
   * @return
215
   *   A string containing the directory name, or FALSE if not applicable.
216
   *
217
   * @see drupal_dirname()
218
   */
219
  public function dirname($uri = NULL);
220
}
221

    
222

    
223
/**
224
 * Drupal stream wrapper base class for local files.
225
 *
226
 * This class provides a complete stream wrapper implementation. URIs such as
227
 * "public://example.txt" are expanded to a normal filesystem path such as
228
 * "sites/default/files/example.txt" and then PHP filesystem functions are
229
 * invoked.
230
 *
231
 * DrupalLocalStreamWrapper implementations need to implement at least the
232
 * getDirectoryPath() and getExternalUrl() methods.
233
 */
234
abstract class DrupalLocalStreamWrapper implements DrupalStreamWrapperInterface {
235
  /**
236
   * Stream context resource.
237
   *
238
   * @var Resource
239
   */
240
  public $context;
241

    
242
  /**
243
   * A generic resource handle.
244
   *
245
   * @var Resource
246
   */
247
  public $handle = NULL;
248

    
249
  /**
250
   * Instance URI (stream).
251
   *
252
   * A stream is referenced as "scheme://target".
253
   *
254
   * @var String
255
   */
256
  protected $uri;
257

    
258
  /**
259
   * Gets the path that the wrapper is responsible for.
260
   * @TODO: Review this method name in D8 per http://drupal.org/node/701358
261
   *
262
   * @return
263
   *   String specifying the path.
264
   */
265
  abstract function getDirectoryPath();
266

    
267
  /**
268
   * Base implementation of setUri().
269
   */
270
  function setUri($uri) {
271
    $this->uri = $uri;
272
  }
273

    
274
  /**
275
   * Base implementation of getUri().
276
   */
277
  function getUri() {
278
    return $this->uri;
279
  }
280

    
281
  /**
282
   * Returns the local writable target of the resource within the stream.
283
   *
284
   * This function should be used in place of calls to realpath() or similar
285
   * functions when attempting to determine the location of a file. While
286
   * functions like realpath() may return the location of a read-only file, this
287
   * method may return a URI or path suitable for writing that is completely
288
   * separate from the URI used for reading.
289
   *
290
   * @param $uri
291
   *   Optional URI.
292
   *
293
   * @return
294
   *   Returns a string representing a location suitable for writing of a file,
295
   *   or FALSE if unable to write to the file such as with read-only streams.
296
   */
297
  protected function getTarget($uri = NULL) {
298
    if (!isset($uri)) {
299
      $uri = $this->uri;
300
    }
301

    
302
    list($scheme, $target) = explode('://', $uri, 2);
303

    
304
    // Remove erroneous leading or trailing, forward-slashes and backslashes.
305
    return trim($target, '\/');
306
  }
307

    
308
  /**
309
   * Base implementation of getMimeType().
310
   */
311
  static function getMimeType($uri, $mapping = NULL) {
312
    if (!isset($mapping)) {
313
      // The default file map, defined in file.mimetypes.inc is quite big.
314
      // We only load it when necessary.
315
      include_once DRUPAL_ROOT . '/includes/file.mimetypes.inc';
316
      $mapping = file_mimetype_mapping();
317
    }
318

    
319
    $extension = '';
320
    $file_parts = explode('.', drupal_basename($uri));
321

    
322
    // Remove the first part: a full filename should not match an extension.
323
    array_shift($file_parts);
324

    
325
    // Iterate over the file parts, trying to find a match.
326
    // For my.awesome.image.jpeg, we try:
327
    //   - jpeg
328
    //   - image.jpeg, and
329
    //   - awesome.image.jpeg
330
    while ($additional_part = array_pop($file_parts)) {
331
      $extension = strtolower($additional_part . ($extension ? '.' . $extension : ''));
332
      if (isset($mapping['extensions'][$extension])) {
333
        return $mapping['mimetypes'][$mapping['extensions'][$extension]];
334
      }
335
    }
336

    
337
    return 'application/octet-stream';
338
  }
339

    
340
  /**
341
   * Base implementation of chmod().
342
   */
343
  function chmod($mode) {
344
    $output = @chmod($this->getLocalPath(), $mode);
345
    // We are modifying the underlying file here, so we have to clear the stat
346
    // cache so that PHP understands that URI has changed too.
347
    clearstatcache();
348
    return $output;
349
  }
350

    
351
  /**
352
   * Base implementation of realpath().
353
   */
354
  function realpath() {
355
    return $this->getLocalPath();
356
  }
357

    
358
  /**
359
   * Returns the canonical absolute path of the URI, if possible.
360
   *
361
   * @param string $uri
362
   *   (optional) The stream wrapper URI to be converted to a canonical
363
   *   absolute path. This may point to a directory or another type of file.
364
   *
365
   * @return string|false
366
   *   If $uri is not set, returns the canonical absolute path of the URI
367
   *   previously set by the DrupalStreamWrapperInterface::setUri() function.
368
   *   If $uri is set and valid for this class, returns its canonical absolute
369
   *   path, as determined by the realpath() function. If $uri is set but not
370
   *   valid, returns FALSE.
371
   */
372
  protected function getLocalPath($uri = NULL) {
373
    if (!isset($uri)) {
374
      $uri = $this->uri;
375
    }
376
    $path = $this->getDirectoryPath() . '/' . $this->getTarget($uri);
377
    $realpath = realpath($path);
378
    if (!$realpath) {
379
      // This file does not yet exist.
380
      $realpath = realpath(dirname($path)) . '/' . drupal_basename($path);
381
    }
382
    $directory = realpath($this->getDirectoryPath());
383
    if (!$realpath || !$directory || strpos($realpath, $directory) !== 0) {
384
      return FALSE;
385
    }
386
    return $realpath;
387
  }
388

    
389
  /**
390
   * Support for fopen(), file_get_contents(), file_put_contents() etc.
391
   *
392
   * @param $uri
393
   *   A string containing the URI to the file to open.
394
   * @param $mode
395
   *   The file mode ("r", "wb" etc.).
396
   * @param $options
397
   *   A bit mask of STREAM_USE_PATH and STREAM_REPORT_ERRORS.
398
   * @param $opened_path
399
   *   A string containing the path actually opened.
400
   *
401
   * @return
402
   *   Returns TRUE if file was opened successfully.
403
   *
404
   * @see http://php.net/manual/streamwrapper.stream-open.php
405
   */
406
  public function stream_open($uri, $mode, $options, &$opened_path) {
407
    $this->uri = $uri;
408
    $path = $this->getLocalPath();
409
    $this->handle = ($options & STREAM_REPORT_ERRORS) ? fopen($path, $mode) : @fopen($path, $mode);
410

    
411
    if ((bool) $this->handle && $options & STREAM_USE_PATH) {
412
      $opened_path = $path;
413
    }
414

    
415
    return (bool) $this->handle;
416
  }
417

    
418
  /**
419
   * Support for flock().
420
   *
421
   * @param $operation
422
   *   One of the following:
423
   *   - LOCK_SH to acquire a shared lock (reader).
424
   *   - LOCK_EX to acquire an exclusive lock (writer).
425
   *   - LOCK_UN to release a lock (shared or exclusive).
426
   *   - LOCK_NB if you don't want flock() to block while locking (not
427
   *     supported on Windows).
428
   *
429
   * @return
430
   *   Always returns TRUE at the present time.
431
   *
432
   * @see http://php.net/manual/streamwrapper.stream-lock.php
433
   */
434
  public function stream_lock($operation) {
435
    if (in_array($operation, array(LOCK_SH, LOCK_EX, LOCK_UN, LOCK_NB))) {
436
      return flock($this->handle, $operation);
437
    }
438

    
439
    return TRUE;
440
  }
441

    
442
  /**
443
   * Support for fread(), file_get_contents() etc.
444
   *
445
   * @param $count
446
   *   Maximum number of bytes to be read.
447
   *
448
   * @return
449
   *   The string that was read, or FALSE in case of an error.
450
   *
451
   * @see http://php.net/manual/streamwrapper.stream-read.php
452
   */
453
  public function stream_read($count) {
454
    return fread($this->handle, $count);
455
  }
456

    
457
  /**
458
   * Support for fwrite(), file_put_contents() etc.
459
   *
460
   * @param $data
461
   *   The string to be written.
462
   *
463
   * @return
464
   *   The number of bytes written (integer).
465
   *
466
   * @see http://php.net/manual/streamwrapper.stream-write.php
467
   */
468
  public function stream_write($data) {
469
    return fwrite($this->handle, $data);
470
  }
471

    
472
  /**
473
   * Support for feof().
474
   *
475
   * @return
476
   *   TRUE if end-of-file has been reached.
477
   *
478
   * @see http://php.net/manual/streamwrapper.stream-eof.php
479
   */
480
  public function stream_eof() {
481
    return feof($this->handle);
482
  }
483

    
484
  /**
485
   * Support for fseek().
486
   *
487
   * @param $offset
488
   *   The byte offset to got to.
489
   * @param $whence
490
   *   SEEK_SET, SEEK_CUR, or SEEK_END.
491
   *
492
   * @return
493
   *   TRUE on success.
494
   *
495
   * @see http://php.net/manual/streamwrapper.stream-seek.php
496
   */
497
  public function stream_seek($offset, $whence) {
498
    // fseek returns 0 on success and -1 on a failure.
499
    // stream_seek   1 on success and  0 on a failure.
500
    return !fseek($this->handle, $offset, $whence);
501
  }
502

    
503
  /**
504
   * Support for fflush().
505
   *
506
   * @return
507
   *   TRUE if data was successfully stored (or there was no data to store).
508
   *
509
   * @see http://php.net/manual/streamwrapper.stream-flush.php
510
   */
511
  public function stream_flush() {
512
    return fflush($this->handle);
513
  }
514

    
515
  /**
516
   * Support for ftell().
517
   *
518
   * @return
519
   *   The current offset in bytes from the beginning of file.
520
   *
521
   * @see http://php.net/manual/streamwrapper.stream-tell.php
522
   */
523
  public function stream_tell() {
524
    return ftell($this->handle);
525
  }
526

    
527
  /**
528
   * Support for fstat().
529
   *
530
   * @return
531
   *   An array with file status, or FALSE in case of an error - see fstat()
532
   *   for a description of this array.
533
   *
534
   * @see http://php.net/manual/streamwrapper.stream-stat.php
535
   */
536
  public function stream_stat() {
537
    return fstat($this->handle);
538
  }
539

    
540
  /**
541
   * Support for fclose().
542
   *
543
   * @return
544
   *   TRUE if stream was successfully closed.
545
   *
546
   * @see http://php.net/manual/streamwrapper.stream-close.php
547
   */
548
  public function stream_close() {
549
    return fclose($this->handle);
550
  }
551

    
552
  /**
553
   * Support for unlink().
554
   *
555
   * @param $uri
556
   *   A string containing the URI to the resource to delete.
557
   *
558
   * @return
559
   *   TRUE if resource was successfully deleted.
560
   *
561
   * @see http://php.net/manual/streamwrapper.unlink.php
562
   */
563
  public function unlink($uri) {
564
    $this->uri = $uri;
565
    return drupal_unlink($this->getLocalPath());
566
  }
567

    
568
  /**
569
   * Support for rename().
570
   *
571
   * @param $from_uri,
572
   *   The URI to the file to rename.
573
   * @param $to_uri
574
   *   The new URI for file.
575
   *
576
   * @return
577
   *   TRUE if file was successfully renamed.
578
   *
579
   * @see http://php.net/manual/streamwrapper.rename.php
580
   */
581
  public function rename($from_uri, $to_uri) {
582
    return rename($this->getLocalPath($from_uri), $this->getLocalPath($to_uri));
583
  }
584

    
585
  /**
586
   * Gets the name of the directory from a given path.
587
   *
588
   * This method is usually accessed through drupal_dirname(), which wraps
589
   * around the PHP dirname() function because it does not support stream
590
   * wrappers.
591
   *
592
   * @param $uri
593
   *   A URI or path.
594
   *
595
   * @return
596
   *   A string containing the directory name.
597
   *
598
   * @see drupal_dirname()
599
   */
600
  public function dirname($uri = NULL) {
601
    list($scheme, $target) = explode('://', $uri, 2);
602
    $target  = $this->getTarget($uri);
603
    $dirname = dirname($target);
604

    
605
    if ($dirname == '.') {
606
      $dirname = '';
607
    }
608

    
609
    return $scheme . '://' . $dirname;
610
  }
611

    
612
  /**
613
   * Support for mkdir().
614
   *
615
   * @param $uri
616
   *   A string containing the URI to the directory to create.
617
   * @param $mode
618
   *   Permission flags - see mkdir().
619
   * @param $options
620
   *   A bit mask of STREAM_REPORT_ERRORS and STREAM_MKDIR_RECURSIVE.
621
   *
622
   * @return
623
   *   TRUE if directory was successfully created.
624
   *
625
   * @see http://php.net/manual/streamwrapper.mkdir.php
626
   */
627
  public function mkdir($uri, $mode, $options) {
628
    $this->uri = $uri;
629
    $recursive = (bool) ($options & STREAM_MKDIR_RECURSIVE);
630
    if ($recursive) {
631
      // $this->getLocalPath() fails if $uri has multiple levels of directories
632
      // that do not yet exist.
633
      $localpath = $this->getDirectoryPath() . '/' . $this->getTarget($uri);
634
    }
635
    else {
636
      $localpath = $this->getLocalPath($uri);
637
    }
638
    if ($options & STREAM_REPORT_ERRORS) {
639
      return mkdir($localpath, $mode, $recursive);
640
    }
641
    else {
642
      return @mkdir($localpath, $mode, $recursive);
643
    }
644
  }
645

    
646
  /**
647
   * Support for rmdir().
648
   *
649
   * @param $uri
650
   *   A string containing the URI to the directory to delete.
651
   * @param $options
652
   *   A bit mask of STREAM_REPORT_ERRORS.
653
   *
654
   * @return
655
   *   TRUE if directory was successfully removed.
656
   *
657
   * @see http://php.net/manual/streamwrapper.rmdir.php
658
   */
659
  public function rmdir($uri, $options) {
660
    $this->uri = $uri;
661
    if ($options & STREAM_REPORT_ERRORS) {
662
      return drupal_rmdir($this->getLocalPath());
663
    }
664
    else {
665
      return @drupal_rmdir($this->getLocalPath());
666
    }
667
  }
668

    
669
  /**
670
   * Support for stat().
671
   *
672
   * @param $uri
673
   *   A string containing the URI to get information about.
674
   * @param $flags
675
   *   A bit mask of STREAM_URL_STAT_LINK and STREAM_URL_STAT_QUIET.
676
   *
677
   * @return
678
   *   An array with file status, or FALSE in case of an error - see fstat()
679
   *   for a description of this array.
680
   *
681
   * @see http://php.net/manual/streamwrapper.url-stat.php
682
   */
683
  public function url_stat($uri, $flags) {
684
    $this->uri = $uri;
685
    $path = $this->getLocalPath();
686
    // Suppress warnings if requested or if the file or directory does not
687
    // exist. This is consistent with PHP's plain filesystem stream wrapper.
688
    if ($flags & STREAM_URL_STAT_QUIET || !file_exists($path)) {
689
      return @stat($path);
690
    }
691
    else {
692
      return stat($path);
693
    }
694
  }
695

    
696
  /**
697
   * Support for opendir().
698
   *
699
   * @param $uri
700
   *   A string containing the URI to the directory to open.
701
   * @param $options
702
   *   Unknown (parameter is not documented in PHP Manual).
703
   *
704
   * @return
705
   *   TRUE on success.
706
   *
707
   * @see http://php.net/manual/streamwrapper.dir-opendir.php
708
   */
709
  public function dir_opendir($uri, $options) {
710
    $this->uri = $uri;
711
    $this->handle = opendir($this->getLocalPath());
712

    
713
    return (bool) $this->handle;
714
  }
715

    
716
  /**
717
   * Support for readdir().
718
   *
719
   * @return
720
   *   The next filename, or FALSE if there are no more files in the directory.
721
   *
722
   * @see http://php.net/manual/streamwrapper.dir-readdir.php
723
   */
724
  public function dir_readdir() {
725
    return readdir($this->handle);
726
  }
727

    
728
  /**
729
   * Support for rewinddir().
730
   *
731
   * @return
732
   *   TRUE on success.
733
   *
734
   * @see http://php.net/manual/streamwrapper.dir-rewinddir.php
735
   */
736
  public function dir_rewinddir() {
737
    rewinddir($this->handle);
738
    // We do not really have a way to signal a failure as rewinddir() does not
739
    // have a return value and there is no way to read a directory handler
740
    // without advancing to the next file.
741
    return TRUE;
742
  }
743

    
744
  /**
745
   * Support for closedir().
746
   *
747
   * @return
748
   *   TRUE on success.
749
   *
750
   * @see http://php.net/manual/streamwrapper.dir-closedir.php
751
   */
752
  public function dir_closedir() {
753
    closedir($this->handle);
754
    // We do not really have a way to signal a failure as closedir() does not
755
    // have a return value.
756
    return TRUE;
757
  }
758
}
759

    
760
/**
761
 * Drupal public (public://) stream wrapper class.
762
 *
763
 * Provides support for storing publicly accessible files with the Drupal file
764
 * interface.
765
 */
766
class DrupalPublicStreamWrapper extends DrupalLocalStreamWrapper {
767
  /**
768
   * Implements abstract public function getDirectoryPath()
769
   */
770
  public function getDirectoryPath() {
771
    return variable_get('file_public_path', conf_path() . '/files');
772
  }
773

    
774
  /**
775
   * Overrides getExternalUrl().
776
   *
777
   * Return the HTML URI of a public file.
778
   */
779
  function getExternalUrl() {
780
    $path = str_replace('\\', '/', $this->getTarget());
781
    return $GLOBALS['base_url'] . '/' . self::getDirectoryPath() . '/' . drupal_encode_path($path);
782
  }
783
}
784

    
785

    
786
/**
787
 * Drupal private (private://) stream wrapper class.
788
 *
789
 * Provides support for storing privately accessible files with the Drupal file
790
 * interface.
791
 */
792
class DrupalPrivateStreamWrapper extends DrupalLocalStreamWrapper {
793
  /**
794
   * Implements abstract public function getDirectoryPath()
795
   */
796
  public function getDirectoryPath() {
797
    return variable_get('file_private_path', '');
798
  }
799

    
800
  /**
801
   * Overrides getExternalUrl().
802
   *
803
   * Return the HTML URI of a private file.
804
   */
805
  function getExternalUrl() {
806
    $path = str_replace('\\', '/', $this->getTarget());
807
    return url('system/files/' . $path, array('absolute' => TRUE));
808
  }
809
}
810

    
811
/**
812
 * Drupal temporary (temporary://) stream wrapper class.
813
 *
814
 * Provides support for storing temporarily accessible files with the Drupal
815
 * file interface.
816
 *
817
 * Extends DrupalPublicStreamWrapper.
818
 */
819
class DrupalTemporaryStreamWrapper extends DrupalLocalStreamWrapper {
820
  /**
821
   * Implements abstract public function getDirectoryPath()
822
   */
823
  public function getDirectoryPath() {
824
    return variable_get('file_temporary_path', file_directory_temp());
825
  }
826

    
827
  /**
828
   * Overrides getExternalUrl().
829
   */
830
  public function getExternalUrl() {
831
    $path = str_replace('\\', '/', $this->getTarget());
832
    return url('system/temporary/' . $path, array('absolute' => TRUE));
833
  }
834
}