13 * to license@zend.com so we can send you a copy immediately. |
13 * to license@zend.com so we can send you a copy immediately. |
14 * |
14 * |
15 * @category Zend |
15 * @category Zend |
16 * @package Zend_Service_WindowsAzure_Storage |
16 * @package Zend_Service_WindowsAzure_Storage |
17 * @subpackage Blob |
17 * @subpackage Blob |
18 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
18 * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) |
19 * @license http://todo name_todo |
19 * @license http://todo name_todo |
20 * @version $Id: Stream.php 23167 2010-10-19 17:53:31Z mabe $ |
20 * @version $Id: Stream.php 24593 2012-01-05 20:35:02Z matthew $ |
21 */ |
21 */ |
22 |
|
23 /** |
|
24 * @see Zend_Service_WindowsAzure_Storage_Blob |
|
25 */ |
|
26 require_once 'Zend/Service/WindowsAzure/Storage/Blob.php'; |
|
27 |
|
28 /** |
|
29 * @see Zend_Service_WindowsAzure_Exception |
|
30 */ |
|
31 require_once 'Zend/Service/WindowsAzure/Exception.php'; |
|
32 |
|
33 |
22 |
34 /** |
23 /** |
35 * @category Zend |
24 * @category Zend |
36 * @package Zend_Service_WindowsAzure_Storage |
25 * @package Zend_Service_WindowsAzure_Storage |
37 * @subpackage Blob |
26 * @subpackage Blob |
38 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
27 * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) |
39 * @license http://framework.zend.com/license/new-bsd New BSD License |
28 * @license http://framework.zend.com/license/new-bsd New BSD License |
40 */ |
29 */ |
41 class Zend_Service_WindowsAzure_Storage_Blob_Stream |
30 class Zend_Service_WindowsAzure_Storage_Blob_Stream |
42 { |
31 { |
43 /** |
32 /** |
44 * Current file name |
33 * Current file name |
45 * |
34 * |
46 * @var string |
35 * @var string |
47 */ |
36 */ |
48 private $_fileName = null; |
37 protected $_fileName = null; |
49 |
38 |
50 /** |
39 /** |
51 * Temporary file name |
40 * Temporary file name |
52 * |
41 * |
53 * @var string |
42 * @var string |
54 */ |
43 */ |
55 private $_temporaryFileName = null; |
44 protected $_temporaryFileName = null; |
56 |
45 |
57 /** |
46 /** |
58 * Temporary file handle |
47 * Temporary file handle |
59 * |
48 * |
60 * @var resource |
49 * @var resource |
61 */ |
50 */ |
62 private $_temporaryFileHandle = null; |
51 protected $_temporaryFileHandle = null; |
63 |
52 |
64 /** |
53 /** |
65 * Blob storage client |
54 * Blob storage client |
66 * |
55 * |
67 * @var Zend_Service_WindowsAzure_Storage_Blob |
56 * @var Zend_Service_WindowsAzure_Storage_Blob |
68 */ |
57 */ |
69 private $_storageClient = null; |
58 protected $_storageClient = null; |
70 |
59 |
71 /** |
60 /** |
72 * Write mode? |
61 * Write mode? |
73 * |
62 * |
74 * @var boolean |
63 * @var boolean |
75 */ |
64 */ |
76 private $_writeMode = false; |
65 protected $_writeMode = false; |
77 |
66 |
78 /** |
67 /** |
79 * List of blobs |
68 * List of blobs |
80 * |
69 * |
81 * @var array |
70 * @var array |
82 */ |
71 */ |
83 private $_blobs = null; |
72 protected $_blobs = null; |
84 |
73 |
85 /** |
74 /** |
86 * Retrieve storage client for this stream type |
75 * Retrieve storage client for this stream type |
87 * |
76 * |
88 * @param string $path |
77 * @param string $path |
89 * @return Zend_Service_WindowsAzure_Storage_Blob |
78 * @return Zend_Service_WindowsAzure_Storage_Blob |
90 */ |
79 */ |
91 protected function _getStorageClient($path = '') |
80 protected function _getStorageClient($path = '') |
92 { |
81 { |
93 if ($this->_storageClient === null) { |
82 if (is_null($this->_storageClient)) { |
94 $url = explode(':', $path); |
83 $url = explode(':', $path); |
95 if (!$url) { |
84 if (!$url) { |
96 throw new Zend_Service_WindowsAzure_Exception('Could not parse path "' . $path . '".'); |
85 throw new Zend_Service_WindowsAzure_Exception('Could not parse path "' . $path . '".'); |
97 } |
86 } |
98 |
87 |
148 * @param string $mode |
137 * @param string $mode |
149 * @param integer $options |
138 * @param integer $options |
150 * @param string $opened_path |
139 * @param string $opened_path |
151 * @return boolean |
140 * @return boolean |
152 */ |
141 */ |
153 public function stream_open($path, $mode, $options, $opened_path) |
142 public function stream_open($path, $mode, $options, &$opened_path) |
154 { |
143 { |
155 $this->_fileName = $path; |
144 $this->_fileName = $path; |
156 $this->_temporaryFileName = tempnam(sys_get_temp_dir(), 'azure'); |
145 $this->_temporaryFileName = tempnam(sys_get_temp_dir(), 'azure'); |
157 |
146 |
158 // Check the file can be opened |
147 // Check the file can be opened |
345 { |
334 { |
346 if (!$this->_temporaryFileHandle) { |
335 if (!$this->_temporaryFileHandle) { |
347 return false; |
336 return false; |
348 } |
337 } |
349 |
338 |
|
339 return $this->url_stat($this->_fileName, 0); |
|
340 } |
|
341 |
|
342 /** |
|
343 * Attempt to delete the item |
|
344 * |
|
345 * @param string $path |
|
346 * @return boolean |
|
347 */ |
|
348 public function unlink($path) |
|
349 { |
|
350 $this->_getStorageClient($path)->deleteBlob( |
|
351 $this->_getContainerName($path), |
|
352 $this->_getFileName($path) |
|
353 ); |
|
354 |
|
355 // Clear the stat cache for this path. |
|
356 clearstatcache(true, $path); |
|
357 return true; |
|
358 } |
|
359 |
|
360 /** |
|
361 * Attempt to rename the item |
|
362 * |
|
363 * @param string $path_from |
|
364 * @param string $path_to |
|
365 * @return boolean False |
|
366 */ |
|
367 public function rename($path_from, $path_to) |
|
368 { |
|
369 if ($this->_getContainerName($path_from) != $this->_getContainerName($path_to)) { |
|
370 throw new Zend_Service_WindowsAzure_Exception('Container name can not be changed.'); |
|
371 } |
|
372 |
|
373 if ($this->_getFileName($path_from) == $this->_getContainerName($path_to)) { |
|
374 return true; |
|
375 } |
|
376 |
|
377 $this->_getStorageClient($path_from)->copyBlob( |
|
378 $this->_getContainerName($path_from), |
|
379 $this->_getFileName($path_from), |
|
380 $this->_getContainerName($path_to), |
|
381 $this->_getFileName($path_to) |
|
382 ); |
|
383 $this->_getStorageClient($path_from)->deleteBlob( |
|
384 $this->_getContainerName($path_from), |
|
385 $this->_getFileName($path_from) |
|
386 ); |
|
387 |
|
388 // Clear the stat cache for the affected paths. |
|
389 clearstatcache(true, $path_from); |
|
390 clearstatcache(true, $path_to); |
|
391 return true; |
|
392 } |
|
393 |
|
394 /** |
|
395 * Return array of URL variables |
|
396 * |
|
397 * @param string $path |
|
398 * @param integer $flags |
|
399 * @return array |
|
400 */ |
|
401 public function url_stat($path, $flags) |
|
402 { |
350 $stat = array(); |
403 $stat = array(); |
351 $stat['dev'] = 0; |
404 $stat['dev'] = 0; |
352 $stat['ino'] = 0; |
405 $stat['ino'] = 0; |
353 $stat['mode'] = 0; |
406 $stat['mode'] = 0; |
354 $stat['nlink'] = 0; |
407 $stat['nlink'] = 0; |
362 $stat['blksize'] = 0; |
415 $stat['blksize'] = 0; |
363 $stat['blocks'] = 0; |
416 $stat['blocks'] = 0; |
364 |
417 |
365 $info = null; |
418 $info = null; |
366 try { |
419 try { |
367 $info = $this->_getStorageClient($this->_fileName)->getBlobInstance( |
|
368 $this->_getContainerName($this->_fileName), |
|
369 $this->_getFileName($this->_fileName) |
|
370 ); |
|
371 } catch (Zend_Service_WindowsAzure_Exception $ex) { |
|
372 // Unexisting file... |
|
373 } |
|
374 if ($info !== null) { |
|
375 $stat['size'] = $info->Size; |
|
376 $stat['atime'] = time(); |
|
377 } |
|
378 |
|
379 return $stat; |
|
380 } |
|
381 |
|
382 /** |
|
383 * Attempt to delete the item |
|
384 * |
|
385 * @param string $path |
|
386 * @return boolean |
|
387 */ |
|
388 public function unlink($path) |
|
389 { |
|
390 $this->_getStorageClient($path)->deleteBlob( |
|
391 $this->_getContainerName($path), |
|
392 $this->_getFileName($path) |
|
393 ); |
|
394 } |
|
395 |
|
396 /** |
|
397 * Attempt to rename the item |
|
398 * |
|
399 * @param string $path_from |
|
400 * @param string $path_to |
|
401 * @return boolean False |
|
402 */ |
|
403 public function rename($path_from, $path_to) |
|
404 { |
|
405 if ($this->_getContainerName($path_from) != $this->_getContainerName($path_to)) { |
|
406 throw new Zend_Service_WindowsAzure_Exception('Container name can not be changed.'); |
|
407 } |
|
408 |
|
409 if ($this->_getFileName($path_from) == $this->_getContainerName($path_to)) { |
|
410 return true; |
|
411 } |
|
412 |
|
413 $this->_getStorageClient($path_from)->copyBlob( |
|
414 $this->_getContainerName($path_from), |
|
415 $this->_getFileName($path_from), |
|
416 $this->_getContainerName($path_to), |
|
417 $this->_getFileName($path_to) |
|
418 ); |
|
419 $this->_getStorageClient($path_from)->deleteBlob( |
|
420 $this->_getContainerName($path_from), |
|
421 $this->_getFileName($path_from) |
|
422 ); |
|
423 return true; |
|
424 } |
|
425 |
|
426 /** |
|
427 * Return array of URL variables |
|
428 * |
|
429 * @param string $path |
|
430 * @param integer $flags |
|
431 * @return array |
|
432 */ |
|
433 public function url_stat($path, $flags) |
|
434 { |
|
435 $stat = array(); |
|
436 $stat['dev'] = 0; |
|
437 $stat['ino'] = 0; |
|
438 $stat['mode'] = 0; |
|
439 $stat['nlink'] = 0; |
|
440 $stat['uid'] = 0; |
|
441 $stat['gid'] = 0; |
|
442 $stat['rdev'] = 0; |
|
443 $stat['size'] = 0; |
|
444 $stat['atime'] = 0; |
|
445 $stat['mtime'] = 0; |
|
446 $stat['ctime'] = 0; |
|
447 $stat['blksize'] = 0; |
|
448 $stat['blocks'] = 0; |
|
449 |
|
450 $info = null; |
|
451 try { |
|
452 $info = $this->_getStorageClient($path)->getBlobInstance( |
420 $info = $this->_getStorageClient($path)->getBlobInstance( |
453 $this->_getContainerName($path), |
421 $this->_getContainerName($path), |
454 $this->_getFileName($path) |
422 $this->_getFileName($path) |
455 ); |
423 ); |
|
424 $stat['size'] = $info->Size; |
|
425 |
|
426 // Set the modification time and last modified to the Last-Modified header. |
|
427 $lastmodified = strtotime($info->LastModified); |
|
428 $stat['mtime'] = $lastmodified; |
|
429 $stat['ctime'] = $lastmodified; |
|
430 |
|
431 // Entry is a regular file. |
|
432 $stat['mode'] = 0100000; |
|
433 |
|
434 return array_values($stat) + $stat; |
456 } catch (Zend_Service_WindowsAzure_Exception $ex) { |
435 } catch (Zend_Service_WindowsAzure_Exception $ex) { |
457 // Unexisting file... |
436 // Unexisting file... |
458 } |
437 return false; |
459 if ($info !== null) { |
438 } |
460 $stat['size'] = $info->Size; |
|
461 $stat['atime'] = time(); |
|
462 } |
|
463 |
|
464 return $stat; |
|
465 } |
439 } |
466 |
440 |
467 /** |
441 /** |
468 * Create a new directory |
442 * Create a new directory |
469 * |
443 * |
496 * @return boolean |
471 * @return boolean |
497 */ |
472 */ |
498 public function rmdir($path, $options) |
473 public function rmdir($path, $options) |
499 { |
474 { |
500 if ($this->_getContainerName($path) == $this->_getFileName($path)) { |
475 if ($this->_getContainerName($path) == $this->_getFileName($path)) { |
|
476 // Clear the stat cache so that affected paths are refreshed. |
|
477 clearstatcache(); |
|
478 |
501 // Delete container |
479 // Delete container |
502 try { |
480 try { |
503 $this->_getStorageClient($path)->deleteContainer( |
481 $this->_getStorageClient($path)->deleteContainer( |
504 $this->_getContainerName($path) |
482 $this->_getContainerName($path) |
505 ); |
483 ); |
|
484 return true; |
506 } catch (Zend_Service_WindowsAzure_Exception $ex) { |
485 } catch (Zend_Service_WindowsAzure_Exception $ex) { |
507 return false; |
486 return false; |
508 } |
487 } |
509 } else { |
488 } else { |
510 throw new Zend_Service_WindowsAzure_Exception('rmdir() with multiple levels is not supported on Windows Azure Blob Storage.'); |
489 throw new Zend_Service_WindowsAzure_Exception('rmdir() with multiple levels is not supported on Windows Azure Blob Storage.'); |