File indexing completed on 2025-01-26 05:24:52

0001 <?php
0002 /**
0003  * LICENSE
0004  *
0005  * This source file is subject to the new BSD license that is bundled
0006  * with this package in the file LICENSE.txt.
0007  * It is also available through the world-wide-web at this URL:
0008  * http://framework.zend.com/license/new-bsd
0009  * If you did not receive a copy of the license and are unable to
0010  * obtain it through the world-wide-web, please send an email
0011  * to license@zend.com so we can send you a copy immediately.
0012  *
0013  * @category   Zend
0014  * @package    Zend_Cloud_StorageService
0015  * @subpackage Adapter
0016  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0017  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0018  */
0019 
0020 // require_once 'Zend/Cloud/StorageService/Adapter.php';
0021 // require_once 'Zend/Cloud/StorageService/Exception.php';
0022 // require_once 'Zend/Service/Rackspace/Files.php';
0023 // require_once 'Zend/Service/Rackspace/Exception.php';
0024 
0025 /**
0026  * Adapter for Rackspace cloud storage
0027  *
0028  * @category   Zend
0029  * @package    Zend_Cloud_StorageService
0030  * @subpackage Adapter
0031  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0032  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0033  */
0034 class Zend_Cloud_StorageService_Adapter_Rackspace
0035     implements Zend_Cloud_StorageService_Adapter
0036 {
0037     const USER                = 'user';
0038     const API_KEY             = 'key';
0039     const REMOTE_CONTAINER    = 'container';
0040     const DELETE_METADATA_KEY = 'ZF_metadata_deleted';
0041     
0042     /**
0043      * The Rackspace adapter
0044      * @var Zend_Service_Rackspace_Files
0045      */
0046     protected $_rackspace;
0047 
0048     /**
0049      * Container in which files are stored
0050      * @var string
0051      */
0052     protected $_container = 'default';
0053     
0054     /**
0055      * Constructor
0056      *
0057      * @param  array|Traversable $options
0058      * @return void
0059      */
0060     function __construct($options = array())
0061     {
0062         if ($options instanceof Zend_Config) {
0063             $options = $options->toArray();
0064         }
0065 
0066         if (!is_array($options) || empty($options)) {
0067             throw new Zend_Cloud_StorageService_Exception('Invalid options provided');
0068         }
0069 
0070         try {
0071             $this->_rackspace = new Zend_Service_Rackspace_Files($options[self::USER], $options[self::API_KEY]);
0072         } catch (Zend_Service_Rackspace_Exception $e) {
0073             throw new Zend_Cloud_StorageService_Exception('Error on create: '.$e->getMessage(), $e->getCode(), $e);
0074         }
0075         
0076         if (isset($options[self::HTTP_ADAPTER])) {
0077             $this->_rackspace->getHttpClient()->setAdapter($options[self::HTTP_ADAPTER]);
0078         }
0079         if (!empty($options[self::REMOTE_CONTAINER])) {
0080             $this->_container = $options[self::REMOTE_CONTAINER];
0081         }    
0082     }
0083 
0084      /**
0085      * Get an item from the storage service.
0086      *
0087      * @param  string $path
0088      * @param  array $options
0089      * @return mixed
0090      */
0091     public function fetchItem($path, $options = null)
0092     {
0093         $item = $this->_rackspace->getObject($this->_container,$path, $options);
0094         if (!$this->_rackspace->isSuccessful() && ($this->_rackspace->getErrorCode()!='404')) {
0095             throw new Zend_Cloud_StorageService_Exception('Error on fetch: '.$this->_rackspace->getErrorMsg());
0096         }
0097         if (!empty($item)) {
0098             return $item->getContent();
0099         } else {
0100             return false;
0101         }
0102     }
0103 
0104     /**
0105      * Store an item in the storage service.
0106      * 
0107      * @param  string $destinationPath
0108      * @param  mixed $data
0109      * @param  array $options
0110      * @return void
0111      */
0112     public function storeItem($destinationPath, $data, $options = null)
0113     {
0114         $this->_rackspace->storeObject($this->_container,$destinationPath,$data,$options);
0115         if (!$this->_rackspace->isSuccessful()) {
0116             throw new Zend_Cloud_StorageService_Exception('Error on store: '.$this->_rackspace->getErrorMsg());
0117         }
0118     }
0119 
0120     /**
0121      * Delete an item in the storage service.
0122      *
0123      * @param  string $path
0124      * @param  array $options
0125      * @return void
0126      */
0127     public function deleteItem($path, $options = null)
0128     {
0129         $this->_rackspace->deleteObject($this->_container,$path);
0130         if (!$this->_rackspace->isSuccessful()) {
0131             throw new Zend_Cloud_StorageService_Exception('Error on delete: '.$this->_rackspace->getErrorMsg());
0132         }
0133     }
0134 
0135     /**
0136      * Copy an item in the storage service to a given path.
0137      *
0138      * @param  string $sourcePath
0139      * @param  string $destination path
0140      * @param  array $options
0141      * @return void
0142      */
0143     public function copyItem($sourcePath, $destinationPath, $options = null)
0144     {
0145         $this->_rackspace->copyObject($this->_container,$sourcePath,$this->_container,$destinationPath,$options);
0146         if (!$this->_rackspace->isSuccessful()) {
0147             throw new Zend_Cloud_StorageService_Exception('Error on copy: '.$this->_rackspace->getErrorMsg());
0148         }
0149     }
0150 
0151     /**
0152      * Move an item in the storage service to a given path.
0153      * WARNING: This operation is *very* expensive for services that do not
0154      * support moving an item natively.
0155      *
0156      * @param  string $sourcePath
0157      * @param  string $destination path
0158      * @param  array $options
0159      * @return void
0160      */
0161     public function moveItem($sourcePath, $destinationPath, $options = null)
0162     {
0163         try {
0164             $this->copyItem($sourcePath, $destinationPath, $options);
0165         } catch (Zend_Service_Rackspace_Exception $e) {
0166             throw new Zend_Cloud_StorageService_Exception('Error on move: '.$e->getMessage());
0167         }    
0168         try {
0169             $this->deleteItem($sourcePath);
0170         } catch (Zend_Service_Rackspace_Exception $e) {
0171             $this->deleteItem($destinationPath);
0172             throw new Zend_Cloud_StorageService_Exception('Error on move: '.$e->getMessage());
0173         }    
0174     }
0175 
0176     /**
0177      * Rename an item in the storage service to a given name.
0178      * 
0179      * @param  string $path
0180      * @param  string $name
0181      * @param  array $options
0182      * @return void
0183      */
0184     public function renameItem($path, $name, $options = null)
0185     {
0186         // require_once 'Zend/Cloud/OperationNotAvailableException.php';
0187         throw new Zend_Cloud_OperationNotAvailableException('Renaming not implemented');
0188     }
0189 
0190     /**
0191      * Get a key/value array of metadata for the given path.
0192      *
0193      * @param  string $path
0194      * @param  array $options
0195      * @return array An associative array of key/value pairs specifying the metadata for this object.
0196      *                  If no metadata exists, an empty array is returned.
0197      */
0198     public function fetchMetadata($path, $options = null)
0199     {
0200         $result = $this->_rackspace->getMetadataObject($this->_container,$path);
0201         if (!$this->_rackspace->isSuccessful()) {
0202             throw new Zend_Cloud_StorageService_Exception('Error on fetch metadata: '.$this->_rackspace->getErrorMsg());
0203         }
0204         $metadata = array();
0205         if (isset($result['metadata'])) {
0206             $metadata =  $result['metadata'];
0207         }
0208         // delete the self::DELETE_METADATA_KEY - this is a trick to remove all
0209         // the metadata information of an object (see deleteMetadata). 
0210         // Rackspace doesn't have an API to remove the metadata of an object
0211         unset($metadata[self::DELETE_METADATA_KEY]);
0212         return $metadata;
0213     }
0214 
0215     /**
0216      * Store a key/value array of metadata at the given path.
0217      * WARNING: This operation overwrites any metadata that is located at
0218      * $destinationPath.
0219      *
0220      * @param  string $destinationPath
0221      * @param  array  $metadata        associative array specifying the key/value pairs for the metadata.
0222      * @param  array  $options
0223      * @return void
0224      */
0225     public function storeMetadata($destinationPath, $metadata, $options = null)
0226     {
0227         $this->_rackspace->setMetadataObject($this->_container, $destinationPath, $metadata);
0228         if (!$this->_rackspace->isSuccessful()) {
0229             throw new Zend_Cloud_StorageService_Exception('Error on store metadata: '.$this->_rackspace->getErrorMsg());
0230         }
0231      }
0232 
0233     /**
0234      * Delete a key/value array of metadata at the given path.
0235      *
0236      * @param  string $path
0237      * @param  array $metadata - An associative array specifying the key/value pairs for the metadata
0238      *                           to be deleted.  If null, all metadata associated with the object will
0239      *                           be deleted.
0240      * @param  array $options
0241      * @return void
0242      */
0243     public function deleteMetadata($path, $metadata = null, $options = null)
0244     {
0245         if (empty($metadata)) {
0246             $newMetadata = array(self::DELETE_METADATA_KEY => true);
0247             try {
0248                 $this->storeMetadata($path, $newMetadata);
0249             } catch (Zend_Service_Rackspace_Exception $e) {
0250                 throw new Zend_Cloud_StorageService_Exception('Error on delete metadata: '.$e->getMessage());
0251             }
0252         } else {
0253             try {
0254                 $oldMetadata = $this->fetchMetadata($path);
0255             } catch (Zend_Service_Rackspace_Exception $e) {
0256                 throw new Zend_Cloud_StorageService_Exception('Error on delete metadata: '.$e->getMessage());
0257             }
0258             $newMetadata = array_diff_assoc($oldMetadata, $metadata);
0259             try {
0260                 $this->storeMetadata($path, $newMetadata);
0261             } catch (Zend_Service_Rackspace_Exception $e) {
0262                 throw new Zend_Cloud_StorageService_Exception('Error on delete metadata: '.$e->getMessage());
0263             }
0264         }
0265     }
0266 
0267     /*
0268      * Recursively traverse all the folders and build an array that contains
0269      * the path names for each folder.
0270      *
0271      * @param  string $path        folder path to get the list of folders from.
0272      * @param  array& $resultArray reference to the array that contains the path names
0273      *                             for each folder.
0274      * @return void
0275      */
0276     private function getAllFolders($path, &$resultArray)
0277     {
0278         if (!empty($path)) {
0279             $options = array (
0280                 'prefix'    => $path
0281             );
0282         }    
0283         $files = $this->_rackspace->getObjects($this->_container,$options);
0284         if (!$this->_rackspace->isSuccessful()) {
0285             throw new Zend_Cloud_StorageService_Exception('Error on get all folders: '.$this->_rackspace->getErrorMsg());
0286         }
0287         $resultArray = array();
0288         foreach ($files as $file) {
0289             $resultArray[dirname($file->getName())] = true;
0290         }
0291         $resultArray = array_keys($resultArray);
0292     }
0293 
0294     /**
0295      * Return an array of the items contained in the given path.  The items
0296      * returned are the files or objects that in the specified path.
0297      *
0298      * @param  string $path
0299      * @param  array  $options
0300      * @return array
0301      */
0302     public function listItems($path, $options = null)
0303     {
0304         if (!empty($path)) {
0305             $options = array (
0306                 'prefix'    => $path
0307             );
0308         }   
0309         
0310         $files = $this->_rackspace->getObjects($this->_container,$options);
0311         if (!$this->_rackspace->isSuccessful()) {
0312             throw new Zend_Cloud_StorageService_Exception('Error on list items: '.$this->_rackspace->getErrorMsg());
0313         }
0314         $resultArray = array();
0315         if (!empty($files)) {
0316             foreach ($files as $file) {
0317                 $resultArray[] = $file->getName();
0318             }
0319         }    
0320         return $resultArray;
0321     }
0322 
0323     /**
0324      * Get the concrete client.
0325      *
0326      * @return Zend_Service_Rackspace_File
0327      */
0328     public function getClient()
0329     {
0330          return $this->_rackspace;
0331     }
0332 }