Overview

Namespaces

  • OpenCloud
    • Autoscale
      • Resource
    • CloudMonitoring
      • Exception
      • Resource
    • Common
      • Collection
      • Constants
      • Exceptions
      • Http
        • Message
      • Identity
      • Log
      • Service
    • Compute
      • Constants
      • Exception
      • Resource
    • Database
      • Resource
    • DNS
      • Resource
    • LoadBalancer
      • Resource
    • ObjectStore
      • Constants
      • Exception
      • Resource
      • Upload
    • Orchestration
    • Queues
      • Exception
      • Resource
    • Volume
      • Resource
  • PHP

Classes

  • AbstractContainer
  • AbstractResource
  • Account
  • CDNContainer
  • Container
  • ContainerMetadata
  • DataObject
  • Overview
  • Namespace
  • Class
  • Tree
  • Download
  1: <?php
  2: /**
  3:  * PHP OpenCloud library.
  4:  *
  5:  * @copyright 2013 Rackspace Hosting, Inc. See LICENSE for information.
  6:  * @license   https://www.apache.org/licenses/LICENSE-2.0
  7:  * @author    Jamie Hannaford <jamie.hannaford@rackspace.com>
  8:  * @author    Glen Campbell <glen.campbell@rackspace.com>
  9:  */
 10: 
 11: namespace OpenCloud\ObjectStore\Resource;
 12: 
 13: use Guzzle\Http\EntityBody;
 14: use Guzzle\Http\Message\Response;
 15: use Guzzle\Http\Url;
 16: use OpenCloud\Common\Lang;
 17: use OpenCloud\Common\Exceptions;
 18: use OpenCloud\ObjectStore\Constants\UrlType;
 19: 
 20: /**
 21:  * Objects are the basic storage entities in Cloud Files. They represent the 
 22:  * files and their optional metadata you upload to the system. When you upload 
 23:  * objects to Cloud Files, the data is stored as-is (without compression or 
 24:  * encryption) and consists of a location (container), the object's name, and 
 25:  * any metadata you assign consisting of key/value pairs.
 26:  */
 27: class DataObject extends AbstractResource
 28: {
 29:     const METADATA_LABEL = 'Object';
 30: 
 31:     /**
 32:      * @var Container
 33:      */
 34:     private $container;
 35: 
 36:     /**
 37:      * @var The file name of the object
 38:      */
 39:     protected $name;
 40:     
 41:     /**
 42:      * @var EntityBody 
 43:      */
 44:     protected $content;
 45: 
 46:     /**
 47:      * @var bool Whether or not this object is a "pseudo-directory"
 48:      * @link http://docs.openstack.org/trunk/openstack-object-storage/developer/content/pseudo-hierarchical-folders-directories.html
 49:      */
 50:     protected $directory = false;
 51: 
 52:     /**
 53:      * @var string The object's content type
 54:      */
 55:     protected $contentType;
 56: 
 57:     /**
 58:      * @var The size of this object.
 59:      */
 60:     protected $contentLength;
 61: 
 62:     /**
 63:      * @var string Date of last modification.
 64:      */
 65:     protected $lastModified;
 66: 
 67:     /**
 68:      * @var string Etag.
 69:      */
 70:     protected $etag;
 71: 
 72:     /**
 73:      * Also need to set Container parent and handle pseudo-directories.
 74:      * {@inheritDoc}
 75:      *
 76:      * @param Container $container
 77:      * @param null      $data
 78:      */
 79:     public function __construct(Container $container, $data = null)
 80:     {
 81:         $this->setContainer($container);
 82: 
 83:         parent::__construct($container->getService());
 84:         
 85:         // For pseudo-directories, we need to ensure the name is set
 86:         if (!empty($data->subdir)) {
 87:             $this->setName($data->subdir)->setDirectory(true);
 88:             return;
 89:         }
 90: 
 91:         $this->populate($data);
 92:     }
 93: 
 94:     /**
 95:      * A collection list of DataObjects contains a different data structure than the one returned for the
 96:      * "Retrieve Object" operation. So we need to stock the values differently.
 97:      * {@inheritDoc}
 98:      */
 99:     public function populate($info, $setObjects = true)
100:     {
101:         parent::populate($info, $setObjects);
102: 
103:         if (isset($info->bytes)) {
104:             $this->setContentLength($info->bytes);
105:         }
106:         if (isset($info->last_modified)) {
107:             $this->setLastModified($info->last_modified);
108:         }
109:         if (isset($info->content_type)) {
110:             $this->setContentType($info->content_type);
111:         }
112:         if (isset($info->hash)) {
113:             $this->setEtag($info->hash);
114:         }
115:     }
116: 
117:     /**
118:      * Takes a response and stocks common values from both the body and the headers.
119:      *
120:      * @param Response $response
121:      * @return $this
122:      */
123:     public function populateFromResponse(Response $response)
124:     {
125:         $this->content = $response->getBody();
126: 
127:         $headers = $response->getHeaders();
128: 
129:         return $this->setMetadata($headers, true)
130:             ->setContentType((string) $headers['Content-type'])
131:             ->setLastModified((string) $headers['Last-Modified'])
132:             ->setContentLength((string) $headers['Content-Length'])
133:             ->setEtag((string) $headers['ETag']);
134:     }
135: 
136:     public function refresh()
137:     {
138:         $response = $this->getService()->getClient()
139:             ->get($this->getUrl())
140:             ->send();
141: 
142:         return $this->populateFromResponse($response);
143:     }
144: 
145:     /**
146:      * @param Container $container
147:      * @return $this
148:      */
149:     public function setContainer(Container $container)
150:     {
151:         $this->container = $container;
152:         return $this;
153:     }
154: 
155:     /**
156:      * @return Container
157:      */
158:     public function getContainer()
159:     {
160:         return $this->container;
161:     }
162: 
163:     /**
164:      * @param $name string
165:      * @return $this
166:      */
167:     public function setName($name)
168:     {
169:         $this->name = $name;
170:         return $this;
171:     }
172: 
173:     /**
174:      * @return string
175:      */
176:     public function getName()
177:     {
178:         return $this->name;
179:     }
180: 
181:     /**
182:      * @param $directory bool
183:      * @return $this
184:      */
185:     public function setDirectory($directory)
186:     {
187:         $this->directory = $directory;
188:         return $this;
189:     }
190: 
191:     /**
192:      * @return bool
193:      */
194:     public function getDirectory()
195:     {
196:         return $this->directory;
197:     }
198:     
199:     /**
200:      * @return bool Is this data object a pseudo-directory?
201:      */
202:     public function isDirectory()
203:     {
204:         return (bool) $this->directory;
205:     }
206: 
207:     /**
208:      * @param  mixed $content
209:      * @return $this
210:      */
211:     public function setContent($content)
212:     {
213:         $this->content = EntityBody::factory($content);
214:         return $this;
215:     }
216: 
217:     /**
218:      * @return EntityBody
219:      */
220:     public function getContent()
221:     {
222:         return $this->content;
223:     }
224: 
225:     /**
226:      * @param  string $contentType
227:      * @return $this
228:      */
229:     public function setContentType($contentType)
230:     {
231:         $this->contentType = $contentType;
232:         return $this;
233:     }
234: 
235:     /**
236:      * @return null|string
237:      */
238:     public function getContentType()
239:     {
240:         return $this->contentType ?: $this->content->getContentType();
241:     }
242: 
243:     /**
244:      * @param $contentType int
245:      * @return $this
246:      */
247:     public function setContentLength($contentLength)
248:     {
249:         $this->contentLength = $contentLength;
250:         return $this;
251:     }
252: 
253:     /**
254:      * @return int
255:      */
256:     public function getContentLength()
257:     {
258:         return $this->contentLength ?: $this->content->getContentLength();
259:     }
260: 
261:     /**
262:      * @param $etag
263:      * @return $this
264:      */
265:     public function setEtag($etag)
266:     {
267:         $this->etag = $etag;
268:         return $this;
269:     }
270: 
271:     /**
272:      * @return null|string
273:      */
274:     public function getEtag()
275:     {
276:         return $this->etag ?: $this->content->getContentMd5();
277:     }
278: 
279:     public function setLastModified($lastModified)
280:     {
281:         $this->lastModified = $lastModified;
282:         return $this;
283:     }
284: 
285:     public function getLastModified()
286:     {
287:         return $this->lastModified;
288:     }
289: 
290:     public function primaryKeyField()
291:     {
292:         return 'name';
293:     }
294: 
295:     public function getUrl($path = null, array $params = array())
296:     {
297:         if (!$this->name) {
298:             throw new Exceptions\NoNameError(Lang::translate('Object has no name'));
299:         }
300: 
301:         return $this->container->getUrl($this->name);
302:     }
303: 
304:     public function update($params = array())
305:     {
306:         return $this->container->uploadObject($this->name, $this->content, $this->metadata->toArray());
307:     }
308: 
309:     /**
310:      * @param string $destination Path (`container/object') of new object
311:      * @return \Guzzle\Http\Message\Response
312:      */
313:     public function copy($destination)
314:     {
315:         return $this->getService()
316:             ->getClient()
317:             ->createRequest('COPY', $this->getUrl(), array(
318:                 'Destination' => (string) $destination
319:             ))
320:             ->send();
321:     }
322: 
323:     public function delete($params = array())
324:     {
325:         return $this->getService()->getClient()->delete($this->getUrl())->send();
326:     }
327: 
328:     /**
329:      * Get a temporary URL for this object.
330:      *
331:      * @link http://docs.rackspace.com/files/api/v1/cf-devguide/content/TempURL-d1a4450.html
332:      *
333:      * @param $expires Expiration time in seconds
334:      * @param $method  What method can use this URL? (`GET' or `PUT')
335:      * @return string
336:      * @throws \OpenCloud\Common\Exceptions\InvalidArgumentError
337:      * @throws \OpenCloud\Common\Exceptions\ObjectError
338:      *
339:      */
340:     public function getTemporaryUrl($expires, $method)
341:     {
342:         $method = strtoupper($method);
343:         $expiry = time() + (int) $expires;
344: 
345:         // check for proper method
346:         if ($method != 'GET' && $method != 'PUT') {
347:             throw new Exceptions\InvalidArgumentError(sprintf(
348:                 'Bad method [%s] for TempUrl; only GET or PUT supported',
349:                 $method
350:             ));
351:         }
352:         
353:         // @codeCoverageIgnoreStart
354:         if (!($secret = $this->getService()->getAccount()->getTempUrlSecret())) {
355:             throw new Exceptions\ObjectError('Cannot produce temporary URL without an account secret.');
356:         }
357:         // @codeCoverageIgnoreEnd
358: 
359:         $url  = $this->getUrl();
360:         $urlPath = urldecode($url->getPath());
361:         $body = sprintf("%s\n%d\n%s", $method, $expiry, $urlPath);
362:         $hash = hash_hmac('sha1', $body, $secret);
363: 
364:         return sprintf('%s?temp_url_sig=%s&temp_url_expires=%d', $url, $hash, $expiry);
365:     }
366: 
367:     /**
368:      * Remove this object from the CDN.
369:      *
370:      * @param null $email
371:      * @return mixed
372:      */
373:     public function purge($email = null)
374:     {
375:         if (!$cdn = $this->getContainer()->getCdn()) {
376:             return false;
377:         }
378: 
379:         $url = clone $cdn->getUrl();
380:         $url->addPath($this->name);
381: 
382:         $headers = ($email !== null) ? array('X-Purge-Email' => $email) : array();
383: 
384:         return $this->getService()
385:             ->getClient()
386:             ->delete($url, $headers)
387:             ->send();
388:     }
389: 
390:     /**
391:      * @param string $type
392:      * @return bool|Url
393:      */
394:     public function getPublicUrl($type = UrlType::CDN)
395:     {
396:         $cdn = $this->container->getCdn();
397:         
398:         switch ($type) {
399:             case UrlType::CDN:
400:                 $uri = $cdn->getCdnUri();
401:                 break;
402:             case UrlType::SSL:
403:                 $uri = $cdn->getCdnSslUri();
404:                 break;
405:             case UrlType::STREAMING:
406:                 $uri = $cdn->getCdnStreamingUri();
407:                 break;
408:             case UrlType::IOS_STREAMING:
409:                 $uri = $cdn->getIosStreamingUri();
410:                 break; 
411:         }
412:         
413:         return (isset($uri)) ? Url::factory($uri)->addPath($this->name) : false;
414:     }
415: 
416: }
PHP OpenCloud API API documentation generated by ApiGen 2.8.0