PageRenderTime 74ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/library/Cloud/StorageService/Adapter/WindowsAzure.php

https://github.com/kervin/kyzstudio
PHP | 443 lines | 246 code | 46 blank | 151 comment | 30 complexity | 2e447322f04376d98dd5ecb188ce85f3 MD5 | raw file
  1. <?php
  2. /**
  3. * LICENSE
  4. *
  5. * This source file is subject to the new BSD license that is bundled
  6. * with this package in the file LICENSE.txt.
  7. * It is also available through the world-wide-web at this URL:
  8. * http://framework.zend.com/license/new-bsd
  9. * If you did not receive a copy of the license and are unable to
  10. * obtain it through the world-wide-web, please send an email
  11. * to license@zend.com so we can send you a copy immediately.
  12. *
  13. * @category Zend
  14. * @package Zend_Cloud
  15. * @subpackage StorageService
  16. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  17. * @license http://framework.zend.com/license/new-bsd New BSD License
  18. */
  19. #require_once 'Zend/Cloud/StorageService/Adapter.php';
  20. #require_once 'Zend/Service/WindowsAzure/Storage/Blob.php';
  21. #require_once 'Zend/Cloud/StorageService/Exception.php';
  22. /**
  23. *
  24. * Windows Azure Blob Service abstraction
  25. *
  26. * @category Zend
  27. * @package Zend_Cloud
  28. * @subpackage StorageService
  29. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  30. * @license http://framework.zend.com/license/new-bsd New BSD License
  31. */
  32. class Zend_Cloud_StorageService_Adapter_WindowsAzure
  33. implements Zend_Cloud_StorageService_Adapter
  34. {
  35. const ACCOUNT_NAME = 'storage_accountname';
  36. const ACCOUNT_KEY = 'storage_accountkey';
  37. const HOST = "storage_host";
  38. const PROXY_HOST = "storage_proxy_host";
  39. const PROXY_PORT = "storage_proxy_port";
  40. const PROXY_CREDENTIALS = "storage_proxy_credentials";
  41. const CONTAINER = "storage_container";
  42. const RETURN_TYPE = 'return_type';
  43. const RETURN_PATHNAME = 'return_path';
  44. const RETURN_OPENMODE = 'return_openmode';
  45. /** return types for fetch */
  46. const RETURN_PATH = 1; // return filename
  47. const RETURN_STRING = 2; // return data as string
  48. const RETURN_STREAM = 3; // return PHP stream
  49. /** return types for list */
  50. const RETURN_LIST = 1; // return native list
  51. const RETURN_NAMES = 2; // return only names
  52. const DEFAULT_HOST = Zend_Service_WindowsAzure_Storage::URL_CLOUD_BLOB;
  53. /**
  54. * Storage container to operate on
  55. *
  56. * @var string
  57. */
  58. protected $_container;
  59. /**
  60. * Storage client
  61. *
  62. * @var Zend_Service_WindowsAzure_Storage_Blob
  63. */
  64. protected $_storageClient = null;
  65. /**
  66. * Creates a new Zend_Cloud_Storage_WindowsAzure instance
  67. *
  68. * @param array|Zend_Config $options Options for the Zend_Cloud_Storage_WindowsAzure instance
  69. */
  70. public function __construct($options = array())
  71. {
  72. if ($options instanceof Zend_Config) {
  73. $options = $options->toArray();
  74. }
  75. if (!is_array($options)) {
  76. throw new Zend_Cloud_StorageService_Exception('Invalid options provided');
  77. }
  78. // Build Zend_Service_WindowsAzure_Storage_Blob instance
  79. if (!isset($options[self::HOST])) {
  80. $host = self::DEFAULT_HOST;
  81. } else {
  82. $host = $options[self::HOST];
  83. }
  84. if (!isset($options[self::ACCOUNT_NAME])) {
  85. throw new Zend_Cloud_StorageService_Exception('No Windows Azure account name provided.');
  86. }
  87. if (!isset($options[self::ACCOUNT_KEY])) {
  88. throw new Zend_Cloud_StorageService_Exception('No Windows Azure account key provided.');
  89. }
  90. $this->_storageClient = new Zend_Service_WindowsAzure_Storage_Blob($host,
  91. $options[self::ACCOUNT_NAME], $options[self::ACCOUNT_KEY]);
  92. // Parse other options
  93. if (!empty($options[self::PROXY_HOST])) {
  94. $proxyHost = $options[self::PROXY_HOST];
  95. $proxyPort = isset($options[self::PROXY_PORT]) ? $options[self::PROXY_PORT] : 8080;
  96. $proxyCredentials = isset($options[self::PROXY_CREDENTIALS]) ? $options[self::PROXY_CREDENTIALS] : '';
  97. $this->_storageClient->setProxy(true, $proxyHost, $proxyPort, $proxyCredentials);
  98. }
  99. if (isset($options[self::HTTP_ADAPTER])) {
  100. $this->_storageClient->setHttpClientChannel($options[self::HTTP_ADAPTER]);
  101. }
  102. // Set container
  103. $this->_container = $options[self::CONTAINER];
  104. // Make sure the container exists
  105. if (!$this->_storageClient->containerExists($this->_container)) {
  106. $this->_storageClient->createContainer($this->_container);
  107. }
  108. }
  109. /**
  110. * Get an item from the storage service.
  111. *
  112. * @param string $path
  113. * @param array $options
  114. * @return mixed
  115. */
  116. public function fetchItem($path, $options = null)
  117. {
  118. // Options
  119. $returnType = self::RETURN_STRING;
  120. $returnPath = tempnam('', 'azr');
  121. $openMode = 'r';
  122. // Parse options
  123. if (is_array($options)) {
  124. if (isset($options[self::RETURN_TYPE])) {
  125. $returnType = $options[self::RETURN_TYPE];
  126. }
  127. if (isset($options[self::RETURN_PATHNAME])) {
  128. $returnPath = $options[self::RETURN_PATHNAME];
  129. }
  130. if (isset($options[self::RETURN_OPENMODE])) {
  131. $openMode = $options[self::RETURN_OPENMODE];
  132. }
  133. }
  134. // Fetch the blob
  135. try {
  136. $this->_storageClient->getBlob(
  137. $this->_container,
  138. $path,
  139. $returnPath
  140. );
  141. } catch (Zend_Service_WindowsAzure_Exception $e) {
  142. if (strpos($e->getMessage(), "does not exist") !== false) {
  143. return false;
  144. }
  145. throw new Zend_Cloud_StorageService_Exception('Error on fetch: '.$e->getMessage(), $e->getCode(), $e);
  146. }
  147. // Return value
  148. if ($returnType == self::RETURN_PATH) {
  149. return $returnPath;
  150. }
  151. if ($returnType == self::RETURN_STRING) {
  152. return file_get_contents($returnPath);
  153. }
  154. if ($returnType == self::RETURN_STREAM) {
  155. return fopen($returnPath, $openMode);
  156. }
  157. }
  158. /**
  159. * Store an item in the storage service.
  160. * WARNING: This operation overwrites any item that is located at
  161. * $destinationPath.
  162. * @param string $destinationPath
  163. * @param mixed $data
  164. * @param array $options
  165. * @return boolean
  166. */
  167. public function storeItem($destinationPath, $data, $options = null)
  168. {
  169. // Create a temporary file that will be uploaded
  170. $temporaryFilePath = '';
  171. $removeTemporaryFilePath = false;
  172. if (is_resource($data)) {
  173. $temporaryFilePath = tempnam('', 'azr');
  174. $fpDestination = fopen($temporaryFilePath, 'w');
  175. $fpSource = $data;
  176. rewind($fpSource);
  177. while (!feof($fpSource)) {
  178. fwrite($fpDestination, fread($fpSource, 8192));
  179. }
  180. fclose($fpDestination);
  181. $removeTemporaryFilePath = true;
  182. } elseif (file_exists($data)) {
  183. $temporaryFilePath = $data;
  184. $removeTemporaryFilePath = false;
  185. } else {
  186. $temporaryFilePath = tempnam('', 'azr');
  187. file_put_contents($temporaryFilePath, $data);
  188. $removeTemporaryFilePath = true;
  189. }
  190. try {
  191. // Upload data
  192. $this->_storageClient->putBlob(
  193. $this->_container,
  194. $destinationPath,
  195. $temporaryFilePath
  196. );
  197. } catch(Zend_Service_WindowsAzure_Exception $e) {
  198. @unlink($temporaryFilePath);
  199. throw new Zend_Cloud_StorageService_Exception('Error on store: '.$e->getMessage(), $e->getCode(), $e);
  200. }
  201. if ($removeTemporaryFilePath) {
  202. @unlink($temporaryFilePath);
  203. }
  204. }
  205. /**
  206. * Delete an item in the storage service.
  207. *
  208. * @param string $path
  209. * @param array $options
  210. * @return void
  211. */
  212. public function deleteItem($path, $options = null)
  213. {
  214. try {
  215. $this->_storageClient->deleteBlob(
  216. $this->_container,
  217. $path
  218. );
  219. } catch (Zend_Service_WindowsAzure_Exception $e) {
  220. throw new Zend_Cloud_StorageService_Exception('Error on delete: '.$e->getMessage(), $e->getCode(), $e);
  221. }
  222. }
  223. /**
  224. * Copy an item in the storage service to a given path.
  225. *
  226. * @param string $sourcePath
  227. * @param string $destinationPath
  228. * @param array $options
  229. * @return void
  230. */
  231. public function copyItem($sourcePath, $destinationPath, $options = null)
  232. {
  233. try {
  234. $this->_storageClient->copyBlob(
  235. $this->_container,
  236. $sourcePath,
  237. $this->_container,
  238. $destinationPath
  239. );
  240. } catch (Zend_Service_WindowsAzure_Exception $e) {
  241. throw new Zend_Cloud_StorageService_Exception('Error on copy: '.$e->getMessage(), $e->getCode(), $e);
  242. }
  243. }
  244. /**
  245. * Move an item in the storage service to a given path.
  246. *
  247. * @param string $sourcePath
  248. * @param string $destinationPath
  249. * @param array $options
  250. * @return void
  251. */
  252. public function moveItem($sourcePath, $destinationPath, $options = null)
  253. {
  254. try {
  255. $this->_storageClient->copyBlob(
  256. $this->_container,
  257. $sourcePath,
  258. $this->_container,
  259. $destinationPath
  260. );
  261. $this->_storageClient->deleteBlob(
  262. $this->_container,
  263. $sourcePath
  264. );
  265. } catch (Zend_Service_WindowsAzure_Exception $e) {
  266. throw new Zend_Cloud_StorageService_Exception('Error on move: '.$e->getMessage(), $e->getCode(), $e);
  267. }
  268. }
  269. /**
  270. * Rename an item in the storage service to a given name.
  271. *
  272. *
  273. * @param string $path
  274. * @param string $name
  275. * @param array $options
  276. * @return void
  277. */
  278. public function renameItem($path, $name, $options = null)
  279. {
  280. return $this->moveItem($path, $name, $options);
  281. }
  282. /**
  283. * List items in the given directory in the storage service
  284. *
  285. * The $path must be a directory
  286. *
  287. *
  288. * @param string $path Must be a directory
  289. * @param array $options
  290. * @return array A list of item names
  291. */
  292. public function listItems($path, $options = null)
  293. {
  294. // Options
  295. $returnType = self::RETURN_NAMES; // 1: return list of paths, 2: return raw output from underlying provider
  296. // Parse options
  297. if (is_array($options)&& isset($options[self::RETURN_TYPE])) {
  298. $returnType = $options[self::RETURN_TYPE];
  299. }
  300. try {
  301. // Fetch list
  302. $blobList = $this->_storageClient->listBlobs(
  303. $this->_container,
  304. $path
  305. );
  306. } catch (Zend_Service_WindowsAzure_Exception $e) {
  307. throw new Zend_Cloud_StorageService_Exception('Error on list: '.$e->getMessage(), $e->getCode(), $e);
  308. }
  309. // Return
  310. if ($returnType == self::RETURN_LIST) {
  311. return $blobList;
  312. }
  313. $returnValue = array();
  314. foreach ($blobList as $blob) {
  315. $returnValue[] = $blob->Name;
  316. }
  317. return $returnValue;
  318. }
  319. /**
  320. * Get a key/value array of metadata for the given path.
  321. *
  322. * @param string $path
  323. * @param array $options
  324. * @return array
  325. */
  326. public function fetchMetadata($path, $options = null)
  327. {
  328. try {
  329. return $this->_storageClient->getBlobMetaData(
  330. $this->_container,
  331. $path
  332. );
  333. } catch (Zend_Service_WindowsAzure_Exception $e) {
  334. if (strpos($e->getMessage(), "could not be accessed") !== false) {
  335. return false;
  336. }
  337. throw new Zend_Cloud_StorageService_Exception('Error on fetch: '.$e->getMessage(), $e->getCode(), $e);
  338. }
  339. }
  340. /**
  341. * Store a key/value array of metadata at the given path.
  342. * WARNING: This operation overwrites any metadata that is located at
  343. * $destinationPath.
  344. *
  345. * @param string $destinationPath
  346. * @param array $options
  347. * @return void
  348. */
  349. public function storeMetadata($destinationPath, $metadata, $options = null)
  350. {
  351. try {
  352. $this->_storageClient->setBlobMetadata($this->_container, $destinationPath, $metadata);
  353. } catch (Zend_Service_WindowsAzure_Exception $e) {
  354. if (strpos($e->getMessage(), "could not be accessed") === false) {
  355. throw new Zend_Cloud_StorageService_Exception('Error on store metadata: '.$e->getMessage(), $e->getCode(), $e);
  356. }
  357. }
  358. }
  359. /**
  360. * Delete a key/value array of metadata at the given path.
  361. *
  362. * @param string $path
  363. * @param array $options
  364. * @return void
  365. */
  366. public function deleteMetadata($path, $options = null)
  367. {
  368. try {
  369. $this->_storageClient->setBlobMetadata($this->_container, $destinationPath, array());
  370. } catch (Zend_Service_WindowsAzure_Exception $e) {
  371. if (strpos($e->getMessage(), "could not be accessed") === false) {
  372. throw new Zend_Cloud_StorageService_Exception('Error on delete metadata: '.$e->getMessage(), $e->getCode(), $e);
  373. }
  374. }
  375. }
  376. /**
  377. * Delete container
  378. *
  379. * @return void
  380. */
  381. public function deleteContainer()
  382. {
  383. try {
  384. $this->_storageClient->deleteContainer($this->_container);
  385. } catch (Zend_Service_WindowsAzure_Exception $e) {
  386. throw new Zend_Cloud_StorageService_Exception('Error on delete: '.$e->getMessage(), $e->getCode(), $e);
  387. }
  388. }
  389. /**
  390. * Get the concrete adapter.
  391. * @return Zend_Service_Azure_Storage_Blob
  392. */
  393. public function getClient()
  394. {
  395. return $this->_storageClient;
  396. }
  397. }