SCSWrapper.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <?php
  2. /**
  3. * $Id$
  4. *
  5. * Note: Although this wrapper works, it would be more efficient to use the SCS class instead
  6. */
  7. final class SCSWrapper extends SCS {
  8. private $position = 0, $mode = '', $buffer;
  9. public function url_stat($path, $flags) {
  10. self::__getURL($path);
  11. return (($info = self::getObjectInfo($this->url['host'], $this->url['path'])) !== false) ?
  12. array('size' => $info['size'], 'mtime' => $info['time'], 'ctime' => $info['time']) : false;
  13. }
  14. public function unlink($path) {
  15. self::__getURL($path);
  16. return self::deleteObject($this->url['host'], $this->url['path']);
  17. }
  18. public function mkdir($path, $mode, $options) {
  19. self::__getURL($path);
  20. return self::putBucket($this->url['host'], self::__translateMode($mode));
  21. }
  22. public function rmdir($path) {
  23. self::__getURL($path);
  24. return self::deleteBucket($this->url['host']);
  25. }
  26. public function dir_opendir($path, $options) {
  27. self::__getURL($path);
  28. if (($contents = self::getBucket($this->url['host'], $this->url['path'])) !== false) {
  29. $pathlen = strlen($this->url['path']);
  30. if (substr($this->url['path'], -1) == '/') $pathlen++;
  31. $this->buffer = array();
  32. foreach ($contents as $file) {
  33. if ($pathlen > 0) $file['name'] = substr($file['name'], $pathlen);
  34. $this->buffer[] = $file;
  35. }
  36. return true;
  37. }
  38. return false;
  39. }
  40. public function dir_readdir() {
  41. return (isset($this->buffer[$this->position])) ? $this->buffer[$this->position++]['name'] : false;
  42. }
  43. public function dir_rewinddir() {
  44. $this->position = 0;
  45. }
  46. public function dir_closedir() {
  47. $this->position = 0;
  48. unset($this->buffer);
  49. }
  50. public function stream_close() {
  51. if ($this->mode == 'w') {
  52. self::putObject($this->buffer, $this->url['host'], $this->url['path']);
  53. }
  54. $this->position = 0;
  55. unset($this->buffer);
  56. }
  57. public function stream_stat() {
  58. if (is_object($this->buffer) && isset($this->buffer->headers))
  59. return array(
  60. 'size' => $this->buffer->headers['size'],
  61. 'mtime' => $this->buffer->headers['time'],
  62. 'ctime' => $this->buffer->headers['time']
  63. );
  64. elseif (($info = self::getObjectInfo($this->url['host'], $this->url['path'])) !== false)
  65. return array('size' => $info['size'], 'mtime' => $info['time'], 'ctime' => $info['time']);
  66. return false;
  67. }
  68. public function stream_flush() {
  69. $this->position = 0;
  70. return true;
  71. }
  72. public function stream_open($path, $mode, $options, &$opened_path) {
  73. if (!in_array($mode, array('r', 'rb', 'w', 'wb'))) return false; // Mode not supported
  74. $this->mode = substr($mode, 0, 1);
  75. self::__getURL($path);
  76. $this->position = 0;
  77. if ($this->mode == 'r') {
  78. if (($this->buffer = self::getObject($this->url['host'], $this->url['path'])) !== false) {
  79. if (is_object($this->buffer->body)) $this->buffer->body = (string)$this->buffer->body;
  80. } else return false;
  81. }
  82. return true;
  83. }
  84. public function stream_read($count) {
  85. if ($this->mode !== 'r' && $this->buffer !== false) return false;
  86. $data = substr(is_object($this->buffer) ? $this->buffer->body : $this->buffer, $this->position, $count);
  87. $this->position += strlen($data);
  88. return $data;
  89. }
  90. public function stream_write($data) {
  91. if ($this->mode !== 'w') return 0;
  92. $left = substr($this->buffer, 0, $this->position);
  93. $right = substr($this->buffer, $this->position + strlen($data));
  94. $this->buffer = $left . $data . $right;
  95. $this->position += strlen($data);
  96. return strlen($data);
  97. }
  98. public function stream_tell() {
  99. return $this->position;
  100. }
  101. public function stream_eof() {
  102. return $this->position >= strlen(is_object($this->buffer) ? $this->buffer->body : $this->buffer);
  103. }
  104. public function stream_seek($offset, $whence) {
  105. switch ($whence) {
  106. case SEEK_SET:
  107. if ($offset < strlen($this->buffer->body) && $offset >= 0) {
  108. $this->position = $offset;
  109. return true;
  110. } else return false;
  111. break;
  112. case SEEK_CUR:
  113. if ($offset >= 0) {
  114. $this->position += $offset;
  115. return true;
  116. } else return false;
  117. break;
  118. case SEEK_END:
  119. $bytes = strlen($this->buffer->body);
  120. if ($bytes + $offset >= 0) {
  121. $this->position = $bytes + $offset;
  122. return true;
  123. } else return false;
  124. break;
  125. default: return false;
  126. }
  127. }
  128. private function __getURL($path) {
  129. $this->url = parse_url($path);
  130. if (!isset($this->url['scheme']) || $this->url['scheme'] !== 'scs') return $this->url;
  131. if (isset($this->url['user'], $this->url['pass'])) self::setAuth($this->url['user'], $this->url['pass']);
  132. $this->url['path'] = isset($this->url['path']) ? substr($this->url['path'], 1) : '';
  133. }
  134. private function __translateMode($mode) {
  135. $acl = self::ACL_PRIVATE;
  136. if (($mode & 0x0020) || ($mode & 0x0004))
  137. $acl = self::ACL_PUBLIC_READ;
  138. // You probably don't want to enable public write access
  139. if (($mode & 0x0010) || ($mode & 0x0008) || ($mode & 0x0002) || ($mode & 0x0001))
  140. $acl = self::ACL_PUBLIC_READ; //$acl = self::ACL_PUBLIC_READ_WRITE;
  141. return $acl;
  142. }
  143. } stream_wrapper_register('scs', 'SCSWrapper');