[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Zend Framework 4 * 5 * LICENSE 6 * 7 * This source file is subject to the new BSD license that is bundled 8 * with this package in the file LICENSE.txt. 9 * It is also available through the world-wide-web at this URL: 10 * http://framework.zend.com/license/new-bsd 11 * If you did not receive a copy of the license and are unable to 12 * obtain it through the world-wide-web, please send an email 13 * to [email protected] so we can send you a copy immediately. 14 * 15 * @category Zend 16 * @package Zend_Service_WindowsAzure 17 * @subpackage Storage 18 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) 19 * @license http://todo name_todo 20 * @version $Id$ 21 */ 22 23 /** 24 * @see Zend_Service_WindowsAzure_Credentials_CredentialsAbstract_SharedKey 25 */ 26 require_once 'Zend/Service/WindowsAzure/Credentials/SharedKey.php'; 27 28 /** 29 * @see Zend_Service_WindowsAzure_Credentials_SharedAccessSignature 30 */ 31 require_once 'Zend/Service/WindowsAzure/Credentials/SharedAccessSignature.php'; 32 33 /** 34 * @see Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract 35 */ 36 require_once 'Zend/Service/WindowsAzure/RetryPolicy/RetryPolicyAbstract.php'; 37 38 /** 39 * @see Zend_Http_Client 40 */ 41 require_once 'Zend/Http/Client.php'; 42 43 /** 44 * @see Zend_Http_Response 45 */ 46 require_once 'Zend/Http/Response.php'; 47 48 /** 49 * @see Zend_Service_WindowsAzure_Storage 50 */ 51 require_once 'Zend/Service/WindowsAzure/Storage.php'; 52 53 /** 54 * @see Zend_Service_WindowsAzure_Storage_BlobContainer 55 */ 56 require_once 'Zend/Service/WindowsAzure/Storage/BlobContainer.php'; 57 58 /** 59 * @see Zend_Service_WindowsAzure_Storage_BlobInstance 60 */ 61 require_once 'Zend/Service/WindowsAzure/Storage/BlobInstance.php'; 62 63 /** 64 * @see Zend_Service_WindowsAzure_Storage_SignedIdentifier 65 */ 66 require_once 'Zend/Service/WindowsAzure/Storage/SignedIdentifier.php'; 67 68 /** 69 * @see Zend_Service_WindowsAzure_Exception 70 */ 71 require_once 'Zend/Service/WindowsAzure/Exception.php'; 72 73 74 /** 75 * @category Zend 76 * @package Zend_Service_WindowsAzure 77 * @subpackage Storage 78 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) 79 * @license http://framework.zend.com/license/new-bsd New BSD License 80 */ 81 class Zend_Service_WindowsAzure_Storage_Blob extends Zend_Service_WindowsAzure_Storage 82 { 83 /** 84 * ACL - Private access 85 */ 86 const ACL_PRIVATE = false; 87 88 /** 89 * ACL - Public access 90 */ 91 const ACL_PUBLIC = true; 92 93 /** 94 * Maximal blob size (in bytes) 95 */ 96 const MAX_BLOB_SIZE = 67108864; 97 98 /** 99 * Maximal blob transfer size (in bytes) 100 */ 101 const MAX_BLOB_TRANSFER_SIZE = 4194304; 102 103 /** 104 * Stream wrapper clients 105 * 106 * @var array 107 */ 108 protected static $_wrapperClients = array(); 109 110 /** 111 * SharedAccessSignature credentials 112 * 113 * @var Zend_Service_WindowsAzure_Credentials_SharedAccessSignature 114 */ 115 private $_sharedAccessSignatureCredentials = null; 116 117 /** 118 * Creates a new Zend_Service_WindowsAzure_Storage_Blob instance 119 * 120 * @param string $host Storage host name 121 * @param string $accountName Account name for Windows Azure 122 * @param string $accountKey Account key for Windows Azure 123 * @param boolean $usePathStyleUri Use path-style URI's 124 * @param Zend_Service_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests 125 */ 126 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) 127 { 128 parent::__construct($host, $accountName, $accountKey, $usePathStyleUri, $retryPolicy); 129 130 // API version 131 $this->_apiVersion = '2009-07-17'; 132 133 // SharedAccessSignature credentials 134 $this->_sharedAccessSignatureCredentials = new Zend_Service_WindowsAzure_Credentials_SharedAccessSignature($accountName, $accountKey, $usePathStyleUri); 135 } 136 137 /** 138 * Check if a blob exists 139 * 140 * @param string $containerName Container name 141 * @param string $blobName Blob name 142 * @return boolean 143 */ 144 public function blobExists($containerName = '', $blobName = '') 145 { 146 if ($containerName === '') { 147 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 148 } 149 if (!self::isValidContainerName($containerName)) { 150 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.'); 151 } 152 if ($blobName === '') { 153 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 154 } 155 156 // List blobs 157 $blobs = $this->listBlobs($containerName, $blobName, '', 1); 158 foreach ($blobs as $blob) { 159 if ($blob->Name == $blobName) { 160 return true; 161 } 162 } 163 164 return false; 165 } 166 167 /** 168 * Check if a container exists 169 * 170 * @param string $containerName Container name 171 * @return boolean 172 */ 173 public function containerExists($containerName = '') 174 { 175 if ($containerName === '') { 176 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 177 } 178 if (!self::isValidContainerName($containerName)) { 179 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.'); 180 } 181 182 // List containers 183 $containers = $this->listContainers($containerName, 1); 184 foreach ($containers as $container) { 185 if ($container->Name == $containerName) { 186 return true; 187 } 188 } 189 190 return false; 191 } 192 193 /** 194 * Create container 195 * 196 * @param string $containerName Container name 197 * @param array $metadata Key/value pairs of meta data 198 * @return object Container properties 199 * @throws Zend_Service_WindowsAzure_Exception 200 */ 201 public function createContainer($containerName = '', $metadata = array()) 202 { 203 if ($containerName === '') { 204 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 205 } 206 if (!self::isValidContainerName($containerName)) { 207 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.'); 208 } 209 if (!is_array($metadata)) { 210 throw new Zend_Service_WindowsAzure_Exception('Meta data should be an array of key and value pairs.'); 211 } 212 213 // Create metadata headers 214 $headers = array(); 215 $headers = array_merge($headers, $this->_generateMetadataHeaders($metadata)); 216 217 // Perform request 218 $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); 219 if ($response->isSuccessful()) { 220 return new Zend_Service_WindowsAzure_Storage_BlobContainer( 221 $containerName, 222 $response->getHeader('Etag'), 223 $response->getHeader('Last-modified'), 224 $metadata 225 ); 226 } else { 227 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 228 } 229 } 230 231 /** 232 * Get container ACL 233 * 234 * @param string $containerName Container name 235 * @param bool $signedIdentifiers Display only public/private or display signed identifiers? 236 * @return bool Acl, to be compared with Zend_Service_WindowsAzure_Storage_Blob::ACL_* 237 * @throws Zend_Service_WindowsAzure_Exception 238 */ 239 public function getContainerAcl($containerName = '', $signedIdentifiers = false) 240 { 241 if ($containerName === '') { 242 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 243 } 244 if (!self::isValidContainerName($containerName)) { 245 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.'); 246 } 247 248 // Perform request 249 $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); 250 if ($response->isSuccessful()) { 251 if ($signedIdentifiers == false) { 252 // Only public/private 253 return $response->getHeader('x-ms-prop-publicaccess') == 'True'; 254 } else { 255 // Parse result 256 $result = $this->_parseResponse($response); 257 if (!$result) { 258 return array(); 259 } 260 261 $entries = null; 262 if ($result->SignedIdentifier) { 263 if (count($result->SignedIdentifier) > 1) { 264 $entries = $result->SignedIdentifier; 265 } else { 266 $entries = array($result->SignedIdentifier); 267 } 268 } 269 270 // Return value 271 $returnValue = array(); 272 foreach ($entries as $entry) { 273 $returnValue[] = new Zend_Service_WindowsAzure_Storage_SignedIdentifier( 274 $entry->Id, 275 $entry->AccessPolicy ? $entry->AccessPolicy->Start ? $entry->AccessPolicy->Start : '' : '', 276 $entry->AccessPolicy ? $entry->AccessPolicy->Expiry ? $entry->AccessPolicy->Expiry : '' : '', 277 $entry->AccessPolicy ? $entry->AccessPolicy->Permission ? $entry->AccessPolicy->Permission : '' : '' 278 ); 279 } 280 281 // Return 282 return $returnValue; 283 } 284 } else { 285 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 286 } 287 } 288 289 /** 290 * Set container ACL 291 * 292 * @param string $containerName Container name 293 * @param bool $acl Zend_Service_WindowsAzure_Storage_Blob::ACL_* 294 * @param array $signedIdentifiers Signed identifiers 295 * @throws Zend_Service_WindowsAzure_Exception 296 */ 297 public function setContainerAcl($containerName = '', $acl = self::ACL_PRIVATE, $signedIdentifiers = array()) 298 { 299 if ($containerName === '') { 300 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 301 } 302 if (!self::isValidContainerName($containerName)) { 303 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.'); 304 } 305 306 // Policies 307 $policies = null; 308 if (is_array($signedIdentifiers) && count($signedIdentifiers) > 0) { 309 $policies = ''; 310 $policies .= '<?xml version="1.0" encoding="utf-8"?>' . "\r\n"; 311 $policies .= '<SignedIdentifiers>' . "\r\n"; 312 foreach ($signedIdentifiers as $signedIdentifier) { 313 $policies .= ' <SignedIdentifier>' . "\r\n"; 314 $policies .= ' <Id>' . $signedIdentifier->Id . '</Id>' . "\r\n"; 315 $policies .= ' <AccessPolicy>' . "\r\n"; 316 if ($signedIdentifier->Start != '') 317 $policies .= ' <Start>' . $signedIdentifier->Start . '</Start>' . "\r\n"; 318 if ($signedIdentifier->Expiry != '') 319 $policies .= ' <Expiry>' . $signedIdentifier->Expiry . '</Expiry>' . "\r\n"; 320 if ($signedIdentifier->Permissions != '') 321 $policies .= ' <Permission>' . $signedIdentifier->Permissions . '</Permission>' . "\r\n"; 322 $policies .= ' </AccessPolicy>' . "\r\n"; 323 $policies .= ' </SignedIdentifier>' . "\r\n"; 324 } 325 $policies .= '</SignedIdentifiers>' . "\r\n"; 326 } 327 328 // Perform request 329 $response = $this->_performRequest($containerName, '?restype=container&comp=acl', Zend_Http_Client::PUT, array('x-ms-prop-publicaccess' => $acl), false, $policies, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); 330 if (!$response->isSuccessful()) { 331 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 332 } 333 } 334 335 /** 336 * Get container 337 * 338 * @param string $containerName Container name 339 * @return Zend_Service_WindowsAzure_Storage_BlobContainer 340 * @throws Zend_Service_WindowsAzure_Exception 341 */ 342 public function getContainer($containerName = '') 343 { 344 if ($containerName === '') { 345 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 346 } 347 if (!self::isValidContainerName($containerName)) { 348 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.'); 349 } 350 351 // Perform request 352 $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); 353 if ($response->isSuccessful()) { 354 // Parse metadata 355 $metadata = $this->_parseMetadataHeaders($response->getHeaders()); 356 357 // Return container 358 return new Zend_Service_WindowsAzure_Storage_BlobContainer( 359 $containerName, 360 $response->getHeader('Etag'), 361 $response->getHeader('Last-modified'), 362 $metadata 363 ); 364 } else { 365 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 366 } 367 } 368 369 /** 370 * Get container metadata 371 * 372 * @param string $containerName Container name 373 * @return array Key/value pairs of meta data 374 * @throws Zend_Service_WindowsAzure_Exception 375 */ 376 public function getContainerMetadata($containerName = '') 377 { 378 if ($containerName === '') { 379 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 380 } 381 if (!self::isValidContainerName($containerName)) { 382 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.'); 383 } 384 385 return $this->getContainer($containerName)->Metadata; 386 } 387 388 /** 389 * Set container metadata 390 * 391 * 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. 392 * 393 * @param string $containerName Container name 394 * @param array $metadata Key/value pairs of meta data 395 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. 396 * @throws Zend_Service_WindowsAzure_Exception 397 */ 398 public function setContainerMetadata($containerName = '', $metadata = array(), $additionalHeaders = array()) 399 { 400 if ($containerName === '') { 401 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 402 } 403 if (!self::isValidContainerName($containerName)) { 404 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.'); 405 } 406 if (!is_array($metadata)) { 407 throw new Zend_Service_WindowsAzure_Exception('Meta data should be an array of key and value pairs.'); 408 } 409 if (count($metadata) == 0) { 410 return; 411 } 412 413 // Create metadata headers 414 $headers = array(); 415 $headers = array_merge($headers, $this->_generateMetadataHeaders($metadata)); 416 417 // Additional headers? 418 foreach ($additionalHeaders as $key => $value) { 419 $headers[$key] = $value; 420 } 421 422 // Perform request 423 $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); 424 if (!$response->isSuccessful()) { 425 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 426 } 427 } 428 429 /** 430 * Delete container 431 * 432 * @param string $containerName Container name 433 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. 434 * @throws Zend_Service_WindowsAzure_Exception 435 */ 436 public function deleteContainer($containerName = '', $additionalHeaders = array()) 437 { 438 if ($containerName === '') { 439 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 440 } 441 if (!self::isValidContainerName($containerName)) { 442 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.'); 443 } 444 445 // Additional headers? 446 $headers = array(); 447 foreach ($additionalHeaders as $key => $value) { 448 $headers[$key] = $value; 449 } 450 451 // Perform request 452 $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); 453 if (!$response->isSuccessful()) { 454 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 455 } 456 } 457 458 /** 459 * List containers 460 * 461 * @param string $prefix Optional. Filters the results to return only containers whose name begins with the specified prefix. 462 * @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) 463 * @param string $marker Optional string value that identifies the portion of the list to be returned with the next list operation. 464 * @param int $currentResultCount Current result count (internal use) 465 * @return array 466 * @throws Zend_Service_WindowsAzure_Exception 467 */ 468 public function listContainers($prefix = null, $maxResults = null, $marker = null, $currentResultCount = 0) 469 { 470 // Build query string 471 $queryString = '?comp=list'; 472 if (!is_null($prefix)) { 473 $queryString .= '&prefix=' . $prefix; 474 } 475 if (!is_null($maxResults)) { 476 $queryString .= '&maxresults=' . $maxResults; 477 } 478 if (!is_null($marker)) { 479 $queryString .= '&marker=' . $marker; 480 } 481 482 // Perform request 483 $response = $this->_performRequest('', $queryString, Zend_Http_Client::GET, array(), false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_CONTAINER, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_LIST); 484 if ($response->isSuccessful()) { 485 $xmlContainers = $this->_parseResponse($response)->Containers->Container; 486 $xmlMarker = (string)$this->_parseResponse($response)->NextMarker; 487 488 $containers = array(); 489 if (!is_null($xmlContainers)) { 490 for ($i = 0; $i < count($xmlContainers); $i++) { 491 $containers[] = new Zend_Service_WindowsAzure_Storage_BlobContainer( 492 (string)$xmlContainers[$i]->Name, 493 (string)$xmlContainers[$i]->Etag, 494 (string)$xmlContainers[$i]->LastModified 495 ); 496 } 497 } 498 $currentResultCount = $currentResultCount + count($containers); 499 if (!is_null($maxResults) && $currentResultCount < $maxResults) { 500 if (!is_null($xmlMarker) && $xmlMarker != '') { 501 $containers = array_merge($containers, $this->listContainers($prefix, $maxResults, $xmlMarker, $currentResultCount)); 502 } 503 } 504 if (!is_null($maxResults) && count($containers) > $maxResults) { 505 $containers = array_slice($containers, 0, $maxResults); 506 } 507 508 return $containers; 509 } else { 510 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 511 } 512 } 513 514 /** 515 * Put blob 516 * 517 * @param string $containerName Container name 518 * @param string $blobName Blob name 519 * @param string $localFileName Local file name to be uploaded 520 * @param array $metadata Key/value pairs of meta data 521 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. 522 * @return object Partial blob properties 523 * @throws Zend_Service_WindowsAzure_Exception 524 */ 525 public function putBlob($containerName = '', $blobName = '', $localFileName = '', $metadata = array(), $additionalHeaders = array()) 526 { 527 if ($containerName === '') { 528 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 529 } 530 if (!self::isValidContainerName($containerName)) { 531 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.'); 532 } 533 if ($blobName === '') { 534 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 535 } 536 if ($localFileName === '') { 537 throw new Zend_Service_WindowsAzure_Exception('Local file name is not specified.'); 538 } 539 if (!file_exists($localFileName)) { 540 throw new Zend_Service_WindowsAzure_Exception('Local file not found.'); 541 } 542 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 543 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 544 } 545 546 // Check file size 547 if (filesize($localFileName) >= self::MAX_BLOB_SIZE) { 548 return $this->putLargeBlob($containerName, $blobName, $localFileName, $metadata); 549 } 550 551 // Create metadata headers 552 $headers = array(); 553 $headers = array_merge($headers, $this->_generateMetadataHeaders($metadata)); 554 555 // Additional headers? 556 foreach ($additionalHeaders as $key => $value) { 557 $headers[$key] = $value; 558 } 559 560 // File contents 561 $fileContents = file_get_contents($localFileName); 562 563 // Resource name 564 $resourceName = self::createResourceName($containerName , $blobName); 565 566 // Perform request 567 $response = $this->_performRequest($resourceName, '', Zend_Http_Client::PUT, $headers, false, $fileContents, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); 568 if ($response->isSuccessful()) { 569 return new Zend_Service_WindowsAzure_Storage_BlobInstance( 570 $containerName, 571 $blobName, 572 $response->getHeader('Etag'), 573 $response->getHeader('Last-modified'), 574 $this->getBaseUrl() . '/' . $containerName . '/' . $blobName, 575 strlen($fileContents), 576 '', 577 '', 578 '', 579 false, 580 $metadata 581 ); 582 } else { 583 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 584 } 585 } 586 587 /** 588 * Put large blob (> 64 MB) 589 * 590 * @param string $containerName Container name 591 * @param string $blobName Blob name 592 * @param string $localFileName Local file name to be uploaded 593 * @param array $metadata Key/value pairs of meta data 594 * @return object Partial blob properties 595 * @throws Zend_Service_WindowsAzure_Exception 596 */ 597 public function putLargeBlob($containerName = '', $blobName = '', $localFileName = '', $metadata = array()) 598 { 599 if ($containerName === '') { 600 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 601 } 602 if (!self::isValidContainerName($containerName)) { 603 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.'); 604 } 605 if ($blobName === '') { 606 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 607 } 608 if ($localFileName === '') { 609 throw new Zend_Service_WindowsAzure_Exception('Local file name is not specified.'); 610 } 611 if (!file_exists($localFileName)) { 612 throw new Zend_Service_WindowsAzure_Exception('Local file not found.'); 613 } 614 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 615 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 616 } 617 618 // Check file size 619 if (filesize($localFileName) < self::MAX_BLOB_SIZE) { 620 return $this->putBlob($containerName, $blobName, $localFileName, $metadata); 621 } 622 623 // Determine number of parts 624 $numberOfParts = ceil( filesize($localFileName) / self::MAX_BLOB_TRANSFER_SIZE ); 625 626 // Generate block id's 627 $blockIdentifiers = array(); 628 for ($i = 0; $i < $numberOfParts; $i++) { 629 $blockIdentifiers[] = $this->_generateBlockId($i); 630 } 631 632 // Open file 633 $fp = fopen($localFileName, 'r'); 634 if ($fp === false) { 635 throw new Zend_Service_WindowsAzure_Exception('Could not open local file.'); 636 } 637 638 // Upload parts 639 for ($i = 0; $i < $numberOfParts; $i++) { 640 // Seek position in file 641 fseek($fp, $i * self::MAX_BLOB_TRANSFER_SIZE); 642 643 // Read contents 644 $fileContents = fread($fp, self::MAX_BLOB_TRANSFER_SIZE); 645 646 // Put block 647 $this->putBlock($containerName, $blobName, $blockIdentifiers[$i], $fileContents); 648 649 // Dispose file contents 650 $fileContents = null; 651 unset($fileContents); 652 } 653 654 // Close file 655 fclose($fp); 656 657 // Put block list 658 $this->putBlockList($containerName, $blobName, $blockIdentifiers, $metadata); 659 660 // Return information of the blob 661 return $this->getBlobInstance($containerName, $blobName); 662 } 663 664 /** 665 * Put large blob block 666 * 667 * @param string $containerName Container name 668 * @param string $blobName Blob name 669 * @param string $identifier Block ID 670 * @param array $contents Contents of the block 671 * @throws Zend_Service_WindowsAzure_Exception 672 */ 673 public function putBlock($containerName = '', $blobName = '', $identifier = '', $contents = '') 674 { 675 if ($containerName === '') { 676 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 677 } 678 if (!self::isValidContainerName($containerName)) { 679 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.'); 680 } 681 if ($identifier === '') { 682 throw new Zend_Service_WindowsAzure_Exception('Block identifier is not specified.'); 683 } 684 if (strlen($contents) > self::MAX_BLOB_TRANSFER_SIZE) { 685 throw new Zend_Service_WindowsAzure_Exception('Block size is too big.'); 686 } 687 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 688 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 689 } 690 691 // Resource name 692 $resourceName = self::createResourceName($containerName , $blobName); 693 694 // Upload 695 $response = $this->_performRequest($resourceName, '?comp=block&blockid=' . base64_encode($identifier), Zend_Http_Client::PUT, null, false, $contents, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); 696 if (!$response->isSuccessful()) { 697 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 698 } 699 } 700 701 /** 702 * Put block list 703 * 704 * @param string $containerName Container name 705 * @param string $blobName Blob name 706 * @param array $blockList Array of block identifiers 707 * @param array $metadata Key/value pairs of meta data 708 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. 709 * @throws Zend_Service_WindowsAzure_Exception 710 */ 711 public function putBlockList($containerName = '', $blobName = '', $blockList = array(), $metadata = array(), $additionalHeaders = array()) 712 { 713 if ($containerName === '') { 714 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 715 } 716 if (!self::isValidContainerName($containerName)) { 717 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.'); 718 } 719 if ($blobName === '') { 720 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 721 } 722 if (count($blockList) == 0) { 723 throw new Zend_Service_WindowsAzure_Exception('Block list does not contain any elements.'); 724 } 725 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 726 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 727 } 728 729 // Generate block list 730 $blocks = ''; 731 foreach ($blockList as $block) { 732 $blocks .= ' <Latest>' . base64_encode($block) . '</Latest>' . "\n"; 733 } 734 735 // Generate block list request 736 $fileContents = utf8_encode(implode("\n", array( 737 '<?xml version="1.0" encoding="utf-8"?>', 738 '<BlockList>', 739 $blocks, 740 '</BlockList>' 741 ))); 742 743 // Create metadata headers 744 $headers = array(); 745 $headers = array_merge($headers, $this->_generateMetadataHeaders($metadata)); 746 747 // Additional headers? 748 foreach ($additionalHeaders as $key => $value) { 749 $headers[$key] = $value; 750 } 751 752 // Resource name 753 $resourceName = self::createResourceName($containerName , $blobName); 754 755 // Perform request 756 $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); 757 if (!$response->isSuccessful()) { 758 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 759 } 760 } 761 762 /** 763 * Get block list 764 * 765 * @param string $containerName Container name 766 * @param string $blobName Blob name 767 * @param integer $type Type of block list to retrieve. 0 = all, 1 = committed, 2 = uncommitted 768 * @return array 769 * @throws Zend_Service_WindowsAzure_Exception 770 */ 771 public function getBlockList($containerName = '', $blobName = '', $type = 0) 772 { 773 if ($containerName === '') { 774 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 775 } 776 if (!self::isValidContainerName($containerName)) { 777 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.'); 778 } 779 if ($blobName === '') { 780 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 781 } 782 if ($type < 0 || $type > 2) { 783 throw new Zend_Service_WindowsAzure_Exception('Invalid type of block list to retrieve.'); 784 } 785 786 // Set $blockListType 787 $blockListType = 'all'; 788 if ($type == 1) { 789 $blockListType = 'committed'; 790 } 791 if ($type == 2) { 792 $blockListType = 'uncommitted'; 793 } 794 795 // Resource name 796 $resourceName = self::createResourceName($containerName , $blobName); 797 798 // Perform request 799 $response = $this->_performRequest($resourceName, '?comp=blocklist&blocklisttype=' . $blockListType, Zend_Http_Client::GET, array(), false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ); 800 if ($response->isSuccessful()) { 801 // Parse response 802 $blockList = $this->_parseResponse($response); 803 804 // Create return value 805 $returnValue = array(); 806 if ($blockList->CommittedBlocks) { 807 foreach ($blockList->CommittedBlocks->Block as $block) { 808 $returnValue['CommittedBlocks'][] = (object)array( 809 'Name' => (string)$block->Name, 810 'Size' => (string)$block->Size 811 ); 812 } 813 } 814 if ($blockList->UncommittedBlocks) { 815 foreach ($blockList->UncommittedBlocks->Block as $block) { 816 $returnValue['UncommittedBlocks'][] = (object)array( 817 'Name' => (string)$block->Name, 818 'Size' => (string)$block->Size 819 ); 820 } 821 } 822 823 return $returnValue; 824 } else { 825 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 826 } 827 } 828 829 /** 830 * Copy blob 831 * 832 * @param string $sourceContainerName Source container name 833 * @param string $sourceBlobName Source blob name 834 * @param string $destinationContainerName Destination container name 835 * @param string $destinationBlobName Destination blob name 836 * @param array $metadata Key/value pairs of meta data 837 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd894037.aspx for more information. 838 * @return object Partial blob properties 839 * @throws Zend_Service_WindowsAzure_Exception 840 */ 841 public function copyBlob($sourceContainerName = '', $sourceBlobName = '', $destinationContainerName = '', $destinationBlobName = '', $metadata = array(), $additionalHeaders = array()) 842 { 843 if ($sourceContainerName === '') { 844 throw new Zend_Service_WindowsAzure_Exception('Source container name is not specified.'); 845 } 846 if (!self::isValidContainerName($sourceContainerName)) { 847 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.'); 848 } 849 if ($sourceBlobName === '') { 850 throw new Zend_Service_WindowsAzure_Exception('Source blob name is not specified.'); 851 } 852 if ($destinationContainerName === '') { 853 throw new Zend_Service_WindowsAzure_Exception('Destination container name is not specified.'); 854 } 855 if (!self::isValidContainerName($destinationContainerName)) { 856 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.'); 857 } 858 if ($destinationBlobName === '') { 859 throw new Zend_Service_WindowsAzure_Exception('Destination blob name is not specified.'); 860 } 861 if ($sourceContainerName === '$root' && strpos($sourceBlobName, '/') !== false) { 862 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 863 } 864 if ($destinationContainerName === '$root' && strpos($destinationBlobName, '/') !== false) { 865 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 866 } 867 868 // Create metadata headers 869 $headers = array(); 870 $headers = array_merge($headers, $this->_generateMetadataHeaders($metadata)); 871 872 // Additional headers? 873 foreach ($additionalHeaders as $key => $value) { 874 $headers[$key] = $value; 875 } 876 877 // Resource names 878 $sourceResourceName = self::createResourceName($sourceContainerName, $sourceBlobName); 879 $destinationResourceName = self::createResourceName($destinationContainerName, $destinationBlobName); 880 881 // Set source blob 882 $headers["x-ms-copy-source"] = '/' . $this->_accountName . '/' . $sourceResourceName; 883 884 // Perform request 885 $response = $this->_performRequest($destinationResourceName, '', Zend_Http_Client::PUT, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); 886 if ($response->isSuccessful()) { 887 return new Zend_Service_WindowsAzure_Storage_BlobInstance( 888 $destinationContainerName, 889 $destinationBlobName, 890 $response->getHeader('Etag'), 891 $response->getHeader('Last-modified'), 892 $this->getBaseUrl() . '/' . $destinationContainerName . '/' . $destinationBlobName, 893 0, 894 '', 895 '', 896 '', 897 false, 898 $metadata 899 ); 900 } else { 901 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 902 } 903 } 904 905 /** 906 * Get blob 907 * 908 * @param string $containerName Container name 909 * @param string $blobName Blob name 910 * @param string $localFileName Local file name to store downloaded blob 911 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. 912 * @throws Zend_Service_WindowsAzure_Exception 913 */ 914 public function getBlob($containerName = '', $blobName = '', $localFileName = '', $additionalHeaders = array()) 915 { 916 if ($containerName === '') { 917 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 918 } 919 if (!self::isValidContainerName($containerName)) { 920 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.'); 921 } 922 if ($blobName === '') { 923 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 924 } 925 if ($localFileName === '') { 926 throw new Zend_Service_WindowsAzure_Exception('Local file name is not specified.'); 927 } 928 929 // Additional headers? 930 $headers = array(); 931 foreach ($additionalHeaders as $key => $value) { 932 $headers[$key] = $value; 933 } 934 935 // Resource name 936 $resourceName = self::createResourceName($containerName , $blobName); 937 938 // Perform request 939 $response = $this->_performRequest($resourceName, '', Zend_Http_Client::GET, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ); 940 if ($response->isSuccessful()) { 941 file_put_contents($localFileName, $response->getBody()); 942 } else { 943 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 944 } 945 } 946 947 /** 948 * Get container 949 * 950 * @param string $containerName Container name 951 * @param string $blobName Blob name 952 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. 953 * @return Zend_Service_WindowsAzure_Storage_BlobInstance 954 * @throws Zend_Service_WindowsAzure_Exception 955 */ 956 public function getBlobInstance($containerName = '', $blobName = '', $additionalHeaders = array()) 957 { 958 if ($containerName === '') { 959 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 960 } 961 if (!self::isValidContainerName($containerName)) { 962 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.'); 963 } 964 if ($blobName === '') { 965 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 966 } 967 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 968 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 969 } 970 971 // Additional headers? 972 $headers = array(); 973 foreach ($additionalHeaders as $key => $value) { 974 $headers[$key] = $value; 975 } 976 977 // Resource name 978 $resourceName = self::createResourceName($containerName , $blobName); 979 980 // Perform request 981 $response = $this->_performRequest($resourceName, '', Zend_Http_Client::HEAD, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ); 982 if ($response->isSuccessful()) { 983 // Parse metadata 984 $metadata = $this->_parseMetadataHeaders($response->getHeaders()); 985 986 // Return blob 987 return new Zend_Service_WindowsAzure_Storage_BlobInstance( 988 $containerName, 989 $blobName, 990 $response->getHeader('Etag'), 991 $response->getHeader('Last-modified'), 992 $this->getBaseUrl() . '/' . $containerName . '/' . $blobName, 993 $response->getHeader('Content-Length'), 994 $response->getHeader('Content-Type'), 995 $response->getHeader('Content-Encoding'), 996 $response->getHeader('Content-Language'), 997 false, 998 $metadata 999 ); 1000 } else { 1001 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 1002 } 1003 } 1004 1005 /** 1006 * Get blob metadata 1007 * 1008 * @param string $containerName Container name 1009 * @param string $blobName Blob name 1010 * @return array Key/value pairs of meta data 1011 * @throws Zend_Service_WindowsAzure_Exception 1012 */ 1013 public function getBlobMetadata($containerName = '', $blobName = '') 1014 { 1015 if ($containerName === '') { 1016 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 1017 } 1018 if (!self::isValidContainerName($containerName)) { 1019 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.'); 1020 } 1021 if ($blobName === '') { 1022 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 1023 } 1024 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 1025 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 1026 } 1027 1028 return $this->getBlobInstance($containerName, $blobName)->Metadata; 1029 } 1030 1031 /** 1032 * Set blob metadata 1033 * 1034 * 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. 1035 * 1036 * @param string $containerName Container name 1037 * @param string $blobName Blob name 1038 * @param array $metadata Key/value pairs of meta data 1039 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. 1040 * @throws Zend_Service_WindowsAzure_Exception 1041 */ 1042 public function setBlobMetadata($containerName = '', $blobName = '', $metadata = array(), $additionalHeaders = array()) 1043 { 1044 if ($containerName === '') { 1045 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 1046 } 1047 if (!self::isValidContainerName($containerName)) { 1048 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.'); 1049 } 1050 if ($blobName === '') { 1051 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 1052 } 1053 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 1054 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 1055 } 1056 if (count($metadata) == 0) { 1057 return; 1058 } 1059 1060 // Create metadata headers 1061 $headers = array(); 1062 $headers = array_merge($headers, $this->_generateMetadataHeaders($metadata)); 1063 1064 // Additional headers? 1065 foreach ($additionalHeaders as $key => $value) { 1066 $headers[$key] = $value; 1067 } 1068 1069 // Perform request 1070 $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); 1071 if (!$response->isSuccessful()) { 1072 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 1073 } 1074 } 1075 1076 /** 1077 * Delete blob 1078 * 1079 * @param string $containerName Container name 1080 * @param string $blobName Blob name 1081 * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information. 1082 * @throws Zend_Service_WindowsAzure_Exception 1083 */ 1084 public function deleteBlob($containerName = '', $blobName = '', $additionalHeaders = array()) 1085 { 1086 if ($containerName === '') { 1087 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 1088 } 1089 if (!self::isValidContainerName($containerName)) { 1090 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.'); 1091 } 1092 if ($blobName === '') { 1093 throw new Zend_Service_WindowsAzure_Exception('Blob name is not specified.'); 1094 } 1095 if ($containerName === '$root' && strpos($blobName, '/') !== false) { 1096 throw new Zend_Service_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).'); 1097 } 1098 1099 // Additional headers? 1100 $headers = array(); 1101 foreach ($additionalHeaders as $key => $value) { 1102 $headers[$key] = $value; 1103 } 1104 1105 // Resource name 1106 $resourceName = self::createResourceName($containerName , $blobName); 1107 1108 // Perform request 1109 $response = $this->_performRequest($resourceName, '', Zend_Http_Client::DELETE, $headers, false, null, Zend_Service_WindowsAzure_Storage::RESOURCE_BLOB, Zend_Service_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE); 1110 if (!$response->isSuccessful()) { 1111 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 1112 } 1113 } 1114 1115 /** 1116 * List blobs 1117 * 1118 * @param string $containerName Container name 1119 * @param string $prefix Optional. Filters the results to return only blobs whose name begins with the specified prefix. 1120 * @param string $delimiter Optional. Delimiter, i.e. '/', for specifying folder hierarchy 1121 * @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) 1122 * @param string $marker Optional string value that identifies the portion of the list to be returned with the next list operation. 1123 * @param int $currentResultCount Current result count (internal use) 1124 * @return array 1125 * @throws Zend_Service_WindowsAzure_Exception 1126 */ 1127 public function listBlobs($containerName = '', $prefix = '', $delimiter = '', $maxResults = null, $marker = null, $currentResultCount = 0) 1128 { 1129 if ($containerName === '') { 1130 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 1131 } 1132 if (!self::isValidContainerName($containerName)) { 1133 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.'); 1134 } 1135 1136 // Build query string 1137 $queryString = '?restype=container&comp=list'; 1138 if (!is_null($prefix)) { 1139 $queryString .= '&prefix=' . $prefix; 1140 } 1141 if ($delimiter !== '') { 1142 $queryString .= '&delimiter=' . $delimiter; 1143 } 1144 if (!is_null($maxResults)) { 1145 $queryString .= '&maxresults=' . $maxResults; 1146 } 1147 if (!is_null($marker)) { 1148 $queryString .= '&marker=' . $marker; 1149 } 1150 1151 // Perform request 1152 $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); 1153 if ($response->isSuccessful()) { 1154 // Return value 1155 $blobs = array(); 1156 1157 // Blobs 1158 $xmlBlobs = $this->_parseResponse($response)->Blobs->Blob; 1159 if (!is_null($xmlBlobs)) { 1160 for ($i = 0; $i < count($xmlBlobs); $i++) { 1161 $blobs[] = new Zend_Service_WindowsAzure_Storage_BlobInstance( 1162 $containerName, 1163 (string)$xmlBlobs[$i]->Name, 1164 (string)$xmlBlobs[$i]->Etag, 1165 (string)$xmlBlobs[$i]->LastModified, 1166 (string)$xmlBlobs[$i]->Url, 1167 (string)$xmlBlobs[$i]->Size, 1168 (string)$xmlBlobs[$i]->ContentType, 1169 (string)$xmlBlobs[$i]->ContentEncoding, 1170 (string)$xmlBlobs[$i]->ContentLanguage, 1171 false 1172 ); 1173 } 1174 } 1175 1176 // Blob prefixes (folders) 1177 $xmlBlobs = $this->_parseResponse($response)->Blobs->BlobPrefix; 1178 1179 if (!is_null($xmlBlobs)) { 1180 for ($i = 0; $i < count($xmlBlobs); $i++) { 1181 $blobs[] = new Zend_Service_WindowsAzure_Storage_BlobInstance( 1182 $containerName, 1183 (string)$xmlBlobs[$i]->Name, 1184 '', 1185 '', 1186 '', 1187 0, 1188 '', 1189 '', 1190 '', 1191 true 1192 ); 1193 } 1194 } 1195 1196 // More blobs? 1197 $xmlMarker = (string)$this->_parseResponse($response)->NextMarker; 1198 $currentResultCount = $currentResultCount + count($blobs); 1199 if (!is_null($maxResults) && $currentResultCount < $maxResults) { 1200 if (!is_null($xmlMarker) && $xmlMarker != '') { 1201 $blobs = array_merge($blobs, $this->listBlobs($containerName, $prefix, $delimiter, $maxResults, $marker, $currentResultCount)); 1202 } 1203 } 1204 if (!is_null($maxResults) && count($blobs) > $maxResults) { 1205 $blobs = array_slice($blobs, 0, $maxResults); 1206 } 1207 1208 return $blobs; 1209 } else { 1210 throw new Zend_Service_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.')); 1211 } 1212 } 1213 1214 /** 1215 * Generate shared access URL 1216 * 1217 * @param string $containerName Container name 1218 * @param string $blobName Blob name 1219 * @param string $resource Signed resource - container (c) - blob (b) 1220 * @param string $permissions Signed permissions - read (r), write (w), delete (d) and list (l) 1221 * @param string $start The time at which the Shared Access Signature becomes valid. 1222 * @param string $expiry The time at which the Shared Access Signature becomes invalid. 1223 * @param string $identifier Signed identifier 1224 * @return string 1225 */ 1226 public function generateSharedAccessUrl($containerName = '', $blobName = '', $resource = 'b', $permissions = 'r', $start = '', $expiry = '', $identifier = '') 1227 { 1228 if ($containerName === '') { 1229 throw new Zend_Service_WindowsAzure_Exception('Container name is not specified.'); 1230 } 1231 if (!self::isValidContainerName($containerName)) { 1232 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.'); 1233 } 1234 1235 // Resource name 1236 $resourceName = self::createResourceName($containerName , $blobName); 1237 1238 // Generate URL 1239 return $this->getBaseUrl() . '/' . $resourceName . '?' . 1240 $this->_sharedAccessSignatureCredentials->createSignedQueryString( 1241 $resourceName, 1242 '', 1243 $resource, 1244 $permissions, 1245 $start, 1246 $expiry, 1247 $identifier); 1248 } 1249 1250 /** 1251 * Register this object as stream wrapper client 1252 * 1253 * @param string $name Protocol name 1254 * @return Zend_Service_WindowsAzure_Storage_Blob 1255 */ 1256 public function registerAsClient($name) 1257 { 1258 self::$_wrapperClients[$name] = $this; 1259 return $this; 1260 } 1261 1262 /** 1263 * Unregister this object as stream wrapper client 1264 * 1265 * @param string $name Protocol name 1266 * @return Zend_Service_WindowsAzure_Storage_Blob 1267 */ 1268 public function unregisterAsClient($name) 1269 { 1270 unset(self::$_wrapperClients[$name]); 1271 return $this; 1272 } 1273 1274 /** 1275 * Get wrapper client for stream type 1276 * 1277 * @param string $name Protocol name 1278 * @return Zend_Service_WindowsAzure_Storage_Blob 1279 */ 1280 public static function getWrapperClient($name) 1281 { 1282 return self::$_wrapperClients[$name]; 1283 } 1284 1285 /** 1286 * Register this object as stream wrapper 1287 * 1288 * @param string $name Protocol name 1289 */ 1290 public function registerStreamWrapper($name = 'azure') 1291 { 1292 /** 1293 * @see Zend_Service_WindowsAzure_Storage_Blob_Stream 1294 */ 1295 require_once 'Zend/Service/WindowsAzure/Storage/Blob/Stream.php'; 1296 1297 stream_register_wrapper($name, 'Zend_Service_WindowsAzure_Storage_Blob_Stream'); 1298 $this->registerAsClient($name); 1299 } 1300 1301 /** 1302 * Unregister this object as stream wrapper 1303 * 1304 * @param string $name Protocol name 1305 * @return Zend_Service_WindowsAzure_Storage_Blob 1306 */ 1307 public function unregisterStreamWrapper($name = 'azure') 1308 { 1309 stream_wrapper_unregister($name); 1310 $this->unregisterAsClient($name); 1311 } 1312 1313 /** 1314 * Create resource name 1315 * 1316 * @param string $containerName Container name 1317 * @param string $blobName Blob name 1318 * @return string 1319 */ 1320 public static function createResourceName($containerName = '', $blobName = '') 1321 { 1322 // Resource name 1323 $resourceName = $containerName . '/' . $blobName; 1324 if ($containerName === '' || $containerName === '$root') { 1325 $resourceName = $blobName; 1326 } 1327 if ($blobName === '') { 1328 $resourceName = $containerName; 1329 } 1330 1331 return $resourceName; 1332 } 1333 1334 /** 1335 * Is valid container name? 1336 * 1337 * @param string $containerName Container name 1338 * @return boolean 1339 */ 1340 public static function isValidContainerName($containerName = '') 1341 { 1342 if ($containerName == '$root') { 1343 return true; 1344 } 1345 1346 if (preg_match("/^[a-z0-9][a-z0-9-]*$/", $containerName) === 0) { 1347 return false; 1348 } 1349 1350 if (strpos($containerName, '--') !== false) { 1351 return false; 1352 } 1353 1354 if (strtolower($containerName) != $containerName) { 1355 return false; 1356 } 1357 1358 if (strlen($containerName) < 3 || strlen($containerName) > 63) { 1359 return false; 1360 } 1361 1362 if (substr($containerName, -1) == '-') { 1363 return false; 1364 } 1365 1366 return true; 1367 } 1368 1369 /** 1370 * Get error message from Zend_Http_Response 1371 * 1372 * @param Zend_Http_Response $response Repsonse 1373 * @param string $alternativeError Alternative error message 1374 * @return string 1375 */ 1376 protected function _getErrorMessage(Zend_Http_Response $response, $alternativeError = 'Unknown error.') 1377 { 1378 $response = $this->_parseResponse($response); 1379 if ($response && $response->Message) { 1380 return (string)$response->Message; 1381 } else { 1382 return $alternativeError; 1383 } 1384 } 1385 1386 /** 1387 * Generate block id 1388 * 1389 * @param int $part Block number 1390 * @return string Windows Azure Blob Storage block number 1391 */ 1392 protected function _generateBlockId($part = 0) 1393 { 1394 $returnValue = $part; 1395 while (strlen($returnValue) < 64) { 1396 $returnValue = '0' . $returnValue; 1397 } 1398 1399 return $returnValue; 1400 } 1401 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |