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 0015 * @subpackage StorageService 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/Service/WindowsAzure/Storage/Blob.php'; 0022 // require_once 'Zend/Cloud/StorageService/Exception.php'; 0023 0024 /** 0025 * 0026 * Windows Azure Blob Service abstraction 0027 * 0028 * @category Zend 0029 * @package Zend_Cloud 0030 * @subpackage StorageService 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_WindowsAzure 0035 implements Zend_Cloud_StorageService_Adapter 0036 { 0037 const ACCOUNT_NAME = 'storage_accountname'; 0038 const ACCOUNT_KEY = 'storage_accountkey'; 0039 const HOST = "storage_host"; 0040 const PROXY_HOST = "storage_proxy_host"; 0041 const PROXY_PORT = "storage_proxy_port"; 0042 const PROXY_CREDENTIALS = "storage_proxy_credentials"; 0043 const CONTAINER = "storage_container"; 0044 const RETURN_TYPE = 'return_type'; 0045 const RETURN_PATHNAME = 'return_path'; 0046 const RETURN_OPENMODE = 'return_openmode'; 0047 0048 /** return types for fetch */ 0049 const RETURN_PATH = 1; // return filename 0050 const RETURN_STRING = 2; // return data as string 0051 const RETURN_STREAM = 3; // return PHP stream 0052 0053 /** return types for list */ 0054 const RETURN_LIST = 1; // return native list 0055 const RETURN_NAMES = 2; // return only names 0056 0057 const DEFAULT_HOST = Zend_Service_WindowsAzure_Storage::URL_CLOUD_BLOB; 0058 0059 /** 0060 * Storage container to operate on 0061 * 0062 * @var string 0063 */ 0064 protected $_container; 0065 0066 /** 0067 * Storage client 0068 * 0069 * @var Zend_Service_WindowsAzure_Storage_Blob 0070 */ 0071 protected $_storageClient = null; 0072 0073 /** 0074 * Creates a new Zend_Cloud_Storage_WindowsAzure instance 0075 * 0076 * @param array|Zend_Config $options Options for the Zend_Cloud_Storage_WindowsAzure instance 0077 */ 0078 public function __construct($options = array()) 0079 { 0080 if ($options instanceof Zend_Config) { 0081 $options = $options->toArray(); 0082 } 0083 0084 if (!is_array($options)) { 0085 throw new Zend_Cloud_StorageService_Exception('Invalid options provided'); 0086 } 0087 0088 // Build Zend_Service_WindowsAzure_Storage_Blob instance 0089 if (!isset($options[self::HOST])) { 0090 $host = self::DEFAULT_HOST; 0091 } else { 0092 $host = $options[self::HOST]; 0093 } 0094 0095 if (!isset($options[self::ACCOUNT_NAME])) { 0096 throw new Zend_Cloud_StorageService_Exception('No Windows Azure account name provided.'); 0097 } 0098 if (!isset($options[self::ACCOUNT_KEY])) { 0099 throw new Zend_Cloud_StorageService_Exception('No Windows Azure account key provided.'); 0100 } 0101 0102 $this->_storageClient = new Zend_Service_WindowsAzure_Storage_Blob($host, 0103 $options[self::ACCOUNT_NAME], $options[self::ACCOUNT_KEY]); 0104 0105 // Parse other options 0106 if (!empty($options[self::PROXY_HOST])) { 0107 $proxyHost = $options[self::PROXY_HOST]; 0108 $proxyPort = isset($options[self::PROXY_PORT]) ? $options[self::PROXY_PORT] : 8080; 0109 $proxyCredentials = isset($options[self::PROXY_CREDENTIALS]) ? $options[self::PROXY_CREDENTIALS] : ''; 0110 0111 $this->_storageClient->setProxy(true, $proxyHost, $proxyPort, $proxyCredentials); 0112 } 0113 0114 if (isset($options[self::HTTP_ADAPTER])) { 0115 $this->_storageClient->setHttpClientChannel($options[self::HTTP_ADAPTER]); 0116 } 0117 0118 // Set container 0119 $this->_container = $options[self::CONTAINER]; 0120 0121 // Make sure the container exists 0122 if (!$this->_storageClient->containerExists($this->_container)) { 0123 $this->_storageClient->createContainer($this->_container); 0124 } 0125 } 0126 0127 /** 0128 * Get an item from the storage service. 0129 * 0130 * @param string $path 0131 * @param array $options 0132 * @return mixed 0133 */ 0134 public function fetchItem($path, $options = null) 0135 { 0136 // Options 0137 $returnType = self::RETURN_STRING; 0138 $returnPath = tempnam('', 'azr'); 0139 $openMode = 'r'; 0140 0141 // Parse options 0142 if (is_array($options)) { 0143 if (isset($options[self::RETURN_TYPE])) { 0144 $returnType = $options[self::RETURN_TYPE]; 0145 } 0146 0147 if (isset($options[self::RETURN_PATHNAME])) { 0148 $returnPath = $options[self::RETURN_PATHNAME]; 0149 } 0150 0151 if (isset($options[self::RETURN_OPENMODE])) { 0152 $openMode = $options[self::RETURN_OPENMODE]; 0153 } 0154 } 0155 0156 // Fetch the blob 0157 try { 0158 $this->_storageClient->getBlob( 0159 $this->_container, 0160 $path, 0161 $returnPath 0162 ); 0163 } catch (Zend_Service_WindowsAzure_Exception $e) { 0164 if (strpos($e->getMessage(), "does not exist") !== false) { 0165 return false; 0166 } 0167 throw new Zend_Cloud_StorageService_Exception('Error on fetch: '.$e->getMessage(), $e->getCode(), $e); 0168 } 0169 0170 // Return value 0171 if ($returnType == self::RETURN_PATH) { 0172 return $returnPath; 0173 } 0174 if ($returnType == self::RETURN_STRING) { 0175 return file_get_contents($returnPath); 0176 } 0177 if ($returnType == self::RETURN_STREAM) { 0178 return fopen($returnPath, $openMode); 0179 } 0180 } 0181 0182 /** 0183 * Store an item in the storage service. 0184 * WARNING: This operation overwrites any item that is located at 0185 * $destinationPath. 0186 * @param string $destinationPath 0187 * @param mixed $data 0188 * @param array $options 0189 * @return boolean 0190 */ 0191 public function storeItem($destinationPath, $data, $options = null) 0192 { 0193 // Create a temporary file that will be uploaded 0194 $temporaryFilePath = ''; 0195 $removeTemporaryFilePath = false; 0196 0197 if (is_resource($data)) { 0198 $temporaryFilePath = tempnam('', 'azr'); 0199 $fpDestination = fopen($temporaryFilePath, 'w'); 0200 0201 $fpSource = $data; 0202 rewind($fpSource); 0203 while (!feof($fpSource)) { 0204 fwrite($fpDestination, fread($fpSource, 8192)); 0205 } 0206 0207 fclose($fpDestination); 0208 0209 $removeTemporaryFilePath = true; 0210 } elseif (file_exists($data)) { 0211 $temporaryFilePath = $data; 0212 $removeTemporaryFilePath = false; 0213 } else { 0214 $temporaryFilePath = tempnam('', 'azr'); 0215 file_put_contents($temporaryFilePath, $data); 0216 $removeTemporaryFilePath = true; 0217 } 0218 0219 try { 0220 // Upload data 0221 $this->_storageClient->putBlob( 0222 $this->_container, 0223 $destinationPath, 0224 $temporaryFilePath 0225 ); 0226 } catch(Zend_Service_WindowsAzure_Exception $e) { 0227 @unlink($temporaryFilePath); 0228 throw new Zend_Cloud_StorageService_Exception('Error on store: '.$e->getMessage(), $e->getCode(), $e); 0229 } 0230 if ($removeTemporaryFilePath) { 0231 @unlink($temporaryFilePath); 0232 } 0233 } 0234 0235 /** 0236 * Delete an item in the storage service. 0237 * 0238 * @param string $path 0239 * @param array $options 0240 * @return void 0241 */ 0242 public function deleteItem($path, $options = null) 0243 { 0244 try { 0245 $this->_storageClient->deleteBlob( 0246 $this->_container, 0247 $path 0248 ); 0249 } catch (Zend_Service_WindowsAzure_Exception $e) { 0250 throw new Zend_Cloud_StorageService_Exception('Error on delete: '.$e->getMessage(), $e->getCode(), $e); 0251 } 0252 } 0253 0254 /** 0255 * Copy an item in the storage service to a given path. 0256 * 0257 * @param string $sourcePath 0258 * @param string $destinationPath 0259 * @param array $options 0260 * @return void 0261 */ 0262 public function copyItem($sourcePath, $destinationPath, $options = null) 0263 { 0264 try { 0265 $this->_storageClient->copyBlob( 0266 $this->_container, 0267 $sourcePath, 0268 $this->_container, 0269 $destinationPath 0270 ); 0271 } catch (Zend_Service_WindowsAzure_Exception $e) { 0272 throw new Zend_Cloud_StorageService_Exception('Error on copy: '.$e->getMessage(), $e->getCode(), $e); 0273 } 0274 } 0275 0276 /** 0277 * Move an item in the storage service to a given path. 0278 * 0279 * @param string $sourcePath 0280 * @param string $destinationPath 0281 * @param array $options 0282 * @return void 0283 */ 0284 public function moveItem($sourcePath, $destinationPath, $options = null) 0285 { 0286 try { 0287 $this->_storageClient->copyBlob( 0288 $this->_container, 0289 $sourcePath, 0290 $this->_container, 0291 $destinationPath 0292 ); 0293 0294 $this->_storageClient->deleteBlob( 0295 $this->_container, 0296 $sourcePath 0297 ); 0298 } catch (Zend_Service_WindowsAzure_Exception $e) { 0299 throw new Zend_Cloud_StorageService_Exception('Error on move: '.$e->getMessage(), $e->getCode(), $e); 0300 } 0301 0302 } 0303 0304 /** 0305 * Rename an item in the storage service to a given name. 0306 * 0307 * 0308 * @param string $path 0309 * @param string $name 0310 * @param array $options 0311 * @return void 0312 */ 0313 public function renameItem($path, $name, $options = null) 0314 { 0315 return $this->moveItem($path, $name, $options); 0316 } 0317 0318 /** 0319 * List items in the given directory in the storage service 0320 * 0321 * The $path must be a directory 0322 * 0323 * 0324 * @param string $path Must be a directory 0325 * @param array $options 0326 * @return array A list of item names 0327 */ 0328 public function listItems($path, $options = null) 0329 { 0330 // Options 0331 $returnType = self::RETURN_NAMES; // 1: return list of paths, 2: return raw output from underlying provider 0332 0333 // Parse options 0334 if (is_array($options)&& isset($options[self::RETURN_TYPE])) { 0335 $returnType = $options[self::RETURN_TYPE]; 0336 } 0337 0338 try { 0339 // Fetch list 0340 $blobList = $this->_storageClient->listBlobs( 0341 $this->_container, 0342 $path 0343 ); 0344 } catch (Zend_Service_WindowsAzure_Exception $e) { 0345 throw new Zend_Cloud_StorageService_Exception('Error on list: '.$e->getMessage(), $e->getCode(), $e); 0346 } 0347 0348 // Return 0349 if ($returnType == self::RETURN_LIST) { 0350 return $blobList; 0351 } 0352 0353 $returnValue = array(); 0354 foreach ($blobList as $blob) { 0355 $returnValue[] = $blob->Name; 0356 } 0357 0358 return $returnValue; 0359 } 0360 0361 /** 0362 * Get a key/value array of metadata for the given path. 0363 * 0364 * @param string $path 0365 * @param array $options 0366 * @return array 0367 */ 0368 public function fetchMetadata($path, $options = null) 0369 { 0370 try { 0371 return $this->_storageClient->getBlobMetaData( 0372 $this->_container, 0373 $path 0374 ); 0375 } catch (Zend_Service_WindowsAzure_Exception $e) { 0376 if (strpos($e->getMessage(), "could not be accessed") !== false) { 0377 return false; 0378 } 0379 throw new Zend_Cloud_StorageService_Exception('Error on fetch: '.$e->getMessage(), $e->getCode(), $e); 0380 } 0381 } 0382 0383 /** 0384 * Store a key/value array of metadata at the given path. 0385 * WARNING: This operation overwrites any metadata that is located at 0386 * $destinationPath. 0387 * 0388 * @param string $destinationPath 0389 * @param array $options 0390 * @return void 0391 */ 0392 public function storeMetadata($destinationPath, $metadata, $options = null) 0393 { 0394 try { 0395 $this->_storageClient->setBlobMetadata($this->_container, $destinationPath, $metadata); 0396 } catch (Zend_Service_WindowsAzure_Exception $e) { 0397 if (strpos($e->getMessage(), "could not be accessed") === false) { 0398 throw new Zend_Cloud_StorageService_Exception('Error on store metadata: '.$e->getMessage(), $e->getCode(), $e); 0399 } 0400 } 0401 } 0402 0403 /** 0404 * Delete a key/value array of metadata at the given path. 0405 * 0406 * @param string $path 0407 * @param array $options 0408 * @return void 0409 */ 0410 public function deleteMetadata($path, $options = null) 0411 { 0412 try { 0413 $this->_storageClient->setBlobMetadata($this->_container, $destinationPath, array()); 0414 } catch (Zend_Service_WindowsAzure_Exception $e) { 0415 if (strpos($e->getMessage(), "could not be accessed") === false) { 0416 throw new Zend_Cloud_StorageService_Exception('Error on delete metadata: '.$e->getMessage(), $e->getCode(), $e); 0417 } 0418 } 0419 } 0420 0421 /** 0422 * Delete container 0423 * 0424 * @return void 0425 */ 0426 public function deleteContainer() 0427 { 0428 try { 0429 $this->_storageClient->deleteContainer($this->_container); 0430 } catch (Zend_Service_WindowsAzure_Exception $e) { 0431 throw new Zend_Cloud_StorageService_Exception('Error on delete: '.$e->getMessage(), $e->getCode(), $e); 0432 } 0433 } 0434 0435 /** 0436 * Get the concrete adapter. 0437 * @return Zend_Service_Azure_Storage_Blob 0438 */ 0439 public function getClient() 0440 { 0441 return $this->_storageClient; 0442 } 0443 }