web/lib/Zend/Cloud/StorageService/Adapter/S3.php
changeset 807 877f952ae2bd
parent 207 621fa6caec0c
child 1230 68c69c656a2c
equal deleted inserted replaced
805:5e7a0fedabdf 807:877f952ae2bd
    11  * to license@zend.com so we can send you a copy immediately.
    11  * to license@zend.com so we can send you a copy immediately.
    12  *
    12  *
    13  * @category   Zend
    13  * @category   Zend
    14  * @package    Zend_Cloud
    14  * @package    Zend_Cloud
    15  * @subpackage StorageService
    15  * @subpackage StorageService
    16  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
    16  * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
    17  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    17  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    18  */
    18  */
    19 
    19 
    20 require_once 'Zend/Service/Amazon/S3.php';
    20 require_once 'Zend/Service/Amazon/S3.php';
    21 require_once 'Zend/Cloud/StorageService/Adapter.php';
    21 require_once 'Zend/Cloud/StorageService/Adapter.php';
    25  * S3 adapter for unstructured cloud storage.
    25  * S3 adapter for unstructured cloud storage.
    26  *
    26  *
    27  * @category   Zend
    27  * @category   Zend
    28  * @package    Zend_Cloud
    28  * @package    Zend_Cloud
    29  * @subpackage StorageService
    29  * @subpackage StorageService
    30  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
    30  * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
    31  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    31  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    32  */
    32  */
    33 class Zend_Cloud_StorageService_Adapter_S3 
    33 class Zend_Cloud_StorageService_Adapter_S3
    34     implements Zend_Cloud_StorageService_Adapter
    34     implements Zend_Cloud_StorageService_Adapter
    35 {
    35 {
    36     /*
    36     /*
    37      * Options array keys for the S3 adapter.
    37      * Options array keys for the S3 adapter.
    38      */
    38      */
    39     const BUCKET_NAME      = 'bucket_name';
    39     const BUCKET_NAME      = 'bucket_name';
    40     const BUCKET_AS_DOMAIN = 'bucket_as_domain?';
    40     const BUCKET_AS_DOMAIN = 'bucket_as_domain?';
    41     const FETCH_STREAM     = 'fetch_stream';
    41     const FETCH_STREAM     = 'fetch_stream';
    42     const METADATA         = 'metadata';
    42     const METADATA         = 'metadata';
    43     
    43 
    44     /**
    44     /**
    45      * AWS constants
    45      * AWS constants
    46      */
    46      */
    47     const AWS_ACCESS_KEY   = 'aws_accesskey';
    47     const AWS_ACCESS_KEY   = 'aws_accesskey';
    48     const AWS_SECRET_KEY   = 'aws_secretkey';
    48     const AWS_SECRET_KEY   = 'aws_secretkey';
    55     protected $_defaultBucketName = null;
    55     protected $_defaultBucketName = null;
    56     protected $_defaultBucketAsDomain = false;
    56     protected $_defaultBucketAsDomain = false;
    57 
    57 
    58     /**
    58     /**
    59      * Constructor
    59      * Constructor
    60      * 
    60      *
    61      * @param  array|Zend_Config $options 
    61      * @param  array|Zend_Config $options
    62      * @return void
    62      * @return void
    63      */
    63      */
    64     public function __construct($options = array()) 
    64     public function __construct($options = array())
    65     {
    65     {
    66         if ($options instanceof Zend_Config) {
    66         if ($options instanceof Zend_Config) {
    67             $options = $options->toArray();
    67             $options = $options->toArray();
    68         }
    68         }
    69 
    69 
    76         }
    76         }
    77 
    77 
    78         try {
    78         try {
    79             $this->_s3 = new Zend_Service_Amazon_S3($options[self::AWS_ACCESS_KEY],
    79             $this->_s3 = new Zend_Service_Amazon_S3($options[self::AWS_ACCESS_KEY],
    80                                                 $options[self::AWS_SECRET_KEY]);
    80                                                 $options[self::AWS_SECRET_KEY]);
    81         } catch (Zend_Service_Amazon_S3_Exception  $e) { 
    81         } catch (Zend_Service_Amazon_S3_Exception  $e) {
    82             throw new Zend_Cloud_StorageService_Exception('Error on create: '.$e->getMessage(), $e->getCode(), $e);
    82             throw new Zend_Cloud_StorageService_Exception('Error on create: '.$e->getMessage(), $e->getCode(), $e);
    83         }
    83         }
    84                                                 
    84 
    85         if (isset($options[self::HTTP_ADAPTER])) {
    85         if (isset($options[self::HTTP_ADAPTER])) {
    86             $this->_s3->getHttpClient()->setAdapter($options[self::HTTP_ADAPTER]);
    86             $this->_s3->getHttpClient()->setAdapter($options[self::HTTP_ADAPTER]);
    87         } 
    87         }
    88 
    88 
    89         if (isset($options[self::BUCKET_NAME])) {
    89         if (isset($options[self::BUCKET_NAME])) {
    90             $this->_defaultBucketName = $options[self::BUCKET_NAME];
    90             $this->_defaultBucketName = $options[self::BUCKET_NAME];
    91         }
    91         }
    92 
    92 
   102      *
   102      *
   103      * @param  string $path
   103      * @param  string $path
   104      * @param  array $options
   104      * @param  array $options
   105      * @return string
   105      * @return string
   106      */
   106      */
   107     public function fetchItem($path, $options = array()) 
   107     public function fetchItem($path, $options = array())
   108     {
   108     {
   109         $fullPath = $this->_getFullPath($path, $options);
   109         $fullPath = $this->_getFullPath($path, $options);
   110         try {
   110         try {
   111             if (!empty($options[self::FETCH_STREAM])) {
   111             if (!empty($options[self::FETCH_STREAM])) {
   112                 return $this->_s3->getObjectStream($fullPath, $options[self::FETCH_STREAM]);
   112                 return $this->_s3->getObjectStream($fullPath, $options[self::FETCH_STREAM]);
   113             } else {
   113             } else {
   114                 return $this->_s3->getObject($fullPath);
   114                 return $this->_s3->getObject($fullPath);
   115             }
   115             }
   116         } catch (Zend_Service_Amazon_S3_Exception  $e) { 
   116         } catch (Zend_Service_Amazon_S3_Exception  $e) {
   117             throw new Zend_Cloud_StorageService_Exception('Error on fetch: '.$e->getMessage(), $e->getCode(), $e);
   117             throw new Zend_Cloud_StorageService_Exception('Error on fetch: '.$e->getMessage(), $e->getCode(), $e);
   118         }
   118         }
   119     }
   119     }
   120 
   120 
   121     /**
   121     /**
   129      * @param string $destinationPath
   129      * @param string $destinationPath
   130      * @param string|resource $data
   130      * @param string|resource $data
   131      * @param  array $options
   131      * @param  array $options
   132      * @return void
   132      * @return void
   133      */
   133      */
   134     public function storeItem($destinationPath, $data, $options = array()) 
   134     public function storeItem($destinationPath, $data, $options = array())
   135     {
   135     {
   136         try {
   136         try {
   137             $fullPath = $this->_getFullPath($destinationPath, $options);
   137             $fullPath = $this->_getFullPath($destinationPath, $options);
   138             return $this->_s3->putObject(
   138             return $this->_s3->putObject(
   139                 $fullPath, 
   139                 $fullPath,
   140                 $data, 
   140                 $data,
   141                 empty($options[self::METADATA]) ? null : $options[self::METADATA]
   141                 empty($options[self::METADATA]) ? null : $options[self::METADATA]
   142             );
   142             );
   143         } catch (Zend_Service_Amazon_S3_Exception  $e) { 
   143         } catch (Zend_Service_Amazon_S3_Exception  $e) {
   144             throw new Zend_Cloud_StorageService_Exception('Error on store: '.$e->getMessage(), $e->getCode(), $e);
   144             throw new Zend_Cloud_StorageService_Exception('Error on store: '.$e->getMessage(), $e->getCode(), $e);
   145         }
   145         }
   146     }
   146     }
   147 
   147 
   148     /**
   148     /**
   150      *
   150      *
   151      * @param  string $path
   151      * @param  string $path
   152      * @param  array $options
   152      * @param  array $options
   153      * @return void
   153      * @return void
   154      */
   154      */
   155     public function deleteItem($path, $options = array()) 
   155     public function deleteItem($path, $options = array())
   156     {    
   156     {
   157         try {
   157         try {
   158             $this->_s3->removeObject($this->_getFullPath($path, $options));
   158             $this->_s3->removeObject($this->_getFullPath($path, $options));
   159         } catch (Zend_Service_Amazon_S3_Exception  $e) { 
   159         } catch (Zend_Service_Amazon_S3_Exception  $e) {
   160             throw new Zend_Cloud_StorageService_Exception('Error on delete: '.$e->getMessage(), $e->getCode(), $e);
   160             throw new Zend_Cloud_StorageService_Exception('Error on delete: '.$e->getMessage(), $e->getCode(), $e);
   161         }
   161         }
   162     }
   162     }
   163 
   163 
   164     /**
   164     /**
   172      * @param  string $sourcePath
   172      * @param  string $sourcePath
   173      * @param  string $destination path
   173      * @param  string $destination path
   174      * @param  array $options
   174      * @param  array $options
   175      * @return void
   175      * @return void
   176      */
   176      */
   177     public function copyItem($sourcePath, $destinationPath, $options = array()) 
   177     public function copyItem($sourcePath, $destinationPath, $options = array())
   178     {
   178     {
   179         try {
   179         try {
   180             // TODO We *really* need to add support for object copying in the S3 adapter
   180             $fullSourcePath = $this->_getFullPath($sourcePath, $options);
   181             $item = $this->fetch($_getFullPath(sourcePath), $options);
   181             $fullDestPath   = $this->_getFullPath($destinationPath, $options);
   182             $this->storeItem($item, $destinationPath, $options);
   182             return $this->_s3->copyObject(
   183         } catch (Zend_Service_Amazon_S3_Exception  $e) { 
   183                 $fullSourcePath,
       
   184                 $fullDestPath,
       
   185                 empty($options[self::METADATA]) ? null : $options[self::METADATA]
       
   186             );
       
   187 
       
   188         } catch (Zend_Service_Amazon_S3_Exception  $e) {
   184             throw new Zend_Cloud_StorageService_Exception('Error on copy: '.$e->getMessage(), $e->getCode(), $e);
   189             throw new Zend_Cloud_StorageService_Exception('Error on copy: '.$e->getMessage(), $e->getCode(), $e);
   185         }
   190         }
   186     }
   191     }
   187 
   192 
   188     /**
   193     /**
   193      * @param  string $sourcePath
   198      * @param  string $sourcePath
   194      * @param  string $destination path
   199      * @param  string $destination path
   195      * @param  array $options
   200      * @param  array $options
   196      * @return void
   201      * @return void
   197      */
   202      */
   198     public function moveItem($sourcePath, $destinationPath, $options = array()) 
   203     public function moveItem($sourcePath, $destinationPath, $options = array())
   199     {
   204     {
   200         try {
   205         try {
   201             $fullSourcePath = $this->_getFullPath($sourcePath, $options);
   206             $fullSourcePath = $this->_getFullPath($sourcePath, $options);
   202             $fullDestPath   = $this->_getFullPath($destinationPath, $options);
   207             $fullDestPath   = $this->_getFullPath($destinationPath, $options);
   203             return $this->_s3->moveObject(
   208             return $this->_s3->moveObject(
   204                 $fullSourcePath,
   209                 $fullSourcePath,
   205                 $fullDestPath,
   210                 $fullDestPath,
   206                 empty($options[self::METADATA]) ? null : $options[self::METADATA]
   211                 empty($options[self::METADATA]) ? null : $options[self::METADATA]
   207             );
   212             );
   208         } catch (Zend_Service_Amazon_S3_Exception  $e) { 
   213         } catch (Zend_Service_Amazon_S3_Exception  $e) {
   209             throw new Zend_Cloud_StorageService_Exception('Error on move: '.$e->getMessage(), $e->getCode(), $e);
   214             throw new Zend_Cloud_StorageService_Exception('Error on move: '.$e->getMessage(), $e->getCode(), $e);
   210         }
   215         }
   211      }
   216      }
   212 
   217 
   213     /**
   218     /**
   217      * @param  string $path
   222      * @param  string $path
   218      * @param  string $name
   223      * @param  string $name
   219      * @param  array $options
   224      * @param  array $options
   220      * @return void
   225      * @return void
   221      */
   226      */
   222     public function renameItem($path, $name, $options = null) 
   227     public function renameItem($path, $name, $options = null)
   223     {
   228     {
   224         require_once 'Zend/Cloud/OperationNotAvailableException.php';
   229         require_once 'Zend/Cloud/OperationNotAvailableException.php';
   225         throw new Zend_Cloud_OperationNotAvailableException('Rename not implemented');
   230         throw new Zend_Cloud_OperationNotAvailableException('Rename not implemented');
   226     }
   231     }
   227 
   232 
   233      *
   238      *
   234      * @param  string $path Must be a directory
   239      * @param  string $path Must be a directory
   235      * @param  array $options
   240      * @param  array $options
   236      * @return array A list of item names
   241      * @return array A list of item names
   237      */
   242      */
   238     public function listItems($path, $options = null) 
   243     public function listItems($path, $options = null)
   239     {
   244     {
   240         try {
   245         try {
   241             // TODO Support 'prefix' parameter for Zend_Service_Amazon_S3::getObjectsByBucket()
   246             // TODO Support 'prefix' parameter for Zend_Service_Amazon_S3::getObjectsByBucket()
   242             return $this->_s3->getObjectsByBucket($this->_defaultBucketName);
   247             return $this->_s3->getObjectsByBucket($this->_defaultBucketName);
   243         } catch (Zend_Service_Amazon_S3_Exception  $e) { 
   248         } catch (Zend_Service_Amazon_S3_Exception  $e) {
   244             throw new Zend_Cloud_StorageService_Exception('Error on list: '.$e->getMessage(), $e->getCode(), $e);
   249             throw new Zend_Cloud_StorageService_Exception('Error on list: '.$e->getMessage(), $e->getCode(), $e);
   245         }
   250         }
   246     }
   251     }
   247 
   252 
   248     /**
   253     /**
   250      *
   255      *
   251      * @param  string $path
   256      * @param  string $path
   252      * @param  array $options
   257      * @param  array $options
   253      * @return array
   258      * @return array
   254      */
   259      */
   255     public function fetchMetadata($path, $options = array()) 
   260     public function fetchMetadata($path, $options = array())
   256     {
   261     {
   257         try {
   262         try {
   258             return $this->_s3->getInfo($this->_getFullPath($path, $options));
   263             return $this->_s3->getInfo($this->_getFullPath($path, $options));
   259         } catch (Zend_Service_Amazon_S3_Exception  $e) { 
   264         } catch (Zend_Service_Amazon_S3_Exception  $e) {
   260             throw new Zend_Cloud_StorageService_Exception('Error on fetch: '.$e->getMessage(), $e->getCode(), $e);
   265             throw new Zend_Cloud_StorageService_Exception('Error on fetch: '.$e->getMessage(), $e->getCode(), $e);
   261         }
   266         }
   262     }
   267     }
   263 
   268 
   264     /**
   269     /**
   268      *
   273      *
   269      * @param  string $destinationPath
   274      * @param  string $destinationPath
   270      * @param  array $options
   275      * @param  array $options
   271      * @return void
   276      * @return void
   272      */
   277      */
   273     public function storeMetadata($destinationPath, $metadata, $options = array()) 
   278     public function storeMetadata($destinationPath, $metadata, $options = array())
   274     {
   279     {
   275         require_once 'Zend/Cloud/OperationNotAvailableException.php';
   280         require_once 'Zend/Cloud/OperationNotAvailableException.php';
   276         throw new Zend_Cloud_OperationNotAvailableException('Storing separate metadata is not supported, use storeItem() with \'metadata\' option key');
   281         throw new Zend_Cloud_OperationNotAvailableException('Storing separate metadata is not supported, use storeItem() with \'metadata\' option key');
   277     }
   282     }
   278 
   283 
   281      *
   286      *
   282      * @param  string $path
   287      * @param  string $path
   283      * @param  array $options
   288      * @param  array $options
   284      * @return void
   289      * @return void
   285      */
   290      */
   286     public function deleteMetadata($path) 
   291     public function deleteMetadata($path)
   287     {
   292     {
   288         require_once 'Zend/Cloud/OperationNotAvailableException.php';
   293         require_once 'Zend/Cloud/OperationNotAvailableException.php';
   289         throw new Zend_Cloud_OperationNotAvailableException('Deleting metadata not supported');
   294         throw new Zend_Cloud_OperationNotAvailableException('Deleting metadata not supported');
   290     }
   295     }
   291 
   296 
   292     /**
   297     /**
   293      * Get full path, including bucket, for an object
   298      * Get full path, including bucket, for an object
   294      * 
   299      *
   295      * @param  string $path 
   300      * @param  string $path
   296      * @param  array $options 
   301      * @param  array $options
   297      * @return void
   302      * @return void
   298      */
   303      */
   299     protected function _getFullPath($path, $options) 
   304     protected function _getFullPath($path, $options)
   300     {
   305     {
   301         if (isset($options[self::BUCKET_NAME])) {
   306         if (isset($options[self::BUCKET_NAME])) {
   302             $bucket = $options[self::BUCKET_NAME];
   307             $bucket = $options[self::BUCKET_NAME];
   303         } else if (isset($this->_defaultBucketName)) {
   308         } else if (isset($this->_defaultBucketName)) {
   304             $bucket = $this->_defaultBucketName;
   309             $bucket = $this->_defaultBucketName;
   320      * Get the concrete client.
   325      * Get the concrete client.
   321      * @return Zend_Service_Amazon_S3
   326      * @return Zend_Service_Amazon_S3
   322      */
   327      */
   323     public function getClient()
   328     public function getClient()
   324     {
   329     {
   325          return $this->_s3;       
   330          return $this->_s3;
   326     }
   331     }
   327 }
   332 }