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