[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |