web/lib/Zend/Service/Rackspace/Files.php
changeset 808 6b6c2214f778
child 1230 68c69c656a2c
equal deleted inserted replaced
807:877f952ae2bd 808:6b6c2214f778
       
     1 <?php
       
     2 /**
       
     3  * Zend Framework
       
     4  *
       
     5  * LICENSE
       
     6  *
       
     7  * This source file is subject to the new BSD license that is bundled
       
     8  * with this package in the file LICENSE.txt.
       
     9  * It is also available through the world-wide-web at this URL:
       
    10  * http://framework.zend.com/license/new-bsd
       
    11  * If you did not receive a copy of the license and are unable to
       
    12  * obtain it through the world-wide-web, please send an email
       
    13  * to license@zend.com so we can send you a copy immediately.
       
    14  *
       
    15  * @category   Zend
       
    16  * @package    Zend_Service
       
    17  * @subpackage Rackspace
       
    18  * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
       
    19  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    20  */
       
    21 
       
    22 require_once 'Zend/Service/Rackspace/Abstract.php';
       
    23 require_once 'Zend/Service/Rackspace/Files/ContainerList.php';
       
    24 require_once 'Zend/Service/Rackspace/Files/ObjectList.php';
       
    25 require_once 'Zend/Service/Rackspace/Files/Container.php';
       
    26 require_once 'Zend/Service/Rackspace/Files/Object.php';
       
    27 
       
    28 class Zend_Service_Rackspace_Files extends Zend_Service_Rackspace_Abstract
       
    29 {
       
    30     const ERROR_CONTAINER_NOT_EMPTY            = 'The container is not empty, I cannot delete it.';
       
    31     const ERROR_CONTAINER_NOT_FOUND            = 'The container was not found.';
       
    32     const ERROR_OBJECT_NOT_FOUND               = 'The object was not found.';
       
    33     const ERROR_OBJECT_MISSING_PARAM           = 'Missing Content-Length or Content-Type header in the request';
       
    34     const ERROR_OBJECT_CHECKSUM                = 'Checksum of the file content failed';
       
    35     const ERROR_CONTAINER_EXIST                = 'The container already exists';
       
    36     const ERROR_PARAM_NO_NAME_CONTAINER        = 'You must specify the container name';
       
    37     const ERROR_PARAM_NO_NAME_OBJECT           = 'You must specify the object name';
       
    38     const ERROR_PARAM_NO_CONTENT               = 'You must specify the content of the object';
       
    39     const ERROR_PARAM_NO_NAME_SOURCE_CONTAINER = 'You must specify the source container name';
       
    40     const ERROR_PARAM_NO_NAME_SOURCE_OBJECT    = 'You must specify the source object name';
       
    41     const ERROR_PARAM_NO_NAME_DEST_CONTAINER   = 'You must specify the destination container name';
       
    42     const ERROR_PARAM_NO_NAME_DEST_OBJECT      = 'You must specify the destination object name';
       
    43     const ERROR_PARAM_NO_METADATA              = 'You must specify the metadata array';
       
    44     const ERROR_CDN_TTL_OUT_OF_RANGE           = 'TTL must be a number in seconds, min is 900 sec and maximum is 1577836800 (50 years)';
       
    45     const ERROR_PARAM_UPDATE_CDN               = 'You must specify at least one the parameters: ttl, cdn_enabled or log_retention';
       
    46     const HEADER_CONTENT_TYPE                  = 'Content-Type';
       
    47     const HEADER_HASH                          = 'Etag';
       
    48     const HEADER_LAST_MODIFIED                 = 'Last-Modified';
       
    49     const HEADER_CONTENT_LENGTH                = 'Content-Length';
       
    50     const HEADER_COPY_FROM                     = 'X-Copy-From';
       
    51     const METADATA_OBJECT_HEADER               = "X-Object-Meta-";
       
    52     const METADATA_CONTAINER_HEADER            = "X-Container-Meta-";
       
    53     const CDN_URI                              = "X-CDN-URI";
       
    54     const CDN_SSL_URI                          = "X-CDN-SSL-URI";
       
    55     const CDN_ENABLED                          = "X-CDN-Enabled";
       
    56     const CDN_LOG_RETENTION                    = "X-Log-Retention";
       
    57     const CDN_ACL_USER_AGENT                   = "X-User-Agent-ACL";
       
    58     const CDN_ACL_REFERRER                     = "X-Referrer-ACL";
       
    59     const CDN_TTL                              = "X-TTL";
       
    60     const CDN_TTL_MIN                          = 900;
       
    61     const CDN_TTL_MAX                          = 1577836800;
       
    62     const CDN_EMAIL                            = "X-Purge-Email";
       
    63     const ACCOUNT_CONTAINER_COUNT              = "X-Account-Container-Count";
       
    64     const ACCOUNT_BYTES_USED                   = "X-Account-Bytes-Used";
       
    65     const ACCOUNT_OBJ_COUNT                    = "X-Account-Object-Count";
       
    66     const CONTAINER_OBJ_COUNT                  = "X-Container-Object-Count";
       
    67     const CONTAINER_BYTES_USE                  = "X-Container-Bytes-Used";
       
    68     const MANIFEST_OBJECT_HEADER               = "X-Object-Manifest";
       
    69 
       
    70     /**
       
    71      * Return the total count of containers
       
    72      *
       
    73      * @return integer
       
    74      */
       
    75     public function getCountContainers()
       
    76     {
       
    77         $data= $this->getInfoAccount();
       
    78         return $data['tot_containers'];
       
    79     }
       
    80     /**
       
    81      * Return the size in bytes of all the containers
       
    82      *
       
    83      * @return integer
       
    84      */
       
    85     public function getSizeContainers()
       
    86     {
       
    87         $data= $this->getInfoAccount();
       
    88         return $data['size_containers'];
       
    89     }
       
    90     /**
       
    91      * Return the count of objects contained in all the containers
       
    92      *
       
    93      * @return integer
       
    94      */
       
    95     public function getCountObjects()
       
    96     {
       
    97         $data= $this->getInfoAccount();
       
    98         return $data['tot_objects'];
       
    99     }
       
   100     /**
       
   101      * Get all the containers
       
   102      *
       
   103      * @param array $options
       
   104      * @return Zend_Service_Rackspace_Files_ContainerList|boolean
       
   105      */
       
   106     public function getContainers($options=array())
       
   107     {
       
   108         $result= $this->httpCall($this->getStorageUrl(),'GET',null,$options);
       
   109         if ($result->isSuccessful()) {
       
   110             return new Zend_Service_Rackspace_Files_ContainerList($this,json_decode($result->getBody(),true));
       
   111         }
       
   112         return false;
       
   113     }
       
   114     /**
       
   115      * Get all the CDN containers
       
   116      *
       
   117      * @param array $options
       
   118      * @return array|boolean
       
   119      */
       
   120     public function getCdnContainers($options=array())
       
   121     {
       
   122         $options['enabled_only']= true;
       
   123         $result= $this->httpCall($this->getCdnUrl(),'GET',null,$options);
       
   124         if ($result->isSuccessful()) {
       
   125             return new Zend_Service_Rackspace_Files_ContainerList($this,json_decode($result->getBody(),true));
       
   126         }
       
   127         return false;
       
   128     }
       
   129     /**
       
   130      * Get the metadata information of the accounts:
       
   131      * - total count containers
       
   132      * - size in bytes of all the containers
       
   133      * - total objects in all the containers
       
   134      * 
       
   135      * @return array|boolean
       
   136      */
       
   137     public function getInfoAccount()
       
   138     {
       
   139         $result= $this->httpCall($this->getStorageUrl(),'HEAD');
       
   140         if ($result->isSuccessful()) {
       
   141             $output= array(
       
   142                 'tot_containers'  => $result->getHeader(self::ACCOUNT_CONTAINER_COUNT),
       
   143                 'size_containers' => $result->getHeader(self::ACCOUNT_BYTES_USED),
       
   144                 'tot_objects'     => $result->getHeader(self::ACCOUNT_OBJ_COUNT)
       
   145             );
       
   146             return $output;
       
   147         }
       
   148         return false;
       
   149     }
       
   150     /**
       
   151      * Get all the objects of a container
       
   152      *
       
   153      * @param string $container
       
   154      * @param array $options
       
   155      * @return  Zend_Service_Rackspace_Files_ObjectList|boolean
       
   156      */
       
   157     public function getObjects($container,$options=array())
       
   158     {
       
   159         if (empty($container)) {
       
   160             require_once 'Zend/Service/Rackspace/Exception.php';
       
   161             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
       
   162         }
       
   163         $result= $this->httpCall($this->getStorageUrl().'/'.rawurlencode($container),'GET',null,$options);
       
   164         if ($result->isSuccessful()) {
       
   165             return new Zend_Service_Rackspace_Files_ObjectList($this,json_decode($result->getBody(),true),$container);
       
   166         }
       
   167         return false;
       
   168     }
       
   169     /**
       
   170      * Create a container
       
   171      *
       
   172      * @param string $container
       
   173      * @param array $metadata
       
   174      * @return Zend_Service_Rackspace_Files_Container|boolean
       
   175      */
       
   176     public function createContainer($container,$metadata=array())
       
   177     {
       
   178         if (empty($container)) {
       
   179             require_once 'Zend/Service/Rackspace/Exception.php';
       
   180             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
       
   181         }
       
   182         $headers=array();
       
   183         if (!empty($metadata)) {
       
   184             foreach ($metadata as $key => $value) {
       
   185                 $headers[self::METADATA_CONTAINER_HEADER.rawurlencode(strtolower($key))]= rawurlencode($value);
       
   186             }
       
   187         }
       
   188         $result= $this->httpCall($this->getStorageUrl().'/'.rawurlencode($container),'PUT',$headers);
       
   189         $status= $result->getStatus();
       
   190         switch ($status) {
       
   191             case '201': // break intentionally omitted
       
   192                 $data= array(
       
   193                     'name' => $container
       
   194                 );
       
   195                 return new Zend_Service_Rackspace_Files_Container($this,$data);
       
   196             case '202':
       
   197                 $this->errorMsg= self::ERROR_CONTAINER_EXIST;
       
   198                 break;
       
   199             default:
       
   200                 $this->errorMsg= $result->getBody();
       
   201                 break;
       
   202         }
       
   203         $this->errorCode= $status;
       
   204         return false;
       
   205     }
       
   206     /**
       
   207      * Delete a container (only if it's empty)
       
   208      *
       
   209      * @param sting $container
       
   210      * @return boolean
       
   211      */
       
   212     public function deleteContainer($container)
       
   213     {
       
   214         if (empty($container)) {
       
   215             require_once 'Zend/Service/Rackspace/Exception.php';
       
   216             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
       
   217         }
       
   218         $result= $this->httpCall($this->getStorageUrl().'/'.rawurlencode($container),'DELETE');
       
   219         $status= $result->getStatus();
       
   220         switch ($status) {
       
   221             case '204': // break intentionally omitted
       
   222                 return true;
       
   223             case '409':
       
   224                 $this->errorMsg= self::ERROR_CONTAINER_NOT_EMPTY;
       
   225                 break;
       
   226             case '404':
       
   227                 $this->errorMsg= self::ERROR_CONTAINER_NOT_FOUND;
       
   228                 break;
       
   229             default:
       
   230                 $this->errorMsg= $result->getBody();
       
   231                 break;
       
   232         }
       
   233         $this->errorCode= $status;
       
   234         return false;
       
   235     }
       
   236     /**
       
   237      * Get the metadata of a container
       
   238      *
       
   239      * @param string $container
       
   240      * @return array|boolean
       
   241      */
       
   242     public function getMetadataContainer($container)
       
   243     {
       
   244         if (empty($container)) {
       
   245             require_once 'Zend/Service/Rackspace/Exception.php';
       
   246             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
       
   247         }
       
   248         $result= $this->httpCall($this->getStorageUrl().'/'.rawurlencode($container),'HEAD');
       
   249         $status= $result->getStatus();
       
   250         switch ($status) {
       
   251             case '204': // break intentionally omitted
       
   252                 $headers= $result->getHeaders();
       
   253                 $count= strlen(self::METADATA_CONTAINER_HEADER);
       
   254                 // Zend_Http_Response alters header name in array key, so match our header to what will be in the headers array
       
   255                 $headerName = ucwords(strtolower(self::METADATA_CONTAINER_HEADER)); 
       
   256                 $metadata= array();
       
   257                 foreach ($headers as $type => $value) {
       
   258                     if (strpos($type,$headerName)!==false) {
       
   259                         $metadata[strtolower(substr($type, $count))]= $value;
       
   260                     }
       
   261                 }
       
   262                 $data= array (
       
   263                     'name'     => $container,
       
   264                     'count'    => $result->getHeader(self::CONTAINER_OBJ_COUNT),
       
   265                     'bytes'    => $result->getHeader(self::CONTAINER_BYTES_USE),
       
   266                     'metadata' => $metadata
       
   267                 );
       
   268                 return $data;
       
   269             case '404':
       
   270                 $this->errorMsg= self::ERROR_CONTAINER_NOT_FOUND;
       
   271                 break;
       
   272             default:
       
   273                 $this->errorMsg= $result->getBody();
       
   274                 break;
       
   275         }
       
   276         $this->errorCode= $status;
       
   277         return false;
       
   278     }
       
   279     /**
       
   280      * Get a container
       
   281      * 
       
   282      * @param string $container
       
   283      * @return Container|boolean
       
   284      */
       
   285     public function getContainer($container) {
       
   286         $result= $this->getMetadataContainer($container);
       
   287         if (!empty($result)) {
       
   288             return new Zend_Service_Rackspace_Files_Container($this,$result);
       
   289         }
       
   290         return false;
       
   291     }
       
   292     /**
       
   293      * Get an object in a container
       
   294      *
       
   295      * @param string $container
       
   296      * @param string $object
       
   297      * @param array $headers
       
   298      * @return Zend_Service_Rackspace_Files_Object|boolean
       
   299      */
       
   300     public function getObject($container,$object,$headers=array())
       
   301     {
       
   302         if (empty($container)) {
       
   303             require_once 'Zend/Service/Rackspace/Exception.php';
       
   304             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
       
   305         }
       
   306         if (empty($object)) {
       
   307             require_once 'Zend/Service/Rackspace/Exception.php';
       
   308             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_OBJECT);
       
   309         }
       
   310         $result= $this->httpCall($this->getStorageUrl().'/'.rawurlencode($container).'/'.rawurlencode($object),'GET',$headers);
       
   311         $status= $result->getStatus();
       
   312         switch ($status) {
       
   313             case '200': // break intentionally omitted
       
   314                 $data= array(
       
   315                     'name'          => $object,
       
   316                     'container'     => $container,
       
   317                     'hash'          => $result->getHeader(self::HEADER_HASH),
       
   318                     'bytes'         => $result->getHeader(self::HEADER_CONTENT_LENGTH),
       
   319                     'last_modified' => $result->getHeader(self::HEADER_LAST_MODIFIED),
       
   320                     'content_type'  => $result->getHeader(self::HEADER_CONTENT_TYPE),
       
   321                     'content'       => $result->getBody()
       
   322                 );
       
   323                 return new Zend_Service_Rackspace_Files_Object($this,$data);
       
   324             case '404':
       
   325                 $this->errorMsg= self::ERROR_OBJECT_NOT_FOUND;
       
   326                 break;
       
   327             default:
       
   328                 $this->errorMsg= $result->getBody();
       
   329                 break;
       
   330         }
       
   331         $this->errorCode= $status;
       
   332         return false;
       
   333     }
       
   334     /**
       
   335      * Store a file in a container
       
   336      *
       
   337      * @param string $container
       
   338      * @param string $object
       
   339      * @param string $content
       
   340      * @param array $metadata
       
   341      * @param string $content_type
       
   342      *
       
   343      * @return boolean
       
   344      */
       
   345     public function storeObject($container,$object,$content,$metadata=array(),$content_type=null) {
       
   346         if (empty($container)) {
       
   347             require_once 'Zend/Service/Rackspace/Exception.php';
       
   348             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
       
   349         }
       
   350         if (empty($object)) {
       
   351             require_once 'Zend/Service/Rackspace/Exception.php';
       
   352             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_OBJECT);
       
   353         }
       
   354         if (empty($content)) {
       
   355             require_once 'Zend/Service/Rackspace/Exception.php';
       
   356             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_CONTENT);
       
   357         }
       
   358         if (!empty($content_type)) {
       
   359            $headers[self::HEADER_CONTENT_TYPE]= $content_type;
       
   360         }
       
   361         if (!empty($metadata) && is_array($metadata)) {
       
   362             foreach ($metadata as $key => $value) {
       
   363                 $headers[self::METADATA_OBJECT_HEADER.$key]= $value;
       
   364             }
       
   365         }
       
   366         $headers[self::HEADER_HASH]= md5($content);
       
   367         $headers[self::HEADER_CONTENT_LENGTH]= strlen($content);
       
   368         $result= $this->httpCall($this->getStorageUrl().'/'.rawurlencode($container).'/'.rawurlencode($object),'PUT',$headers,null,$content);
       
   369         $status= $result->getStatus();
       
   370         switch ($status) {
       
   371             case '201': // break intentionally omitted
       
   372                 return true;
       
   373             case '412':
       
   374                 $this->errorMsg= self::ERROR_OBJECT_MISSING_PARAM;
       
   375                 break;
       
   376             case '422':
       
   377                 $this->errorMsg= self::ERROR_OBJECT_CHECKSUM;
       
   378                 break;
       
   379             default:
       
   380                 $this->errorMsg= $result->getBody();
       
   381                 break;
       
   382         }
       
   383         $this->errorCode= $status;
       
   384         return false;
       
   385     }
       
   386     /**
       
   387      * Delete an object in a container
       
   388      *
       
   389      * @param string $container
       
   390      * @param string $object
       
   391      * @return boolean
       
   392      */
       
   393     public function deleteObject($container,$object) {
       
   394         if (empty($container)) {
       
   395             require_once 'Zend/Service/Rackspace/Exception.php';
       
   396             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
       
   397         }
       
   398         if (empty($object)) {
       
   399             require_once 'Zend/Service/Rackspace/Exception.php';
       
   400             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_OBJECT);
       
   401         }
       
   402         $result= $this->httpCall($this->getStorageUrl().'/'.rawurlencode($container).'/'.rawurlencode($object),'DELETE');
       
   403         $status= $result->getStatus();
       
   404         switch ($status) {
       
   405             case '204': // break intentionally omitted
       
   406                 return true;
       
   407             case '404':
       
   408                 $this->errorMsg= self::ERROR_OBJECT_NOT_FOUND;
       
   409                 break;
       
   410             default:
       
   411                 $this->errorMsg= $result->getBody();
       
   412                 break;
       
   413         }
       
   414         $this->errorCode= $status;
       
   415         return false;
       
   416     }
       
   417     /**
       
   418      * Copy an object from a container to another
       
   419      *
       
   420      * @param string $container_source
       
   421      * @param string $obj_source
       
   422      * @param string $container_dest
       
   423      * @param string $obj_dest
       
   424      * @param array $metadata
       
   425      * @param string $content_type
       
   426      * @return boolean
       
   427      */
       
   428     public function copyObject($container_source,$obj_source,$container_dest,$obj_dest,$metadata=array(),$content_type=null) {
       
   429         if (empty($container_source)) {
       
   430             require_once 'Zend/Service/Rackspace/Exception.php';
       
   431             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_SOURCE_CONTAINER);
       
   432         }
       
   433         if (empty($obj_source)) {
       
   434             require_once 'Zend/Service/Rackspace/Exception.php';
       
   435             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_SOURCE_OBJECT);
       
   436         }
       
   437         if (empty($container_dest)) {
       
   438             require_once 'Zend/Service/Rackspace/Exception.php';
       
   439             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_DEST_CONTAINER);
       
   440         }
       
   441         if (empty($obj_dest)) {
       
   442             require_once 'Zend/Service/Rackspace/Exception.php';
       
   443             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_DEST_OBJECT);
       
   444         }
       
   445         $headers= array(
       
   446             self::HEADER_COPY_FROM => '/'.rawurlencode($container_source).'/'.rawurlencode($obj_source),
       
   447             self::HEADER_CONTENT_LENGTH => 0
       
   448         );
       
   449         if (!empty($content_type)) {
       
   450             $headers[self::HEADER_CONTENT_TYPE]= $content_type;
       
   451         }
       
   452         if (!empty($metadata) && is_array($metadata)) {
       
   453             foreach ($metadata as $key => $value) {
       
   454                 $headers[self::METADATA_OBJECT_HEADER.$key]= $value;
       
   455             }
       
   456         }
       
   457         $result= $this->httpCall($this->getStorageUrl().'/'.rawurlencode($container_dest).'/'.rawurlencode($obj_dest),'PUT',$headers);
       
   458         $status= $result->getStatus();
       
   459         switch ($status) {
       
   460             case '201': // break intentionally omitted
       
   461                 return true;
       
   462             default:
       
   463                 $this->errorMsg= $result->getBody();
       
   464                 break;
       
   465         }
       
   466         $this->errorCode= $status;
       
   467         return false;
       
   468     }
       
   469     /**
       
   470      * Get the metadata of an object
       
   471      *
       
   472      * @param string $container
       
   473      * @param string $object
       
   474      * @return array|boolean
       
   475      */
       
   476     public function getMetadataObject($container,$object) {
       
   477         if (empty($container)) {
       
   478             require_once 'Zend/Service/Rackspace/Exception.php';
       
   479             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
       
   480         }
       
   481         if (empty($object)) {
       
   482             require_once 'Zend/Service/Rackspace/Exception.php';
       
   483             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_OBJECT);
       
   484         }
       
   485         $result= $this->httpCall($this->getStorageUrl().'/'.rawurlencode($container).'/'.rawurlencode($object),'HEAD');
       
   486         $status= $result->getStatus();
       
   487         switch ($status) {
       
   488             case '200': // break intentionally omitted
       
   489                 $headers= $result->getHeaders();
       
   490                 $count= strlen(self::METADATA_OBJECT_HEADER);
       
   491                 // Zend_Http_Response alters header name in array key, so match our header to what will be in the headers array
       
   492                 $headerName = ucwords(strtolower(self::METADATA_OBJECT_HEADER)); 
       
   493                 $metadata= array();
       
   494                 foreach ($headers as $type => $value) {
       
   495                     if (strpos($type,$headerName)!==false) {
       
   496                         $metadata[strtolower(substr($type, $count))]= $value;
       
   497                     }
       
   498                 }
       
   499                 $data= array (
       
   500                     'name'          => $object,
       
   501                     'container'     => $container,
       
   502                     'hash'          => $result->getHeader(self::HEADER_HASH),
       
   503                     'bytes'         => $result->getHeader(self::HEADER_CONTENT_LENGTH),
       
   504                     'content_type'  => $result->getHeader(self::HEADER_CONTENT_TYPE),
       
   505                     'last_modified' => $result->getHeader(self::HEADER_LAST_MODIFIED),
       
   506                     'metadata'      => $metadata
       
   507                 );
       
   508                 return $data;
       
   509             case '404':
       
   510                 $this->errorMsg= self::ERROR_OBJECT_NOT_FOUND;
       
   511                 break;
       
   512             default:
       
   513                 $this->errorMsg= $result->getBody();
       
   514                 break;
       
   515         }
       
   516         $this->errorCode= $status;
       
   517         return false;
       
   518     }
       
   519     /**
       
   520      * Set the metadata of a object in a container
       
   521      * The old metadata values are replaced with the new one
       
   522      * 
       
   523      * @param string $container
       
   524      * @param string $object
       
   525      * @param array $metadata
       
   526      * @return boolean
       
   527      */
       
   528     public function setMetadataObject($container,$object,$metadata)
       
   529     {
       
   530         if (empty($container)) {
       
   531             require_once 'Zend/Service/Rackspace/Exception.php';
       
   532             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
       
   533         }
       
   534         if (empty($object)) {
       
   535             require_once 'Zend/Service/Rackspace/Exception.php';
       
   536             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_OBJECT);
       
   537         }
       
   538         if (empty($metadata) || !is_array($metadata)) {
       
   539             require_once 'Zend/Service/Rackspace/Exception.php';
       
   540             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_OBJECT);
       
   541         }
       
   542         $headers=array();
       
   543         foreach ($metadata as $key => $value) {
       
   544             $headers[self::METADATA_OBJECT_HEADER.$key]= $value;
       
   545         }
       
   546         $result= $this->httpCall($this->getStorageUrl().'/'.rawurlencode($container).'/'.rawurlencode($object),'POST',$headers);
       
   547         $status= $result->getStatus();
       
   548         switch ($status) {
       
   549             case '202': // break intentionally omitted
       
   550                 return true;
       
   551             case '404':
       
   552                 $this->errorMsg= self::ERROR_OBJECT_NOT_FOUND;
       
   553                 break;
       
   554             default:
       
   555                 $this->errorMsg= $result->getBody();
       
   556                 break;
       
   557         }
       
   558         $this->errorCode= $status;
       
   559         return false;
       
   560     }
       
   561     /**
       
   562      * Enable the CDN for a container
       
   563      *
       
   564      * @param  string $container
       
   565      * @param  integer $ttl
       
   566      * @return array|boolean
       
   567      */
       
   568     public function enableCdnContainer ($container,$ttl=self::CDN_TTL_MIN) {
       
   569         if (empty($container)) {
       
   570             require_once 'Zend/Service/Rackspace/Exception.php';
       
   571             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
       
   572         }
       
   573         $headers=array();
       
   574         if (is_numeric($ttl) && ($ttl>=self::CDN_TTL_MIN) && ($ttl<=self::CDN_TTL_MAX)) {
       
   575             $headers[self::CDN_TTL]= $ttl;
       
   576         } else {
       
   577             require_once 'Zend/Service/Rackspace/Exception.php';
       
   578             throw new Zend_Service_Rackspace_Exception(self::ERROR_CDN_TTL_OUT_OF_RANGE);
       
   579         }
       
   580         $result= $this->httpCall($this->getCdnUrl().'/'.rawurlencode($container),'PUT',$headers);
       
   581         $status= $result->getStatus();
       
   582         switch ($status) {
       
   583             case '201':
       
   584             case '202': // break intentionally omitted
       
   585                 $data= array (
       
   586                     'cdn_uri'     => $result->getHeader(self::CDN_URI),
       
   587                     'cdn_uri_ssl' => $result->getHeader(self::CDN_SSL_URI)
       
   588                 );
       
   589                 return $data;
       
   590             case '404':
       
   591                 $this->errorMsg= self::ERROR_CONTAINER_NOT_FOUND;
       
   592                 break;
       
   593             default:
       
   594                 $this->errorMsg= $result->getBody();
       
   595                 break;
       
   596         }
       
   597         $this->errorCode= $status;
       
   598         return false;
       
   599     }
       
   600     /**
       
   601      * Update the attribute of a CDN container
       
   602      *
       
   603      * @param  string $container
       
   604      * @param  integer $ttl
       
   605      * @param  boolean $cdn_enabled
       
   606      * @param  boolean $log
       
   607      * @return boolean
       
   608      */
       
   609     public function updateCdnContainer($container,$ttl=null,$cdn_enabled=null,$log=null)
       
   610     {
       
   611         if (empty($container)) {
       
   612             require_once 'Zend/Service/Rackspace/Exception.php';
       
   613             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
       
   614         }
       
   615         if (empty($ttl) && (!isset($cdn_enabled)) && (!isset($log))) {
       
   616             require_once 'Zend/Service/Rackspace/Exception.php';
       
   617             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_UPDATE_CDN);
       
   618         }
       
   619         $headers=array();
       
   620         if (isset($ttl)) {
       
   621             if (is_numeric($ttl) && ($ttl>=self::CDN_TTL_MIN) && ($ttl<=self::CDN_TTL_MAX)) {
       
   622                 $headers[self::CDN_TTL]= $ttl;
       
   623             } else {
       
   624                 require_once 'Zend/Service/Rackspace/Exception.php';
       
   625                 throw new Zend_Service_Rackspace_Exception(self::ERROR_CDN_TTL_OUT_OF_RANGE);
       
   626             }
       
   627         }
       
   628         if (isset($cdn_enabled)) {
       
   629             if ($cdn_enabled===true) {
       
   630                 $headers[self::CDN_ENABLED]= 'true';
       
   631             } else {
       
   632                 $headers[self::CDN_ENABLED]= 'false';
       
   633             }
       
   634         }
       
   635         if (isset($log)) {
       
   636             if ($log===true) {
       
   637                 $headers[self::CDN_LOG_RETENTION]= 'true';
       
   638             } else  {
       
   639                 $headers[self::CDN_LOG_RETENTION]= 'false';
       
   640             }
       
   641         }
       
   642         $result= $this->httpCall($this->getCdnUrl().'/'.rawurlencode($container),'POST',$headers);
       
   643         $status= $result->getStatus();
       
   644         switch ($status) {
       
   645             case '200':
       
   646             case '202': // break intentionally omitted
       
   647                 return true;
       
   648             case '404':
       
   649                 $this->errorMsg= self::ERROR_CONTAINER_NOT_FOUND;
       
   650                 break;
       
   651             default:
       
   652                 $this->errorMsg= $result->getBody();
       
   653                 break;
       
   654         }
       
   655         $this->errorCode= $status;
       
   656         return false;
       
   657     }
       
   658     /**
       
   659      * Get the information of a Cdn container
       
   660      *
       
   661      * @param string $container
       
   662      * @return array|boolean
       
   663      */
       
   664     public function getInfoCdnContainer($container) {
       
   665         if (empty($container)) {
       
   666             require_once 'Zend/Service/Rackspace/Exception.php';
       
   667             throw new Zend_Service_Rackspace_Exception(self::ERROR_PARAM_NO_NAME_CONTAINER);
       
   668         }
       
   669         $result= $this->httpCall($this->getCdnUrl().'/'.rawurlencode($container),'HEAD');
       
   670         $status= $result->getStatus();
       
   671         switch ($status) {
       
   672             case '204': // break intentionally omitted
       
   673                 $data= array (
       
   674                     'ttl'         => $result->getHeader(self::CDN_TTL),
       
   675                     'cdn_uri'     => $result->getHeader(self::CDN_URI),
       
   676                     'cdn_uri_ssl' => $result->getHeader(self::CDN_SSL_URI)
       
   677                 );
       
   678                 $data['cdn_enabled']= (strtolower($result->getHeader(self::CDN_ENABLED))!=='false');
       
   679                 $data['log_retention']= (strtolower($result->getHeader(self::CDN_LOG_RETENTION))!=='false');
       
   680                 return $data;
       
   681             case '404':
       
   682                 $this->errorMsg= self::ERROR_CONTAINER_NOT_FOUND;
       
   683                 break;
       
   684             default:
       
   685                 $this->errorMsg= $result->getBody();
       
   686                 break;
       
   687         }
       
   688         $this->errorCode= $status;
       
   689         return false;
       
   690     }
       
   691 }