/** * Render Browse Tab in the Windows Azure Storage popup dialog * * @since 3.0.0 Add nonce checks and reformat HTML. * @since 3.0.1 Fix nonce checks on initial browse. * * @return void */ function windows_azure_storage_dialog_browse_tab() { // remove all registerd filters for the tabs //TODO: switch to remove_all_filters('media_upload_tabs') and only call it once unset($GLOBALS['wp_filter']['media_upload_tabs']); // register our filter for the tabs add_filter("media_upload_tabs", "windows_azure_storage_dialog_add_tab"); media_upload_header(); /** * The post ID of the originating editor page. * * Passed via $_GET from the post being edited when the iframe is loaded. * If iframe is accessed outside an originating editor, this will be 0 and * nonces will fail. :) * * @var int $post_id */ $post_id = isset($_GET['post_id']) ? (int) $_GET['post_id'] : 0; $azure_storage_account_name = WindowsAzureStorageUtil::getAccountName(); $azure_storage_account_primary_access_key = WindowsAzureStorageUtil::getAccountKey(); $default_azure_storage_account_container_name = WindowsAzureStorageUtil::getDefaultContainer(); if (empty($azure_storage_account_name) || empty($azure_storage_account_primary_access_key)) { echo '<h3 style="margin: 10px;">Azure Storage Account not yet configured</h3>'; echo '<p style="margin: 10px;">Please configure the account in Windows Azure Settings Tab.</p>'; } else { $storageClient = WindowsAzureStorageUtil::getStorageClient(); // Set selected container. If none, then use default container $selected_container_name = $default_azure_storage_account_container_name; //TODO: can we just check $_REQUEST here? if (!empty($_POST['selected_container']) && check_admin_referer('browse_select_container_' . $post_id, 'browse_select_container_nonce')) { $selected_container_name = sanitize_text_field($_POST['selected_container']); } elseif (!empty($_GET['selected_container']) && check_admin_referer('browse_select_container_' . $post_id, 'browse_select_container_nonce')) { $selected_container_name = sanitize_text_field($_GET['selected_container']); } // Check if blob has to be deleted if (isset($_GET['delete_blob']) && check_admin_referer('delete_blob_' . $post_id, 'delete_blob')) { if (!WindowsAzureStorageUtil::check_action_permissions('delete_blob')) { //TODO: extract notices into a function that can be customized ?> <div class="notice notice-error is-dismissible" role="banner"> <p role="alert"> <?php /* translators: %s is the file name */ printf(esc_html__('Sorry, "%s" could not be deleted.', 'windows-azure-storage'), esc_html(sanitize_text_field($_GET['filename']))); ?> </p> <p role="status"> <?php esc_html_e('You do not have permission to delete files from this container.', 'windows-azure-storage'); ?> </p> </div> <?php } else { deleteBlob($selected_container_name, sanitize_text_field($_GET['filename'])); } } // delete_blob // Check if all blobs are to be deleted if (isset($_POST['delete_all_blobs']) && check_admin_referer('delete_all_blobs_' . $post_id, 'delete_all_blobs_nonce')) { if (!WindowsAzureStorageUtil::check_action_permissions('delete_all_blobs')) { ?> <div class="notice notice-error is-dismissible" role="banner"> <p role="alert"> <?php esc_html_e('Sorry, these files could not be deleted.', 'windows-azure-storage'); ?> </p> <p role="status"> <?php esc_html_e('You do not have permission to delete files from this container.', 'windows-azure-storage'); ?> </p> </div> <?php } else { // Get list of blobs in specified container $listBlobResult = $storageClient->listBlobs($selected_container_name); // Delete each blob in specified container foreach ($listBlobResult->getBlobs() as $blob) { deleteBlob($selected_container_name, $blob->getName()); } echo '<p style="margin: 10px; color: red;">' . 'Deleted all files in Windows Azure Storage Container "' . esc_html($selected_container_name) . '"</p><br/>'; } } // Handle file search if (isset($_POST['action']) && 'search_azure_storage' === $_POST['action']) { try { if (false === check_admin_referer('search_' . $post_id, 'search_nonce')) { throw new Exception(__('The security check failed. Please try again, or contact the site administrator for assistance.', 'windows-azure-storage')); } $fileTagFilter = sanitize_text_field($_POST["searchFileTag"]); $fileNameFilter = sanitize_text_field($_POST["searchFileName"]); $fileTypeFilter = sanitize_text_field($_POST["searchFileType"]); $searchContainer = sanitize_text_field($_POST["searchContainer"]); if (empty($fileTagFilter) && empty($fileNameFilter) && empty($fileTypeFilter)) { echo '<p style="margin: 10px;">Search criteria not specified.</p><br/>'; } else { $criteria = array(); if (!empty($fileNameFilter)) { $criteria[] = "file name like " . $fileNameFilter; } if (!empty($fileTypeFilter)) { $criteria[] = "file type like " . $fileTypeFilter; } if (!empty($fileTagFilter)) { $criteria[] = "tag like '" . $fileTagFilter . "'"; } $searchResult = array(); if ('ALL_CONTAINERS' === $searchContainer) { $criteria[] = "in 'all containers'"; $listContainerResult = $storageClient->listContainers(); foreach ($listContainerResult->getContainers() as $container) { // Get list of blobs in specified container $listBlobResult = $storageClient->listBlobs($container->getName()); foreach ($listBlobResult->getBlobs() as $blob) { if (!empty($fileNameFilter)) { if (stripos($blob->getName(), $fileNameFilter) === false) { continue; } } // TODO This is a temporary fix (replacing space with %20) will be removed once fixed in the core $blobName = str_replace(" ", "%20", $blob->getName()); $getBlobMetadataResult = $storageClient->getBlobMetadata($container->getName(), $blobName); $metadata = $getBlobMetadataResult->getMetadata(); if (!empty($fileTypeFilter)) { if (stripos($metadata["mimetype"], $fileTypeFilter) === false) { continue; } } if (!empty($fileTagFilter)) { if (stripos($metadata["tag"], $fileTagFilter) === false) { continue; } } $searchResult[] = sprintf('%1$s/%2$s/%3$s', untrailingslashit(WindowsAzureStorageUtil::get_storage_url_base(false)), $container->getName(), $blob->getName()); } } } else { $criteria[] = "in container '" . $searchContainer . "'"; // Get list of blobs in specified container $listBlobResult = $storageClient->listBlobs($searchContainer); foreach ($listBlobResult->getBlobs() as $blob) { if (!empty($fileNameFilter)) { if (stripos($blob->getName(), $fileNameFilter) === false) { continue; } } // TODO This is a temporary fix (replacing space with %20) will be removed once fixed in the core $blobName = str_replace(" ", "%20", $blob->getName()); $getBlobMetadataResult = $storageClient->getBlobMetadata($searchContainer, $blobName); $metadata = $getBlobMetadataResult->getMetadata(); if (!empty($fileTypeFilter)) { if (stripos($metadata["mimetype"], $fileTypeFilter) === false) { continue; } } if (!empty($fileTagFilter)) { if (stripos($metadata["tag"], $fileTagFilter) === false) { continue; } } $searchResult[] = sprintf('%1$s/%2$s/%3$s', untrailingslashit(WindowsAzureStorageUtil::get_storage_url_base(false)), $searchContainer, $blob->getName()); } } echo '<h3 style="margin: 10px;">Search Result</h3>'; if (empty($searchResult)) { echo '<p style="margin: 10px;">No file found matching specified criteria (' . implode(', ', esc_html($criteria)) . ')</p><br/>'; } else { echo '<p style="margin: 10px;">Found ' . esc_html(count($searchResult)) . ' file(s) matching specified criteria (' . implode(', ', esc_html($criteria)) . ')</p><br/>'; foreach ($searchResult as $url) { //TODO: remove inline JS and CSS $style = 'margin: 10px;'; $onmouseover_js = 'this.height=50; this.width=50; this.style.border="3px solid yellow";'; $onmouseout_js = 'this.height=32; this.width=32; this.style.border="0 solid black";'; $onclick_js = 'return insertImageTag("%s");'; printf('<img src="%1$s" style="%2$s" width="32" height="32" onmouseover="%3$s" onmouseout="%4$s" onclick="%5$s" />', esc_url($url), esc_attr($style), esc_js($onmouseover_js), esc_js($onmouseout_js), esc_js(sprintf($onclick_js, esc_url($url)))); } } echo "<hr/>"; return; } } catch (Exception $e) { ?> <div class="notice notice-error" role="banner"> <p role="alert"> <?php esc_html_e('Sorry, but there was a problem searching the container.', 'windows-azure-storage'); ?> </p> <p role="status"> <?php echo esc_html($e->getMessage()); ?> </p> </div> <?php // If this exception is thrown, don't continue loading media. return; } } $first_container_name = ""; $form_action_url = add_query_arg(array('post_id' => $post_id, 'tab' => 'browse'), MSFT_AZURE_PLUGIN_LEGACY_MEDIA_URL); ?> <form name="SelectContainerForm" style="margin: 10px;" method="post" action="<?php echo esc_url($form_action_url); ?> "> <?php wp_nonce_field('browse_select_container_' . $post_id, 'browse_select_container_nonce'); ?> <table> <tr> <th> <label for="selected_container"> <?php esc_html_e('Container Name:', 'windows-azure-storage'); ?> </label> </th> <td> <select name="selected_container" id="selected_container" title="<?php esc_attr_e('Container to use for storing media files.', 'windows-azure-storage'); ?> " onchange="<?php echo esc_js('this.form.setAttribute( "aria-busy", true ); this.form.submit(); this.disabled = true;'); ?> "> <?php try { $storageClient = WindowsAzureStorageUtil::getStorageClient(); $listContainerResult = $storageClient->listContainers(); foreach ($listContainerResult->getContainers() as $container) { if (empty($first_container_name)) { $first_container_name = $container->getName(); } ?> <option value="<?php echo esc_attr($container->getName()); ?> " <?php selected($container->getName(), $selected_container_name, true); ?> > <?php echo esc_html($container->getName()); ?> </option> <?php } } catch (Exception $ex) { // Fires if account keys are not yet set error_log($ex->getMessage(), E_USER_WARNING); } ?> </select> </td> </tr> </table> </form> <table id="media-items"> <tr> <td> <?php try { if (empty($selected_container_name)) { echo '<p style="margin: 10px; color: red;">Default Azure Storage Container name is not yet configured. Please configure it in the Windows Azure Settings Tab.</p>'; $selected_container_name = $first_container_name; } // Get list of blobs in specified container $listBlobResult = $storageClient->listBlobs($selected_container_name); $blobs = $listBlobResult->getBlobs(); if (empty($blobs)) { ?> <p style="margin: 10px;"><?php printf(esc_html__('No items in container "%s".', 'windows-azure-storage'), esc_html($selected_container_name)); ?> </p> <?php } else { echo '<p style="margin: 10px;">Note: Click on the image to insert image URL into the blog!</p><br/>'; /** @var WindowsAzure\Blob\Models\Blob $blob */ foreach ($blobs as $blob) { $url = sprintf('%1$s/%2$s/%3$s', untrailingslashit(WindowsAzureStorageUtil::get_storage_url_base(false)), $selected_container_name, $blob->getName()); // TODO switch to wp_check_filetype_and_ext() $fileExt = substr(strrchr($blob->getName(), '.'), 1); //TODO: remove inline JS and CSS $style = 'margin: 10px;'; $onmouseover_js = 'this.height=50; this.width=50; this.style.border="3px solid yellow";'; $onmouseout_js = 'this.height=32; this.width=32; this.style.border="0 solid black";'; $onclick_js = 'return insertImageTag( "%s", false );'; switch (strtolower($fileExt)) { case "jpg": case "jpeg": case "gif": case "bmp": case "png": case "tiff": printf('<img src="%1$s" style="%2$s" width="32" height="32" onmouseover="%3$s" onmouseout="%4$s" onclick="%5$s" />', esc_url($url), esc_attr($style), esc_js($onmouseover_js), esc_js($onmouseout_js), esc_js(sprintf($onclick_js, esc_url($url)))); break; default: printf('<a href="%1$s" style="%2$s" onclick="%3$s">%4$s</a>', esc_url($url), esc_attr($style), esc_js(sprintf($onclick_js, esc_url($url))), esc_html($blob->getName())); break; } if (WindowsAzureStorageUtil::check_action_permissions('delete_blob')) { // Generate an absolute URL used for deleting files $delete_blob_url = add_query_arg(array('post_id' => $post_id, 'tab' => 'browse', 'filename' => $blob->getName(), 'selected_container' => $selected_container_name), MSFT_AZURE_PLUGIN_LEGACY_MEDIA_URL); $delete_blob_url = wp_nonce_url($delete_blob_url, 'delete_blob_' . $post_id, 'delete_blob'); /* translators: 1: URL, 2: link description, 3: link text */ printf('<a class="delete-permanently" href="%1$s" role="button" title="%2$s" aria-label="%2$s">%3$s</a>', esc_url($delete_blob_url), sprintf(esc_attr__('Delete "%s" from this container.', 'windows-azure-storage'), esc_html($blob->getName())), 'x'); } } } } catch (Exception $e) { echo '<p style="margin: 10px; color: red;">Error in listing storage containers: ' . esc_html($e->getMessage()) . "</p><br/>"; } ?> </td> </tr> </table> <?php // TODO: add an AYS check before submitting this form. if (!empty($blobs) && WindowsAzureStorageUtil::check_action_permissions('delete_all_blobs')) { $form_action_url = add_query_arg(array('post_id' => $post_id, 'tab' => 'browse'), MSFT_AZURE_PLUGIN_LEGACY_MEDIA_URL); ?> <form name="DeleteAllBlobsForm" method="POST" action="<?php echo esc_url($form_action_url); ?> "> <?php wp_nonce_field('delete_all_blobs_' . $post_id, 'delete_all_blobs_nonce'); ?> <input type='hidden' name='selected_container' value='<?php echo esc_attr($selected_container_name); ?> ' /> <?php submit_button(__('Delete All Files', 'windows-azure-storage'), 'delete', 'delete_all_blobs', true, array('aria-label' => __('Delete all blobs from this container.', 'windows-azure-storage'), 'id' => 'was-delete-all-blobs', 'role' => 'button')); ?> </form> <?php } ?> <?php } }
/** * 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; }