PageRenderTime 54ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/MoodleWebRole/azure/Microsoft/WindowsAzure/Storage/Blob.php

#
PHP | 1413 lines | 822 code | 142 blank | 449 comment | 190 complexity | f2b33784e0d02c21ed50ffd75bcbadec MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, LGPL-2.0, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * Copyright (c) 2009, RealDolmen
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are met:
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * * Neither the name of RealDolmen nor the
  14. * names of its contributors may be used to endorse or promote products
  15. * derived from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
  18. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20. * DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
  21. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  22. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  24. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  26. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. *
  28. * @category Microsoft
  29. * @package Microsoft_WindowsAzure
  30. * @subpackage Storage
  31. * @copyright Copyright (c) 2009, RealDolmen (http://www.realdolmen.com)
  32. * @license http://todo name_todo
  33. * @version $Id: Blob.php 33934 2009-11-03 07:21:49Z unknown $
  34. */
  35. /**
  36. * @see Microsoft_WindowsAzure_SharedKeyCredentials
  37. */
  38. require_once 'Microsoft/WindowsAzure/SharedKeyCredentials.php';
  39. /**
  40. * @see Microsoft_WindowsAzure_SharedAccessSignatureCredentials
  41. */
  42. require_once 'Microsoft/WindowsAzure/SharedAccessSignatureCredentials.php';
  43. /**
  44. * @see Microsoft_WindowsAzure_RetryPolicy
  45. */
  46. require_once 'Microsoft/WindowsAzure/RetryPolicy.php';
  47. /**
  48. * @see Microsoft_Http_Transport
  49. */
  50. require_once 'Microsoft/Http/Transport.php';
  51. /**
  52. * @see Microsoft_Http_Response
  53. */
  54. require_once 'Microsoft/Http/Response.php';
  55. /**
  56. * @see Microsoft_WindowsAzure_Storage
  57. */
  58. require_once 'Microsoft/WindowsAzure/Storage.php';
  59. /**
  60. * @see Microsoft_WindowsAzure_Storage_BlobContainer
  61. */
  62. require_once 'Microsoft/WindowsAzure/Storage/BlobContainer.php';
  63. /**
  64. * @see Microsoft_WindowsAzure_Storage_BlobInstance
  65. */
  66. require_once 'Microsoft/WindowsAzure/Storage/BlobInstance.php';
  67. /**
  68. * @see Microsoft_WindowsAzure_Storage_SignedIdentifier
  69. */
  70. require_once 'Microsoft/WindowsAzure/Storage/SignedIdentifier.php';
  71. /**
  72. * @see Microsoft_WindowsAzure_Exception
  73. */
  74. require_once 'Microsoft/WindowsAzure/Exception.php';
  75. /**
  76. * @category Microsoft
  77. * @package Microsoft_WindowsAzure
  78. * @subpackage Storage
  79. * @copyright Copyright (c) 2009, RealDolmen (http://www.realdolmen.com)
  80. * @license http://phpazure.codeplex.com/license
  81. */
  82. class Microsoft_WindowsAzure_Storage_Blob extends Microsoft_WindowsAzure_Storage
  83. {
  84. /**
  85. * ACL - Private access
  86. */
  87. const ACL_PRIVATE = false;
  88. /**
  89. * ACL - Public access
  90. */
  91. const ACL_PUBLIC = true;
  92. /**
  93. * Maximal blob size (in bytes)
  94. */
  95. const MAX_BLOB_SIZE = 67108864;
  96. /**
  97. * Maximal blob transfer size (in bytes)
  98. */
  99. const MAX_BLOB_TRANSFER_SIZE = 4194304;
  100. /**
  101. * Stream wrapper clients
  102. *
  103. * @var array
  104. */
  105. protected static $_wrapperClients = array();
  106. /**
  107. * SharedAccessSignature credentials
  108. *
  109. * @var Microsoft_WindowsAzure_SharedAccessSignatureCredentials
  110. */
  111. private $_sharedAccessSignatureCredentials = null;
  112. /**
  113. * Creates a new Microsoft_WindowsAzure_Storage_Blob instance
  114. *
  115. * @param string $host Storage host name
  116. * @param string $accountName Account name for Windows Azure
  117. * @param string $accountKey Account key for Windows Azure
  118. * @param boolean $usePathStyleUri Use path-style URI's
  119. * @param Microsoft_WindowsAzure_RetryPolicy $retryPolicy Retry policy to use when making requests
  120. */
  121. public function __construct($host = Microsoft_WindowsAzure_Storage::URL_DEV_BLOB, $accountName = Microsoft_WindowsAzure_SharedKeyCredentials::DEVSTORE_ACCOUNT, $accountKey = Microsoft_WindowsAzure_SharedKeyCredentials::DEVSTORE_KEY, $usePathStyleUri = false, Microsoft_WindowsAzure_RetryPolicy $retryPolicy = null)
  122. {
  123. parent::__construct($host, $accountName, $accountKey, $usePathStyleUri, $retryPolicy);
  124. // API version
  125. $this->_apiVersion = '2009-07-17';
  126. // SharedAccessSignature credentials
  127. $this->_sharedAccessSignatureCredentials = new Microsoft_WindowsAzure_SharedAccessSignatureCredentials($accountName, $accountKey, $usePathStyleUri);
  128. }
  129. /**
  130. * Check if a blob exists
  131. *
  132. * @param string $containerName Container name
  133. * @param string $blobName Blob name
  134. * @return boolean
  135. */
  136. public function blobExists($containerName = '', $blobName = '')
  137. {
  138. if ($containerName === '')
  139. throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
  140. if (!self::isValidContainerName($containerName))
  141. throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
  142. if ($blobName === '')
  143. throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
  144. // List blobs
  145. $blobs = $this->listBlobs($containerName, $blobName, '', 1);
  146. foreach ($blobs as $blob)
  147. {
  148. if ($blob->Name == $blobName)
  149. return true;
  150. }
  151. return false;
  152. }
  153. /**
  154. * Check if a container exists
  155. *
  156. * @param string $containerName Container name
  157. * @return boolean
  158. */
  159. public function containerExists($containerName = '')
  160. {
  161. if ($containerName === '')
  162. throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
  163. if (!self::isValidContainerName($containerName))
  164. throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
  165. // List containers
  166. $containers = $this->listContainers($containerName, 1);
  167. foreach ($containers as $container)
  168. {
  169. if ($container->Name == $containerName)
  170. return true;
  171. }
  172. return false;
  173. }
  174. /**
  175. * Create container
  176. *
  177. * @param string $containerName Container name
  178. * @param array $metadata Key/value pairs of meta data
  179. * @return object Container properties
  180. * @throws Microsoft_WindowsAzure_Exception
  181. */
  182. public function createContainer($containerName = '', $metadata = array())
  183. {
  184. if ($containerName === '')
  185. throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
  186. if (!self::isValidContainerName($containerName))
  187. throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
  188. if (!is_array($metadata))
  189. throw new Microsoft_WindowsAzure_Exception('Meta data should be an array of key and value pairs.');
  190. // Create metadata headers
  191. $headers = array();
  192. foreach ($metadata as $key => $value)
  193. {
  194. $headers["x-ms-meta-" . strtolower($key)] = $value;
  195. }
  196. // Perform request
  197. $response = $this->performRequest($containerName, '?restype=container', Microsoft_Http_Transport::VERB_PUT, $headers, false, null, Microsoft_WindowsAzure_Storage::RESOURCE_CONTAINER, Microsoft_WindowsAzure_Credentials::PERMISSION_WRITE);
  198. if ($response->isSuccessful())
  199. {
  200. return new Microsoft_WindowsAzure_Storage_BlobContainer(
  201. $containerName,
  202. $response->getHeader('Etag'),
  203. $response->getHeader('Last-modified'),
  204. $metadata
  205. );
  206. }
  207. else
  208. {
  209. throw new Microsoft_WindowsAzure_Exception($this->getErrorMessage($response, 'Resource could not be accessed.'));
  210. }
  211. }
  212. /**
  213. * Get container ACL
  214. *
  215. * @param string $containerName Container name
  216. * @param bool $signedIdentifiers Display only public/private or display signed identifiers?
  217. * @return bool Acl, to be compared with Microsoft_WindowsAzure_Storage_Blob::ACL_*
  218. * @throws Microsoft_WindowsAzure_Exception
  219. */
  220. public function getContainerAcl($containerName = '', $signedIdentifiers = false)
  221. {
  222. if ($containerName === '')
  223. throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
  224. if (!self::isValidContainerName($containerName))
  225. throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
  226. // Perform request
  227. $response = $this->performRequest($containerName, '?restype=container&comp=acl', Microsoft_Http_Transport::VERB_GET, array(), false, null, Microsoft_WindowsAzure_Storage::RESOURCE_CONTAINER, Microsoft_WindowsAzure_Credentials::PERMISSION_READ);
  228. if ($response->isSuccessful())
  229. {
  230. if ($signedIdentifiers == false)
  231. {
  232. // Only public/private
  233. return $response->getHeader('x-ms-prop-publicaccess') == 'True';
  234. }
  235. else
  236. {
  237. // Parse result
  238. $result = $this->parseResponse($response);
  239. if (!$result)
  240. return array();
  241. $entries = null;
  242. if ($result->SignedIdentifier)
  243. {
  244. if (count($result->SignedIdentifier) > 1)
  245. {
  246. $entries = $result->SignedIdentifier;
  247. }
  248. else
  249. {
  250. $entries = array($result->SignedIdentifier);
  251. }
  252. }
  253. // Return value
  254. $returnValue = array();
  255. foreach ($entries as $entry)
  256. {
  257. $returnValue[] = new Microsoft_WindowsAzure_Storage_SignedIdentifier(
  258. $entry->Id,
  259. $entry->AccessPolicy ? $entry->AccessPolicy->Start ? $entry->AccessPolicy->Start : '' : '',
  260. $entry->AccessPolicy ? $entry->AccessPolicy->Expiry ? $entry->AccessPolicy->Expiry : '' : '',
  261. $entry->AccessPolicy ? $entry->AccessPolicy->Permission ? $entry->AccessPolicy->Permission : '' : ''
  262. );
  263. }
  264. // Return
  265. return $returnValue;
  266. }
  267. }
  268. else
  269. {
  270. throw new Microsoft_WindowsAzure_Exception($this->getErrorMessage($response, 'Resource could not be accessed.'));
  271. }
  272. }
  273. /**
  274. * Set container ACL
  275. *
  276. * @param string $containerName Container name
  277. * @param bool $acl Microsoft_WindowsAzure_Storage_Blob::ACL_*
  278. * @param array $signedIdentifiers Signed identifiers
  279. * @throws Microsoft_WindowsAzure_Exception
  280. */
  281. public function setContainerAcl($containerName = '', $acl = self::ACL_PRIVATE, $signedIdentifiers = array())
  282. {
  283. if ($containerName === '')
  284. throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
  285. if (!self::isValidContainerName($containerName))
  286. throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
  287. // Policies
  288. $policies = null;
  289. if (is_array($signedIdentifiers) && count($signedIdentifiers) > 0)
  290. {
  291. $policies = '';
  292. $policies .= '<?xml version="1.0" encoding="utf-8"?>' . "\r\n";
  293. $policies .= '<SignedIdentifiers>' . "\r\n";
  294. foreach ($signedIdentifiers as $signedIdentifier)
  295. {
  296. $policies .= ' <SignedIdentifier>' . "\r\n";
  297. $policies .= ' <Id>' . $signedIdentifier->Id . '</Id>' . "\r\n";
  298. $policies .= ' <AccessPolicy>' . "\r\n";
  299. if ($signedIdentifier->Start != '')
  300. $policies .= ' <Start>' . $signedIdentifier->Start . '</Start>' . "\r\n";
  301. if ($signedIdentifier->Expiry != '')
  302. $policies .= ' <Expiry>' . $signedIdentifier->Expiry . '</Expiry>' . "\r\n";
  303. if ($signedIdentifier->Permissions != '')
  304. $policies .= ' <Permission>' . $signedIdentifier->Permissions . '</Permission>' . "\r\n";
  305. $policies .= ' </AccessPolicy>' . "\r\n";
  306. $policies .= ' </SignedIdentifier>' . "\r\n";
  307. }
  308. $policies .= '</SignedIdentifiers>' . "\r\n";
  309. }
  310. // Perform request
  311. $response = $this->performRequest($containerName, '?restype=container&comp=acl', Microsoft_Http_Transport::VERB_PUT, array('x-ms-prop-publicaccess' => $acl), false, $policies, Microsoft_WindowsAzure_Storage::RESOURCE_CONTAINER, Microsoft_WindowsAzure_Credentials::PERMISSION_WRITE);
  312. if (!$response->isSuccessful())
  313. {
  314. throw new Microsoft_WindowsAzure_Exception($this->getErrorMessage($response, 'Resource could not be accessed.'));
  315. }
  316. }
  317. /**
  318. * Get container
  319. *
  320. * @param string $containerName Container name
  321. * @return Microsoft_WindowsAzure_Storage_BlobContainer
  322. * @throws Microsoft_WindowsAzure_Exception
  323. */
  324. public function getContainer($containerName = '')
  325. {
  326. if ($containerName === '')
  327. throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
  328. if (!self::isValidContainerName($containerName))
  329. throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
  330. // Perform request
  331. $response = $this->performRequest($containerName, '?restype=container', Microsoft_Http_Transport::VERB_GET, array(), false, null, Microsoft_WindowsAzure_Storage::RESOURCE_CONTAINER, Microsoft_WindowsAzure_Credentials::PERMISSION_READ);
  332. if ($response->isSuccessful())
  333. {
  334. // Parse metadata
  335. $metadata = array();
  336. foreach ($response->getHeaders() as $key => $value)
  337. {
  338. if (substr(strtolower($key), 0, 10) == "x-ms-meta-")
  339. {
  340. $metadata[str_replace("x-ms-meta-", '', strtolower($key))] = $value;
  341. }
  342. }
  343. // Return container
  344. return new Microsoft_WindowsAzure_Storage_BlobContainer(
  345. $containerName,
  346. $response->getHeader('Etag'),
  347. $response->getHeader('Last-modified'),
  348. $metadata
  349. );
  350. }
  351. else
  352. {
  353. throw new Microsoft_WindowsAzure_Exception($this->getErrorMessage($response, 'Resource could not be accessed.'));
  354. }
  355. }
  356. /**
  357. * Get container metadata
  358. *
  359. * @param string $containerName Container name
  360. * @return array Key/value pairs of meta data
  361. * @throws Microsoft_WindowsAzure_Exception
  362. */
  363. public function getContainerMetadata($containerName = '')
  364. {
  365. if ($containerName === '')
  366. throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
  367. if (!self::isValidContainerName($containerName))
  368. throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
  369. return $this->getContainer($containerName)->Metadata;
  370. }
  371. /**
  372. * Set container metadata
  373. *
  374. * 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.
  375. *
  376. * @param string $containerName Container name
  377. * @param array $metadata Key/value pairs of meta data
  378. * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
  379. * @throws Microsoft_WindowsAzure_Exception
  380. */
  381. public function setContainerMetadata($containerName = '', $metadata = array(), $additionalHeaders = array())
  382. {
  383. if ($containerName === '')
  384. throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
  385. if (!self::isValidContainerName($containerName))
  386. throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
  387. if (!is_array($metadata))
  388. throw new Microsoft_WindowsAzure_Exception('Meta data should be an array of key and value pairs.');
  389. if (count($metadata) == 0)
  390. return;
  391. // Create metadata headers
  392. $headers = array();
  393. foreach ($metadata as $key => $value)
  394. {
  395. $headers["x-ms-meta-" . strtolower($key)] = $value;
  396. }
  397. // Additional headers?
  398. foreach ($additionalHeaders as $key => $value)
  399. {
  400. $headers[$key] = $value;
  401. }
  402. // Perform request
  403. $response = $this->performRequest($containerName, '?restype=container&comp=metadata', Microsoft_Http_Transport::VERB_PUT, $headers, false, null, Microsoft_WindowsAzure_Storage::RESOURCE_CONTAINER, Microsoft_WindowsAzure_Credentials::PERMISSION_WRITE);
  404. if (!$response->isSuccessful())
  405. {
  406. throw new Microsoft_WindowsAzure_Exception($this->getErrorMessage($response, 'Resource could not be accessed.'));
  407. }
  408. }
  409. /**
  410. * Delete container
  411. *
  412. * @param string $containerName Container name
  413. * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
  414. * @throws Microsoft_WindowsAzure_Exception
  415. */
  416. public function deleteContainer($containerName = '', $additionalHeaders = array())
  417. {
  418. if ($containerName === '')
  419. throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
  420. if (!self::isValidContainerName($containerName))
  421. throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
  422. // Additional headers?
  423. $headers = array();
  424. foreach ($additionalHeaders as $key => $value)
  425. {
  426. $headers[$key] = $value;
  427. }
  428. // Perform request
  429. $response = $this->performRequest($containerName, '?restype=container', Microsoft_Http_Transport::VERB_DELETE, $headers, false, null, Microsoft_WindowsAzure_Storage::RESOURCE_CONTAINER, Microsoft_WindowsAzure_Credentials::PERMISSION_WRITE);
  430. if (!$response->isSuccessful())
  431. {
  432. throw new Microsoft_WindowsAzure_Exception($this->getErrorMessage($response, 'Resource could not be accessed.'));
  433. }
  434. }
  435. /**
  436. * List containers
  437. *
  438. * @param string $prefix Optional. Filters the results to return only containers whose name begins with the specified prefix.
  439. * @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)
  440. * @param string $marker Optional string value that identifies the portion of the list to be returned with the next list operation.
  441. * @param int $currentResultCount Current result count (internal use)
  442. * @return array
  443. * @throws Microsoft_WindowsAzure_Exception
  444. */
  445. public function listContainers($prefix = null, $maxResults = null, $marker = null, $currentResultCount = 0)
  446. {
  447. // Build query string
  448. $queryString = '?comp=list';
  449. if (!is_null($prefix))
  450. $queryString .= '&prefix=' . $prefix;
  451. if (!is_null($maxResults))
  452. $queryString .= '&maxresults=' . $maxResults;
  453. if (!is_null($marker))
  454. $queryString .= '&marker=' . $marker;
  455. // Perform request
  456. $response = $this->performRequest('', $queryString, Microsoft_Http_Transport::VERB_GET, array(), false, null, Microsoft_WindowsAzure_Storage::RESOURCE_CONTAINER, Microsoft_WindowsAzure_Credentials::PERMISSION_LIST);
  457. if ($response->isSuccessful())
  458. {
  459. $xmlContainers = $this->parseResponse($response)->Containers->Container;
  460. $xmlMarker = (string)$this->parseResponse($response)->NextMarker;
  461. $containers = array();
  462. if (!is_null($xmlContainers))
  463. {
  464. for ($i = 0; $i < count($xmlContainers); $i++)
  465. {
  466. $containers[] = new Microsoft_WindowsAzure_Storage_BlobContainer(
  467. (string)$xmlContainers[$i]->Name,
  468. (string)$xmlContainers[$i]->Etag,
  469. (string)$xmlContainers[$i]->LastModified
  470. );
  471. }
  472. }
  473. $currentResultCount = $currentResultCount + count($containers);
  474. if (!is_null($maxResults) && $currentResultCount < $maxResults)
  475. {
  476. if (!is_null($xmlMarker) && $xmlMarker != '')
  477. {
  478. $containers = array_merge($containers, $this->listContainers($prefix, $maxResults, $xmlMarker, $currentResultCount));
  479. }
  480. }
  481. if (!is_null($maxResults) && count($containers) > $maxResults)
  482. $containers = array_slice($containers, 0, $maxResults);
  483. return $containers;
  484. }
  485. else
  486. {
  487. throw new Microsoft_WindowsAzure_Exception($this->getErrorMessage($response, 'Resource could not be accessed.'));
  488. }
  489. }
  490. /**
  491. * Put blob
  492. *
  493. * @param string $containerName Container name
  494. * @param string $blobName Blob name
  495. * @param string $localFileName Local file name to be uploaded
  496. * @param array $metadata Key/value pairs of meta data
  497. * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
  498. * @return object Partial blob properties
  499. * @throws Microsoft_WindowsAzure_Exception
  500. */
  501. public function putBlob($containerName = '', $blobName = '', $localFileName = '', $metadata = array(), $additionalHeaders = array())
  502. {
  503. if ($containerName === '')
  504. throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
  505. if (!self::isValidContainerName($containerName))
  506. throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
  507. if ($blobName === '')
  508. throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
  509. if ($localFileName === '')
  510. throw new Microsoft_WindowsAzure_Exception('Local file name is not specified.');
  511. if (!file_exists($localFileName))
  512. throw new Microsoft_WindowsAzure_Exception('Local file not found.');
  513. if ($containerName === '$root' && strpos($blobName, '/') !== false)
  514. throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  515. // Check file size
  516. if (filesize($localFileName) >= self::MAX_BLOB_SIZE)
  517. return $this->putLargeBlob($containerName, $blobName, $localFileName, $metadata);
  518. // Create metadata headers
  519. $headers = array();
  520. foreach ($metadata as $key => $value)
  521. {
  522. $headers["x-ms-meta-" . strtolower($key)] = $value;
  523. }
  524. // Additional headers?
  525. foreach ($additionalHeaders as $key => $value)
  526. {
  527. $headers[$key] = $value;
  528. }
  529. // File contents
  530. $fileContents = file_get_contents($localFileName);
  531. // Resource name
  532. $resourceName = self::createResourceName($containerName , $blobName);
  533. // Perform request
  534. $response = $this->performRequest($resourceName, '', Microsoft_Http_Transport::VERB_PUT, $headers, false, $fileContents, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials::PERMISSION_WRITE);
  535. if ($response->isSuccessful())
  536. {
  537. return new Microsoft_WindowsAzure_Storage_BlobInstance(
  538. $containerName,
  539. $blobName,
  540. $response->getHeader('Etag'),
  541. $response->getHeader('Last-modified'),
  542. $this->getBaseUrl() . '/' . $containerName . '/' . $blobName,
  543. strlen($fileContents),
  544. '',
  545. '',
  546. '',
  547. false,
  548. $metadata
  549. );
  550. }
  551. else
  552. {
  553. throw new Microsoft_WindowsAzure_Exception($this->getErrorMessage($response, 'Resource could not be accessed.'));
  554. }
  555. }
  556. /**
  557. * Put large blob (> 64 MB)
  558. *
  559. * @param string $containerName Container name
  560. * @param string $blobName Blob name
  561. * @param string $localFileName Local file name to be uploaded
  562. * @param array $metadata Key/value pairs of meta data
  563. * @return object Partial blob properties
  564. * @throws Microsoft_WindowsAzure_Exception
  565. */
  566. public function putLargeBlob($containerName = '', $blobName = '', $localFileName = '', $metadata = array())
  567. {
  568. if ($containerName === '')
  569. throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
  570. if (!self::isValidContainerName($containerName))
  571. throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
  572. if ($blobName === '')
  573. throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
  574. if ($localFileName === '')
  575. throw new Microsoft_WindowsAzure_Exception('Local file name is not specified.');
  576. if (!file_exists($localFileName))
  577. throw new Microsoft_WindowsAzure_Exception('Local file not found.');
  578. if ($containerName === '$root' && strpos($blobName, '/') !== false)
  579. throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  580. // Check file size
  581. if (filesize($localFileName) < self::MAX_BLOB_SIZE)
  582. return $this->putBlob($containerName, $blobName, $localFileName, $metadata);
  583. // Determine number of parts
  584. $numberOfParts = ceil( filesize($localFileName) / self::MAX_BLOB_TRANSFER_SIZE );
  585. // Generate block id's
  586. $blockIdentifiers = array();
  587. for ($i = 0; $i < $numberOfParts; $i++)
  588. {
  589. $blockIdentifiers[] = $this->generateBlockId($i);
  590. }
  591. // Open file
  592. $fp = fopen($localFileName, 'r');
  593. if ($fp === false)
  594. throw new Microsoft_WindowsAzure_Exception('Could not open local file.');
  595. // Upload parts
  596. for ($i = 0; $i < $numberOfParts; $i++)
  597. {
  598. // Seek position in file
  599. fseek($fp, $i * self::MAX_BLOB_TRANSFER_SIZE);
  600. // Read contents
  601. $fileContents = fread($fp, self::MAX_BLOB_TRANSFER_SIZE);
  602. // Put block
  603. $this->putBlock($containerName, $blobName, $blockIdentifiers[$i], $fileContents);
  604. // Dispose file contents
  605. $fileContents = null;
  606. unset($fileContents);
  607. }
  608. // Close file
  609. fclose($fp);
  610. // Put block list
  611. $this->putBlockList($containerName, $blobName, $blockIdentifiers, $metadata);
  612. // Return information of the blob
  613. return $this->getBlobInstance($containerName, $blobName);
  614. }
  615. /**
  616. * Put large blob block
  617. *
  618. * @param string $containerName Container name
  619. * @param string $blobName Blob name
  620. * @param string $identifier Block ID
  621. * @param array $contents Contents of the block
  622. * @throws Microsoft_WindowsAzure_Exception
  623. */
  624. public function putBlock($containerName = '', $blobName = '', $identifier = '', $contents = '')
  625. {
  626. if ($containerName === '')
  627. throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
  628. if (!self::isValidContainerName($containerName))
  629. throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
  630. if ($identifier === '')
  631. throw new Microsoft_WindowsAzure_Exception('Block identifier is not specified.');
  632. if (strlen($contents) > self::MAX_BLOB_TRANSFER_SIZE)
  633. throw new Microsoft_WindowsAzure_Exception('Block size is too big.');
  634. if ($containerName === '$root' && strpos($blobName, '/') !== false)
  635. throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  636. // Resource name
  637. $resourceName = self::createResourceName($containerName , $blobName);
  638. // Upload
  639. $response = $this->performRequest($resourceName, '?comp=block&blockid=' . base64_encode($identifier), Microsoft_Http_Transport::VERB_PUT, null, false, $contents, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials::PERMISSION_WRITE);
  640. if (!$response->isSuccessful())
  641. {
  642. throw new Microsoft_WindowsAzure_Exception($this->getErrorMessage($response, 'Resource could not be accessed.'));
  643. }
  644. }
  645. /**
  646. * Put block list
  647. *
  648. * @param string $containerName Container name
  649. * @param string $blobName Blob name
  650. * @param array $blockList Array of block identifiers
  651. * @param array $metadata Key/value pairs of meta data
  652. * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
  653. * @throws Microsoft_WindowsAzure_Exception
  654. */
  655. public function putBlockList($containerName = '', $blobName = '', $blockList = array(), $metadata = array(), $additionalHeaders = array())
  656. {
  657. if ($containerName === '')
  658. throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
  659. if (!self::isValidContainerName($containerName))
  660. throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
  661. if ($blobName === '')
  662. throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
  663. if (count($blockList) == 0)
  664. throw new Microsoft_WindowsAzure_Exception('Block list does not contain any elements.');
  665. if ($containerName === '$root' && strpos($blobName, '/') !== false)
  666. throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  667. // Generate block list
  668. $blocks = '';
  669. foreach ($blockList as $block)
  670. {
  671. $blocks .= ' <Latest>' . base64_encode($block) . '</Latest>' . "\n";
  672. }
  673. // Generate block list request
  674. $fileContents = utf8_encode(implode("\n", array(
  675. '<?xml version="1.0" encoding="utf-8"?>',
  676. '<BlockList>',
  677. $blocks,
  678. '</BlockList>'
  679. )));
  680. // Create metadata headers
  681. $headers = array();
  682. foreach ($metadata as $key => $value)
  683. {
  684. $headers["x-ms-meta-" . strtolower($key)] = $value;
  685. }
  686. // Additional headers?
  687. foreach ($additionalHeaders as $key => $value)
  688. {
  689. $headers[$key] = $value;
  690. }
  691. // Resource name
  692. $resourceName = self::createResourceName($containerName , $blobName);
  693. // Perform request
  694. $response = $this->performRequest($resourceName, '?comp=blocklist', Microsoft_Http_Transport::VERB_PUT, $headers, false, $fileContents, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials::PERMISSION_WRITE);
  695. if (!$response->isSuccessful())
  696. {
  697. throw new Microsoft_WindowsAzure_Exception($this->getErrorMessage($response, 'Resource could not be accessed.'));
  698. }
  699. }
  700. /**
  701. * Get block list
  702. *
  703. * @param string $containerName Container name
  704. * @param string $blobName Blob name
  705. * @param integer $type Type of block list to retrieve. 0 = all, 1 = committed, 2 = uncommitted
  706. * @return array
  707. * @throws Microsoft_WindowsAzure_Exception
  708. */
  709. public function getBlockList($containerName = '', $blobName = '', $type = 0)
  710. {
  711. if ($containerName === '')
  712. throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
  713. if (!self::isValidContainerName($containerName))
  714. throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
  715. if ($blobName === '')
  716. throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
  717. if ($type < 0 || $type > 2)
  718. throw new Microsoft_WindowsAzure_Exception('Invalid type of block list to retrieve.');
  719. // Set $blockListType
  720. $blockListType = 'all';
  721. if ($type == 1)
  722. $blockListType = 'committed';
  723. if ($type == 2)
  724. $blockListType = 'uncommitted';
  725. // Resource name
  726. $resourceName = self::createResourceName($containerName , $blobName);
  727. // Perform request
  728. $response = $this->performRequest($resourceName, '?comp=blocklist&blocklisttype=' . $blockListType, Microsoft_Http_Transport::VERB_GET, array(), false, null, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials::PERMISSION_READ);
  729. if ($response->isSuccessful())
  730. {
  731. // Parse response
  732. $blockList = $this->parseResponse($response);
  733. // Create return value
  734. $returnValue = array();
  735. if ($blockList->CommittedBlocks)
  736. {
  737. foreach ($blockList->CommittedBlocks->Block as $block)
  738. {
  739. $returnValue['CommittedBlocks'][] = (object)array(
  740. 'Name' => (string)$block->Name,
  741. 'Size' => (string)$block->Size
  742. );
  743. }
  744. }
  745. if ($blockList->UncommittedBlocks)
  746. {
  747. foreach ($blockList->UncommittedBlocks->Block as $block)
  748. {
  749. $returnValue['UncommittedBlocks'][] = (object)array(
  750. 'Name' => (string)$block->Name,
  751. 'Size' => (string)$block->Size
  752. );
  753. }
  754. }
  755. return $returnValue;
  756. }
  757. else
  758. {
  759. throw new Microsoft_WindowsAzure_Exception($this->getErrorMessage($response, 'Resource could not be accessed.'));
  760. }
  761. }
  762. /**
  763. * Copy blob
  764. *
  765. * @param string $sourceContainerName Source container name
  766. * @param string $sourceBlobName Source blob name
  767. * @param string $destinationContainerName Destination container name
  768. * @param string $destinationBlobName Destination blob name
  769. * @param array $metadata Key/value pairs of meta data
  770. * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd894037.aspx for more information.
  771. * @return object Partial blob properties
  772. * @throws Microsoft_WindowsAzure_Exception
  773. */
  774. public function copyBlob($sourceContainerName = '', $sourceBlobName = '', $destinationContainerName = '', $destinationBlobName = '', $metadata = array(), $additionalHeaders = array())
  775. {
  776. if ($sourceContainerName === '')
  777. throw new Microsoft_WindowsAzure_Exception('Source container name is not specified.');
  778. if (!self::isValidContainerName($sourceContainerName))
  779. throw new Microsoft_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.');
  780. if ($sourceBlobName === '')
  781. throw new Microsoft_WindowsAzure_Exception('Source blob name is not specified.');
  782. if ($destinationContainerName === '')
  783. throw new Microsoft_WindowsAzure_Exception('Destination container name is not specified.');
  784. if (!self::isValidContainerName($destinationContainerName))
  785. throw new Microsoft_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.');
  786. if ($destinationBlobName === '')
  787. throw new Microsoft_WindowsAzure_Exception('Destination blob name is not specified.');
  788. if ($sourceContainerName === '$root' && strpos($sourceBlobName, '/') !== false)
  789. throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  790. if ($destinationContainerName === '$root' && strpos($destinationBlobName, '/') !== false)
  791. throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  792. // Create metadata headers
  793. $headers = array();
  794. foreach ($metadata as $key => $value)
  795. {
  796. $headers["x-ms-meta-" . strtolower($key)] = $value;
  797. }
  798. // Additional headers?
  799. foreach ($additionalHeaders as $key => $value)
  800. {
  801. $headers[$key] = $value;
  802. }
  803. // Resource names
  804. $sourceResourceName = self::createResourceName($sourceContainerName, $sourceBlobName);
  805. $destinationResourceName = self::createResourceName($destinationContainerName, $destinationBlobName);
  806. // Set source blob
  807. $headers["x-ms-copy-source"] = '/' . $this->_accountName . '/' . $sourceResourceName;
  808. // Perform request
  809. $response = $this->performRequest($destinationResourceName, '', Microsoft_Http_Transport::VERB_PUT, $headers, false, null, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials::PERMISSION_WRITE);
  810. if ($response->isSuccessful())
  811. {
  812. return new Microsoft_WindowsAzure_Storage_BlobInstance(
  813. $destinationContainerName,
  814. $destinationBlobName,
  815. $response->getHeader('Etag'),
  816. $response->getHeader('Last-modified'),
  817. $this->getBaseUrl() . '/' . $destinationContainerName . '/' . $destinationBlobName,
  818. 0,
  819. '',
  820. '',
  821. '',
  822. false,
  823. $metadata
  824. );
  825. }
  826. else
  827. {
  828. throw new Microsoft_WindowsAzure_Exception($this->getErrorMessage($response, 'Resource could not be accessed.'));
  829. }
  830. }
  831. /**
  832. * Get blob
  833. *
  834. * @param string $containerName Container name
  835. * @param string $blobName Blob name
  836. * @param string $localFileName Local file name to store downloaded blob
  837. * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
  838. * @throws Microsoft_WindowsAzure_Exception
  839. */
  840. public function getBlob($containerName = '', $blobName = '', $localFileName = '', $additionalHeaders = array())
  841. {
  842. if ($containerName === '')
  843. throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
  844. if (!self::isValidContainerName($containerName))
  845. throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
  846. if ($blobName === '')
  847. throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
  848. if ($localFileName === '')
  849. throw new Microsoft_WindowsAzure_Exception('Local file name is not specified.');
  850. // Additional headers?
  851. $headers = array();
  852. foreach ($additionalHeaders as $key => $value)
  853. {
  854. $headers[$key] = $value;
  855. }
  856. // Resource name
  857. $resourceName = self::createResourceName($containerName , $blobName);
  858. // Perform request
  859. $response = $this->performRequest($resourceName, '', Microsoft_Http_Transport::VERB_GET, $headers, false, null, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials::PERMISSION_READ);
  860. if ($response->isSuccessful())
  861. file_put_contents($localFileName, $response->getBody());
  862. else
  863. {
  864. throw new Microsoft_WindowsAzure_Exception($this->getErrorMessage($response, 'Resource could not be accessed.'));
  865. }
  866. }
  867. /**
  868. * Get container
  869. *
  870. * @param string $containerName Container name
  871. * @param string $blobName Blob name
  872. * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
  873. * @return Microsoft_WindowsAzure_Storage_BlobInstance
  874. * @throws Microsoft_WindowsAzure_Exception
  875. */
  876. public function getBlobInstance($containerName = '', $blobName = '', $additionalHeaders = array())
  877. {
  878. if ($containerName === '')
  879. throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
  880. if (!self::isValidContainerName($containerName))
  881. throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
  882. if ($blobName === '')
  883. throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
  884. if ($containerName === '$root' && strpos($blobName, '/') !== false)
  885. throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  886. // Additional headers?
  887. $headers = array();
  888. foreach ($additionalHeaders as $key => $value)
  889. {
  890. $headers[$key] = $value;
  891. }
  892. // Resource name
  893. $resourceName = self::createResourceName($containerName , $blobName);
  894. // Perform request
  895. $response = $this->performRequest($resourceName, '', Microsoft_Http_Transport::VERB_HEAD, $headers, false, null, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials::PERMISSION_READ);
  896. if ($response->isSuccessful())
  897. {
  898. // Parse metadata
  899. $metadata = array();
  900. foreach ($response->getHeaders() as $key => $value)
  901. {
  902. if (substr(strtolower($key), 0, 10) == "x-ms-meta-")
  903. {
  904. $metadata[str_replace("x-ms-meta-", '', strtolower($key))] = $value;
  905. }
  906. }
  907. // Return blob
  908. return new Microsoft_WindowsAzure_Storage_BlobInstance(
  909. $containerName,
  910. $blobName,
  911. $response->getHeader('Etag'),
  912. $response->getHeader('Last-modified'),
  913. $this->getBaseUrl() . '/' . $containerName . '/' . $blobName,
  914. $response->getHeader('Content-Length'),
  915. $response->getHeader('Content-Type'),
  916. $response->getHeader('Content-Encoding'),
  917. $response->getHeader('Content-Language'),
  918. false,
  919. $metadata
  920. );
  921. }
  922. else
  923. {
  924. throw new Microsoft_WindowsAzure_Exception($this->getErrorMessage($response, 'Resource could not be accessed.'));
  925. }
  926. }
  927. /**
  928. * Get blob metadata
  929. *
  930. * @param string $containerName Container name
  931. * @param string $blobName Blob name
  932. * @return array Key/value pairs of meta data
  933. * @throws Microsoft_WindowsAzure_Exception
  934. */
  935. public function getBlobMetadata($containerName = '', $blobName = '')
  936. {
  937. if ($containerName === '')
  938. throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
  939. if (!self::isValidContainerName($containerName))
  940. throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
  941. if ($blobName === '')
  942. throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
  943. if ($containerName === '$root' && strpos($blobName, '/') !== false)
  944. throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  945. return $this->getBlobInstance($containerName, $blobName)->Metadata;
  946. }
  947. /**
  948. * Set blob metadata
  949. *
  950. * 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.
  951. *
  952. * @param string $containerName Container name
  953. * @param string $blobName Blob name
  954. * @param array $metadata Key/value pairs of meta data
  955. * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
  956. * @throws Microsoft_WindowsAzure_Exception
  957. */
  958. public function setBlobMetadata($containerName = '', $blobName = '', $metadata = array(), $additionalHeaders = array())
  959. {
  960. if ($containerName === '')
  961. throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
  962. if (!self::isValidContainerName($containerName))
  963. throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
  964. if ($blobName === '')
  965. throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
  966. if ($containerName === '$root' && strpos($blobName, '/') !== false)
  967. throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  968. if (count($metadata) == 0)
  969. return;
  970. // Create metadata headers
  971. $headers = array();
  972. foreach ($metadata as $key => $value)
  973. {
  974. $headers["x-ms-meta-" . strtolower($key)] = $value;
  975. }
  976. // Additional headers?
  977. foreach ($additionalHeaders as $key => $value)
  978. {
  979. $headers[$key] = $value;
  980. }
  981. // Perform request
  982. $response = $this->performRequest($containerName . '/' . $blobName, '?comp=metadata', Microsoft_Http_Transport::VERB_PUT, $headers, false, null, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials::PERMISSION_WRITE);
  983. if (!$response->isSuccessful())
  984. {
  985. throw new Microsoft_WindowsAzure_Exception($this->getErrorMessage($response, 'Resource could not be accessed.'));
  986. }
  987. }
  988. /**
  989. * Delete blob
  990. *
  991. * @param string $containerName Container name
  992. * @param string $blobName Blob name
  993. * @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
  994. * @throws Microsoft_WindowsAzure_Exception
  995. */
  996. public function deleteBlob($containerName = '', $blobName = '', $additionalHeaders = array())
  997. {
  998. if ($containerName === '')
  999. throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
  1000. if (!self::isValidContainerName($containerName))
  1001. throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
  1002. if ($blobName === '')
  1003. throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
  1004. if ($containerName === '$root' && strpos($blobName, '/') !== false)
  1005. throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
  1006. // Additional headers?
  1007. $headers = array();
  1008. foreach ($additionalHeaders as $key => $value)
  1009. {
  1010. $headers[$key] = $value;
  1011. }
  1012. // Resource name
  1013. $resourceName = self::createResourceName($containerName , $blobName);
  1014. // Perform request
  1015. $response = $this->performRequest($resourceName, '', Microsoft_Http_Transport::VERB_DELETE, $headers, false, null, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials::PERMISSION_WRITE);
  1016. if (!$response->isSuccessful())
  1017. {
  1018. throw new Microsoft_WindowsAzure_Exception($this->getErrorMessage($response, 'Resource could not be accessed.'));
  1019. }
  1020. }
  1021. /**
  1022. * List blobs
  1023. *
  1024. * @param string $containerName Container name
  1025. * @param string $prefix Optional. Filters the results to return only blobs whose name begins with the specified prefix.
  1026. * @param string $delimiter Optional. Delimiter, i.e. '/', for specifying folder hierarchy
  1027. * @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)
  1028. * @param string $marker Optional string value that identifies the portion of the list to be returned with the next list operation.
  1029. * @param int $currentResultCount Current result count (internal use)
  1030. * @return array
  1031. * @throws Microsoft_WindowsAzure_Exception
  1032. */
  1033. public function listBlobs($containerName = '', $prefix = '', $delimiter = '', $maxResults = null, $marker = null, $currentResultCount = 0)
  1034. {
  1035. if ($containerName === '')
  1036. throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
  1037. if (!self::isValidContainerName($containerName))
  1038. throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
  1039. // Build query string
  1040. $queryString = '?restype=container&comp=list';
  1041. if (!is_null($prefix))
  1042. $queryString .= '&prefix=' . $prefix;
  1043. if ($delimiter !== '')
  1044. $queryString .= '&delimiter=' . $delimiter;
  1045. if (!is_null($maxResults))
  1046. $queryString .= '&maxresults=' . $maxResults;
  1047. if (!is_null($marker))
  1048. $queryString .= '&marker=' . $marker;
  1049. // Perform request
  1050. $response = $this->performRequest($containerName, $queryString, Microsoft_Http_Transport::VERB_GET, array(), false, null, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials::PERMISSION_LIST);
  1051. if ($response->isSuccessful())
  1052. {
  1053. // Return value
  1054. $blobs = array();
  1055. // Blobs
  1056. $xmlBlobs = $this->parseResponse($response)->Blobs->Blob;
  1057. if (!is_null($xmlBlobs))
  1058. {
  1059. for ($i = 0; $i < count($xmlBlobs); $i++)
  1060. {
  1061. $blobs[] = new Microsoft_WindowsAzure_Storage_BlobInstance(
  1062. $containerName,
  1063. (string)$xmlBlobs[$i]->Name,
  1064. (string)$xmlBlobs[$i]->Etag,
  1065. (string)$xmlBlobs[$i]->LastModified,
  1066. (string)$xmlBlobs[$i]->Url,
  1067. (string)$xmlBlobs[$i]->Size,
  1068. (string)$xmlBlobs[$i]->ContentType,
  1069. (string)$xmlBlobs[$i]->ContentEncoding,
  1070. (string)$xmlBlobs[$i]->ContentLanguage,
  1071. false
  1072. );
  1073. }
  1074. }
  1075. // Bl…

Large files files are truncated, but you can click here to view the full file