PageRenderTime 53ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/library/Zend/Cloud/StorageService/Adapter/Nirvanix.php

https://github.com/mrbanzai/zf2
PHP | 403 lines | 221 code | 26 blank | 156 comment | 26 complexity | 9eb7baf7757a2a115576e6b12c046355 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\StorageService
  15. * @subpackage Adapter
  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
  18. */
  19. /**
  20. * namespace
  21. */
  22. namespace Zend\Cloud\StorageService\Adapter;
  23. use Zend\Cloud\StorageService\Adapter,
  24. Zend\Cloud\StorageService\Exception,
  25. Zend\Service\Nirvanix\Nirvanix as NirvanixService,
  26. Zend\Http\Client as HttpClient;
  27. /**
  28. * Adapter for Nirvanix cloud storage
  29. *
  30. * @category Zend
  31. * @package Zend\Cloud\StorageService
  32. * @subpackage Adapter
  33. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  34. * @license http://framework.zend.com/license/new-bsd New BSD License
  35. */
  36. class Nirvanix implements Adapter
  37. {
  38. const USERNAME = 'auth_username';
  39. const PASSWORD = 'auth_password';
  40. const APP_KEY = 'auth_accesskey';
  41. const REMOTE_DIRECTORY = 'remote_directory';
  42. /**
  43. * The Nirvanix adapter
  44. * @var Zend\Service\Nirvanix
  45. */
  46. protected $_nirvanix;
  47. protected $_imfNs;
  48. protected $_metadataNs;
  49. protected $_remoteDirectory;
  50. private $maxPageSize = 500;
  51. /**
  52. * Constructor
  53. *
  54. * @param array|Zend\Config\Config $options
  55. * @return void
  56. */
  57. function __construct($options = array())
  58. {
  59. if ($options instanceof \Zend\Config\Config) {
  60. $options = $options->toArray();
  61. }
  62. if (!is_array($options)) {
  63. throw new Exception\InvalidArgumentException('Invalid options provided');
  64. }
  65. $auth = array(
  66. 'username' => $options[self::USERNAME],
  67. 'password' => $options[self::PASSWORD],
  68. 'appKey' => $options[self::APP_KEY],
  69. );
  70. $nirvanix_options = array();
  71. if (isset($options[self::HTTP_ADAPTER])) {
  72. $httpc = new HttpClient();
  73. $httpc->setAdapter($options[self::HTTP_ADAPTER]);
  74. $nirvanix_options['httpClient'] = $httpc;
  75. }
  76. try {
  77. $this->_nirvanix = new NirvanixService($auth, $nirvanix_options);
  78. $this->_remoteDirectory = $options[self::REMOTE_DIRECTORY];
  79. $this->_imfNs = $this->_nirvanix->getService('IMFS');
  80. $this->_metadataNs = $this->_nirvanix->getService('Metadata');
  81. } catch (Zend\Service\Nirvanix\Exception $e) {
  82. throw new Exception\RuntimeException('Error on create: '.$e->getMessage(), $e->getCode(), $e);
  83. }
  84. }
  85. /**
  86. * Get an item from the storage service.
  87. *
  88. * @param string $path
  89. * @param array $options
  90. * @return mixed
  91. */
  92. public function fetchItem($path, $options = null)
  93. {
  94. $path = $this->_getFullPath($path);
  95. try {
  96. $item = $this->_imfNs->getContents($path);
  97. } catch (Zend\Service\Nirvanix\Exception $e) {
  98. throw new Exception\RuntimeException('Error on fetch: '.$e->getMessage(), $e->getCode(), $e);
  99. }
  100. return $item;
  101. }
  102. /**
  103. * Store an item in the storage service.
  104. * WARNING: This operation overwrites any item that is located at
  105. * $destinationPath.
  106. * @param string $destinationPath
  107. * @param mixed $data
  108. * @param array $options
  109. * @return void
  110. */
  111. public function storeItem($destinationPath, $data, $options = null)
  112. {
  113. try {
  114. $path = $this->_getFullPath($destinationPath);
  115. $this->_imfNs->putContents($path, $data);
  116. } catch (Zend\Service\Nirvanix\Exception $e) {
  117. throw new Exception\RuntimeException('Error on store: '.$e->getMessage(), $e->getCode(), $e);
  118. }
  119. return true;
  120. }
  121. /**
  122. * Delete an item in the storage service.
  123. *
  124. * @param string $path
  125. * @param array $options
  126. * @return void
  127. */
  128. public function deleteItem($path, $options = null)
  129. {
  130. try {
  131. $path = $this->_getFullPath($path);
  132. $this->_imfNs->unlink($path);
  133. } catch(Zend\Service\Nirvanix\Exception $e) {
  134. // if (trim(strtoupper($e->getMessage())) != 'INVALID PATH') {
  135. // // TODO Differentiate among errors in the Nirvanix adapter
  136. throw new Exception\RunTimeException('Error on delete: '.$e->getMessage(), $e->getCode(), $e);
  137. }
  138. }
  139. /**
  140. * Copy an item in the storage service to a given path.
  141. * WARNING: This operation is *very* expensive for services that do not
  142. * support copying an item natively.
  143. *
  144. * @param string $sourcePath
  145. * @param string $destination path
  146. * @param array $options
  147. * @return void
  148. */
  149. public function copyItem($sourcePath, $destinationPath, $options = null)
  150. {
  151. try {
  152. $sourcePath = $this->_getFullPath($sourcePath);
  153. $destinationPath = $this->_getFullPath($destinationPath);
  154. $this->_imfNs->CopyFiles(array('srcFilePath' => $sourcePath,
  155. 'destFolderPath' => $destinationPath));
  156. } catch (Zend\Service\Nirvanix\Exception $e) {
  157. throw new Exception\RuntimeException('Error on copy: '.$e->getMessage(), $e->getCode(), $e);
  158. }
  159. }
  160. /**
  161. * Move an item in the storage service to a given path.
  162. * WARNING: This operation is *very* expensive for services that do not
  163. * support moving an item natively.
  164. *
  165. * @param string $sourcePath
  166. * @param string $destination path
  167. * @param array $options
  168. * @return void
  169. */
  170. public function moveItem($sourcePath, $destinationPath, $options = null)
  171. {
  172. try {
  173. $sourcePath = $this->_getFullPath($sourcePath);
  174. $destinationPath = $this->_getFullPath($destinationPath);
  175. $this->_imfNs->RenameFile(array('filePath' => $sourcePath,
  176. 'newFileName' => $destinationPath));
  177. // $this->_imfNs->MoveFiles(array('srcFilePath' => $sourcePath,
  178. // 'destFolderPath' => $destinationPath));
  179. } catch (Zend\Service\Nirvanix\Exception $e) {
  180. throw new Exception\RuntimeException('Error on move: '.$e->getMessage(), $e->getCode(), $e);
  181. }
  182. }
  183. /**
  184. * Rename an item in the storage service to a given name.
  185. *
  186. *
  187. * @param string $path
  188. * @param string $name
  189. * @param array $options
  190. * @return void
  191. */
  192. public function renameItem($path, $name, $options = null)
  193. {
  194. throw new Exception\OperationNotAvailableException('Renaming not implemented');
  195. }
  196. /**
  197. * Get a key/value array of metadata for the given path.
  198. *
  199. * @param string $path
  200. * @param array $options
  201. * @return array An associative array of key/value pairs specifying the metadata for this object.
  202. * If no metadata exists, an empty array is returned.
  203. */
  204. public function fetchMetadata($path, $options = null)
  205. {
  206. $path = $this->_getFullPath($path);
  207. try {
  208. $metadataNode = $this->_metadataNs->getMetadata(array('path' => $path));
  209. } catch (Zend\Service\Nirvanix\Exception $e) {
  210. throw new Exception\RuntimeException('Error on fetching metadata: '.$e->getMessage(), $e->getCode(), $e);
  211. }
  212. $metadata = array();
  213. $length = count($metadataNode->Metadata);
  214. // Need to special case this as Nirvanix returns an array if there is
  215. // more than one, but doesn't return an array if there is only one.
  216. if ($length == 1)
  217. {
  218. $metadata[(string)$metadataNode->Metadata->Type->value] = (string)$metadataNode->Metadata->Value;
  219. }
  220. else if ($length > 1)
  221. {
  222. for ($i=0; $i<$length; $i++)
  223. {
  224. $metadata[(string)$metadataNode->Metadata[$i]->Type] = (string)$metadataNode->Metadata[$i]->Value;
  225. }
  226. }
  227. return $metadata;
  228. }
  229. /**
  230. * Store a key/value array of metadata at the given path.
  231. * WARNING: This operation overwrites any metadata that is located at
  232. * $destinationPath.
  233. *
  234. * @param string $destinationPath
  235. * @param array $metadata associative array specifying the key/value pairs for the metadata.
  236. * @param array $options
  237. * @return void
  238. */
  239. public function storeMetadata($destinationPath, $metadata, $options = null)
  240. {
  241. $destinationPath = $this->_getFullPath($destinationPath);
  242. if ($metadata != null) {
  243. try {
  244. foreach ($metadata AS $key=>$value) {
  245. $metadataString = $key . ":" . $value;
  246. $this->_metadataNs->SetMetadata(array(
  247. 'path' => $destinationPath,
  248. 'metadata' => $metadataString,
  249. ));
  250. }
  251. } catch (Zend\Service\Nirvanix\Exception $e) {
  252. throw new Exception\RunTimeException('Error on storing metadata: '.$e->getMessage(), $e->getCode(), $e);
  253. }
  254. }
  255. }
  256. /**
  257. * Delete a key/value array of metadata at the given path.
  258. *
  259. * @param string $path
  260. * @param array $metadata - An associative array specifying the key/value pairs for the metadata
  261. * to be deleted. If null, all metadata associated with the object will
  262. * be deleted.
  263. * @param array $options
  264. * @return void
  265. */
  266. public function deleteMetadata($path, $metadata = null, $options = null)
  267. {
  268. $path = $this->_getFullPath($path);
  269. try {
  270. if ($metadata == null) {
  271. $this->_metadataNs->DeleteAllMetadata(array('path' => $path));
  272. } else {
  273. foreach ($metadata AS $key=>$value) {
  274. $this->_metadataNs->DeleteMetadata(array(
  275. 'path' => $path,
  276. 'metadata' => $key,
  277. ));
  278. }
  279. }
  280. } catch (Zend\Service\Nirvanix\Exception $e) {
  281. throw new Exception\RuntimeException('Error on deleting metadata: '.$e->getMessage(), $e->getCode(), $e);
  282. }
  283. }
  284. /*
  285. * Recursively traverse all the folders and build an array that contains
  286. * the path names for each folder.
  287. *
  288. * @param string $path folder path to get the list of folders from.
  289. * @param array& $resultArray reference to the array that contains the path names
  290. * for each folder.
  291. */
  292. private function getAllFolders($path, &$resultArray)
  293. {
  294. $response = $this->_imfNs->ListFolder(array(
  295. 'folderPath' => $path,
  296. 'pageNumber' => 1,
  297. 'pageSize' => $this->maxPageSize,
  298. ));
  299. $numFolders = $response->ListFolder->TotalFolderCount;
  300. if ($numFolders == 0) {
  301. return;
  302. } else {
  303. //Need to special case this as Nirvanix returns an array if there is
  304. //more than one, but doesn't return an array if there is only one.
  305. if ($numFolders == 1) {
  306. $folderPath = $response->ListFolder->Folder->Path;
  307. array_push($resultArray, $folderPath);
  308. $this->getAllFolders('/' . $folderPath, $resultArray);
  309. } else {
  310. foreach ($response->ListFolder->Folder as $arrayElem) {
  311. $folderPath = $arrayElem->Path;
  312. array_push($resultArray, $folderPath);
  313. $this->getAllFolders('/' . $folderPath, $resultArray);
  314. }
  315. }
  316. }
  317. }
  318. /**
  319. * Return an array of the items contained in the given path. The items
  320. * returned are the files or objects that in the specified path.
  321. *
  322. * @param string $path
  323. * @param array $options
  324. * @return array
  325. */
  326. public function listItems($path, $options = null)
  327. {
  328. $path = $this->_getFullPath($path);
  329. $resultArray = array();
  330. if (!isset($path)) {
  331. return false;
  332. } else {
  333. try {
  334. $response = $this->_imfNs->ListFolder(array(
  335. 'folderPath' => $path,
  336. 'pageNumber' => 1,
  337. 'pageSize' => $this->maxPageSize,
  338. ));
  339. } catch (Zend\Service\Nirvanix\Exception $e) {
  340. throw new Exception\RuntimeException('Error on list: '.$e->getMessage(), $e->getCode(), $e);
  341. }
  342. $numFiles = $response->ListFolder->TotalFileCount;
  343. //Add the file names to the array
  344. if ($numFiles != 0) {
  345. //Need to special case this as Nirvanix returns an array if there is
  346. //more than one, but doesn't return an array if there is only one.
  347. if ($numFiles == 1) {
  348. $resultArray[] = (string)$response->ListFolder->File->Name;
  349. }
  350. else {
  351. foreach ($response->ListFolder->File as $arrayElem) {
  352. $resultArray[] = (string) $arrayElem->Name;
  353. }
  354. }
  355. }
  356. }
  357. return $resultArray;
  358. }
  359. /**
  360. * Get full path to an object
  361. *
  362. * @param string $path
  363. * @return string
  364. */
  365. private function _getFullPath($path)
  366. {
  367. return $this->_remoteDirectory . $path;
  368. }
  369. /**
  370. * Get the concrete client.
  371. * @return Zend\Service\Nirvanix
  372. */
  373. public function getClient()
  374. {
  375. return $this->_nirvanix;
  376. }
  377. }