PageRenderTime 25ms CodeModel.GetById 17ms app.highlight 6ms RepoModel.GetById 0ms app.codeStats 0ms

/zf/library/Zend/Cloud/StorageService/Adapter/S3.php

http://github.com/eryx/php-framework-benchmark
PHP | 327 lines | 152 code | 25 blank | 150 comment | 14 complexity | 0c0a59c7b1b0670d51032c7ddf5e3d03 MD5 | raw file
Possible License(s): MIT, BSD-3-Clause, Apache-2.0, LGPL-2.1, LGPL-3.0, BSD-2-Clause
  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-2011 Zend Technologies USA Inc. (http://www.zend.com)
 17 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 18 */
 19
 20require_once 'Zend/Service/Amazon/S3.php';
 21require_once 'Zend/Cloud/StorageService/Adapter.php';
 22require_once 'Zend/Cloud/StorageService/Exception.php';
 23
 24/**
 25 * S3 adapter for unstructured cloud storage.
 26 *
 27 * @category   Zend
 28 * @package    Zend_Cloud
 29 * @subpackage StorageService
 30 * @copyright  Copyright (c) 2005-2011 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_S3
 34    implements Zend_Cloud_StorageService_Adapter
 35{
 36    /*
 37     * Options array keys for the S3 adapter.
 38     */
 39    const BUCKET_NAME      = 'bucket_name';
 40    const BUCKET_AS_DOMAIN = 'bucket_as_domain?';
 41    const FETCH_STREAM     = 'fetch_stream';
 42    const METADATA         = 'metadata';
 43
 44    /**
 45     * AWS constants
 46     */
 47    const AWS_ACCESS_KEY   = 'aws_accesskey';
 48    const AWS_SECRET_KEY   = 'aws_secretkey';
 49
 50    /**
 51     * S3 service instance.
 52     * @var Zend_Service_Amazon_S3
 53     */
 54    protected $_s3;
 55    protected $_defaultBucketName = null;
 56    protected $_defaultBucketAsDomain = false;
 57
 58    /**
 59     * Constructor
 60     *
 61     * @param  array|Zend_Config $options
 62     * @return void
 63     */
 64    public function __construct($options = array())
 65    {
 66        if ($options instanceof Zend_Config) {
 67            $options = $options->toArray();
 68        }
 69
 70        if (!is_array($options)) {
 71            throw new Zend_Cloud_StorageService_Exception('Invalid options provided');
 72        }
 73
 74        if (!isset($options[self::AWS_ACCESS_KEY]) || !isset($options[self::AWS_SECRET_KEY])) {
 75            throw new Zend_Cloud_StorageService_Exception('AWS keys not specified!');
 76        }
 77
 78        try {
 79            $this->_s3 = new Zend_Service_Amazon_S3($options[self::AWS_ACCESS_KEY],
 80                                                $options[self::AWS_SECRET_KEY]);
 81        } catch (Zend_Service_Amazon_S3_Exception  $e) {
 82            throw new Zend_Cloud_StorageService_Exception('Error on create: '.$e->getMessage(), $e->getCode(), $e);
 83        }
 84
 85        if (isset($options[self::HTTP_ADAPTER])) {
 86            $this->_s3->getHttpClient()->setAdapter($options[self::HTTP_ADAPTER]);
 87        }
 88
 89        if (isset($options[self::BUCKET_NAME])) {
 90            $this->_defaultBucketName = $options[self::BUCKET_NAME];
 91        }
 92
 93        if (isset($options[self::BUCKET_AS_DOMAIN])) {
 94            $this->_defaultBucketAsDomain = $options[self::BUCKET_AS_DOMAIN];
 95        }
 96    }
 97
 98    /**
 99     * Get an item from the storage service.
100     *
101     * @TODO Support streams
102     *
103     * @param  string $path
104     * @param  array $options
105     * @return string
106     */
107    public function fetchItem($path, $options = array())
108    {
109        $fullPath = $this->_getFullPath($path, $options);
110        try {
111            if (!empty($options[self::FETCH_STREAM])) {
112                return $this->_s3->getObjectStream($fullPath, $options[self::FETCH_STREAM]);
113            } else {
114                return $this->_s3->getObject($fullPath);
115            }
116        } catch (Zend_Service_Amazon_S3_Exception  $e) {
117            throw new Zend_Cloud_StorageService_Exception('Error on fetch: '.$e->getMessage(), $e->getCode(), $e);
118        }
119    }
120
121    /**
122     * Store an item in the storage service.
123     *
124     * WARNING: This operation overwrites any item that is located at
125     * $destinationPath.
126     *
127     * @TODO Support streams
128     *
129     * @param string $destinationPath
130     * @param string|resource $data
131     * @param  array $options
132     * @return void
133     */
134    public function storeItem($destinationPath, $data, $options = array())
135    {
136        try {
137            $fullPath = $this->_getFullPath($destinationPath, $options);
138            return $this->_s3->putObject(
139                $fullPath,
140                $data,
141                empty($options[self::METADATA]) ? null : $options[self::METADATA]
142            );
143        } catch (Zend_Service_Amazon_S3_Exception  $e) {
144            throw new Zend_Cloud_StorageService_Exception('Error on store: '.$e->getMessage(), $e->getCode(), $e);
145        }
146    }
147
148    /**
149     * Delete an item in the storage service.
150     *
151     * @param  string $path
152     * @param  array $options
153     * @return void
154     */
155    public function deleteItem($path, $options = array())
156    {
157        try {
158            $this->_s3->removeObject($this->_getFullPath($path, $options));
159        } catch (Zend_Service_Amazon_S3_Exception  $e) {
160            throw new Zend_Cloud_StorageService_Exception('Error on delete: '.$e->getMessage(), $e->getCode(), $e);
161        }
162    }
163
164    /**
165     * Copy an item in the storage service to a given path.
166     *
167     * WARNING: This operation is *very* expensive for services that do not
168     * support copying an item natively.
169     *
170     * @TODO Support streams for those services that don't support natively
171     *
172     * @param  string $sourcePath
173     * @param  string $destination path
174     * @param  array $options
175     * @return void
176     */
177    public function copyItem($sourcePath, $destinationPath, $options = array())
178    {
179        try {
180            // TODO We *really* need to add support for object copying in the S3 adapter
181            $item = $this->fetch($_getFullPath(sourcePath), $options);
182            $this->storeItem($item, $destinationPath, $options);
183        } catch (Zend_Service_Amazon_S3_Exception  $e) {
184            throw new Zend_Cloud_StorageService_Exception('Error on copy: '.$e->getMessage(), $e->getCode(), $e);
185        }
186    }
187
188    /**
189     * Move an item in the storage service to a given path.
190     *
191     * @TODO Support streams for those services that don't support natively
192     *
193     * @param  string $sourcePath
194     * @param  string $destination path
195     * @param  array $options
196     * @return void
197     */
198    public function moveItem($sourcePath, $destinationPath, $options = array())
199    {
200        try {
201            $fullSourcePath = $this->_getFullPath($sourcePath, $options);
202            $fullDestPath   = $this->_getFullPath($destinationPath, $options);
203            return $this->_s3->moveObject(
204                $fullSourcePath,
205                $fullDestPath,
206                empty($options[self::METADATA]) ? null : $options[self::METADATA]
207            );
208        } catch (Zend_Service_Amazon_S3_Exception  $e) {
209            throw new Zend_Cloud_StorageService_Exception('Error on move: '.$e->getMessage(), $e->getCode(), $e);
210        }
211     }
212
213    /**
214     * Rename an item in the storage service to a given name.
215     *
216     *
217     * @param  string $path
218     * @param  string $name
219     * @param  array $options
220     * @return void
221     */
222    public function renameItem($path, $name, $options = null)
223    {
224        require_once 'Zend/Cloud/OperationNotAvailableException.php';
225        throw new Zend_Cloud_OperationNotAvailableException('Rename not implemented');
226    }
227
228    /**
229     * List items in the given directory in the storage service
230     *
231     * The $path must be a directory
232     *
233     *
234     * @param  string $path Must be a directory
235     * @param  array $options
236     * @return array A list of item names
237     */
238    public function listItems($path, $options = null)
239    {
240        try {
241            // TODO Support 'prefix' parameter for Zend_Service_Amazon_S3::getObjectsByBucket()
242            return $this->_s3->getObjectsByBucket($this->_defaultBucketName);
243        } catch (Zend_Service_Amazon_S3_Exception  $e) {
244            throw new Zend_Cloud_StorageService_Exception('Error on list: '.$e->getMessage(), $e->getCode(), $e);
245        }
246    }
247
248    /**
249     * Get a key/value array of metadata for the given path.
250     *
251     * @param  string $path
252     * @param  array $options
253     * @return array
254     */
255    public function fetchMetadata($path, $options = array())
256    {
257        try {
258            return $this->_s3->getInfo($this->_getFullPath($path, $options));
259        } catch (Zend_Service_Amazon_S3_Exception  $e) {
260            throw new Zend_Cloud_StorageService_Exception('Error on fetch: '.$e->getMessage(), $e->getCode(), $e);
261        }
262    }
263
264    /**
265     * Store a key/value array of metadata at the given path.
266     * WARNING: This operation overwrites any metadata that is located at
267     * $destinationPath.
268     *
269     * @param  string $destinationPath
270     * @param  array $options
271     * @return void
272     */
273    public function storeMetadata($destinationPath, $metadata, $options = array())
274    {
275        require_once 'Zend/Cloud/OperationNotAvailableException.php';
276        throw new Zend_Cloud_OperationNotAvailableException('Storing separate metadata is not supported, use storeItem() with \'metadata\' option key');
277    }
278
279    /**
280     * Delete a key/value array of metadata at the given path.
281     *
282     * @param  string $path
283     * @param  array $options
284     * @return void
285     */
286    public function deleteMetadata($path)
287    {
288        require_once 'Zend/Cloud/OperationNotAvailableException.php';
289        throw new Zend_Cloud_OperationNotAvailableException('Deleting metadata not supported');
290    }
291
292    /**
293     * Get full path, including bucket, for an object
294     *
295     * @param  string $path
296     * @param  array $options
297     * @return void
298     */
299    protected function _getFullPath($path, $options)
300    {
301        if (isset($options[self::BUCKET_NAME])) {
302            $bucket = $options[self::BUCKET_NAME];
303        } else if (isset($this->_defaultBucketName)) {
304            $bucket = $this->_defaultBucketName;
305        } else {
306            require_once 'Zend/Cloud/StorageService/Exception.php';
307            throw new Zend_Cloud_StorageService_Exception('Bucket name must be specified for S3 adapter.');
308        }
309
310        if (isset($options[self::BUCKET_AS_DOMAIN])) {
311            // TODO: support bucket domain names
312            require_once 'Zend/Cloud/StorageService/Exception.php';
313            throw new Zend_Cloud_StorageService_Exception('The S3 adapter does not currently support buckets in domain names.');
314        }
315
316        return trim($bucket) . '/' . trim($path);
317    }
318
319    /**
320     * Get the concrete client.
321     * @return Zend_Service_Amazon_S3
322     */
323    public function getClient()
324    {
325         return $this->_s3;
326    }
327}