[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/zend/Zend/Service/Amazon/S3/ -> Stream.php (source)

   1  <?php
   2  /**
   3   * Zend Framework
   4   *
   5   * LICENSE
   6   *
   7   * This source file is subject to the new BSD license that is bundled
   8   * with this package in the file LICENSE.txt.
   9   * It is also available through the world-wide-web at this URL:
  10   * http://framework.zend.com/license/new-bsd
  11   * If you did not receive a copy of the license and are unable to
  12   * obtain it through the world-wide-web, please send an email
  13   * to [email protected] so we can send you a copy immediately.
  14   *
  15   * @category   Zend
  16   * @package    Zend_Service
  17   * @subpackage Amazon_S3
  18   * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  19   * @license    http://framework.zend.com/license/new-bsd     New BSD License
  20   * @version    $Id$
  21   */
  22  
  23  /**
  24   * @see Zend_Service_Amazon_S3
  25   */
  26  require_once 'Zend/Service/Amazon/S3.php';
  27  
  28  /**
  29   * Amazon S3 PHP stream wrapper
  30   *
  31   * @category   Zend
  32   * @package    Zend_Service
  33   * @subpackage Amazon_S3
  34   * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  35   * @license    http://framework.zend.com/license/new-bsd     New BSD License
  36   */
  37  class Zend_Service_Amazon_S3_Stream
  38  {
  39      /**
  40       * @var boolean Write the buffer on fflush()?
  41       */
  42      private $_writeBuffer = false;
  43  
  44      /**
  45       * @var integer Current read/write position
  46       */
  47      private $_position = 0;
  48  
  49      /**
  50       * @var integer Total size of the object as returned by S3 (Content-length)
  51       */
  52      private $_objectSize = 0;
  53  
  54      /**
  55       * @var string File name to interact with
  56       */
  57      private $_objectName = null;
  58  
  59      /**
  60       * @var string Current read/write buffer
  61       */
  62      private $_objectBuffer = null;
  63  
  64      /**
  65       * @var array Available buckets
  66       */
  67      private $_bucketList = array();
  68  
  69      /**
  70       * @var Zend_Service_Amazon_S3
  71       */
  72      private $_s3 = null;
  73  
  74      /**
  75       * Retrieve client for this stream type
  76       *
  77       * @param  string $path
  78       * @return Zend_Service_Amazon_S3
  79       */
  80      protected function _getS3Client($path)
  81      {
  82          if ($this->_s3 === null) {
  83              $url = explode(':', $path);
  84  
  85              if (!$url) {
  86                  /**
  87                   * @see Zend_Service_Amazon_S3_Exception
  88                   */
  89                  require_once 'Zend/Service/Amazon/S3/Exception.php';
  90                  throw new Zend_Service_Amazon_S3_Exception("Unable to parse URL $path");
  91              }
  92  
  93              $this->_s3 = Zend_Service_Amazon_S3::getWrapperClient($url[0]);
  94              if (!$this->_s3) {
  95                  /**
  96                   * @see Zend_Service_Amazon_S3_Exception
  97                   */
  98                  require_once 'Zend/Service/Amazon/S3/Exception.php';
  99                  throw new Zend_Service_Amazon_S3_Exception("Unknown client for wrapper {$url[0]}");
 100              }
 101          }
 102  
 103          return $this->_s3;
 104      }
 105  
 106      /**
 107       * Extract object name from URL
 108       *
 109       * @param string $path
 110       * @return string
 111       */
 112      protected function _getNamePart($path)
 113      {
 114          $url = parse_url($path);
 115          if ($url['host']) {
 116              return !empty($url['path']) ? $url['host'].$url['path'] : $url['host'];
 117          }
 118  
 119          return '';
 120      }
 121      /**
 122       * Open the stream
 123       *
 124       * @param  string  $path
 125       * @param  string  $mode
 126       * @param  integer $options
 127       * @param  string  $opened_path
 128       * @return boolean
 129       */
 130      public function stream_open($path, $mode, $options, $opened_path)
 131      {
 132          $name = $this->_getNamePart($path);
 133          // If we open the file for writing, just return true. Create the object
 134          // on fflush call
 135          if (strpbrk($mode, 'wax')) {
 136              $this->_objectName = $name;
 137              $this->_objectBuffer = null;
 138              $this->_objectSize = 0;
 139              $this->_position = 0;
 140              $this->_writeBuffer = true;
 141              $this->_getS3Client($path);
 142              return true;
 143          }
 144          else {
 145              // Otherwise, just see if the file exists or not
 146              $info = $this->_getS3Client($path)->getInfo($name);
 147              if ($info) {
 148                  $this->_objectName = $name;
 149                  $this->_objectBuffer = null;
 150                  $this->_objectSize = $info['size'];
 151                  $this->_position = 0;
 152                  $this->_writeBuffer = false;
 153                  $this->_getS3Client($path);
 154                  return true;
 155              }
 156          }
 157          return false;
 158      }
 159  
 160      /**
 161       * Close the stream
 162       *
 163       * @return void
 164       */
 165      public function stream_close()
 166      {
 167          $this->_objectName = null;
 168          $this->_objectBuffer = null;
 169          $this->_objectSize = 0;
 170          $this->_position = 0;
 171          $this->_writeBuffer = false;
 172          unset($this->_s3);
 173      }
 174  
 175      /**
 176       * Read from the stream
 177       *
 178       * @param  integer $count
 179       * @return string
 180       */
 181      public function stream_read($count)
 182      {
 183          if (!$this->_objectName) {
 184              return false;
 185          }
 186  
 187          $range_start = $this->_position;
 188          $range_end = $this->_position+$count;
 189  
 190          // Only fetch more data from S3 if we haven't fetched any data yet (postion=0)
 191          // OR, the range end position is greater than the size of the current object
 192          // buffer AND if the range end position is less than or equal to the object's
 193          // size returned by S3
 194          if (($this->_position == 0) || (($range_end > strlen($this->_objectBuffer)) && ($range_end <= $this->_objectSize))) {
 195  
 196              $headers = array(
 197                  'Range' => "$range_start-$range_end"
 198              );
 199  
 200              $response = $this->_s3->_makeRequest('GET', $this->_objectName, null, $headers);
 201  
 202              if ($response->getStatus() == 200) {
 203                  $this->_objectBuffer .= $response->getBody();
 204              }
 205          }
 206  
 207          $data = substr($this->_objectBuffer, $this->_position, $count);
 208          $this->_position += strlen($data);
 209          return $data;
 210      }
 211  
 212      /**
 213       * Write to the stream
 214       *
 215       * @param  string $data
 216       * @return integer
 217       */
 218      public function stream_write($data)
 219      {
 220          if (!$this->_objectName) {
 221              return 0;
 222          }
 223          $len = strlen($data);
 224          $this->_objectBuffer .= $data;
 225          $this->_objectSize += $len;
 226          // TODO: handle current position for writing!
 227          return $len;
 228      }
 229  
 230      /**
 231       * End of the stream?
 232       *
 233       * @return boolean
 234       */
 235      public function stream_eof()
 236      {
 237          if (!$this->_objectName) {
 238              return true;
 239          }
 240  
 241          return ($this->_position >= $this->_objectSize);
 242      }
 243  
 244      /**
 245       * What is the current read/write position of the stream
 246       *
 247       * @return integer
 248       */
 249      public function stream_tell()
 250      {
 251          return $this->_position;
 252      }
 253  
 254      /**
 255       * Update the read/write position of the stream
 256       *
 257       * @param  integer $offset
 258       * @param  integer $whence
 259       * @return boolean
 260       */
 261      public function stream_seek($offset, $whence)
 262      {
 263          if (!$this->_objectName) {
 264              return false;
 265          }
 266  
 267          switch ($whence) {
 268              case SEEK_CUR:
 269                  // Set position to current location plus $offset
 270                  $new_pos = $this->_position + $offset;
 271                  break;
 272              case SEEK_END:
 273                  // Set position to end-of-file plus $offset
 274                  $new_pos = $this->_objectSize + $offset;
 275                  break;
 276              case SEEK_SET:
 277              default:
 278                  // Set position equal to $offset
 279                  $new_pos = $offset;
 280                  break;
 281          }
 282          $ret = ($new_pos >= 0 && $new_pos <= $this->_objectSize);
 283          if ($ret) {
 284              $this->_position = $new_pos;
 285          }
 286          return $ret;
 287      }
 288  
 289      /**
 290       * Flush current cached stream data to storage
 291       *
 292       * @return boolean
 293       */
 294      public function stream_flush()
 295      {
 296          // If the stream wasn't opened for writing, just return false
 297          if (!$this->_writeBuffer) {
 298              return false;
 299          }
 300  
 301          $ret = $this->_s3->putObject($this->_objectName, $this->_objectBuffer);
 302  
 303          $this->_objectBuffer = null;
 304  
 305          return $ret;
 306      }
 307  
 308      /**
 309       * Returns data array of stream variables
 310       *
 311       * @return array
 312       */
 313      public function stream_stat()
 314      {
 315          if (!$this->_objectName) {
 316              return false;
 317          }
 318  
 319          $stat = array();
 320          $stat['dev'] = 0;
 321          $stat['ino'] = 0;
 322          $stat['mode'] = 0777;
 323          $stat['nlink'] = 0;
 324          $stat['uid'] = 0;
 325          $stat['gid'] = 0;
 326          $stat['rdev'] = 0;
 327          $stat['size'] = 0;
 328          $stat['atime'] = 0;
 329          $stat['mtime'] = 0;
 330          $stat['ctime'] = 0;
 331          $stat['blksize'] = 0;
 332          $stat['blocks'] = 0;
 333  
 334      if(($slash = strchr($this->_objectName, '/')) === false || $slash == strlen($this->_objectName)-1) {
 335          /* bucket */
 336          $stat['mode'] |= 040000;
 337      } else {
 338          $stat['mode'] |= 0100000;
 339      }
 340             $info = $this->_s3->getInfo($this->_objectName);
 341          if (!empty($info)) {
 342              $stat['size']  = $info['size'];
 343              $stat['atime'] = time();
 344              $stat['mtime'] = $info['mtime'];
 345          }
 346  
 347          return $stat;
 348      }
 349  
 350      /**
 351       * Attempt to delete the item
 352       *
 353       * @param  string $path
 354       * @return boolean
 355       */
 356      public function unlink($path)
 357      {
 358          return $this->_getS3Client($path)->removeObject($this->_getNamePart($path));
 359      }
 360  
 361      /**
 362       * Attempt to rename the item
 363       *
 364       * @param  string  $path_from
 365       * @param  string  $path_to
 366       * @return boolean False
 367       */
 368      public function rename($path_from, $path_to)
 369      {
 370          // TODO: Renaming isn't supported, always return false
 371          return false;
 372      }
 373  
 374      /**
 375       * Create a new directory
 376       *
 377       * @param  string  $path
 378       * @param  integer $mode
 379       * @param  integer $options
 380       * @return boolean
 381       */
 382      public function mkdir($path, $mode, $options)
 383      {
 384          return $this->_getS3Client($path)->createBucket(parse_url($path, PHP_URL_HOST));
 385      }
 386  
 387      /**
 388       * Remove a directory
 389       *
 390       * @param  string  $path
 391       * @param  integer $options
 392       * @return boolean
 393       */
 394      public function rmdir($path, $options)
 395      {
 396          return $this->_getS3Client($path)->removeBucket(parse_url($path, PHP_URL_HOST));
 397      }
 398  
 399      /**
 400       * Attempt to open a directory
 401       *
 402       * @param  string $path
 403       * @param  integer $options
 404       * @return boolean
 405       */
 406      public function dir_opendir($path, $options)
 407      {
 408  
 409          if (preg_match('@^([a-z0-9+.]|-)+://$@', $path)) {
 410              $this->_bucketList = $this->_getS3Client($path)->getBuckets();
 411          }
 412          else {
 413              $host = parse_url($path, PHP_URL_HOST);
 414              $this->_bucketList = $this->_getS3Client($path)->getObjectsByBucket($host);
 415          }
 416  
 417          return ($this->_bucketList !== false);
 418      }
 419  
 420      /**
 421       * Return array of URL variables
 422       *
 423       * @param  string $path
 424       * @param  integer $flags
 425       * @return array
 426       */
 427      public function url_stat($path, $flags)
 428      {
 429          $stat = array();
 430          $stat['dev'] = 0;
 431          $stat['ino'] = 0;
 432          $stat['mode'] = 0777;
 433          $stat['nlink'] = 0;
 434          $stat['uid'] = 0;
 435          $stat['gid'] = 0;
 436          $stat['rdev'] = 0;
 437          $stat['size'] = 0;
 438          $stat['atime'] = 0;
 439          $stat['mtime'] = 0;
 440          $stat['ctime'] = 0;
 441          $stat['blksize'] = 0;
 442          $stat['blocks'] = 0;
 443  
 444      $name = $this->_getNamePart($path);
 445      if(($slash = strchr($name, '/')) === false || $slash == strlen($name)-1) {
 446          /* bucket */
 447          $stat['mode'] |= 040000;
 448      } else {
 449          $stat['mode'] |= 0100000;
 450      }
 451             $info = $this->_getS3Client($path)->getInfo($name);
 452  
 453          if (!empty($info)) {
 454              $stat['size']  = $info['size'];
 455              $stat['atime'] = time();
 456              $stat['mtime'] = $info['mtime'];
 457          }
 458  
 459          return $stat;
 460      }
 461  
 462      /**
 463       * Return the next filename in the directory
 464       *
 465       * @return string
 466       */
 467      public function dir_readdir()
 468      {
 469          $object = current($this->_bucketList);
 470          if ($object !== false) {
 471              next($this->_bucketList);
 472          }
 473          return $object;
 474      }
 475  
 476      /**
 477       * Reset the directory pointer
 478       *
 479       * @return boolean True
 480       */
 481      public function dir_rewinddir()
 482      {
 483          reset($this->_bucketList);
 484          return true;
 485      }
 486  
 487      /**
 488       * Close a directory
 489       *
 490       * @return boolean True
 491       */
 492      public function dir_closedir()
 493      {
 494          $this->_bucketList = array();
 495          return true;
 496      }
 497  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1