/** * Hook for handling deleting media files from standard WordpRess dialog * * @param string $postID post id * * @return void */ function windows_azure_storage_delete_attachment($postID) { if (is_numeric($postID)) { $mediaInfo = get_post_meta($postID, 'windows_azure_storage_info', true); if (!empty($mediaInfo)) { // Delete media file from blob storage $containerName = $mediaInfo['container']; $blobName = $mediaInfo['blob']; WindowsAzureStorageUtil::deleteBlob($containerName, $blobName); // Delete associated thumbnails from blob storage (if any) $thumbnails = $mediaInfo['thumbnails']; if (!empty($thumbnails)) { foreach ($thumbnails as $thumbnail_blob) { WindowsAzureStorageUtil::deleteBlob($containerName, $thumbnail_blob); } } } } }
/** * Render Windows Azure Storage Plugin Options Screen * * @param string $mode mode for logged in user (admin/nonadmin) * * @return void */ function show_windows_azure_storage_settings($mode) { $containerCreationStatus = true; $message = createContainerIfRequired($containerCreationStatus); // Storage Account Settings from db if already set $storageAccountName = WindowsAzureStorageUtil::getAccountName(); $storageAccountKey = WindowsAzureStorageUtil::getAccountKey(); $httpProxyHost = WindowsAzureStorageUtil::getHttpProxyHost(); $httpProxyPort = WindowsAzureStorageUtil::getHttpProxyPort(); $httpProxyUserName = WindowsAzureStorageUtil::getHttpProxyUserName(); $httpProxyPassword = WindowsAzureStorageUtil::getHttpProxyPassword(); $newContainerName = null; // Use the account settings in the $_POST if this page load is // a result of container creation operation. if (array_key_exists("azure_storage_account_name", $_POST)) { $storageAccountName = $_POST["azure_storage_account_name"]; } if (array_key_exists("azure_storage_account_primary_access_key", $_POST)) { $storageAccountKey = $_POST["azure_storage_account_primary_access_key"]; } if (array_key_exists("http_proxy_host", $_POST)) { $httpProxyHost = $_POST["http_proxy_host"]; } if (array_key_exists("http_proxy_port", $_POST)) { $httpProxyPort = $_POST["http_proxy_port"]; } if (array_key_exists("http_proxy_host", $_POST)) { $httpProxyUserName = $_POST["http_proxy_host"]; } if (array_key_exists("http_proxy_password", $_POST)) { $httpProxyPassword = $_POST["http_proxy_password"]; } // We need to show the container name if the request for // container creation fails. if (!$containerCreationStatus) { $newContainerName = $_POST["newcontainer"]; } $ContainerResult = null; try { if (!empty($storageAccountName) && !empty($storageAccountKey)) { $storageClient = WindowsAzureStorageUtil::getStorageClient($storageAccountName, $storageAccountKey, $httpProxyHost, $httpProxyPort, $httpProxyUserName, $httpProxyPassword); $ContainerResult = $storageClient->listContainers(); $defaultContainer = WindowsAzureStorageUtil::getDefaultContainer(); $privateContainerWarning = null; if (!empty($defaultContainer)) { $getContainerAclResult = $storageClient->getContainerAcl($defaultContainer); $containerAcl = $getContainerAclResult->getContainerAcl(); if ($containerAcl->getPublicAccess() == PublicAccessType::NONE) { $privateContainerWarning = "<p style=\"margin: 10px; color: red;\">Warning: The container '{$defaultContainer}' you set as default is a private container. Plugin supports only public container, please set a public container as default</p>"; } } } } catch (Exception $ex) { // Ignore exception as account keys are not yet set } echo $privateContainerWarning; ?> <table class="form-table" border="0"> <tr valign="top"> <th scope="row"> <label for="storage_account_name" title="Windows Azure Storage Account Name">Store Account Name</label> </th> <td> <input type="text" name="azure_storage_account_name" title="Windows Azure Storage Account Name" value="<?php echo $storageAccountName; ?> " /> </td> <td></td> </tr> <tr valign="top"> <th scope="row"> <label for="azure_storage_account_primary_access_key" title="Windows Azure Storage Account Primary Access Key">Primary Access Key</label> </th> <td> <input type="text" name="azure_storage_account_primary_access_key" title="Windows Azure Storage Account Primary Access Key" value="<?php echo $storageAccountKey; ?> " /> </td> <td></td> </tr> <tr valign="top"> <th scope="row"> <label for="storage_container_name" title="Default container to be used for storing media files">Default Storage Container</label> </th> <td WIDTH="80px"> <select name="default_azure_storage_account_container_name" title="Default container to be used for storing media files" onChange="onContainerSelectionChanged(false)"> <?php if (!empty($ContainerResult) && count($ContainerResult->getContainers()) > 0) { foreach ($ContainerResult->getContainers() as $container) { ?> <option value="<?php echo $container->getName(); ?> " <?php echo $container->getName() == $defaultContainer ? 'selected="selected"' : ''; ?> > <?php echo $container->getName(); ?> </option> <?php } ?> <option value="<Create New Container>"><Create New Container></option> <?php } ?> </select> </td> <td> <div id="divCreateContainer" name="divCreateContainer" style="display:none;"> <table style="border:1px solid black;"> <tr> <td><label for="newcontainer" title="Name of the new container to create">Create New Container: </label></td> <td> <input type="text" name="newcontainer" title="Name of the new container to create" value="<?php echo $newContainerName; ?> " /> <input type="button" class="button-primary" value="<?php _e('Create'); ?> " <?php echo "onclick=\"createContainer('" . $_SERVER['REQUEST_URI'] . "')\""; ?> /> </td> </tr> </table> </dv> </td> </tr> <tr valign="top"> <td colspan="3" WIDTH="300" align="center"><?php echo $message; ?> </td> </tr> <tr valign="top"> <th scope="row"> <label for="cname" title="Use CNAME insted of Windows Azure Blob URL">CNAME</label> </th> <td colspan="2"> <input type="text" name="cname" title="Use CNAME insted of Windows Azure Blob URL" value="<?php echo WindowsAzureStorageUtil::getCNAME(); ?> " /> <br /><small>Note: Use this option if you would like to display image urls belonging to your domain like http://MyDomain.com/ instead of http://YourAccountName.blob.core.windows.net/.</small> <br /><small>This CNAME must start with http(s) and administrator will have to update DNS entries accordingly.</small> </td> </tr> <tr valign="top"> <th scope="row"> <label for="http_proxy_host" title="Use HTTP proxy server host name if web proxy server is configured">HTTP Proxy Host Name</label> </th> <td> <input type="text" name="http_proxy_host" title="Use HTTP proxy server host name if web proxy server is configured" value="<?php echo $httpProxyHost; ?> " /> </td> <td></td> </tr> <tr valign="top"> <th scope="row"> <label for="http_proxy_port" title="Use HTTP proxy port if web proxy server is configured">HTTP Proxy Port Name</label> </th> <td> <input type="text" name="http_proxy_port" title="Use HTTP proxy port if web proxy server is configured" value="<?php echo $httpProxyPort; ?> " /> </td> <td></td> </tr> <tr valign="top"> <th scope="row"> <label for="http_proxy_username" title="Use HTTP proxy user name if credential is required to access web proxy server">HTTP Proxy User Name</label> </th> <td> <input type="text" name="http_proxy_username" title="Use HTTP proxy user name if credential is required to access web proxy server" value="<?php echo $httpProxyUserName; ?> " /> </td> <td></td> </tr> <tr valign="top"> <th scope="row"> <label for="http_proxy_password" title="Use HTTP proxy password if credential is required to access web proxy server">HTTP Proxy Password</label> </th> <td> <input type="text" name="http_proxy_password" title="Use HTTP proxy password if credential is required to access web proxy server" value="<?php echo $httpProxyPassword; ?> " /> </td> <td></td> </tr> <tr valign="top"> <th scope="row"> <label for="azure_storage_use_for_default_upload" title="Use Windows Azure Storage for default upload">Use Windows Azure Storage for default upload</label> </th> <td colspan="2"> <input type="checkbox" name="azure_storage_use_for_default_upload" title="Use Windows Azure Storage for default upload" value="1" id="azure_storage_use_for_default_upload" <?php echo get_option('azure_storage_use_for_default_upload') ? 'checked="checked" ' : ''; ?> /> <label for="wp-uploads"> Use Windows Azure Storage when uploading via WordPress' upload tab.</label> <br /><small>Note: Uncheck this to revert back to using your own web host for storage at anytime.</small> </td> </tr> </table> <?php if (empty($ContainerResult) || !$containerCreationStatus || count($ContainerResult->getContainers()) === 0) { // 1. If $containerResult object is null means the storage account is not yet set // show the create container div ?> <script type="text/javascript"> onContainerSelectionChanged(true); </script> <?php } }
/** * 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; } }
/** * Delete a blob from specified container * * @param string $containerName Name of the parent container * * @param string $blobName Name of the blob to be deleted * * @return void */ function deleteBlob($containerName, $blobName) { try { if (WindowsAzureStorageUtil::blobExists($containerName, $blobName)) { $_SERVER['REQUEST_URI'] = remove_query_arg(array('delete_blob', 'filename', 'selected_container'), $_SERVER['REQUEST_URI']); WindowsAzureStorageUtil::deleteBlob($containerName, $blobName); } } catch (Exception $e) { /* translators: 1: blob (file) name, 2: container name, 3: error message */ $message = sprintf(__('Error in deleting blob %1$s from container %2$s: %3$s', 'windows-azure-storage'), $blobName, $containerName, $e->getMessage()); echo '<p class="warning">' . esc_html($message) . '</p>'; } }
/** * Delete a blob from specified container * * @param string $containerName Name of the parent container * * @param string $blobName Name of the blob to be deleted * * @return void */ function deleteBlob($containerName, $blobName) { try { if (WindowsAzureStorageUtil::blobExists($containerName, $blobName)) { remove_query_arg('deleteBlob', $_SERVER['REQUEST_URI']); WindowsAzureStorageUtil::deleteBlob($containerName, $blobName); } } catch (Exception $e) { echo '<p style="margin: 10px; color: red;">' . 'Error in deleting blob $blobName from container $containerName : ' . $e->getMessage() . "</p><br/>"; } }
/** * Render Windows Azure Storage Plugin Options Screen * * @param string $mode mode for logged in user (admin/nonadmin) * * @return void */ function show_windows_azure_storage_settings($mode) { $containerCreationStatus = true; $message = createContainerIfRequired($containerCreationStatus); // Storage Account Settings from db if already set //TODO: check POST values first and use these for fallbacks $storageAccountName = WindowsAzureStorageUtil::getAccountName(); $storageAccountKey = WindowsAzureStorageUtil::getAccountKey(); $httpProxyHost = WindowsAzureStorageUtil::getHttpProxyHost(); $httpProxyPort = WindowsAzureStorageUtil::getHttpProxyPort(); $httpProxyUserName = WindowsAzureStorageUtil::getHttpProxyUserName(); $httpProxyPassword = WindowsAzureStorageUtil::getHttpProxyPassword(); $defaultContainer = WindowsAzureStorageUtil::getDefaultContainer(); $newContainerName = null; // Use the account settings in the $_POST if this page load is // a result of container creation operation. if (wp_verify_nonce($_REQUEST['_wpnonce'], 'windows-azure-storage-settings-group-options') && isset($_POST['action2']) && 'update' === $_POST['action2']) { //TODO sanitize and set from a loop instead of a bunch of if…then statements if (array_key_exists("azure_storage_account_name", $_POST)) { $storageAccountName = sanitize_text_field($_POST["azure_storage_account_name"]); } if (array_key_exists("azure_storage_account_primary_access_key", $_POST)) { $storageAccountKey = sanitize_text_field($_POST["azure_storage_account_primary_access_key"]); } if (array_key_exists("http_proxy_host", $_POST)) { $httpProxyHost = sanitize_text_field($_POST["http_proxy_host"]); } if (array_key_exists("http_proxy_port", $_POST)) { $httpProxyPort = absint($_POST["http_proxy_port"]); } if (array_key_exists("http_proxy_username", $_POST)) { $httpProxyUserName = sanitize_text_field($_POST["http_proxy_username"]); } if (array_key_exists("http_proxy_password", $_POST)) { $httpProxyPassword = sanitize_text_field($_POST["http_proxy_password"]); } } // We need to show the container name if the request for // container creation fails. if (!$containerCreationStatus) { $newContainerName = sanitize_text_field($_POST["newcontainer"]); } $ContainerResult = null; try { if (!empty($storageAccountName) && !empty($storageAccountKey)) { //TODO: store the connection string and use it instead of always generating the client connection this way $storageClient = WindowsAzureStorageUtil::getStorageClient($storageAccountName, $storageAccountKey, $httpProxyHost, $httpProxyPort, $httpProxyUserName, $httpProxyPassword); $ContainerResult = $storageClient->listContainers(); $privateContainerWarning = null; if (!empty($defaultContainer)) { $getContainerAclResult = $storageClient->getContainerAcl($defaultContainer); $containerAcl = $getContainerAclResult->getContainerAcl(); if ($containerAcl->getPublicAccess() === PublicAccessType::NONE) { /* translators: %s is the container name and is used twice */ $privateContainerWarning = sprintf(__('Warning: The container "%1$s" is set to "private" and cannot be used.' . 'Please choose a public container as the default, or set the "%1$s" container to ' . '"public" in your Azure Storage settings.', 'windows-azure-storage'), $defaultContainer); } } if (!is_null($privateContainerWarning)) { printf('<p style="margin: 10px; color: red;">%s</p>', esc_html($privateContainerWarning)); } } } catch (Exception $ex) { // Fires if account keys are not yet set error_log($ex->getMessage(), E_USER_WARNING); } ?> <table class="form-table" border="0"> <tr valign="top"> <th scope="row"> <label for="storage_account_name" title="Windows Azure Storage Account Name">Store Account Name</label> </th> <td> <input type="text" name="azure_storage_account_name" title="Windows Azure Storage Account Name" value="<?php echo esc_attr($storageAccountName); ?> " /> </td> <td></td> </tr> <tr valign="top"> <th scope="row"> <label for="azure_storage_account_primary_access_key" title="Windows Azure Storage Account Primary Access Key">Primary Access Key</label> </th> <td> <input type="text" name="azure_storage_account_primary_access_key" title="Windows Azure Storage Account Primary Access Key" value="<?php echo esc_attr($storageAccountKey); ?> " /> </td> <td></td> </tr> <tr valign="top"> <th scope="row"> <label for="storage_container_name" title="Default container to be used for storing media files">Default Storage Container</label> </th> <td WIDTH="80px"> <select name="default_azure_storage_account_container_name" title="Default container to be used for storing media files" onChange="<?php echo esc_js('onContainerSelectionChanged( false );'); ?> "> <?php if (!empty($ContainerResult) && count($ContainerResult->getContainers()) > 0) { foreach ($ContainerResult->getContainers() as $container) { ?> <option value="<?php echo esc_attr($container->getName()); ?> " <?php selected($container->getName(), $defaultContainer); ?> > <?php echo esc_html($container->getName()); ?> </option> <?php } if (WindowsAzureStorageUtil::check_action_permissions('create_container')) { ?> <option value="__newContainer__">— <?php esc_html_e('Create New Container', 'windows-azure-storage'); ?>  —</option> <?php } } ?> </select> </td> <?php if (WindowsAzureStorageUtil::check_action_permissions('create_container')) { wp_nonce_field('create_container', 'create_new_container_settings'); ?> <td> <div id="divCreateContainer" name="divCreateContainer" style="display:none;"> <table style="border:1px solid black;"> <tr> <td> <label for="newcontainer" title="Name of the new container to create">Create New Container: </label> </td> <td> <input type="text" name="newcontainer" title="Name of the new container to create" value="<?php echo esc_attr($newContainerName); ?> " /> <input type="button" class="button-primary" value="<?php esc_attr_e('Create', 'windows-azure-storage'); ?> " onclick="<?php echo esc_js(sprintf('createContainer("%s");', esc_url($_SERVER['REQUEST_URI']))); ?> " /> </td> </tr> </table> </div> </td> <?php } ?> </tr> <tr valign="top"> <td colspan="3" WIDTH="300" align="center"><?php echo wp_kses_post($message); ?> </td> </tr> <tr valign="top"> <th scope="row"> <label for="cname" title="Use CNAME instead of Windows Azure Blob URL">CNAME</label> </th> <td colspan="2"> <input type="url" name="cname" title="Use CNAME instead of Windows Azure Blob URL" value="<?php echo esc_attr(WindowsAzureStorageUtil::getCNAME()); ?> " /> <p class="field-description"> <?php $notice = __('Note: Use this option if you would like to display image URLs belonging to your domain like <samp>http://MyDomain.com/</samp> instead of <samp>http://YourAccountName.blob.core.windows.net/</samp>.', 'windows-azure-storage'); echo wp_kses($notice, array('samp' => array())); ?> </p> <div id="cname-notice"> <?php if (is_ssl()) { ?> <h4><?php echo esc_html_x('Notice', 'verb', 'windows-azure-storage'); ?> </h4> <p><?php //TODO: add a different notice if 'https' is set, regardless of is_ssl. $notice = sprintf(__('Windows Azure Storage <a href="%1$s" title="%2$s">does not currently support ' . 'SSL certificates for custom domain names</a>. ' . 'Since this WordPress site is configured to serve content over HTTPS, ' . 'it\'s recommended that you use the default Azure storage endpoint to avoid ' . 'mixed-content warnings for your visitors.', 'windows-azure-storage'), esc_url('https://feedback.azure.com/forums/217298-storage/suggestions/3007732-make-it-possible-to-use-ssl-on-blob-storage-using'), esc_html__('How can we improve Azure Storage? on Azure Forums', 'windows-azure-storage')); echo wp_kses($notice, array('a' => array('href' => array(), 'title' => array()))); ?> </p> <?php } else { ?> <p><?php $notice = sprintf(__('This CNAME must start with <samp>http://</samp> and the administrator will have to update <abbr title="%s">DNS</abbr> entries accordingly.', 'windows-azure-storage'), _x('Domain Name System', 'The proper name of the Internet name resolution system', 'windows-azure-storage')); echo wp_kses($notice, array('samp' => array(), 'abbr' => array('title' => array()))); ?> </p> <?php } ?> </div> </td> </tr> <tr valign="top"> <th scope="row"> <label for="http_proxy_host" title="Use HTTP proxy server host name if web proxy server is configured">HTTP Proxy Host Name</label> </th> <td> <input type="text" name="http_proxy_host" title="Use HTTP proxy server host name if web proxy server is configured" value="<?php echo esc_attr($httpProxyHost); ?> " /> </td> <td></td> </tr> <tr valign="top"> <th scope="row"> <label for="http_proxy_port" title="Use HTTP proxy port if web proxy server is configured">HTTP Proxy Port</label> </th> <td> <input type="number" name="http_proxy_port" title="Use HTTP proxy port if web proxy server is configured" value="<?php echo esc_attr($httpProxyPort); ?> " /> </td> <td></td> </tr> <tr valign="top"> <th scope="row"> <label for="http_proxy_username" title="Use HTTP proxy user name if credential is required to access web proxy server">HTTP Proxy User Name</label> </th> <td> <input type="text" name="http_proxy_username" title="Use HTTP proxy user name if credential is required to access web proxy server" value="<?php echo esc_attr($httpProxyUserName); ?> " /> </td> <td></td> </tr> <tr valign="top"> <th scope="row"> <label for="http_proxy_password" title="Use HTTP proxy password if credential is required to access web proxy server">HTTP Proxy Password</label> </th> <td> <input type="text" name="http_proxy_password" title="Use HTTP proxy password if credential is required to access web proxy server" value="<?php echo esc_attr($httpProxyPassword); ?> " /> </td> <td></td> </tr> <tr valign="top"> <th scope="row"> <label for="azure_storage_use_for_default_upload" title="Use Windows Azure Storage for default upload">Use Windows Azure Storage for default upload</label> </th> <td colspan="2"> <input type="checkbox" name="azure_storage_use_for_default_upload" title="Use Windows Azure Storage for default upload" value="1" id="azure_storage_use_for_default_upload" <?php checked((bool) get_option('azure_storage_use_for_default_upload')); ?> /> <label for="wp-uploads"> Use Windows Azure Storage when uploading via WordPress' upload tab.</label> <br /> <small>Note: Uncheck this to revert back to using your own web host for storage at anytime.</small> </td> </tr> </table> <?php if (empty($ContainerResult) || !$containerCreationStatus || 0 === count($ContainerResult->getContainers())) { // 1. If $containerResult object is null means the storage account is not yet set // show the create container div ?> <script type="text/javascript"> onContainerSelectionChanged( true ); </script> <?php } }
/** * 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; } }
/** * Filter the image source URLs to point 'srcset' to Azure Storage blobs. * * @since 3.0.0 * @internal Callback for 'wp_calculate_image_srcset' filter. * @see wp_calculate_image_srcset() * @link http://projectnami.org/fix-for-azure-storage-plugin-and-wp-4-4/ * * @param array $sources { * One or more arrays of source data to include in the 'srcset'. * * @type array $width { * @type string $url The URL of an image source. * @type string $descriptor The descriptor type used in the image candidate string, * either 'w' or 'x'. * @type int $value The source width if paired with a 'w' descriptor, or a * pixel density value if paired with an 'x' descriptor. * } * } * @param array $size_array Array of width and height values in pixels (in that order). * @param string $image_src The 'src' of the image. * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. * @param int $attachment_id Image attachment ID or 0. * @return array The filtered $sources array. */ function windows_azure_storage_wp_calculate_image_srcset($sources, $size_array, $image_src, $image_meta, $attachment_id) { $media_info = get_post_meta($attachment_id, 'windows_azure_storage_info', true); // If a CNAME is configured, make sure only 'http' is used for the protocol. $azure_cname = WindowsAzureStorageUtil::getCNAME(); $esc_url_protocols = !empty($azure_cname) ? array('https', 'http', '//') : null; if (!empty($media_info)) { $base_url = trailingslashit(WindowsAzureStorageUtil::get_storage_url_base(false) . $media_info['container']); foreach ($sources as &$source) { $img_filename = substr($source['url'], strrpos($source['url'], '/') + 1); if (substr($media_info['blob'], strrpos($media_info['blob'], '/') + 1) === $img_filename) { $source['url'] = esc_url($base_url . $media_info['blob'], $esc_url_protocols); } else { foreach ($media_info['thumbnails'] as $thumbnail) { if (substr($thumbnail, strrpos($thumbnail, '/') + 1) === $img_filename) { $source['url'] = esc_url($base_url . $thumbnail, $esc_url_protocols); break; } } } } } return $sources; }