Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/zend/Zend/Service/Amazon/S3/Stream.php
Go to the documentation of this file.
00001 <?php
00026 require_once 'Zend/Service/Amazon/S3.php';
00027 
00037 class Zend_Service_Amazon_S3_Stream
00038 {
00042     private $_writeBuffer = false;
00043 
00047     private $_position = 0;
00048 
00052     private $_objectSize = 0;
00053 
00057     private $_objectName = null;
00058 
00062     private $_objectBuffer = null;
00063 
00067     private $_bucketList = array();
00068 
00072     private $_s3 = null;
00073 
00080     protected function _getS3Client($path)
00081     {
00082         if ($this->_s3 === null) {
00083             $url = explode(':', $path);
00084 
00085             if (!$url) {
00089                 require_once 'Zend/Service/Amazon/S3/Exception.php';
00090                 throw new Zend_Service_Amazon_S3_Exception("Unable to parse URL $path");
00091             }
00092 
00093             $this->_s3 = Zend_Service_Amazon_S3::getWrapperClient($url[0]);
00094             if (!$this->_s3) {
00098                 require_once 'Zend/Service/Amazon/S3/Exception.php';
00099                 throw new Zend_Service_Amazon_S3_Exception("Unknown client for wrapper {$url[0]}");
00100             }
00101         }
00102 
00103         return $this->_s3;
00104     }
00105 
00112     protected function _getNamePart($path)
00113     {
00114         $url = parse_url($path);
00115         if ($url['host']) {
00116             return !empty($url['path']) ? $url['host'].$url['path'] : $url['host'];
00117         }
00118 
00119         return '';
00120     }
00130     public function stream_open($path, $mode, $options, $opened_path)
00131     {
00132         $name = $this->_getNamePart($path);
00133         // If we open the file for writing, just return true. Create the object
00134         // on fflush call
00135         if (strpbrk($mode, 'wax')) {
00136             $this->_objectName = $name;
00137             $this->_objectBuffer = null;
00138             $this->_objectSize = 0;
00139             $this->_position = 0;
00140             $this->_writeBuffer = true;
00141             $this->_getS3Client($path);
00142             return true;
00143         }
00144         else {
00145             // Otherwise, just see if the file exists or not
00146             $info = $this->_getS3Client($path)->getInfo($name);
00147             if ($info) {
00148                 $this->_objectName = $name;
00149                 $this->_objectBuffer = null;
00150                 $this->_objectSize = $info['size'];
00151                 $this->_position = 0;
00152                 $this->_writeBuffer = false;
00153                 $this->_getS3Client($path);
00154                 return true;
00155             }
00156         }
00157         return false;
00158     }
00159 
00165     public function stream_close()
00166     {
00167         $this->_objectName = null;
00168         $this->_objectBuffer = null;
00169         $this->_objectSize = 0;
00170         $this->_position = 0;
00171         $this->_writeBuffer = false;
00172         unset($this->_s3);
00173     }
00174 
00181     public function stream_read($count)
00182     {
00183         if (!$this->_objectName) {
00184             return false;
00185         }
00186 
00187         $range_start = $this->_position;
00188         $range_end = $this->_position+$count;
00189 
00190         // Only fetch more data from S3 if we haven't fetched any data yet (postion=0)
00191         // OR, the range end position is greater than the size of the current object
00192         // buffer AND if the range end position is less than or equal to the object's
00193         // size returned by S3
00194         if (($this->_position == 0) || (($range_end > strlen($this->_objectBuffer)) && ($range_end <= $this->_objectSize))) {
00195 
00196             $headers = array(
00197                 'Range' => "$range_start-$range_end"
00198             );
00199 
00200             $response = $this->_s3->_makeRequest('GET', $this->_objectName, null, $headers);
00201 
00202             if ($response->getStatus() == 200) {
00203                 $this->_objectBuffer .= $response->getBody();
00204             }
00205         }
00206 
00207         $data = substr($this->_objectBuffer, $this->_position, $count);
00208         $this->_position += strlen($data);
00209         return $data;
00210     }
00211 
00218     public function stream_write($data)
00219     {
00220         if (!$this->_objectName) {
00221             return 0;
00222         }
00223         $len = strlen($data);
00224         $this->_objectBuffer .= $data;
00225         $this->_objectSize += $len;
00226         // TODO: handle current position for writing!
00227         return $len;
00228     }
00229 
00235     public function stream_eof()
00236     {
00237         if (!$this->_objectName) {
00238             return true;
00239         }
00240 
00241         return ($this->_position >= $this->_objectSize);
00242     }
00243 
00249     public function stream_tell()
00250     {
00251         return $this->_position;
00252     }
00253 
00261     public function stream_seek($offset, $whence)
00262     {
00263         if (!$this->_objectName) {
00264             return false;
00265         }
00266 
00267         switch ($whence) {
00268             case SEEK_CUR:
00269                 // Set position to current location plus $offset
00270                 $new_pos = $this->_position + $offset;
00271                 break;
00272             case SEEK_END:
00273                 // Set position to end-of-file plus $offset
00274                 $new_pos = $this->_objectSize + $offset;
00275                 break;
00276             case SEEK_SET:
00277             default:
00278                 // Set position equal to $offset
00279                 $new_pos = $offset;
00280                 break;
00281         }
00282         $ret = ($new_pos >= 0 && $new_pos <= $this->_objectSize);
00283         if ($ret) {
00284             $this->_position = $new_pos;
00285         }
00286         return $ret;
00287     }
00288 
00294     public function stream_flush()
00295     {
00296         // If the stream wasn't opened for writing, just return false
00297         if (!$this->_writeBuffer) {
00298             return false;
00299         }
00300 
00301         $ret = $this->_s3->putObject($this->_objectName, $this->_objectBuffer);
00302 
00303         $this->_objectBuffer = null;
00304 
00305         return $ret;
00306     }
00307 
00313     public function stream_stat()
00314     {
00315         if (!$this->_objectName) {
00316             return false;
00317         }
00318 
00319         $stat = array();
00320         $stat['dev'] = 0;
00321         $stat['ino'] = 0;
00322         $stat['mode'] = 0777;
00323         $stat['nlink'] = 0;
00324         $stat['uid'] = 0;
00325         $stat['gid'] = 0;
00326         $stat['rdev'] = 0;
00327         $stat['size'] = 0;
00328         $stat['atime'] = 0;
00329         $stat['mtime'] = 0;
00330         $stat['ctime'] = 0;
00331         $stat['blksize'] = 0;
00332         $stat['blocks'] = 0;
00333 
00334     if(($slash = strchr($this->_objectName, '/')) === false || $slash == strlen($this->_objectName)-1) {
00335         /* bucket */
00336         $stat['mode'] |= 040000;
00337     } else {
00338         $stat['mode'] |= 0100000;
00339     }
00340            $info = $this->_s3->getInfo($this->_objectName);
00341         if (!empty($info)) {
00342             $stat['size']  = $info['size'];
00343             $stat['atime'] = time();
00344             $stat['mtime'] = $info['mtime'];
00345         }
00346 
00347         return $stat;
00348     }
00349 
00356     public function unlink($path)
00357     {
00358         return $this->_getS3Client($path)->removeObject($this->_getNamePart($path));
00359     }
00360 
00368     public function rename($path_from, $path_to)
00369     {
00370         // TODO: Renaming isn't supported, always return false
00371         return false;
00372     }
00373 
00382     public function mkdir($path, $mode, $options)
00383     {
00384         return $this->_getS3Client($path)->createBucket(parse_url($path, PHP_URL_HOST));
00385     }
00386 
00394     public function rmdir($path, $options)
00395     {
00396         return $this->_getS3Client($path)->removeBucket(parse_url($path, PHP_URL_HOST));
00397     }
00398 
00406     public function dir_opendir($path, $options)
00407     {
00408 
00409         if (preg_match('@^([a-z0-9+.]|-)+://$@', $path)) {
00410             $this->_bucketList = $this->_getS3Client($path)->getBuckets();
00411         }
00412         else {
00413             $host = parse_url($path, PHP_URL_HOST);
00414             $this->_bucketList = $this->_getS3Client($path)->getObjectsByBucket($host);
00415         }
00416 
00417         return ($this->_bucketList !== false);
00418     }
00419 
00427     public function url_stat($path, $flags)
00428     {
00429         $stat = array();
00430         $stat['dev'] = 0;
00431         $stat['ino'] = 0;
00432         $stat['mode'] = 0777;
00433         $stat['nlink'] = 0;
00434         $stat['uid'] = 0;
00435         $stat['gid'] = 0;
00436         $stat['rdev'] = 0;
00437         $stat['size'] = 0;
00438         $stat['atime'] = 0;
00439         $stat['mtime'] = 0;
00440         $stat['ctime'] = 0;
00441         $stat['blksize'] = 0;
00442         $stat['blocks'] = 0;
00443 
00444     $name = $this->_getNamePart($path);
00445     if(($slash = strchr($name, '/')) === false || $slash == strlen($name)-1) {
00446         /* bucket */
00447         $stat['mode'] |= 040000;
00448     } else {
00449         $stat['mode'] |= 0100000;
00450     }
00451            $info = $this->_getS3Client($path)->getInfo($name);
00452 
00453         if (!empty($info)) {
00454             $stat['size']  = $info['size'];
00455             $stat['atime'] = time();
00456             $stat['mtime'] = $info['mtime'];
00457         }
00458 
00459         return $stat;
00460     }
00461 
00467     public function dir_readdir()
00468     {
00469         $object = current($this->_bucketList);
00470         if ($object !== false) {
00471             next($this->_bucketList);
00472         }
00473         return $object;
00474     }
00475 
00481     public function dir_rewinddir()
00482     {
00483         reset($this->_bucketList);
00484         return true;
00485     }
00486 
00492     public function dir_closedir()
00493     {
00494         $this->_bucketList = array();
00495         return true;
00496     }
00497 }
 All Data Structures Namespaces Files Functions Variables Enumerations