/** * Upload the given file to an Azure Storage container as a block blob. * * Block blobs are comprised of blocks, each of which is identified by a block ID. * This allows creation or modification of a block blob by writing a set of blocks * and committing them by their block IDs, resulting in an overall efficient upload. * * If writing a block blob that is no more than 64MB in size, upload it * in its entirety with a single write operation. Otherwise, chunk the blob into discrete * blocks and upload each of them, then commit the blob ID to signal to Azure that they * should be combined into a blob. Files over 64MB are then deleted from temporary local storage. * * When you upload a block to a blob in your storage account, it is associated with the * specified block blob, but it does not become part of the blob until you commit a list * of blocks that includes the new block's ID. * * @param string $containerName The container to add the blob to. * @param string $blobName The name of the blob to upload. * @param string $localFileName The full path to local file to be uploaded. * @param string $blobContentType Optional. Content type of the blob. * @param array $metadata Optional. Metadata to describe the blob. * * @throws \Exception|ServiceException Exception if local file can't be read; * ServiceException if response code is incorrect. */ public static function putBlockBlob($containerName, $blobName, $localFileName, $blobContentType = null, $metadata = array()) { $copyBlobResult = null; $is_large_file = false; // Open file $handle = fopen($localFileName, 'r'); if ($handle === false) { throw new Exception('Could not open the local file ' . $localFileName); } /** @var \WindowsAzure\Blob\BlobRestProxy $blobRestProxy */ $blobRestProxy = WindowsAzureStorageUtil::getStorageClient(); try { if (filesize($localFileName) < self::MAX_BLOB_SIZE) { $createBlobOptions = new CreateBlobOptions(); $createBlobOptions->setBlobContentType($blobContentType); $createBlobOptions->setMetadata($metadata); $blobRestProxy->createBlockBlob($containerName, $blobName, $handle, $createBlobOptions); fclose($handle); } else { $is_large_file = true; // Determine number of page blocks $numberOfBlocks = ceil(filesize($localFileName) / self::MAX_BLOB_TRANSFER_SIZE); // Generate block id's $blocks = array(); for ($i = 0; $i < $numberOfBlocks; $i++) { /** @var WindowsAzure\Blob\Models\Block */ $block = new Block(); $block->setBlockId(self::_generateBlockId($i)); $block->setType(BlobBlockType::LATEST_TYPE); // Seek position in file fseek($handle, $i * self::MAX_BLOB_TRANSFER_SIZE); // Read contents $fileContents = fread($handle, self::MAX_BLOB_TRANSFER_SIZE); // Put block $blobRestProxy->createBlobBlock($containerName, $blobName, $block->getBlockId(), $fileContents); // Save it for later $blocks[$i] = $block; } // Close file fclose($handle); // Set Block Blob's content type and metadata $commitBlockBlobOptions = new CommitBlobBlocksOptions(); $commitBlockBlobOptions->setBlobContentType($blobContentType); $commitBlockBlobOptions->setMetadata($metadata); // Commit the block list $blobRestProxy->commitBlobBlocks($containerName, $blobName, $blocks, $commitBlockBlobOptions); if ($is_large_file) { // Delete large temp files when we're done try { //TODO: add option to keep this file if so desired if (self::blob_exists_in_container($blobName, $containerName)) { wp_delete_file($localFileName); // Dispose file contents $fileContents = null; unset($fileContents); } else { throw new Exception(sprintf(__('The blob %1$2 was not uploaded to container %2$2. Please try again.', 'windows-azure-storage'), $blobName, $containerName)); } } catch (Exception $ex) { echo '<p class="notice">' . esc_html($ex->getMessage()) . '</p>'; } } } } catch (ServiceException $exception) { if (!$handle) { fclose($handle); } throw $exception; } }
/** * @covers WindowsAzure\Blob\Models\CommitBlobBlocksOptions::setAccessCondition */ public function testSetAccessCondition() { // Setup $expected = AccessCondition::none(); $result = new CommitBlobBlocksOptions(); // Test $result->setAccessCondition($expected); // Assert $this->assertEquals($expected, $result->getAccessCondition()); }
/** * This method writes a blob by specifying the list of block IDs that make up the * blob. In order to be written as part of a blob, a block must have been * successfully written to the server in a prior createBlobBlock method. * * You can call Put Block List to update a blob by uploading only those blocks * that have changed, then committing the new and existing blocks together. * You can do this by specifying whether to commit a block from the committed * block list or from the uncommitted block list, or to commit the most recently * uploaded version of the block, whichever list it may belong to. * * @param string $container The container name. * @param string $blob The blob name. * @param Models\BlockList|array $blockList The block entries. * @param Models\CommitBlobBlocksOptions $options The optional parameters. * * @return CopyBlobResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179467.aspx */ public function commitBlobBlocks($container, $blob, $blockList, $options = null) { Validate::isString($container, 'container'); Validate::isString($blob, 'blob'); Validate::notNullOrEmpty($blob, 'blob'); Validate::isTrue($blockList instanceof BlockList || is_array($blockList), sprintf(Resources::INVALID_PARAM_MSG, 'blockList', get_class(new BlockList()))); $method = Resources::HTTP_PUT; $headers = array(); $postParams = array(); $queryParams = array(); $path = $this->_createPath($container, $blob); $statusCode = Resources::STATUS_CREATED; $isArray = is_array($blockList); $blockList = $isArray ? BlockList::create($blockList) : $blockList; $body = $blockList->toXml($this->dataSerializer); if (is_null($options)) { $options = new CommitBlobBlocksOptions(); } $blobContentType = $options->getBlobContentType(); $blobContentEncoding = $options->getBlobContentEncoding(); $blobContentLanguage = $options->getBlobContentLanguage(); $blobContentMD5 = $options->getBlobContentMD5(); $blobCacheControl = $options->getBlobCacheControl(); $leaseId = $options->getLeaseId(); $contentType = Resources::URL_ENCODED_CONTENT_TYPE; $metadata = $options->getMetadata(); $headers = $this->generateMetadataHeaders($metadata); $headers = $this->addOptionalAccessConditionHeader($headers, $options->getAccessCondition()); $this->addOptionalHeader($headers, Resources::X_MS_LEASE_ID, $leaseId); $this->addOptionalHeader($headers, Resources::X_MS_BLOB_CACHE_CONTROL, $blobCacheControl); $this->addOptionalHeader($headers, Resources::X_MS_BLOB_CONTENT_TYPE, $blobContentType); $this->addOptionalHeader($headers, Resources::X_MS_BLOB_CONTENT_ENCODING, $blobContentEncoding); $this->addOptionalHeader($headers, Resources::X_MS_BLOB_CONTENT_LANGUAGE, $blobContentLanguage); $this->addOptionalHeader($headers, Resources::X_MS_BLOB_CONTENT_MD5, $blobContentMD5); $this->addOptionalHeader($headers, Resources::CONTENT_TYPE, $contentType); $this->addOptionalQueryParam($queryParams, Resources::QP_TIMEOUT, $options->getTimeout()); $this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'blocklist'); return $this->send($method, $headers, $queryParams, $postParams, $path, $statusCode, $body); }
/** * Upload the given file to an azure storage container as a block blob. * Block blobs let us upload large blobs efficiently. Block blobs are comprised of blocks, * each of which is identified by a block ID. This allows create (or modify) a block blob * by writing a set of blocks and committing them by their block IDs. * If we are writing a block blob that is no more than 64 MB in size, you can upload it * in its entirety with a single write operation. * When you upload a block to a blob in your storage account, it is associated with the * specified block blob, but it does not become part of the blob until you commit a list * of blocks that includes the new block's ID. * * @param string $containerName Container name * * @param string $blobName Blob name * * @param string $localFileName Path to local file to be uploaded * * @param string $blobContentType Content type of the blob * * @param array $metadata Array of metadata * * @return void * * @throws ServiceException */ public static function putBlockBlob($containerName, $blobName, $localFileName, $blobContentType = null, $metadata = array()) { $copyBlobResult = null; // Open file $handle = fopen($localFileName, 'r'); if ($handle === false) { throw new Exception('Could not open the local file ' . localFileName); } $blobRestProxy = WindowsAzureStorageUtil::getStorageClient(); try { if (filesize($localFileName) < self::MAX_BLOB_SIZE) { $createBlobOptions = new CreateBlobOptions(); $createBlobOptions->setBlobContentType($blobContentType); $createBlobOptions->setMetadata($metadata); $blobRestProxy->createBlockBlob($containerName, $blobName, $handle, $createBlobOptions); fclose($handle); } else { // Determine number of page blocks $numberOfBlocks = ceil(filesize($localFileName) / self::MAX_BLOB_TRANSFER_SIZE); // Generate block id's $blocks = array(); for ($i = 0; $i < $numberOfBlocks; $i++) { $blocks[$i] = new Block(); $blocks[$i]->setBlockId(self::_generateBlockId($i)); $blocks[$i]->setType(BlobBlockType::LATEST_TYPE); } // Upload blocks for ($i = 0; $i < $numberOfBlocks; $i++) { // Seek position in file fseek($handle, $i * self::MAX_BLOB_TRANSFER_SIZE); // Read contents $fileContents = fread($handle, self::MAX_BLOB_TRANSFER_SIZE); // Put block $blobRestProxy->createBlobBlock($containerName, $blobName, $blocks[$i]->getBlockId(), $fileContents); // Dispose file contents $fileContents = null; unset($fileContents); } // Close file fclose($handle); // Set Block Blob's content type and metadata $commitBlockBlobOptions = new CommitBlobBlocksOptions(); $commitBlockBlobOptions->setBlobContentType($blobContentType); $commitBlockBlobOptions->setMetadata($metadata); // Commit the block list $blobRestProxy->commitBlobBlocks($containerName, $blobName, $blocks, $commitBlockBlobOptions); } } catch (ServiceException $exception) { if (!$handle) { fclose($handle); } throw $exception; } }