/**
  * Queries the server for the location constraint for this bucket and
  * propagates the locationConstraint property.
  *
  * @return void
  * @throws Services_Amazon_S3_Exception
  */
 public function loadLocationConstraint()
 {
     $response = $this->s3->sendRequest($this, '?location');
     $xPath = Services_Amazon_S3::getDOMXPath($response);
     $s = $xPath->evaluate('string(/s3:LocationConstraint)');
     $this->locationConstraint = $s ? $s : false;
 }
 /**
  * Copies data to this object from another S3 object
  *
  * @param Services_Amazon_S3_Resource_Object $source       the object from
  *        which to copy.
  * @param boolean                            $copyMetadata optional. Whether
  *        or not to copy the metadata from the <kbd>$source</kbd> or replace
  *        it with the metadata specified in this object. If true, the meta-
  *        data is copied from the source object. If false, the metadata set
  *        on this object is saved. Defaults to true.
  *
  * @return void
  */
 public function copyFrom(Services_Amazon_S3_Resource_Object $source, $copyMetadata = true)
 {
     // when overwriting an object, the existing acl is lost
     if ($this->exists && !$this->acl) {
         $this->loadACL();
     }
     $headers = array();
     $headers['x-amz-copy-source'] = '/' . rawurlencode($source->bucket->name) . '/' . rawurlencode($source->key);
     if ($copyMetadata) {
         $headers['x-amz-metadata-directive'] = 'COPY';
     } else {
         $headers['x-amz-metadata-directive'] = 'REPLACE';
         if ($this->contentType) {
             $headers['content-type'] = $this->contentType;
         }
         foreach ($this->userMetadata as $name => $value) {
             $headers['x-amz-meta-' . strtolower($name)] = $value;
         }
     }
     if (!isset($headers['content-type'])) {
         // If no content-type is specified, the HTTP_Request2 package
         // sets a content-type of 'application/x-www-form-urlencoded'.
         // Amazon S3 says if the content-type is not specified, it should
         // be 'binary/octet-stream'. We set it explicitly here so the
         // correct value is sent and the request is signed correctly.
         $headers['content-type'] = 'binary/octet-stream';
     }
     foreach ($this->httpHeaders as $name => $value) {
         $name = strtolower($name);
         if (in_array($name, self::$allowedHeaders)) {
             $headers[$name] = $value;
         }
     }
     if (is_string($this->acl)) {
         $headers['x-amz-acl'] = $this->acl;
     }
     $response = $this->s3->sendRequest($this, false, null, HTTP_Request2::METHOD_PUT, $headers);
     $xPath = Services_Amazon_S3::getDOMXPath($response);
     $this->eTag = trim($xPath->evaluate('string(s3:CopyObjectResult/s3:ETag)'), '"');
     $this->lastModified = $xPath->evaluate('string(s3:CopyObjectResult/s3:LastModified)');
     if ($this->acl instanceof Services_Amazon_S3_AccessControlList) {
         $this->acl->save();
     }
 }
 /**
  * Fetches a list of the next $maxKeys entries from the web service.
  *
  * @return void
  * @see Services_Amazon_S3::$maxKeys
  * @throws Services_Amazon_S3_Exception
  */
 private function _sendRequest()
 {
     $this->_isFirstPage = !$this->_isTruncated;
     $query = array();
     if ($this->maxKeys) {
         $query['max-keys'] = $this->maxKeys;
     }
     if ($this->_isTruncated) {
         $query['marker'] = $this->_nextMarker;
     }
     if ($this->delimiter) {
         $query['delimiter'] = $this->delimiter;
     }
     if ($this->prefix) {
         $query['prefix'] = $this->prefix;
     }
     $response = $this->bucket->s3->sendRequest($this->bucket, '', $query);
     $this->_xPath = Services_Amazon_S3::getDOMXPath($response);
     $this->_nodeList = $this->_xPath->evaluate('/s3:ListBucketResult/s3:Contents | ' . '/s3:ListBucketResult/s3:CommonPrefixes/s3:Prefix/text()');
     $this->_isTruncated = $this->_xPath->evaluate('string(/s3:ListBucketResult/s3:IsTruncated) = "true"');
     // <NextMarker> is only present when a delimiter is specified.
     if ($this->delimiter) {
         $this->_nextMarker = $this->_xPath->evaluate('string(/s3:ListBucketResult/s3:NextMarker)');
     } else {
         $this->_nextMarker = $this->_xPath->evaluate('string(/s3:ListBucketResult/s3:Contents[last()]/s3:Key)');
     }
     $this->_currentIndex = 0;
 }
 /**
  * Loads this ACL from the server.
  *
  * @return void
  * @throws Services_Amazon_S3_Exception
  */
 public function load()
 {
     $response = $this->resource->s3->sendRequest($this->resource, '?acl');
     $xPath = Services_Amazon_S3::getDOMXPath($response);
     $this->ownerId = $xPath->evaluate('string(/s3:AccessControlPolicy/s3:Owner/s3:ID)');
     $nlGrants = $xPath->evaluate('/s3:AccessControlPolicy/s3:AccessControlList/s3:Grant');
     $this->_grantees = array();
     foreach ($nlGrants as $elGrant) {
         $type = $xPath->evaluate('string(s3:Grantee/@xsi:type)', $elGrant);
         $nlGrantee = $xPath->evaluate('s3:Grantee', $elGrant);
         $elGrantee = $nlGrantee->item(0);
         switch ($type) {
             case self::TYPE_CANONICAL_USER:
                 $grantee = array('type' => self::TYPE_CANONICAL_USER, 'ID' => $xPath->evaluate('string(s3:ID)', $elGrantee), 'displayName' => $xPath->evaluate('string(s3:DisplayName)', $elGrantee));
                 break;
             case self::TYPE_GROUP:
                 $grantee = array('type' => self::TYPE_GROUP, 'URI' => $xPath->evaluate('string(s3:URI)', $elGrantee));
                 break;
             default:
                 // TYPE_AMAZON_CUSTOMER_BY_EMAIL is never sent by the server
                 throw new Services_Amazon_S3_Exception('Invalid grantee type : ' . $type, $response);
         }
         $key = $this->_getGranteeKey($grantee);
         if (!isset($this->_grantees[$key])) {
             $this->_grantees[$key] = $grantee;
             $this->_grantees[$key]['permissions'] = 0;
         }
         $permission = $xPath->evaluate('string(s3:Permission)', $elGrant);
         if (!isset(self::$_string2flag[$permission])) {
             throw new Services_Amazon_S3_Exception('Invalid permission value: ' . $permission, $response);
         }
         $this->_grantees[$key]['permissions'] |= self::$_string2flag[$permission];
     }
 }