File indexing completed on 2024-12-29 05:28:04
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Service_WindowsAzure 0017 * @subpackage Storage 0018 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0019 * @license http://todo name_todo 0020 * @version $Id$ 0021 */ 0022 0023 /** 0024 * @see Zend_Service_WindowsAzure_Storage 0025 */ 0026 // require_once 'Zend/Service/WindowsAzure/Storage.php'; 0027 0028 /** 0029 * @see Zend_Service_WindowsAzure_Storage_BlobInstance 0030 */ 0031 // require_once 'Zend/Service/WindowsAzure/Storage/BlobInstance.php'; 0032 0033 /** 0034 * @see Zend_Service_WindowsAzure_Storage_BlobContainer 0035 */ 0036 // require_once 'Zend/Service/WindowsAzure/Storage/BlobContainer.php'; 0037 0038 /** 0039 * @see Zend_Service_WindowsAzure_Storage_PageRegionInstance 0040 */ 0041 // require_once 'Zend/Service/WindowsAzure/Storage/PageRegionInstance.php'; 0042 0043 /** 0044 * @see Zend_Service_WindowsAzure_Storage_LeaseInstance 0045 */ 0046 // require_once 'Zend/Service/WindowsAzure/Storage/LeaseInstance.php'; 0047 0048 /** 0049 * @see Zend_Service_WindowsAzure_Storage_Blob_Stream 0050 */ 0051 // require_once 'Zend/Service/WindowsAzure/Storage/Blob/Stream.php'; 0052 0053 /** 0054 * @see Zend_Service_WindowsAzure_Credentials_SharedAccessSignature 0055 */ 0056 // require_once 'Zend/Service/WindowsAzure/Credentials/SharedAccessSignature.php'; 0057 /** 0058 * @category Zend 0059 * @package Zend_Service_WindowsAzure 0060 * @subpackage Storage 0061 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0062 * @license http://framework.zend.com/license/new-bsd New BSD License 0063 */ 0064 class Zend_Service_WindowsAzure_Storage_Blob extends Zend_Service_WindowsAzure_Storage 0065 { 0066 /** 0067 * ACL - Private access 0068 */ 0069 const ACL_PRIVATE = null; 0070 0071 /** 0072 * ACL - Public access (read all blobs) 0073 * 0074 * @deprecated Use ACL_PUBLIC_CONTAINER or ACL_PUBLIC_BLOB instead. 0075 */ 0076 const ACL_PUBLIC = 'container'; 0077 0078 /** 0079 * ACL - Blob Public access (read all blobs) 0080 */ 0081 const ACL_PUBLIC_BLOB = 'blob'; 0082 0083 /** 0084 * ACL - Container Public access (enumerate and read all blobs) 0085 */ 0086 const ACL_PUBLIC_CONTAINER = 'container'; 0087 0088 /** 0089 * Blob lease constants 0090 */ 0091 const LEASE_ACQUIRE = 'acquire'; 0092 const LEASE_RENEW = 'renew'; 0093 const LEASE_RELEASE = 'release'; 0094 const LEASE_BREAK = 'break'; 0095 0096 /** 0097 * Maximal blob size (in bytes) 0098 */ 0099 const MAX_BLOB_SIZE = 67108864; 0100 0101 /** 0102 * Maximal blob transfer size (in bytes) 0103 */ 0104 const MAX_BLOB_TRANSFER_SIZE = 4194304; 0105 0106 /** 0107 * Blob types 0108 */ 0109 const BLOBTYPE_BLOCK = 'BlockBlob'; 0110 const BLOBTYPE_PAGE = 'PageBlob'; 0111 0112 /** 0113 * Put page write options 0114 */ 0115 const PAGE_WRITE_UPDATE = 'update'; 0116 const PAGE_WRITE_CLEAR = 'clear'; 0117 0118 /** 0119 * Stream wrapper clients 0120 * 0121 * @var array 0122 */ 0123 protected static $_wrapperClients = array(); 0124 0125 /** 0126 * SharedAccessSignature credentials 0127 * 0128 * @var Zend_Service_WindowsAzure_Credentials_SharedAccessSignature 0129 */ 0130 protected $_sharedAccessSignatureCredentials = null; 0131 0132 /** 0133 * Creates a new Zend_Service_WindowsAzure_Storage_Blob instance 0134 * 0135 * @param string $host Storage host name 0136 * @param string $accountName Account name for Windows Azure 0137 * @param string $accountKey Account key for Windows Azure 0138 * @param boolean $usePathStyleUri Use path-style URI's 0139 * @param Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests 0140 */ 0141 public function __construct($host = Zend_Service_WindowsAzure_Storage::URL_DEV_BLOB, $accountName = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_ACCOUNT, $accountKey = Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_KEY, $usePathStyleUri = false, Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null) 0142 { 0143 parent::__construct($host, $accountName, $accountKey, $usePathStyleUri, $retryPolicy); 0144 0145 // API version 0146 $this->_apiVersion = '2009-09-19'; 0147 0148 // SharedAccessSignature credentials 0149 $this->_sharedAccessSignatureCredentials = new Zend_Service_WindowsAzure_Credentials_SharedAccessSignature($accountName, $accountKey, $usePathStyleUri); 0150 } 0151 0152 /** 0153 * Check if a blob exists 0154 * 0155 * @param string $containerName Container name 0156 * @param string $blobName Blob name 0157 * @param string $snapshotId Snapshot identifier 0158 * @return boolean 0159 */ 0160 public function blobExists($containerName = '', $blobName = '', $snapshotId = null) 0161 { 0162 if ($containerName === '') { 0163 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0164 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 0165 } 0166 if (!self::isValidContainerName($containerName)) { 0167 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0168 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 0169 } 0170 if ($blobName === '') { 0171 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0172 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 0173 } 0174 0175 // Get blob instance 0176 try { 0177 $this->getBlobInstance($containerName, $blobName, $snapshotId); 0178 } catch (Zend_Service_WindowsAzure_Exception $e) { 0179 return false; 0180 } 0181 0182 return true; 0183 } 0184 0185 /** 0186 * Check if a container exists 0187 * 0188 * @param string $containerName Container name 0189 * @return boolean 0190 */ 0191 public function containerExists($containerName = '') 0192 { 0193 if ($containerName === '') { 0194 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0195 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 0196 } 0197 if (!self::isValidContainerName($containerName)) { 0198 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0199 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 0200 } 0201 0202 // List containers 0203 $containers = $this->listContainers($containerName, 1); 0204 foreach ($containers as $container) { 0205 if ($container->Name == $containerName) { 0206 return true; 0207 } 0208 } 0209 0210 return false; 0211 } 0212 0213 /** 0214 * Create container 0215 * 0216 * @param string $containerName Container name 0217 * @param array $metadata Key/value pairs of meta data 0218 * @return object Container properties 0219 * @throws Zend_Service_WindowsAzure_Exception 0220 */ 0221 public function createContainer($containerName = '', $metadata = array()) 0222 { 0223 if ($containerName === '') { 0224 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0225 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 0226 } 0227 if (!self::isValidContainerName($containerName)) { 0228 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0229 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 0230 } 0231 if (!is_array($metadata)) { 0232 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0233 throw new Zend_Service_WindowsAzure_Exception('Meta data should be an array of key and value pairs.'); 0234 } 0235 0236 // Create metadata headers 0237 $headers = array(); 0238 $headers = array_merge($headers, $this->_generateMetadataHeaders($metadata)); 0239 0240 // Perform request 0241 $response = $this->_performRequest($containerName, '?restype=container', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); 0242 if ($response->isSuccessful()) { 0243 0244 return new Zend_Service_WindowsAzure_Storage_BlobContainer( 0245 $containerName, 0246 $response->getHeader('Etag'), 0247 $response->getHeader('Last-modified'), 0248 $metadata 0249 ); 0250 } else { 0251 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0252 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 0253 } 0254 } 0255 0256 /** 0257 * Create container if it does not exist 0258 * 0259 * @param string $containerName Container name 0260 * @param array $metadata Key/value pairs of meta data 0261 * @throws Zend_Service_WindowsAzure_Exception 0262 */ 0263 public function createContainerIfNotExists($containerName = '', $metadata = array()) 0264 { 0265 if (!$this->containerExists($containerName)) { 0266 $this->createContainer($containerName, $metadata); 0267 } 0268 } 0269 0270 /** 0271 * Get container ACL 0272 * 0273 * @param string $containerName Container name 0274 * @param bool $signedIdentifiers Display only private/blob/container or display signed identifiers? 0275 * @return string Acl, to be compared with Zend_Service_WindowsAzure_Storage_Blob::ACL_* 0276 * @throws Zend_Service_WindowsAzure_Exception 0277 */ 0278 public function getContainerAcl($containerName = '', $signedIdentifiers = false) 0279 { 0280 if ($containerName === '') { 0281 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0282 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 0283 } 0284 if (!self::isValidContainerName($containerName)) { 0285 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0286 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 0287 } 0288 0289 // Perform request 0290 $response = $this->_performRequest($containerName, '?restype=container&comp=acl', Zend_Http_Client::GET, array(), false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ); 0291 if ($response->isSuccessful()) { 0292 if ($signedIdentifiers == false) { 0293 // Only private/blob/container 0294 $accessType = $response->getHeader(Zend_Service_WindowsAzure_Storage::PREFIX_STORAGE_HEADER . 'blob-public-access'); 0295 if (strtolower($accessType) == 'true') { 0296 $accessType = self::ACL_PUBLIC_CONTAINER; 0297 } 0298 return $accessType; 0299 } else { 0300 // Parse result 0301 $result = $this->_parseResponse($response); 0302 if (!$result) { 0303 return array(); 0304 } 0305 0306 $entries = null; 0307 if ($result->SignedIdentifier) { 0308 if (count($result->SignedIdentifier) > 1) { 0309 $entries = $result->SignedIdentifier; 0310 } else { 0311 $entries = array($result->SignedIdentifier); 0312 } 0313 } 0314 0315 // require_once 'Zend/Service/WindowsAzure/Storage/SignedIdentifier.php'; 0316 // Return value 0317 $returnValue = array(); 0318 foreach ($entries as $entry) { 0319 $returnValue[] = new Zend_Service_WindowsAzure_Storage_SignedIdentifier( 0320 $entry->Id, 0321 $entry->AccessPolicy ? $entry->AccessPolicy->Start ? $entry->AccessPolicy->Start : '' : '', 0322 $entry->AccessPolicy ? $entry->AccessPolicy->Expiry ? $entry->AccessPolicy->Expiry : '' : '', 0323 $entry->AccessPolicy ? $entry->AccessPolicy->Permission ? $entry->AccessPolicy->Permission : '' : '' 0324 ); 0325 } 0326 0327 // Return 0328 return $returnValue; 0329 } 0330 } else { 0331 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0332 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 0333 } 0334 } 0335 0336 /** 0337 * Set container ACL 0338 * 0339 * @param string $containerName Container name 0340 * @param bool $acl Zend_Service_WindowsAzure_Storage_Blob::ACL_* 0341 * @param array $signedIdentifiers Signed identifiers 0342 * @throws Zend_Service_WindowsAzure_Exception 0343 */ 0344 public function setContainerAcl($containerName = '', $acl = self::ACL_PRIVATE, $signedIdentifiers = array()) 0345 { 0346 if ($containerName === '') { 0347 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0348 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 0349 } 0350 if (!self::isValidContainerName($containerName)) { 0351 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0352 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 0353 } 0354 0355 // Headers 0356 $headers = array(); 0357 0358 // Acl specified? 0359 if ($acl != self::ACL_PRIVATE && !is_null($acl) && $acl != '') { 0360 $headers[Zend_Service_WindowsAzure_Storage::PREFIX_STORAGE_HEADER . 'blob-public-access'] = $acl; 0361 } 0362 0363 // Policies 0364 $policies = null; 0365 if (is_array($signedIdentifiers) && count($signedIdentifiers) > 0) { 0366 $policies = ''; 0367 $policies .= '<?xml version="1.0" encoding="utf-8"?>' . "\r\n"; 0368 $policies .= '<SignedIdentifiers>' . "\r\n"; 0369 foreach ($signedIdentifiers as $signedIdentifier) { 0370 $policies .= ' <SignedIdentifier>' . "\r\n"; 0371 $policies .= ' <Id>' . $signedIdentifier->Id . '</Id>' . "\r\n"; 0372 $policies .= ' <AccessPolicy>' . "\r\n"; 0373 if ($signedIdentifier->Start != '') 0374 $policies .= ' <Start>' . $signedIdentifier->Start . '</Start>' . "\r\n"; 0375 if ($signedIdentifier->Expiry != '') 0376 $policies .= ' <Expiry>' . $signedIdentifier->Expiry . '</Expiry>' . "\r\n"; 0377 if ($signedIdentifier->Permissions != '') 0378 $policies .= ' <Permission>' . $signedIdentifier->Permissions . '</Permission>' . "\r\n"; 0379 $policies .= ' </AccessPolicy>' . "\r\n"; 0380 $policies .= ' </SignedIdentifier>' . "\r\n"; 0381 } 0382 $policies .= '</SignedIdentifiers>' . "\r\n"; 0383 } 0384 0385 // Perform request 0386 $response = $this->_performRequest($containerName, '?restype=container&comp=acl', Zend_Http_Client::PUT, $headers, false, $policies, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); 0387 if (!$response->isSuccessful()) { 0388 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0389 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 0390 } 0391 } 0392 0393 /** 0394 * Get container 0395 * 0396 * @param string $containerName Container name 0397 * @return Zend_Service_WindowsAzure_Storage_BlobContainer 0398 * @throws Zend_Service_WindowsAzure_Exception 0399 */ 0400 public function getContainer($containerName = '') 0401 { 0402 if ($containerName === '') { 0403 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0404 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 0405 } 0406 if (!self::isValidContainerName($containerName)) { 0407 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0408 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 0409 } 0410 0411 // Perform request 0412 $response = $this->_performRequest($containerName, '?restype=container', Zend_Http_Client::GET, array(), false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ); 0413 if ($response->isSuccessful()) { 0414 // Parse metadata 0415 $metadata = $this->_parseMetadataHeaders($response->getHeaders()); 0416 0417 // Return container 0418 return new Zend_Service_WindowsAzure_Storage_BlobContainer( 0419 $containerName, 0420 $response->getHeader('Etag'), 0421 $response->getHeader('Last-modified'), 0422 $metadata 0423 ); 0424 } else { 0425 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0426 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 0427 } 0428 } 0429 0430 /** 0431 * Get container metadata 0432 * 0433 * @param string $containerName Container name 0434 * @return array Key/value pairs of meta data 0435 * @throws Zend_Service_WindowsAzure_Exception 0436 */ 0437 public function getContainerMetadata($containerName = '') 0438 { 0439 if ($containerName === '') { 0440 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0441 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 0442 } 0443 if (!self::isValidContainerName($containerName)) { 0444 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0445 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 0446 } 0447 0448 return $this->getContainer($containerName)->Metadata; 0449 } 0450 0451 /** 0452 * Set container metadata 0453 * 0454 * Calling the Set Container Metadata operation overwrites all existing metadata that is associated with the container. It's not possible to modify an individual name/value pair. 0455 * 0456 * @param string $containerName Container name 0457 * @param array $metadata Key/value pairs of meta data 0458 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. 0459 * @throws Zend_Service_WindowsAzure_Exception 0460 */ 0461 public function setContainerMetadata($containerName = '', $metadata = array(), $additionalHeaders = array()) 0462 { 0463 if ($containerName === '') { 0464 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0465 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 0466 } 0467 if (!self::isValidContainerName($containerName)) { 0468 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0469 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 0470 } 0471 if (!is_array($metadata)) { 0472 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0473 throw new Zend_Service_WindowsAzure_Exception('Meta data should be an array of key and value pairs.'); 0474 } 0475 if (count($metadata) == 0) { 0476 return; 0477 } 0478 0479 // Create metadata headers 0480 $headers = array(); 0481 $headers = array_merge($headers, $this->_generateMetadataHeaders($metadata)); 0482 0483 // Additional headers? 0484 foreach ($additionalHeaders as $key => $value) { 0485 $headers[$key] = $value; 0486 } 0487 0488 // Perform request 0489 $response = $this->_performRequest($containerName, '?restype=container&comp=metadata', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); 0490 if (!$response->isSuccessful()) { 0491 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0492 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 0493 } 0494 } 0495 0496 /** 0497 * Delete container 0498 * 0499 * @param string $containerName Container name 0500 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. 0501 * @throws Zend_Service_WindowsAzure_Exception 0502 */ 0503 public function deleteContainer($containerName = '', $additionalHeaders = array()) 0504 { 0505 if ($containerName === '') { 0506 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0507 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 0508 } 0509 if (!self::isValidContainerName($containerName)) { 0510 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0511 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 0512 } 0513 0514 // Additional headers? 0515 $headers = array(); 0516 foreach ($additionalHeaders as $key => $value) { 0517 $headers[$key] = $value; 0518 } 0519 0520 // Perform request 0521 $response = $this->_performRequest($containerName, '?restype=container', Zend_Http_Client::DELETE, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); 0522 if (!$response->isSuccessful()) { 0523 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0524 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 0525 } 0526 } 0527 0528 /** 0529 * List containers 0530 * 0531 * @param string $prefix Optional. Filters the results to return only containers whose name begins with the specified prefix. 0532 * @param int $maxResults Optional. Specifies the maximum number of containers to return per call to Azure storage. This does NOT affect list size returned by this function. (maximum: 5000) 0533 * @param string $marker Optional string value that identifies the portion of the list to be returned with the next list operation. 0534 * @param string $include Optional. Include this parameter to specify that the container's metadata be returned as part of the response body. (allowed values: '', 'metadata') 0535 * @param int $currentResultCount Current result count (internal use) 0536 * @return array 0537 * @throws Zend_Service_WindowsAzure_Exception 0538 */ 0539 public function listContainers($prefix = null, $maxResults = null, $marker = null, $include = null, $currentResultCount = 0) 0540 { 0541 // Build query string 0542 $queryString = array('comp=list'); 0543 if (!is_null($prefix)) { 0544 $queryString[] = 'prefix=' . $prefix; 0545 } 0546 if (!is_null($maxResults)) { 0547 $queryString[] = 'maxresults=' . $maxResults; 0548 } 0549 if (!is_null($marker)) { 0550 $queryString[] = 'marker=' . $marker; 0551 } 0552 if (!is_null($include)) { 0553 $queryString[] = 'include=' . $include; 0554 } 0555 $queryString = self::createQueryStringFromArray($queryString); 0556 0557 // Perform request 0558 $response = $this->_performRequest('', $queryString, Zend_Http_Client::GET, array(), false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_LIST); 0559 if ($response->isSuccessful()) { 0560 $xmlContainers = $this->_parseResponse($response)->Containers->Container; 0561 $xmlMarker = (string)$this->_parseResponse($response)->NextMarker; 0562 0563 $containers = array(); 0564 if (!is_null($xmlContainers)) { 0565 for ($i = 0; $i < count($xmlContainers); $i++) { 0566 0567 $containers[] = new Zend_Service_WindowsAzure_Storage_BlobContainer( 0568 (string)$xmlContainers[$i]->Name, 0569 (string)$xmlContainers[$i]->Etag, 0570 (string)$xmlContainers[$i]->LastModified, 0571 $this->_parseMetadataElement($xmlContainers[$i]) 0572 ); 0573 } 0574 } 0575 $currentResultCount = $currentResultCount + count($containers); 0576 if (!is_null($maxResults) && $currentResultCount < $maxResults) { 0577 if (!is_null($xmlMarker) && $xmlMarker != '') { 0578 $containers = array_merge($containers, $this->listContainers($prefix, $maxResults, $xmlMarker, $include, $currentResultCount)); 0579 } 0580 } 0581 if (!is_null($maxResults) && count($containers) > $maxResults) { 0582 $containers = array_slice($containers, 0, $maxResults); 0583 } 0584 0585 return $containers; 0586 } else { 0587 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0588 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 0589 } 0590 } 0591 0592 /** 0593 * Put blob 0594 * 0595 * @param string $containerName Container name 0596 * @param string $blobName Blob name 0597 * @param string $localFileName Local file name to be uploaded 0598 * @param array $metadata Key/value pairs of meta data 0599 * @param string $leaseId Lease identifier 0600 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. 0601 * @return object Partial blob properties 0602 * @throws Zend_Service_WindowsAzure_Exception 0603 */ 0604 public function putBlob($containerName = '', $blobName = '', $localFileName = '', $metadata = array(), $leaseId = null, $additionalHeaders = array()) 0605 { 0606 if ($containerName === '') { 0607 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0608 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 0609 } 0610 if (!self::isValidContainerName($containerName)) { 0611 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0612 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 0613 } 0614 if ($blobName === '') { 0615 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0616 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 0617 } 0618 if ($localFileName === '') { 0619 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0620 throw new Zend_Service_WindowsAzure_Exception('Local file name is not specified.'); 0621 } 0622 if (!file_exists($localFileName)) { 0623 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0624 throw new Zend_Service_WindowsAzure_Exception('Local file not found.'); 0625 } 0626 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 0627 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0628 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 0629 } 0630 0631 // Check file size 0632 if (filesize($localFileName) >= self::MAX_BLOB_SIZE) { 0633 return $this->putLargeBlob($containerName, $blobName, $localFileName, $metadata, $leaseId, $additionalHeaders); 0634 } 0635 0636 // Put the data to Windows Azure Storage 0637 return $this->putBlobData($containerName, $blobName, file_get_contents($localFileName), $metadata, $leaseId, $additionalHeaders); 0638 } 0639 0640 /** 0641 * Put blob data 0642 * 0643 * @param string $containerName Container name 0644 * @param string $blobName Blob name 0645 * @param mixed $data Data to store 0646 * @param array $metadata Key/value pairs of meta data 0647 * @param string $leaseId Lease identifier 0648 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. 0649 * @return object Partial blob properties 0650 * @throws Zend_Service_WindowsAzure_Exception 0651 */ 0652 public function putBlobData($containerName = '', $blobName = '', $data = '', $metadata = array(), $leaseId = null, $additionalHeaders = array()) 0653 { 0654 if ($containerName === '') { 0655 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0656 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 0657 } 0658 if (!self::isValidContainerName($containerName)) { 0659 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0660 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 0661 } 0662 if ($blobName === '') { 0663 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0664 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 0665 } 0666 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 0667 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0668 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 0669 } 0670 0671 // Create metadata headers 0672 $headers = array(); 0673 if (!is_null($leaseId)) { 0674 $headers['x-ms-lease-id'] = $leaseId; 0675 } 0676 $headers = array_merge($headers, $this->_generateMetadataHeaders($metadata)); 0677 0678 // Additional headers? 0679 foreach ($additionalHeaders as $key => $value) { 0680 $headers[$key] = $value; 0681 } 0682 0683 // Specify blob type 0684 $headers[Zend_Service_WindowsAzure_Storage::PREFIX_STORAGE_HEADER . 'blob-type'] = self::BLOBTYPE_BLOCK; 0685 0686 // Resource name 0687 $resourceName = self::createResourceName($containerName , $blobName); 0688 0689 // Perform request 0690 $response = $this->_performRequest($resourceName, '', Zend_Http_Client::PUT, $headers, false, $data, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); 0691 if ($response->isSuccessful()) { 0692 0693 return new Zend_Service_WindowsAzure_Storage_BlobInstance( 0694 $containerName, 0695 $blobName, 0696 null, 0697 $response->getHeader('Etag'), 0698 $response->getHeader('Last-modified'), 0699 $this->getBaseUrl() . '/' . $containerName . '/' . $blobName, 0700 strlen($data), 0701 '', 0702 '', 0703 '', 0704 false, 0705 $metadata 0706 ); 0707 } else { 0708 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0709 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 0710 } 0711 } 0712 0713 /** 0714 * Put large blob (> 64 MB) 0715 * 0716 * @param string $containerName Container name 0717 * @param string $blobName Blob name 0718 * @param string $localFileName Local file name to be uploaded 0719 * @param array $metadata Key/value pairs of meta data 0720 * @param string $leaseId Lease identifier 0721 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. 0722 * @return object Partial blob properties 0723 * @throws Zend_Service_WindowsAzure_Exception 0724 */ 0725 public function putLargeBlob($containerName = '', $blobName = '', $localFileName = '', $metadata = array(), $leaseId = null, $additionalHeaders = array()) 0726 { 0727 if ($containerName === '') { 0728 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0729 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 0730 } 0731 if (!self::isValidContainerName($containerName)) { 0732 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0733 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 0734 } 0735 if ($blobName === '') { 0736 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0737 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 0738 } 0739 if ($localFileName === '') { 0740 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0741 throw new Zend_Service_WindowsAzure_Exception('Local file name is not specified.'); 0742 } 0743 if (!file_exists($localFileName)) { 0744 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0745 throw new Zend_Service_WindowsAzure_Exception('Local file not found.'); 0746 } 0747 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 0748 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0749 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 0750 } 0751 0752 // Check file size 0753 if (filesize($localFileName) < self::MAX_BLOB_SIZE) { 0754 return $this->putBlob($containerName, $blobName, $localFileName, $metadata, $leaseId, $additionalHeaders); 0755 } 0756 0757 // Determine number of parts 0758 $numberOfParts = ceil( filesize($localFileName) / self::MAX_BLOB_TRANSFER_SIZE ); 0759 0760 // Generate block id's 0761 $blockIdentifiers = array(); 0762 for ($i = 0; $i < $numberOfParts; $i++) { 0763 $blockIdentifiers[] = $this->_generateBlockId($i); 0764 } 0765 0766 // Open file 0767 $fp = fopen($localFileName, 'r'); 0768 if ($fp === false) { 0769 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0770 throw new Zend_Service_WindowsAzure_Exception('Could not open local file.'); 0771 } 0772 0773 // Upload parts 0774 for ($i = 0; $i < $numberOfParts; $i++) { 0775 // Seek position in file 0776 fseek($fp, $i * self::MAX_BLOB_TRANSFER_SIZE); 0777 0778 // Read contents 0779 $fileContents = fread($fp, self::MAX_BLOB_TRANSFER_SIZE); 0780 0781 // Put block 0782 $this->putBlock($containerName, $blobName, $blockIdentifiers[$i], $fileContents, $leaseId); 0783 0784 // Dispose file contents 0785 $fileContents = null; 0786 unset($fileContents); 0787 } 0788 0789 // Close file 0790 fclose($fp); 0791 0792 // Put block list 0793 $this->putBlockList($containerName, $blobName, $blockIdentifiers, $metadata, $leaseId, $additionalHeaders); 0794 0795 // Return information of the blob 0796 return $this->getBlobInstance($containerName, $blobName, null, $leaseId); 0797 } 0798 0799 /** 0800 * Put large blob block 0801 * 0802 * @param string $containerName Container name 0803 * @param string $blobName Blob name 0804 * @param string $identifier Block ID 0805 * @param array $contents Contents of the block 0806 * @param string $leaseId Lease identifier 0807 * @throws Zend_Service_WindowsAzure_Exception 0808 */ 0809 public function putBlock($containerName = '', $blobName = '', $identifier = '', $contents = '', $leaseId = null) 0810 { 0811 if ($containerName === '') { 0812 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0813 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 0814 } 0815 if (!self::isValidContainerName($containerName)) { 0816 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0817 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 0818 } 0819 if ($identifier === '') { 0820 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0821 throw new Zend_Service_WindowsAzure_Exception('Block identifier is not specified.'); 0822 } 0823 if (strlen($contents) > self::MAX_BLOB_TRANSFER_SIZE) { 0824 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0825 throw new Zend_Service_WindowsAzure_Exception('Block size is too big.'); 0826 } 0827 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 0828 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0829 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 0830 } 0831 0832 // Headers 0833 $headers = array(); 0834 if (!is_null($leaseId)) { 0835 $headers['x-ms-lease-id'] = $leaseId; 0836 } 0837 0838 // Resource name 0839 $resourceName = self::createResourceName($containerName , $blobName); 0840 0841 // Upload 0842 $response = $this->_performRequest($resourceName, '?comp=block&blockid=' . base64_encode($identifier), Zend_Http_Client::PUT, $headers, false, $contents, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); 0843 if (!$response->isSuccessful()) { 0844 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0845 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 0846 } 0847 } 0848 0849 /** 0850 * Put block list 0851 * 0852 * @param string $containerName Container name 0853 * @param string $blobName Blob name 0854 * @param array $blockList Array of block identifiers 0855 * @param array $metadata Key/value pairs of meta data 0856 * @param string $leaseId Lease identifier 0857 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. 0858 * @throws Zend_Service_WindowsAzure_Exception 0859 */ 0860 public function putBlockList($containerName = '', $blobName = '', $blockList = array(), $metadata = array(), $leaseId = null, $additionalHeaders = array()) 0861 { 0862 if ($containerName === '') { 0863 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0864 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 0865 } 0866 if (!self::isValidContainerName($containerName)) { 0867 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0868 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 0869 } 0870 if ($blobName === '') { 0871 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0872 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 0873 } 0874 if (count($blockList) == 0) { 0875 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0876 throw new Zend_Service_WindowsAzure_Exception('Block list does not contain any elements.'); 0877 } 0878 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 0879 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0880 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 0881 } 0882 0883 // Generate block list 0884 $blocks = ''; 0885 foreach ($blockList as $block) { 0886 $blocks .= ' <Latest>' . base64_encode($block) . '</Latest>' . "\n"; 0887 } 0888 0889 // Generate block list request 0890 $fileContents = utf8_encode(implode("\n", array( 0891 '<?xml version="1.0" encoding="utf-8"?>', 0892 '<BlockList>', 0893 $blocks, 0894 '</BlockList>' 0895 ))); 0896 0897 // Create metadata headers 0898 $headers = array(); 0899 if (!is_null($leaseId)) { 0900 $headers['x-ms-lease-id'] = $leaseId; 0901 } 0902 $headers = array_merge($headers, $this->_generateMetadataHeaders($metadata)); 0903 0904 // Additional headers? 0905 foreach ($additionalHeaders as $key => $value) { 0906 $headers[$key] = $value; 0907 } 0908 0909 // Resource name 0910 $resourceName = self::createResourceName($containerName , $blobName); 0911 0912 // Perform request 0913 $response = $this->_performRequest($resourceName, '?comp=blocklist', Zend_Http_Client::PUT, $headers, false, $fileContents, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); 0914 if (!$response->isSuccessful()) { 0915 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0916 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 0917 } 0918 } 0919 0920 /** 0921 * Get block list 0922 * 0923 * @param string $containerName Container name 0924 * @param string $blobName Blob name 0925 * @param string $snapshotId Snapshot identifier 0926 * @param string $leaseId Lease identifier 0927 * @param integer $type Type of block list to retrieve. 0 = all, 1 = committed, 2 = uncommitted 0928 * @return array 0929 * @throws Zend_Service_WindowsAzure_Exception 0930 */ 0931 public function getBlockList($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null, $type = 0) 0932 { 0933 if ($containerName === '') { 0934 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0935 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 0936 } 0937 if (!self::isValidContainerName($containerName)) { 0938 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0939 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 0940 } 0941 if ($blobName === '') { 0942 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0943 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 0944 } 0945 if ($type < 0 || $type > 2) { 0946 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 0947 throw new Zend_Service_WindowsAzure_Exception('Invalid type of block list to retrieve.'); 0948 } 0949 0950 // Set $blockListType 0951 $blockListType = 'all'; 0952 if ($type == 1) { 0953 $blockListType = 'committed'; 0954 } 0955 if ($type == 2) { 0956 $blockListType = 'uncommitted'; 0957 } 0958 0959 // Headers 0960 $headers = array(); 0961 if (!is_null($leaseId)) { 0962 $headers['x-ms-lease-id'] = $leaseId; 0963 } 0964 0965 // Build query string 0966 $queryString = array('comp=blocklist', 'blocklisttype=' . $blockListType); 0967 if (!is_null($snapshotId)) { 0968 $queryString[] = 'snapshot=' . $snapshotId; 0969 } 0970 $queryString = self::createQueryStringFromArray($queryString); 0971 0972 // Resource name 0973 $resourceName = self::createResourceName($containerName , $blobName); 0974 0975 // Perform request 0976 $response = $this->_performRequest($resourceName, $queryString, Zend_Http_Client::GET, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ); 0977 if ($response->isSuccessful()) { 0978 // Parse response 0979 $blockList = $this->_parseResponse($response); 0980 0981 // Create return value 0982 $returnValue = array(); 0983 if ($blockList->CommittedBlocks) { 0984 foreach ($blockList->CommittedBlocks->Block as $block) { 0985 $returnValue['CommittedBlocks'][] = (object)array( 0986 'Name' => (string)$block->Name, 0987 'Size' => (string)$block->Size 0988 ); 0989 } 0990 } 0991 if ($blockList->UncommittedBlocks) { 0992 foreach ($blockList->UncommittedBlocks->Block as $block) { 0993 $returnValue['UncommittedBlocks'][] = (object)array( 0994 'Name' => (string)$block->Name, 0995 'Size' => (string)$block->Size 0996 ); 0997 } 0998 } 0999 1000 return $returnValue; 1001 } else { 1002 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1003 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 1004 } 1005 } 1006 1007 /** 1008 * Create page blob 1009 * 1010 * @param string $containerName Container name 1011 * @param string $blobName Blob name 1012 * @param int $size Size of the page blob in bytes 1013 * @param array $metadata Key/value pairs of meta data 1014 * @param string $leaseId Lease identifier 1015 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. 1016 * @return object Partial blob properties 1017 * @throws Zend_Service_WindowsAzure_Exception 1018 */ 1019 public function createPageBlob($containerName = '', $blobName = '', $size = 0, $metadata = array(), $leaseId = null, $additionalHeaders = array()) 1020 { 1021 if ($containerName === '') { 1022 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1023 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 1024 } 1025 if (!self::isValidContainerName($containerName)) { 1026 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1027 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 1028 } 1029 if ($blobName === '') { 1030 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1031 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 1032 } 1033 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 1034 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1035 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 1036 } 1037 if ($size <= 0) { 1038 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1039 throw new Zend_Service_WindowsAzure_Exception('Page blob size must be specified.'); 1040 } 1041 1042 // Create metadata headers 1043 $headers = array(); 1044 if (!is_null($leaseId)) { 1045 $headers['x-ms-lease-id'] = $leaseId; 1046 } 1047 $headers = array_merge($headers, $this->_generateMetadataHeaders($metadata)); 1048 1049 // Additional headers? 1050 foreach ($additionalHeaders as $key => $value) { 1051 $headers[$key] = $value; 1052 } 1053 1054 // Specify blob type & blob length 1055 $headers[Zend_Service_WindowsAzure_Storage::PREFIX_STORAGE_HEADER . 'blob-type'] = self::BLOBTYPE_PAGE; 1056 $headers[Zend_Service_WindowsAzure_Storage::PREFIX_STORAGE_HEADER . 'blob-content-length'] = $size; 1057 $headers['Content-Length'] = 0; 1058 1059 // Resource name 1060 $resourceName = self::createResourceName($containerName , $blobName); 1061 1062 // Perform request 1063 $response = $this->_performRequest($resourceName, '', Zend_Http_Client::PUT, $headers, false, '', Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); 1064 if ($response->isSuccessful()) { 1065 1066 return new Zend_Service_WindowsAzure_Storage_BlobInstance( 1067 $containerName, 1068 $blobName, 1069 null, 1070 $response->getHeader('Etag'), 1071 $response->getHeader('Last-modified'), 1072 $this->getBaseUrl() . '/' . $containerName . '/' . $blobName, 1073 $size, 1074 '', 1075 '', 1076 '', 1077 false, 1078 $metadata 1079 ); 1080 } else { 1081 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1082 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 1083 } 1084 } 1085 1086 /** 1087 * Put page in page blob 1088 * 1089 * @param string $containerName Container name 1090 * @param string $blobName Blob name 1091 * @param int $startByteOffset Start byte offset 1092 * @param int $endByteOffset End byte offset 1093 * @param mixed $contents Page contents 1094 * @param string $writeMethod Write method (Zend_Service_WindowsAzure_Storage_Blob::PAGE_WRITE_*) 1095 * @param string $leaseId Lease identifier 1096 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. 1097 * @throws Zend_Service_WindowsAzure_Exception 1098 */ 1099 public function putPage($containerName = '', $blobName = '', $startByteOffset = 0, $endByteOffset = 0, $contents = '', $writeMethod = self::PAGE_WRITE_UPDATE, $leaseId = null, $additionalHeaders = array()) 1100 { 1101 if ($containerName === '') { 1102 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1103 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 1104 } 1105 if (!self::isValidContainerName($containerName)) { 1106 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1107 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 1108 } 1109 if ($blobName === '') { 1110 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1111 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 1112 } 1113 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 1114 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1115 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 1116 } 1117 if ($startByteOffset % 512 != 0) { 1118 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1119 throw new Zend_Service_WindowsAzure_Exception('Start byte offset must be a modulus of 512.'); 1120 } 1121 if (($endByteOffset + 1) % 512 != 0) { 1122 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1123 throw new Zend_Service_WindowsAzure_Exception('End byte offset must be a modulus of 512 minus 1.'); 1124 } 1125 1126 // Determine size 1127 $size = strlen($contents); 1128 if ($size >= self::MAX_BLOB_TRANSFER_SIZE) { 1129 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1130 throw new Zend_Service_WindowsAzure_Exception('Page blob size must not be larger than ' + self::MAX_BLOB_TRANSFER_SIZE . ' bytes.'); 1131 } 1132 1133 // Create metadata headers 1134 $headers = array(); 1135 if (!is_null($leaseId)) { 1136 $headers['x-ms-lease-id'] = $leaseId; 1137 } 1138 1139 // Additional headers? 1140 foreach ($additionalHeaders as $key => $value) { 1141 $headers[$key] = $value; 1142 } 1143 1144 // Specify range 1145 $headers['Range'] = 'bytes=' . $startByteOffset . '-' . $endByteOffset; 1146 1147 // Write method 1148 $headers[Zend_Service_WindowsAzure_Storage::PREFIX_STORAGE_HEADER . 'page-write'] = $writeMethod; 1149 1150 // Resource name 1151 $resourceName = self::createResourceName($containerName , $blobName); 1152 1153 // Perform request 1154 $response = $this->_performRequest($resourceName, '?comp=page', Zend_Http_Client::PUT, $headers, false, $contents, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); 1155 if (!$response->isSuccessful()) { 1156 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1157 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 1158 } 1159 } 1160 1161 /** 1162 * Put page in page blob 1163 * 1164 * @param string $containerName Container name 1165 * @param string $blobName Blob name 1166 * @param int $startByteOffset Start byte offset 1167 * @param int $endByteOffset End byte offset 1168 * @param string $leaseId Lease identifier 1169 * @return array Array of page ranges 1170 * @throws Zend_Service_WindowsAzure_Exception 1171 */ 1172 public function getPageRegions($containerName = '', $blobName = '', $startByteOffset = 0, $endByteOffset = 0, $leaseId = null) 1173 { 1174 if ($containerName === '') { 1175 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1176 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 1177 } 1178 if (!self::isValidContainerName($containerName)) { 1179 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1180 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 1181 } 1182 if ($blobName === '') { 1183 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1184 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 1185 } 1186 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 1187 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1188 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 1189 } 1190 if ($startByteOffset % 512 != 0) { 1191 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1192 throw new Zend_Service_WindowsAzure_Exception('Start byte offset must be a modulus of 512.'); 1193 } 1194 if ($endByteOffset > 0 && ($endByteOffset + 1) % 512 != 0) { 1195 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1196 throw new Zend_Service_WindowsAzure_Exception('End byte offset must be a modulus of 512 minus 1.'); 1197 } 1198 1199 // Create metadata headers 1200 $headers = array(); 1201 if (!is_null($leaseId)) { 1202 $headers['x-ms-lease-id'] = $leaseId; 1203 } 1204 1205 // Specify range? 1206 if ($endByteOffset > 0) { 1207 $headers['Range'] = 'bytes=' . $startByteOffset . '-' . $endByteOffset; 1208 } 1209 1210 // Resource name 1211 $resourceName = self::createResourceName($containerName , $blobName); 1212 1213 // Perform request 1214 $response = $this->_performRequest($resourceName, '?comp=pagelist', Zend_Http_Client::GET, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); 1215 if ($response->isSuccessful()) { 1216 $result = $this->_parseResponse($response); 1217 $xmlRanges = null; 1218 if (count($result->PageRange) > 1) { 1219 $xmlRanges = $result->PageRange; 1220 } else { 1221 $xmlRanges = array($result->PageRange); 1222 } 1223 1224 1225 $ranges = array(); 1226 1227 for ($i = 0; $i < count($xmlRanges); $i++) { 1228 $ranges[] = new Zend_Service_WindowsAzure_Storage_PageRegionInstance( 1229 (int)$xmlRanges[$i]->Start, 1230 (int)$xmlRanges[$i]->End 1231 ); 1232 } 1233 1234 return $ranges; 1235 } else { 1236 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1237 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 1238 } 1239 } 1240 1241 /** 1242 * Copy blob 1243 * 1244 * @param string $sourceContainerName Source container name 1245 * @param string $sourceBlobName Source blob name 1246 * @param string $destinationContainerName Destination container name 1247 * @param string $destinationBlobName Destination blob name 1248 * @param array $metadata Key/value pairs of meta data 1249 * @param string $sourceSnapshotId Source snapshot identifier 1250 * @param string $destinationLeaseId Destination lease identifier 1251 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd894037.aspx for more information. 1252 * @return object Partial blob properties 1253 * @throws Zend_Service_WindowsAzure_Exception 1254 */ 1255 public function copyBlob($sourceContainerName = '', $sourceBlobName = '', $destinationContainerName = '', $destinationBlobName = '', $metadata = array(), $sourceSnapshotId = null, $destinationLeaseId = null, $additionalHeaders = array()) 1256 { 1257 if ($sourceContainerName === '') { 1258 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1259 throw new Zend_Service_WindowsAzure_Exception('Source container name is not specified.'); 1260 } 1261 if (!self::isValidContainerName($sourceContainerName)) { 1262 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1263 throw new Zend_Service_WindowsAzure_Exception('Source container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 1264 } 1265 if ($sourceBlobName === '') { 1266 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1267 throw new Zend_Service_WindowsAzure_Exception('Source blob name is not specified.'); 1268 } 1269 if ($destinationContainerName === '') { 1270 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1271 throw new Zend_Service_WindowsAzure_Exception('Destination container name is not specified.'); 1272 } 1273 if (!self::isValidContainerName($destinationContainerName)) { 1274 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1275 throw new Zend_Service_WindowsAzure_Exception('Destination container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 1276 } 1277 if ($destinationBlobName === '') { 1278 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1279 throw new Zend_Service_WindowsAzure_Exception('Destination blob name is not specified.'); 1280 } 1281 if ($sourceContainerName === '$root' && strpos($sourceBlobName, '/') !== false) { 1282 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1283 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 1284 } 1285 if ($destinationContainerName === '$root' && strpos($destinationBlobName, '/') !== false) { 1286 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1287 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 1288 } 1289 1290 // Create metadata headers 1291 $headers = array(); 1292 if (!is_null($destinationLeaseId)) { 1293 $headers['x-ms-lease-id'] = $destinationLeaseId; 1294 } 1295 $headers = array_merge($headers, $this->_generateMetadataHeaders($metadata)); 1296 1297 // Additional headers? 1298 foreach ($additionalHeaders as $key => $value) { 1299 $headers[$key] = $value; 1300 } 1301 1302 // Resource names 1303 $sourceResourceName = self::createResourceName($sourceContainerName, $sourceBlobName); 1304 if (!is_null($sourceSnapshotId)) { 1305 $sourceResourceName .= '?snapshot=' . $sourceSnapshotId; 1306 } 1307 $destinationResourceName = self::createResourceName($destinationContainerName, $destinationBlobName); 1308 1309 // Set source blob 1310 $headers["x-ms-copy-source"] = '/' . $this->_accountName . '/' . $sourceResourceName; 1311 1312 // Perform request 1313 $response = $this->_performRequest($destinationResourceName, '', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); 1314 if ($response->isSuccessful()) { 1315 1316 return new Zend_Service_WindowsAzure_Storage_BlobInstance( 1317 $destinationContainerName, 1318 $destinationBlobName, 1319 null, 1320 $response->getHeader('Etag'), 1321 $response->getHeader('Last-modified'), 1322 $this->getBaseUrl() . '/' . $destinationContainerName . '/' . $destinationBlobName, 1323 0, 1324 '', 1325 '', 1326 '', 1327 false, 1328 $metadata 1329 ); 1330 } else { 1331 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1332 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 1333 } 1334 } 1335 1336 /** 1337 * Get blob 1338 * 1339 * @param string $containerName Container name 1340 * @param string $blobName Blob name 1341 * @param string $localFileName Local file name to store downloaded blob 1342 * @param string $snapshotId Snapshot identifier 1343 * @param string $leaseId Lease identifier 1344 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. 1345 * @throws Zend_Service_WindowsAzure_Exception 1346 */ 1347 public function getBlob($containerName = '', $blobName = '', $localFileName = '', $snapshotId = null, $leaseId = null, $additionalHeaders = array()) 1348 { 1349 if ($containerName === '') { 1350 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1351 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 1352 } 1353 if (!self::isValidContainerName($containerName)) { 1354 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1355 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 1356 } 1357 if ($blobName === '') { 1358 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1359 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 1360 } 1361 if ($localFileName === '') { 1362 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1363 throw new Zend_Service_WindowsAzure_Exception('Local file name is not specified.'); 1364 } 1365 1366 // Fetch data 1367 file_put_contents($localFileName, $this->getBlobData($containerName, $blobName, $snapshotId, $leaseId, $additionalHeaders)); 1368 } 1369 1370 /** 1371 * Get blob data 1372 * 1373 * @param string $containerName Container name 1374 * @param string $blobName Blob name 1375 * @param string $snapshotId Snapshot identifier 1376 * @param string $leaseId Lease identifier 1377 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. 1378 * @return mixed Blob contents 1379 * @throws Zend_Service_WindowsAzure_Exception 1380 */ 1381 public function getBlobData($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null, $additionalHeaders = array()) 1382 { 1383 if ($containerName === '') { 1384 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1385 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 1386 } 1387 if (!self::isValidContainerName($containerName)) { 1388 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1389 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 1390 } 1391 if ($blobName === '') { 1392 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1393 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 1394 } 1395 1396 // Build query string 1397 $queryString = array(); 1398 if (!is_null($snapshotId)) { 1399 $queryString[] = 'snapshot=' . $snapshotId; 1400 } 1401 $queryString = self::createQueryStringFromArray($queryString); 1402 1403 // Additional headers? 1404 $headers = array(); 1405 if (!is_null($leaseId)) { 1406 $headers['x-ms-lease-id'] = $leaseId; 1407 } 1408 foreach ($additionalHeaders as $key => $value) { 1409 $headers[$key] = $value; 1410 } 1411 1412 // Resource name 1413 $resourceName = self::createResourceName($containerName , $blobName); 1414 1415 // Perform request 1416 $response = $this->_performRequest($resourceName, $queryString, Zend_Http_Client::GET, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ); 1417 if ($response->isSuccessful()) { 1418 return $response->getBody(); 1419 } else { 1420 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1421 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 1422 } 1423 } 1424 1425 /** 1426 * Get blob instance 1427 * 1428 * @param string $containerName Container name 1429 * @param string $blobName Blob name 1430 * @param string $snapshotId Snapshot identifier 1431 * @param string $leaseId Lease identifier 1432 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. 1433 * @return Zend_Service_WindowsAzure_Storage_BlobInstance 1434 * @throws Zend_Service_WindowsAzure_Exception 1435 */ 1436 public function getBlobInstance($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null, $additionalHeaders = array()) 1437 { 1438 if ($containerName === '') { 1439 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1440 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 1441 } 1442 if (!self::isValidContainerName($containerName)) { 1443 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1444 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 1445 } 1446 if ($blobName === '') { 1447 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1448 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 1449 } 1450 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 1451 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1452 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 1453 } 1454 1455 // Build query string 1456 $queryString = array(); 1457 if (!is_null($snapshotId)) { 1458 $queryString[] = 'snapshot=' . $snapshotId; 1459 } 1460 $queryString = self::createQueryStringFromArray($queryString); 1461 1462 // Additional headers? 1463 $headers = array(); 1464 if (!is_null($leaseId)) { 1465 $headers['x-ms-lease-id'] = $leaseId; 1466 } 1467 foreach ($additionalHeaders as $key => $value) { 1468 $headers[$key] = $value; 1469 } 1470 1471 // Resource name 1472 $resourceName = self::createResourceName($containerName , $blobName); 1473 1474 // Perform request 1475 $response = $this->_performRequest($resourceName, $queryString, Zend_Http_Client::HEAD, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ); 1476 if ($response->isSuccessful()) { 1477 // Parse metadata 1478 $metadata = $this->_parseMetadataHeaders($response->getHeaders()); 1479 1480 // Return blob 1481 return new Zend_Service_WindowsAzure_Storage_BlobInstance( 1482 $containerName, 1483 $blobName, 1484 $snapshotId, 1485 $response->getHeader('Etag'), 1486 $response->getHeader('Last-modified'), 1487 $this->getBaseUrl() . '/' . $containerName . '/' . $blobName, 1488 $response->getHeader('Content-Length'), 1489 $response->getHeader('Content-Type'), 1490 $response->getHeader('Content-Encoding'), 1491 $response->getHeader('Content-Language'), 1492 $response->getHeader('Cache-Control'), 1493 $response->getHeader('x-ms-blob-type'), 1494 $response->getHeader('x-ms-lease-status'), 1495 false, 1496 $metadata 1497 ); 1498 } else { 1499 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1500 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 1501 } 1502 } 1503 1504 /** 1505 * Get blob metadata 1506 * 1507 * @param string $containerName Container name 1508 * @param string $blobName Blob name 1509 * @param string $snapshotId Snapshot identifier 1510 * @param string $leaseId Lease identifier 1511 * @return array Key/value pairs of meta data 1512 * @throws Zend_Service_WindowsAzure_Exception 1513 */ 1514 public function getBlobMetadata($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null) 1515 { 1516 if ($containerName === '') { 1517 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1518 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 1519 } 1520 if (!self::isValidContainerName($containerName)) { 1521 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1522 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 1523 } 1524 if ($blobName === '') { 1525 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1526 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 1527 } 1528 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 1529 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1530 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 1531 } 1532 1533 return $this->getBlobInstance($containerName, $blobName, $snapshotId, $leaseId)->Metadata; 1534 } 1535 1536 /** 1537 * Set blob metadata 1538 * 1539 * Calling the Set Blob Metadata operation overwrites all existing metadata that is associated with the blob. It's not possible to modify an individual name/value pair. 1540 * 1541 * @param string $containerName Container name 1542 * @param string $blobName Blob name 1543 * @param array $metadata Key/value pairs of meta data 1544 * @param string $leaseId Lease identifier 1545 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. 1546 * @throws Zend_Service_WindowsAzure_Exception 1547 */ 1548 public function setBlobMetadata($containerName = '', $blobName = '', $metadata = array(), $leaseId = null, $additionalHeaders = array()) 1549 { 1550 if ($containerName === '') { 1551 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1552 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 1553 } 1554 if (!self::isValidContainerName($containerName)) { 1555 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1556 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 1557 } 1558 if ($blobName === '') { 1559 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1560 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 1561 } 1562 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 1563 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1564 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 1565 } 1566 if (count($metadata) == 0) { 1567 return; 1568 } 1569 1570 // Create metadata headers 1571 $headers = array(); 1572 if (!is_null($leaseId)) { 1573 $headers['x-ms-lease-id'] = $leaseId; 1574 } 1575 $headers = array_merge($headers, $this->_generateMetadataHeaders($metadata)); 1576 1577 // Additional headers? 1578 foreach ($additionalHeaders as $key => $value) { 1579 $headers[$key] = $value; 1580 } 1581 1582 // Perform request 1583 $response = $this->_performRequest($containerName . '/' . $blobName, '?comp=metadata', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); 1584 if (!$response->isSuccessful()) { 1585 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1586 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 1587 } 1588 } 1589 1590 /** 1591 * Set blob properties 1592 * 1593 * All available properties are listed at http://msdn.microsoft.com/en-us/library/ee691966.aspx and should be provided in the $additionalHeaders parameter. 1594 * 1595 * @param string $containerName Container name 1596 * @param string $blobName Blob name 1597 * @param string $leaseId Lease identifier 1598 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. 1599 * @throws Zend_Service_WindowsAzure_Exception 1600 */ 1601 public function setBlobProperties($containerName = '', $blobName = '', $leaseId = null, $additionalHeaders = array()) 1602 { 1603 if ($containerName === '') { 1604 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1605 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 1606 } 1607 if (!self::isValidContainerName($containerName)) { 1608 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1609 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 1610 } 1611 if ($blobName === '') { 1612 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1613 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 1614 } 1615 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 1616 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1617 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 1618 } 1619 if (count($additionalHeaders) == 0) { 1620 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1621 throw new Zend_Service_WindowsAzure_Exception('No additional headers are specified.'); 1622 } 1623 1624 // Create headers 1625 $headers = array(); 1626 1627 // Lease set? 1628 if (!is_null($leaseId)) { 1629 $headers['x-ms-lease-id'] = $leaseId; 1630 } 1631 1632 // Additional headers? 1633 foreach ($additionalHeaders as $key => $value) { 1634 $headers[$key] = $value; 1635 } 1636 1637 // Perform request 1638 $response = $this->_performRequest($containerName . '/' . $blobName, '?comp=properties', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); 1639 if (!$response->isSuccessful()) { 1640 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1641 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 1642 } 1643 } 1644 1645 /** 1646 * Get blob properties 1647 * 1648 * @param string $containerName Container name 1649 * @param string $blobName Blob name 1650 * @param string $snapshotId Snapshot identifier 1651 * @param string $leaseId Lease identifier 1652 * @return Zend_Service_WindowsAzure_Storage_BlobInstance 1653 * @throws Zend_Service_WindowsAzure_Exception 1654 */ 1655 public function getBlobProperties($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null) 1656 { 1657 if ($containerName === '') { 1658 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1659 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 1660 } 1661 if (!self::isValidContainerName($containerName)) { 1662 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1663 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 1664 } 1665 if ($blobName === '') { 1666 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1667 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 1668 } 1669 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 1670 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1671 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 1672 } 1673 1674 return $this->getBlobInstance($containerName, $blobName, $snapshotId, $leaseId); 1675 } 1676 1677 /** 1678 * Delete blob 1679 * 1680 * @param string $containerName Container name 1681 * @param string $blobName Blob name 1682 * @param string $snapshotId Snapshot identifier 1683 * @param string $leaseId Lease identifier 1684 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. 1685 * @throws Zend_Service_WindowsAzure_Exception 1686 */ 1687 public function deleteBlob($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null, $additionalHeaders = array()) 1688 { 1689 if ($containerName === '') { 1690 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1691 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 1692 } 1693 if (!self::isValidContainerName($containerName)) { 1694 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1695 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 1696 } 1697 if ($blobName === '') { 1698 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1699 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 1700 } 1701 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 1702 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1703 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 1704 } 1705 1706 // Build query string 1707 $queryString = array(); 1708 if (!is_null($snapshotId)) { 1709 $queryString[] = 'snapshot=' . $snapshotId; 1710 } 1711 $queryString = self::createQueryStringFromArray($queryString); 1712 1713 // Additional headers? 1714 $headers = array(); 1715 if (!is_null($leaseId)) { 1716 $headers['x-ms-lease-id'] = $leaseId; 1717 } 1718 foreach ($additionalHeaders as $key => $value) { 1719 $headers[$key] = $value; 1720 } 1721 1722 // Resource name 1723 $resourceName = self::createResourceName($containerName , $blobName); 1724 1725 // Perform request 1726 $response = $this->_performRequest($resourceName, $queryString, Zend_Http_Client::DELETE, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); 1727 if (!$response->isSuccessful()) { 1728 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1729 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 1730 } 1731 } 1732 1733 /** 1734 * Snapshot blob 1735 * 1736 * @param string $containerName Container name 1737 * @param string $blobName Blob name 1738 * @param array $metadata Key/value pairs of meta data 1739 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. 1740 * @return string Date/Time value representing the snapshot identifier. 1741 * @throws Zend_Service_WindowsAzure_Exception 1742 */ 1743 public function snapshotBlob($containerName = '', $blobName = '', $metadata = array(), $additionalHeaders = array()) 1744 { 1745 if ($containerName === '') { 1746 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1747 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 1748 } 1749 if (!self::isValidContainerName($containerName)) { 1750 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1751 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 1752 } 1753 if ($blobName === '') { 1754 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1755 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 1756 } 1757 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 1758 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1759 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 1760 } 1761 1762 // Additional headers? 1763 $headers = array(); 1764 foreach ($additionalHeaders as $key => $value) { 1765 $headers[$key] = $value; 1766 } 1767 1768 // Resource name 1769 $resourceName = self::createResourceName($containerName , $blobName); 1770 1771 // Perform request 1772 $response = $this->_performRequest($resourceName, '?comp=snapshot', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); 1773 if ($response->isSuccessful()) { 1774 return $response->getHeader('x-ms-snapshot'); 1775 } else { 1776 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1777 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 1778 } 1779 } 1780 1781 /** 1782 * Lease blob - See (http://msdn.microsoft.com/en-us/library/ee691972.aspx) 1783 * 1784 * @param string $containerName Container name 1785 * @param string $blobName Blob name 1786 * @param string $leaseAction Lease action (Zend_Service_WindowsAzure_Storage_Blob::LEASE_*) 1787 * @param string $leaseId Lease identifier, required to renew the lease or to release the lease. 1788 * @return Zend_Service_WindowsAzure_Storage_LeaseInstance Lease instance 1789 * @throws Zend_Service_WindowsAzure_Exception 1790 */ 1791 public function leaseBlob($containerName = '', $blobName = '', $leaseAction = self::LEASE_ACQUIRE, $leaseId = null) 1792 { 1793 if ($containerName === '') { 1794 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1795 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 1796 } 1797 if (!self::isValidContainerName($containerName)) { 1798 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1799 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 1800 } 1801 if ($blobName === '') { 1802 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1803 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 1804 } 1805 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 1806 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1807 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 1808 } 1809 1810 // Additional headers? 1811 $headers = array(); 1812 $headers['x-ms-lease-action'] = strtolower($leaseAction); 1813 if (!is_null($leaseId)) { 1814 $headers['x-ms-lease-id'] = $leaseId; 1815 } 1816 1817 // Resource name 1818 $resourceName = self::createResourceName($containerName , $blobName); 1819 1820 // Perform request 1821 $response = $this->_performRequest($resourceName, '?comp=lease', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); 1822 1823 1824 1825 if ($response->isSuccessful()) { 1826 return new Zend_Service_WindowsAzure_Storage_LeaseInstance( 1827 $containerName, 1828 $blobName, 1829 $response->getHeader('x-ms-lease-id'), 1830 $response->getHeader('x-ms-lease-time')); 1831 } else { 1832 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1833 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 1834 } 1835 } 1836 1837 /** 1838 * List blobs 1839 * 1840 * @param string $containerName Container name 1841 * @param string $prefix Optional. Filters the results to return only blobs whose name begins with the specified prefix. 1842 * @param string $delimiter Optional. Delimiter, i.e. '/', for specifying folder hierarchy 1843 * @param int $maxResults Optional. Specifies the maximum number of blobs to return per call to Azure storage. This does NOT affect list size returned by this function. (maximum: 5000) 1844 * @param string $marker Optional string value that identifies the portion of the list to be returned with the next list operation. 1845 * @param string $include Optional. Specifies that the response should include one or more of the following subsets: '', 'metadata', 'snapshots', 'uncommittedblobs'). Multiple values can be added separated with a comma (,) 1846 * @param int $currentResultCount Current result count (internal use) 1847 * @return array 1848 * @throws Zend_Service_WindowsAzure_Exception 1849 */ 1850 public function listBlobs($containerName = '', $prefix = '', $delimiter = '', $maxResults = null, $marker = null, $include = null, $currentResultCount = 0) 1851 { 1852 if ($containerName === '') { 1853 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1854 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 1855 } 1856 if (!self::isValidContainerName($containerName)) { 1857 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1858 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 1859 } 1860 1861 // Build query string 1862 $queryString = array('restype=container', 'comp=list'); 1863 if (!is_null($prefix)) { 1864 $queryString[] = 'prefix=' . $prefix; 1865 } 1866 if ($delimiter !== '') { 1867 $queryString[] = 'delimiter=' . $delimiter; 1868 } 1869 if (!is_null($maxResults)) { 1870 $queryString[] = 'maxresults=' . $maxResults; 1871 } 1872 if (!is_null($marker)) { 1873 $queryString[] = 'marker=' . $marker; 1874 } 1875 if (!is_null($include)) { 1876 $queryString[] = 'include=' . $include; 1877 } 1878 $queryString = self::createQueryStringFromArray($queryString); 1879 1880 // Perform request 1881 $response = $this->_performRequest($containerName, $queryString, Zend_Http_Client::GET, array(), false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_LIST); 1882 if ($response->isSuccessful()) { 1883 // Return value 1884 $blobs = array(); 1885 1886 // Blobs 1887 $xmlBlobs = $this->_parseResponse($response)->Blobs->Blob; 1888 if (!is_null($xmlBlobs)) { 1889 1890 for ($i = 0; $i < count($xmlBlobs); $i++) { 1891 $properties = (array)$xmlBlobs[$i]->Properties; 1892 1893 $blobs[] = new Zend_Service_WindowsAzure_Storage_BlobInstance( 1894 $containerName, 1895 (string)$xmlBlobs[$i]->Name, 1896 (string)$xmlBlobs[$i]->Snapshot, 1897 (string)$properties['Etag'], 1898 (string)$properties['Last-Modified'], 1899 (string)$xmlBlobs[$i]->Url, 1900 (string)$properties['Content-Length'], 1901 (string)$properties['Content-Type'], 1902 (string)$properties['Content-Encoding'], 1903 (string)$properties['Content-Language'], 1904 (string)$properties['Cache-Control'], 1905 (string)$properties['BlobType'], 1906 (string)$properties['LeaseStatus'], 1907 false, 1908 $this->_parseMetadataElement($xmlBlobs[$i]) 1909 ); 1910 } 1911 } 1912 1913 // Blob prefixes (folders) 1914 $xmlBlobs = $this->_parseResponse($response)->Blobs->BlobPrefix; 1915 1916 if (!is_null($xmlBlobs)) { 1917 1918 for ($i = 0; $i < count($xmlBlobs); $i++) { 1919 $blobs[] = new Zend_Service_WindowsAzure_Storage_BlobInstance( 1920 $containerName, 1921 (string)$xmlBlobs[$i]->Name, 1922 null, 1923 '', 1924 '', 1925 '', 1926 0, 1927 '', 1928 '', 1929 '', 1930 '', 1931 '', 1932 '', 1933 true, 1934 $this->_parseMetadataElement($xmlBlobs[$i]) 1935 ); 1936 } 1937 } 1938 1939 // More blobs? 1940 $xmlMarker = (string)$this->_parseResponse($response)->NextMarker; 1941 $currentResultCount = $currentResultCount + count($blobs); 1942 if (!is_null($maxResults) && $currentResultCount < $maxResults) { 1943 if (!is_null($xmlMarker) && $xmlMarker != '') { 1944 $blobs = array_merge($blobs, $this->listBlobs($containerName, $prefix, $delimiter, $maxResults, $marker, $include, $currentResultCount)); 1945 } 1946 } 1947 if (!is_null($maxResults) && count($blobs) > $maxResults) { 1948 $blobs = array_slice($blobs, 0, $maxResults); 1949 } 1950 1951 return $blobs; 1952 } else { 1953 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1954 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 1955 } 1956 } 1957 1958 /** 1959 * Generate shared access URL 1960 * 1961 * @param string $containerName Container name 1962 * @param string $blobName Blob name 1963 * @param string $resource Signed resource - container (c) - blob (b) 1964 * @param string $permissions Signed permissions - read (r), write (w), delete (d) and list (l) 1965 * @param string $start The time at which the Shared Access Signature becomes valid. 1966 * @param string $expiry The time at which the Shared Access Signature becomes invalid. 1967 * @param string $identifier Signed identifier 1968 * @return string 1969 */ 1970 public function generateSharedAccessUrl($containerName = '', $blobName = '', $resource = 'b', $permissions = 'r', $start = '', $expiry = '', $identifier = '') 1971 { 1972 if ($containerName === '') { 1973 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1974 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 1975 } 1976 if (!self::isValidContainerName($containerName)) { 1977 // require_once 'Zend/Service/WindowsAzure/Exception.php'; 1978 throw new Zend_Service_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.'); 1979 } 1980 1981 // Resource name 1982 $resourceName = self::createResourceName($containerName , $blobName); 1983 1984 // Generate URL 1985 return $this->getBaseUrl() . '/' . $resourceName . '?' . 1986 $this->_sharedAccessSignatureCredentials->createSignedQueryString( 1987 $resourceName, 1988 '', 1989 $resource, 1990 $permissions, 1991 $start, 1992 $expiry, 1993 $identifier); 1994 } 1995 1996 /** 1997 * Register this object as stream wrapper client 1998 * 1999 * @param string $name Protocol name 2000 * @return Zend_Service_WindowsAzure_Storage_Blob 2001 */ 2002 public function registerAsClient($name) 2003 { 2004 self::$_wrapperClients[$name] = $this; 2005 return $this; 2006 } 2007 2008 /** 2009 * Unregister this object as stream wrapper client 2010 * 2011 * @param string $name Protocol name 2012 * @return Zend_Service_WindowsAzure_Storage_Blob 2013 */ 2014 public function unregisterAsClient($name) 2015 { 2016 unset(self::$_wrapperClients[$name]); 2017 return $this; 2018 } 2019 2020 /** 2021 * Get wrapper client for stream type 2022 * 2023 * @param string $name Protocol name 2024 * @return Zend_Service_WindowsAzure_Storage_Blob 2025 */ 2026 public static function getWrapperClient($name) 2027 { 2028 return self::$_wrapperClients[$name]; 2029 } 2030 2031 /** 2032 * Register this object as stream wrapper 2033 * 2034 * @param string $name Protocol name 2035 */ 2036 public function registerStreamWrapper($name = 'azure') 2037 { 2038 stream_register_wrapper($name, 'Zend_Service_WindowsAzure_Storage_Blob_Stream'); 2039 $this->registerAsClient($name); 2040 } 2041 2042 /** 2043 * Unregister this object as stream wrapper 2044 * 2045 * @param string $name Protocol name 2046 * @return Zend_Service_WindowsAzure_Storage_Blob 2047 */ 2048 public function unregisterStreamWrapper($name = 'azure') 2049 { 2050 stream_wrapper_unregister($name); 2051 $this->unregisterAsClient($name); 2052 } 2053 2054 /** 2055 * Create resource name 2056 * 2057 * @param string $containerName Container name 2058 * @param string $blobName Blob name 2059 * @return string 2060 */ 2061 public static function createResourceName($containerName = '', $blobName = '') 2062 { 2063 // Resource name 2064 $resourceName = $containerName . '/' . $blobName; 2065 if ($containerName === '' || $containerName === '$root') { 2066 $resourceName = $blobName; 2067 } 2068 if ($blobName === '') { 2069 $resourceName = $containerName; 2070 } 2071 2072 return $resourceName; 2073 } 2074 2075 /** 2076 * Is valid container name? 2077 * 2078 * @param string $containerName Container name 2079 * @return boolean 2080 */ 2081 public static function isValidContainerName($containerName = '') 2082 { 2083 if ($containerName == '$root') { 2084 return true; 2085 } 2086 2087 if (preg_match("/^[a-z0-9][a-z0-9-]*$/", $containerName) === 0) { 2088 return false; 2089 } 2090 2091 if (strpos($containerName, '--') !== false) { 2092 return false; 2093 } 2094 2095 if (strtolower($containerName) != $containerName) { 2096 return false; 2097 } 2098 2099 if (strlen($containerName) < 3 || strlen($containerName) > 63) { 2100 return false; 2101 } 2102 2103 if (substr($containerName, -1) == '-') { 2104 return false; 2105 } 2106 2107 return true; 2108 } 2109 2110 /** 2111 * Get error message from Zend_Http_Response 2112 * 2113 * @param Zend_Http_Response $response Repsonse 2114 * @param string $alternativeError Alternative error message 2115 * @return string 2116 */ 2117 protected function _getErrorMessage(Zend_Http_Response $response, $alternativeError = 'Unknown error.') 2118 { 2119 $response = $this->_parseResponse($response); 2120 if ($response && $response->Message) { 2121 return (string)$response->Message; 2122 } else { 2123 return $alternativeError; 2124 } 2125 } 2126 2127 /** 2128 * Generate block id 2129 * 2130 * @param int $part Block number 2131 * @return string Windows Azure Blob Storage block number 2132 */ 2133 protected function _generateBlockId($part = 0) 2134 { 2135 $returnValue = $part; 2136 while (strlen($returnValue) < 64) { 2137 $returnValue = '0' . $returnValue; 2138 } 2139 2140 return $returnValue; 2141 } 2142 }