PageRenderTime 56ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/htdocs/zend/1.10.2-minapp/library/Zend/Service/WindowsAzure/Storage/Blob.php

http://github.com/pmjones/php-framework-benchmarks
PHP | 1401 lines | 823 code | 142 blank | 436 comment | 197 complexity | a59483368cd8992a98c062a1a8df793e MD5 | raw file
Possible License(s): LGPL-3.0, Apache-2.0, BSD-3-Clause, ISC, AGPL-3.0, LGPL-2.1

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

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

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