PageRenderTime 51ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/www/system/library/Zend/Service/WindowsAzure/Storage/Blob.php

https://bitbucket.org/vmihailenco/zf-blog
PHP | 1401 lines | 812 code | 153 blank | 436 comment | 197 complexity | 2183ec9a5af7a7fbc700e11db8059b50 MD5 | raw file

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

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