From 94bd9b0cb742c620772bb36faa800ea2b9aa80b5 Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Wed, 12 Jul 2017 14:29:33 +0200 Subject: [PATCH 01/38] Hotfix: bump version to 1.6.8. --- imagify.php | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/imagify.php b/imagify.php index 9acaffb0b..44ed9f00a 100644 --- a/imagify.php +++ b/imagify.php @@ -3,7 +3,7 @@ * Plugin Name: Imagify * Plugin URI: https://wordpress.org/plugins/imagify/ * Description: Dramaticaly reduce image file sizes without losing quality, make your website load faster, boost your SEO and save money on your bandwidth using Imagify, the new most advanced image optimization tool. - * Version: 1.6.7 + * Version: 1.6.8 * Author: WP Media * Author URI: http://wp-media.me * Licence: GPLv2 @@ -17,7 +17,7 @@ defined( 'ABSPATH' ) || die( 'Cheatin\' uh?' ); // Imagify defines. -define( 'IMAGIFY_VERSION' , '1.6.7' ); +define( 'IMAGIFY_VERSION' , '1.6.8' ); define( 'IMAGIFY_SLUG' , 'imagify' ); define( 'IMAGIFY_SETTINGS_SLUG' , IMAGIFY_SLUG . '_settings' ); define( 'IMAGIFY_WEB_MAIN' , 'https://imagify.io' ); diff --git a/package.json b/package.json index 8b4150eff..c72b1d03d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "imagify", "description": "Imagify Image Optimizer. Dramatically reduce image file sizes without losing quality, make your website load faster, boost your SEO and save money on your bandwidth.", - "version": "1.6.7", + "version": "1.6.8", "homepage": "https://wordpress.org/plugins/imagify/", "license": "GPL-2.0", "private": true, From aae9956dcb8b76bfe8a039a08a45cf9ef2c41e48 Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Wed, 12 Jul 2017 14:30:17 +0200 Subject: [PATCH 02/38] Hotfix: we make typo. --- readme.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.txt b/readme.txt index 5e969ccbe..cde7792de 100755 --- a/readme.txt +++ b/readme.txt @@ -143,7 +143,7 @@ When the plugin is disabled, your existing images remain optimized. Backups of t * Improvement: Use cURL directly only to optimize an image. It helps when cURL is not available: less things will break in that case. * Bug Fix: Fixed a bug with the plugin Screets Live Chat, prior to version 2.2.8. * Regression fix: Fixed the buffer size on the bulk optimization page. -* Dev stuff: Added a hook allowing to filter arguments when doing a request to our API. It can be used to increate the timeout value for example. +* Dev stuff: Added a hook allowing to filter arguments when doing a request to our API. It can be used to increase the timeout value for example. = 1.6.6 = * New: Compatibility with the plugin WP Offload S3 Lite. Your images now will be sent to Amazon S3 after being optimized. Also works when you store your images only on S3, not locally. From 92ae99ae99cc860157f8dd4b01012591fbe543b2 Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Wed, 12 Jul 2017 14:57:31 +0200 Subject: [PATCH 03/38] Made the "Save & Go to Bulk Optimizer" button work (redirect) even if settings haven't changed. --- inc/admin/options.php | 51 ++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/inc/admin/options.php b/inc/admin/options.php index d85120ff8..daf9200b4 100755 --- a/inc/admin/options.php +++ b/inc/admin/options.php @@ -93,37 +93,52 @@ function _imagify_after_save_network_options( $option, $value, $old_value ) { _imagify_after_save_options( $old_value, $value ); } +add_filter( 'pre_update_option_' . IMAGIFY_SETTINGS_SLUG, '_imagify_maybe_set_redirection_before_save_options', 10, 2 ); +/** + * If the user clicked the "Save & Go to Bulk Optimizer" button, set a redirection to the bulk optimizer. + * We use this hook because it can be triggered even if the option value hasn't changed. + * + * @since 1.6.8 + * @author Grégory Viguier + * + * @param mixed $value The new, unserialized option value. + * @param mixed $old_value The old option value. + * @return mixed The option value. + */ +function _imagify_maybe_set_redirection_before_save_options( $value, $old_value ) { + + if ( ! is_admin() || ! isset( $_POST['submit-goto-bulk'] ) ) { // WPCS: CSRF ok. + return $value; + } + + $_REQUEST['_wp_http_referer'] = esc_url_raw( get_admin_url( get_current_blog_id(), 'upload.php?page=imagify-bulk-optimization' ) ); + + return $value; +} + add_action( 'update_option_' . IMAGIFY_SETTINGS_SLUG, '_imagify_after_save_options', 10, 2 ); /** * Used to launch some actions after saving the options. * * @author Jonathan - * @since 1.0 - * @since 1.5 Used to redirect user to Bulk Optimizer (if requested). + * @since 1.0 + * @since 1.5 Used to redirect user to Bulk Optimizer (if requested). + * @since 1.6.8 Not used to redirect user to Bulk Optimizer anymore: see _imagify_maybe_set_redirection_before_save_options(). * * @param mixed $old_value The old option value. * @param mixed $value The new option value. */ function _imagify_after_save_options( $old_value, $value ) { - if ( $old_value && $value && ( ! isset( $old_value['api_key'] ) || $old_value['api_key'] !== $value['api_key'] ) ) { - if ( is_wp_error( get_imagify_user() ) ) { - imagify_renew_notice( 'wrong-api-key' ); - delete_site_transient( 'imagify_check_licence_1' ); - } else { - imagify_dismiss_notice( 'wrong-api-key' ); - } + if ( ! $old_value || ! $value || isset( $old_value['api_key'], $value['api_key'] ) && $old_value['api_key'] === $value['api_key'] ) { + return; } - /** - * Redirect the user to the bulk optimization. - * - * @author Geoffrey - * @since 1.5 - */ - if ( isset( $_POST['submit-goto-bulk'] ) ) { // WPCS: CSRF ok. - wp_safe_redirect( get_admin_url( get_current_blog_id(), 'upload.php?page=imagify-bulk-optimization' ) ); - exit; + if ( is_wp_error( get_imagify_user() ) ) { + imagify_renew_notice( 'wrong-api-key' ); + delete_site_transient( 'imagify_check_licence_1' ); + } else { + imagify_dismiss_notice( 'wrong-api-key' ); } } From 2348dd13f20fe21ab7c6f0f6517e275edcbdfaef Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Wed, 12 Jul 2017 15:51:32 +0200 Subject: [PATCH 04/38] Added support for multisite: the user will be redirected to the main site's bulk optimization page. --- inc/admin/options.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/inc/admin/options.php b/inc/admin/options.php index daf9200b4..d43fddbc9 100755 --- a/inc/admin/options.php +++ b/inc/admin/options.php @@ -93,7 +93,11 @@ function _imagify_after_save_network_options( $option, $value, $old_value ) { _imagify_after_save_options( $old_value, $value ); } -add_filter( 'pre_update_option_' . IMAGIFY_SETTINGS_SLUG, '_imagify_maybe_set_redirection_before_save_options', 10, 2 ); +if ( imagify_is_active_for_network() ) { + add_filter( 'pre_update_site_option_' . IMAGIFY_SETTINGS_SLUG, '_imagify_maybe_set_redirection_before_save_options', 10, 2 ); +} else { + add_filter( 'pre_update_option_' . IMAGIFY_SETTINGS_SLUG, '_imagify_maybe_set_redirection_before_save_options', 10, 2 ); +} /** * If the user clicked the "Save & Go to Bulk Optimizer" button, set a redirection to the bulk optimizer. * We use this hook because it can be triggered even if the option value hasn't changed. From 1a1f85750965e75d492bbcf84302356ea4a4f5d4 Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Wed, 12 Jul 2017 16:03:38 +0200 Subject: [PATCH 05/38] Reordered things a bit and added `imagify_is_active_for_network()` tests for `_imagify_after_save_network_options()` and `_imagify_after_save_options()` hooks. --- inc/admin/options.php | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/inc/admin/options.php b/inc/admin/options.php index d43fddbc9..ca0451685 100755 --- a/inc/admin/options.php +++ b/inc/admin/options.php @@ -78,21 +78,6 @@ function _imagify_pre_update_option( $value, $old_value ) { return $value; } -add_action( 'update_site_option_' . IMAGIFY_SETTINGS_SLUG, '_imagify_after_save_network_options', 10, 3 ); -/** - * Used to launch some actions after saving the network options. - * - * @author Grégory Viguier - * @since 1.6.5 - * - * @param string $option Name of the network option. - * @param mixed $value Current value of the network option. - * @param mixed $old_value Old value of the network option. - */ -function _imagify_after_save_network_options( $option, $value, $old_value ) { - _imagify_after_save_options( $old_value, $value ); -} - if ( imagify_is_active_for_network() ) { add_filter( 'pre_update_site_option_' . IMAGIFY_SETTINGS_SLUG, '_imagify_maybe_set_redirection_before_save_options', 10, 2 ); } else { @@ -120,7 +105,26 @@ function _imagify_maybe_set_redirection_before_save_options( $value, $old_value return $value; } -add_action( 'update_option_' . IMAGIFY_SETTINGS_SLUG, '_imagify_after_save_options', 10, 2 ); +if ( imagify_is_active_for_network() ) { + add_action( 'update_site_option_' . IMAGIFY_SETTINGS_SLUG, '_imagify_after_save_network_options', 10, 3 ); +} +/** + * Used to launch some actions after saving the network options. + * + * @author Grégory Viguier + * @since 1.6.5 + * + * @param string $option Name of the network option. + * @param mixed $value Current value of the network option. + * @param mixed $old_value Old value of the network option. + */ +function _imagify_after_save_network_options( $option, $value, $old_value ) { + _imagify_after_save_options( $old_value, $value ); +} + +if ( ! imagify_is_active_for_network() ) { + add_action( 'update_option_' . IMAGIFY_SETTINGS_SLUG, '_imagify_after_save_options', 10, 2 ); +} /** * Used to launch some actions after saving the options. * From 2618fe62cd2ec3a491c3f468e68a9c2ef35cc552 Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Thu, 13 Jul 2017 00:52:13 +0200 Subject: [PATCH 06/38] In the medias library, display the "Restore Original" bulk action only if there are restorable items, or if the backup option is enabled. --- assets/js/upload.js | 8 ++++++-- assets/js/upload.min.js | 2 +- inc/admin/enqueue.php | 9 ++++++++- inc/functions/admin-ui.php | 13 +++++++++++-- 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/assets/js/upload.js b/assets/js/upload.js index a93b04dca..11dca3c11 100755 --- a/assets/js/upload.js +++ b/assets/js/upload.js @@ -20,8 +20,12 @@ window.imagify = window.imagify || { */ var bulk_opt, get_var, check_modal; - bulk_opt = ''; - bulk_opt += ''; + bulk_opt = ''; + + if ( imagifyUpload.backup_option || $( '.attachment-has-backup' ).length ) { + // If the backup option is enabled, or if we have items that can be restored. + bulk_opt += ''; + } $( '.bulkactions select[name="action"]' ).find( 'option:last-child' ).before( bulk_opt ); $( '.bulkactions select[name="action2"]' ).find( 'option:last-child' ).before( bulk_opt ); diff --git a/assets/js/upload.min.js b/assets/js/upload.min.js index 9d784d33a..2844e21da 100755 --- a/assets/js/upload.min.js +++ b/assets/js/upload.min.js @@ -1 +1 @@ -window.imagify=window.imagify||{concat:ajaxurl.indexOf("?")>0?"&":"?",log:function(a){void 0!==console&&console.log(a)},info:function(a){void 0!==console&&console.info(a)}},function(a,b,c,d){function e(b){b.each(function(){var b=parseInt(a(this).closest(".imagify-chart").next(".imagify-chart-value").text()),c=[{value:b,color:"#00B3D3"},{value:100-b,color:"#D8D8D8"}];new Chart(a(this)[0].getContext("2d")).Doughnut(c,{segmentStrokeColor:"#FFF",segmentStrokeWidth:1,animateRotate:!0,tooltipEvents:[]})})}var f,g,h;f='",f+='",a('.bulkactions select[name="action"]').find("option:last-child").before(f),a('.bulkactions select[name="action2"]').find("option:last-child").before(f),a("#doaction").add("#doaction2").on("click",function(b){var c,d,e=a(this).prev("select").val().split("-");"imagify"===e[0]&&(b.preventDefault(),c=e[2],d=a('input[name^="media"]:checked').map(function(){return this.value}).get(),d.forEach(function(b,d){setTimeout(function(){a("#imagify-"+c+"-"+b).trigger("click")},300*d)}))}),a(b).on("click",".button-imagify-restore, .button-imagify-manual-upload, .button-imagify-manual-override-upload",function(b){var c=a(this),d=c.parents(".column-imagify_optimized_file, .compat-field-imagify .field"),f=c.attr("href");b.preventDefault(),d.length||(d=c.closest(".column")),d.html('
'+c.data("waiting-label")+"
"),a.get(f.replace("admin-post.php","admin-ajax.php")).done(function(a){d.html(a.data),d.find(".imagify-datas-more-action a").addClass("is-open").find(".the-text").text(d.find(".imagify-datas-more-action a").data("close")),d.find(".imagify-datas-details").addClass("is-open"),e(d.find(".imagify-chart-container").find("canvas"))})}),a(".imagify-datas-details").hide(),a(b).on("click",".imagify-datas-more-action a",function(b){var c=a(this);b.preventDefault(),c.hasClass("is-open")?(a(c.attr("href")).slideUp(300).removeClass("is-open"),c.removeClass("is-open").find(".the-text").text(c.data("open"))):(a(c.attr("href")).slideDown(300).addClass("is-open"),c.addClass("is-open").find(".the-text").text(c.data("close")))}),g=function(a){var b={};return c.location.href.replace(/[?&]+([^=&]+)=?([^&]*)?/gi,function(a,c,d){b[c]=void 0!==d?d:""}),a?b[a]?b[a]:null:b},h=function(){var b=setInterval(function(){var c=a(".media-modal .imagify-datas-details");c.length&&(c.hide(),e(a("#imagify-consumption-chart")),clearInterval(b),b=null)},20)},a(".upload-php").find(".media-frame.mode-grid").on("click",".attachment",function(){h()}),a(".upload-php").length&&g("item")&&h(),a("#insert-media-button").on("click.imagify",function(){var b=setInterval(function(){var c=a(".media-frame-content .attachments");c.length&&(c.on("click.imagify",".attachment",function(){h()}),clearInterval(b),b=null)},100)}),e(a(".imagify-chart-container").find("canvas"))}(jQuery,document,window); \ No newline at end of file +window.imagify=window.imagify||{concat:ajaxurl.indexOf("?")>0?"&":"?",log:function(a){void 0!==console&&console.log(a)},info:function(a){void 0!==console&&console.info(a)}},function(a,b,c,d){function e(b){b.each(function(){var b=parseInt(a(this).closest(".imagify-chart").next(".imagify-chart-value").text()),c=[{value:b,color:"#00B3D3"},{value:100-b,color:"#D8D8D8"}];new Chart(a(this)[0].getContext("2d")).Doughnut(c,{segmentStrokeColor:"#FFF",segmentStrokeWidth:1,animateRotate:!0,tooltipEvents:[]})})}var f,g,h;f='",(imagifyUpload.backup_option||a(".attachment-has-backup").length)&&(f+='"),a('.bulkactions select[name="action"]').find("option:last-child").before(f),a('.bulkactions select[name="action2"]').find("option:last-child").before(f),a("#doaction").add("#doaction2").on("click",function(b){var c,d,e=a(this).prev("select").val().split("-");"imagify"===e[0]&&(b.preventDefault(),c=e[2],d=a('input[name^="media"]:checked').map(function(){return this.value}).get(),d.forEach(function(b,d){setTimeout(function(){a("#imagify-"+c+"-"+b).trigger("click")},300*d)}))}),a(b).on("click",".button-imagify-restore, .button-imagify-manual-upload, .button-imagify-manual-override-upload",function(b){var c=a(this),d=c.parents(".column-imagify_optimized_file, .compat-field-imagify .field"),f=c.attr("href");b.preventDefault(),d.length||(d=c.closest(".column")),d.html('
'+c.data("waiting-label")+"
"),a.get(f.replace("admin-post.php","admin-ajax.php")).done(function(a){d.html(a.data),d.find(".imagify-datas-more-action a").addClass("is-open").find(".the-text").text(d.find(".imagify-datas-more-action a").data("close")),d.find(".imagify-datas-details").addClass("is-open"),e(d.find(".imagify-chart-container").find("canvas"))})}),a(".imagify-datas-details").hide(),a(b).on("click",".imagify-datas-more-action a",function(b){var c=a(this);b.preventDefault(),c.hasClass("is-open")?(a(c.attr("href")).slideUp(300).removeClass("is-open"),c.removeClass("is-open").find(".the-text").text(c.data("open"))):(a(c.attr("href")).slideDown(300).addClass("is-open"),c.addClass("is-open").find(".the-text").text(c.data("close")))}),g=function(a){var b={};return c.location.href.replace(/[?&]+([^=&]+)=?([^&]*)?/gi,function(a,c,d){b[c]=void 0!==d?d:""}),a?b[a]?b[a]:null:b},h=function(){var b=setInterval(function(){var c=a(".media-modal .imagify-datas-details");c.length&&(c.hide(),e(a("#imagify-consumption-chart")),clearInterval(b),b=null)},20)},a(".upload-php").find(".media-frame.mode-grid").on("click",".attachment",function(){h()}),a(".upload-php").length&&g("item")&&h(),a("#insert-media-button").on("click.imagify",function(){var b=setInterval(function(){var c=a(".media-frame-content .attachments");c.length&&(c.on("click.imagify",".attachment",function(){h()}),clearInterval(b),b=null)},100)}),e(a(".imagify-chart-container").find("canvas"))}(jQuery,document,window); \ No newline at end of file diff --git a/inc/admin/enqueue.php b/inc/admin/enqueue.php index 6c4c1e055..75cfd8afb 100755 --- a/inc/admin/enqueue.php +++ b/inc/admin/enqueue.php @@ -151,7 +151,14 @@ function _imagify_admin_print_styles() { */ if ( isset( $current_screen ) && ( 'upload' === $current_screen->base || 'post' === $current_screen->base ) ) { wp_enqueue_script( 'imagify-js-upload' ); - wp_localize_script( 'imagify-js-upload', 'imagifyUpload', get_imagify_localize_script_translations( 'upload' ) ); + + $upload_data = get_imagify_localize_script_translations( 'upload' ); + + if ( 'upload' === $current_screen->base && get_imagify_option( 'backup' ) ) { + $upload_data['backup_option'] = 1; + } + + wp_localize_script( 'imagify-js-upload', 'imagifyUpload', $upload_data ); } /** diff --git a/inc/functions/admin-ui.php b/inc/functions/admin-ui.php index 2bc0e6dae..9d7b9944b 100644 --- a/inc/functions/admin-ui.php +++ b/inc/functions/admin-ui.php @@ -21,9 +21,13 @@ function get_imagify_attachment_optimization_text( $attachment, $context = 'wp' $reoptimize_output = $reoptimize_link ? $reoptimize_link : ''; $reoptimize_output_before = ''; - $error = get_imagify_attachment_error_text( $attachment, $context ); + $error = get_imagify_attachment_error_text( $attachment, $context ); if ( $error ) { + if ( $attachment->has_backup() ) { + $reoptimize_output .= ''; + } + $reoptimize_output = $reoptimize_output_before . $reoptimize_output . $reoptimize_output_after; return 'post.php' === $pagenow ? $output_before . $error . $reoptimize_output . $output_after : $error . $reoptimize_output; @@ -86,7 +90,7 @@ function get_imagify_attachment_optimization_text( $attachment, $context = 'wp' 'attachment_id' => $attachment_id, 'context' => $context, ); - $class = ( 'post.php' !== $pagenow ) ? 'button-imagify-restore' : ''; + $class = ( 'post.php' !== $pagenow ) ? 'button-imagify-restore attachment-has-backup' : ''; $output .= ''; $output .= '' . __( 'Restore Original', 'imagify' ); $output .= ''; @@ -245,6 +249,11 @@ function get_imagify_media_column_content( $attachment, $context = 'wp' ) { 'context' => $context, ); $output .= '' . __( 'Optimize', 'imagify' ) . ''; + + if ( $attachment->has_backup() ) { + $output .= ''; + } + return $output; } From 10911c5b440fd9ad561836b56e65473dc803f308 Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Thu, 13 Jul 2017 11:46:42 +0200 Subject: [PATCH 07/38] Hotfix: bring 1.6.7.1 in. --- inc/functions/admin.php | 2 ++ readme.txt | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/inc/functions/admin.php b/inc/functions/admin.php index 98578e064..722b35c45 100755 --- a/inc/functions/admin.php +++ b/inc/functions/admin.php @@ -258,6 +258,8 @@ function get_imagify_bulk_buffer_size() { * ) */ function imagify_get_wpdb_metas( $metas, $ids ) { + global $wpdb; + if ( ! $ids ) { return array_fill_keys( array_keys( $metas ), array() ); } diff --git a/readme.txt b/readme.txt index cde7792de..7c1132186 100755 --- a/readme.txt +++ b/readme.txt @@ -3,7 +3,7 @@ Contributors: wp_media, GregLone Tags: compress image, images, performance, optimization, photos, upload, resize, gif, png, jpg, reduce image size, retina Requires at least: 3.7.0 Tested up to: 4.8.0 -Stable tag: 1.6.7 +Stable tag: 1.6.7.1 Dramatically reduce image file sizes without losing quality, make your website load faster, boost your SEO and save money on your bandwidth. @@ -136,6 +136,9 @@ When the plugin is disabled, your existing images remain optimized. Backups of t 3. Media Page == Changelog == += 1.6.7.1 = +* Bug Fix: Fixed the "Unknown error" during a bulk optimization. + = 1.6.7 = * Improvement: Compatibility with the plugin WP Offload S3 Pro, and fixed a few things for both Lite and Pro versions. * Improvement: Improved performance on the bulk optimization page for huge image libraries. From 11bf908ac23abb8176c9803f8ff6674deebbdf38 Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Thu, 13 Jul 2017 15:47:11 +0200 Subject: [PATCH 08/38] Introduced `imagify_is_attachment_mime_type_supported()` as a replacement for `wp_attachment_is_image()`. The main difference is that this new function will return true only for the mime types supported by Imagify, instead of all image formats. Deprecated `Imagify_AS3CF::is_mime_type_supported()`. --- .../class-imagify-as3cf-attachment.php | 2 +- .../inc/classes/class-imagify-as3cf.php | 25 +++++--------- inc/admin/media.php | 2 +- inc/classes/class-imagify-attachment.php | 33 +++++++++++-------- inc/functions/admin-ui.php | 2 +- inc/functions/attachments.php | 28 ++++++++++++++++ 6 files changed, 58 insertions(+), 34 deletions(-) diff --git a/inc/3rd-party/amazon-s3-and-cloudfront/inc/classes/class-imagify-as3cf-attachment.php b/inc/3rd-party/amazon-s3-and-cloudfront/inc/classes/class-imagify-as3cf-attachment.php index 6137c3ba3..f4a4c845c 100644 --- a/inc/3rd-party/amazon-s3-and-cloudfront/inc/classes/class-imagify-as3cf-attachment.php +++ b/inc/3rd-party/amazon-s3-and-cloudfront/inc/classes/class-imagify-as3cf-attachment.php @@ -820,6 +820,6 @@ protected function file_should_be_deleted( $file_path ) { * @return bool */ public function is_mime_type_supported() { - return $this->id && imagify_as3cf()->is_mime_type_supported( $this->id ); + return imagify_is_attachment_mime_type_supported( $this->id ); } } diff --git a/inc/3rd-party/amazon-s3-and-cloudfront/inc/classes/class-imagify-as3cf.php b/inc/3rd-party/amazon-s3-and-cloudfront/inc/classes/class-imagify-as3cf.php index 397e1dc4d..0074a68f2 100644 --- a/inc/3rd-party/amazon-s3-and-cloudfront/inc/classes/class-imagify-as3cf.php +++ b/inc/3rd-party/amazon-s3-and-cloudfront/inc/classes/class-imagify-as3cf.php @@ -127,7 +127,7 @@ public function init() { * @return string The new context. */ public function optimize_attachment_context( $context, $attachment_id ) { - if ( self::CONTEXT === $context || $this->is_mime_type_supported( $attachment_id ) ) { + if ( self::CONTEXT === $context || imagify_is_attachment_mime_type_supported( $attachment_id ) ) { return self::CONTEXT; } return $context; @@ -287,7 +287,7 @@ function add_stats_for_s3_files( $size_and_count, $image_id, $files, $image_ids */ public function store_upload_ids( $metadata, $attachment_id ) { - if ( $this->is_mime_type_supported( $attachment_id ) ) { + if ( imagify_is_attachment_mime_type_supported( $attachment_id ) ) { $this->uploads[ $attachment_id ] = 1; } @@ -311,7 +311,7 @@ public function do_async_job( $metadata, $attachment_id ) { $is_new_upload = ! empty( $this->uploads[ $attachment_id ] ); unset( $this->uploads[ $attachment_id ] ); - if ( ! $metadata || ! $this->is_mime_type_supported( $attachment_id ) ) { + if ( ! $metadata || ! imagify_is_attachment_mime_type_supported( $attachment_id ) ) { return $metadata; } @@ -369,7 +369,7 @@ public function optimize() { die(); } - if ( ! $this->is_mime_type_supported( $attachment_id ) ) { + if ( ! imagify_is_attachment_mime_type_supported( $attachment_id ) ) { die(); } @@ -403,26 +403,17 @@ public function optimize() { * Tell if the attachment has a supported mime type. * * @since 1.6.6 + * @since 1.6.8 Deprecated. + * @see imagify_is_attachment_mime_type_supported() * @author Grégory Viguier * * @param int $post_id The attachment ID. * @return bool */ public function is_mime_type_supported( $post_id ) { - static $is = array( false ); + _deprecated_function( 'Imagify_AS3CF::is_mime_type_supported()', '1.6.8', 'imagify_is_attachment_mime_type_supported()' ); - $post_id = absint( $post_id ); - - if ( isset( $is[ $post_id ] ) ) { - return $is[ $post_id ]; - } - - $mime_types = get_imagify_mime_type(); - $mime_types = array_flip( $mime_types ); - $mime_type = get_post_mime_type( $post_id ); - $is[ $post_id ] = isset( $mime_types[ $mime_type ] ); - - return $is[ $post_id ]; + return imagify_is_attachment_mime_type_supported( $post_id ); } } diff --git a/inc/admin/media.php b/inc/admin/media.php index 082bc06a3..003a155de 100755 --- a/inc/admin/media.php +++ b/inc/admin/media.php @@ -46,7 +46,7 @@ function _imagify_attachment_fields_to_edit( $form_fields, $post ) { */ function _imagify_add_actions_to_media_list_row( $actions, $post ) { // If this attachment is not an image, do nothing. - if ( ! wp_attachment_is_image( $post->ID ) ) { + if ( ! imagify_is_attachment_mime_type_supported( $post->ID ) ) { return $actions; } diff --git a/inc/classes/class-imagify-attachment.php b/inc/classes/class-imagify-attachment.php index f0f45cf2e..7856ba223 100644 --- a/inc/classes/class-imagify-attachment.php +++ b/inc/classes/class-imagify-attachment.php @@ -105,7 +105,8 @@ public function get_original_url() { * @return bool */ public function update_metadata_size() { - if ( ! wp_attachment_is_image( $this->id ) ) { + // Check if the attachment extension is allowed. + if ( ! imagify_is_attachment_mime_type_supported( $this->id ) ) { return false; } @@ -203,31 +204,30 @@ public function fill_data( $data, $response, $url, $size = 'full' ) { * @return array $optimized_data The optimization data. */ public function optimize( $optimization_level = null, $metadata = array() ) { - $optimization_level = is_null( $optimization_level ) ? (int) get_imagify_option( 'optimization_level', 1 ) : (int) $optimization_level; + // Check if the attachment extension is allowed. + if ( ! imagify_is_attachment_mime_type_supported( $this->id ) ) { + return; + } - $metadata = $metadata ? $metadata : wp_get_attachment_metadata( $this->id ); - $sizes = isset( $metadata['sizes'] ) ? (array) $metadata['sizes'] : array(); + $optimization_level = is_null( $optimization_level ) ? (int) get_imagify_option( 'optimization_level', 1 ) : (int) $optimization_level; + $metadata = $metadata ? $metadata : wp_get_attachment_metadata( $this->id ); + $sizes = isset( $metadata['sizes'] ) ? (array) $metadata['sizes'] : array(); // To avoid issue with "original_size" at 0 in "_imagify_data". if ( 0 === (int) $this->get_stats_data( 'original_size' ) ) { $this->delete_imagify_data(); } - // Get file path & URL for original image. - $attachment_path = $this->get_original_path(); - $attachment_url = $this->get_original_url(); - $attachment_original_size = $this->get_original_size( false ); - - // Check if the attachment extension is allowed. - if ( ! $this->id || ! wp_attachment_is_image( $this->id ) ) { - return; - } - // Check if the full size is already optimized. if ( $this->is_optimized() && ( $this->get_optimization_level() === $optimization_level ) ) { return; } + // Get file path & URL for original image. + $attachment_path = $this->get_original_path(); + $attachment_url = $this->get_original_url(); + $attachment_original_size = $this->get_original_size( false ); + /** * Fires before optimizing an attachment. * @@ -371,6 +371,11 @@ public function optimize( $optimization_level = null, $metadata = array() ) { * @return void */ public function restore() { + // Check if the attachment extension is allowed. + if ( ! imagify_is_attachment_mime_type_supported( $this->id ) ) { + return; + } + // Stop the process if there is no backup file to restore. if ( ! $this->has_backup() ) { return; diff --git a/inc/functions/admin-ui.php b/inc/functions/admin-ui.php index 2bc0e6dae..085100490 100644 --- a/inc/functions/admin-ui.php +++ b/inc/functions/admin-ui.php @@ -218,7 +218,7 @@ function get_imagify_media_column_content( $attachment, $context = 'wp' ) { $output = ''; // Check if the attachment extension is allowed. - if ( 'wp' === $context && ! wp_attachment_is_image( $attachment_id ) ) { + if ( 'wp' === $context && ! imagify_is_attachment_mime_type_supported( $attachment_id ) ) { /* translators: %s is a file extension. */ return sprintf( __( '%s can\'t be optimized', 'imagify' ), strtoupper( $attachment_ext ) ); } diff --git a/inc/functions/attachments.php b/inc/functions/attachments.php index dc7e61928..7d4de29c5 100755 --- a/inc/functions/attachments.php +++ b/inc/functions/attachments.php @@ -16,6 +16,34 @@ function get_imagify_mime_type() { ); } +/** + * Tell if an attachment has a supported mime type. + * Was previously Imagify_AS3CF::is_mime_type_supported() since 1.6.6. + * + * @since 1.6.8 + * @author Grégory Viguier + * + * @param int $attachment_id The attachment ID. + * @return bool + */ +function imagify_is_attachment_mime_type_supported( $attachment_id ) { + static $is = array( false ); + + $attachment_id = absint( $attachment_id ); + + if ( isset( $is[ $attachment_id ] ) ) { + return $is[ $attachment_id ]; + } + + $mime_types = get_imagify_mime_type(); + $mime_types = array_flip( $mime_types ); + $mime_type = (string) get_post_mime_type( $attachment_id ); + + $is[ $attachment_id ] = isset( $mime_types[ $mime_type ] ); + + return $is[ $attachment_id ]; +} + /** * Get the backup path of a specific attachement. * From e7a4779dba34c71edbf8fddfead073c8ccf3ecfb Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Thu, 13 Jul 2017 16:37:24 +0200 Subject: [PATCH 09/38] Don't display the Optimize button in the metabox if the attachment can't be optimized. --- inc/admin/meta-boxes.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/inc/admin/meta-boxes.php b/inc/admin/meta-boxes.php index 9f7a8e259..aeb5c8765 100755 --- a/inc/admin/meta-boxes.php +++ b/inc/admin/meta-boxes.php @@ -14,6 +14,10 @@ function _imagify_attachment_submitbox_misc_actions() { return; } + if ( ! imagify_is_attachment_mime_type_supported( $post->ID ) ) { + return; + } + $class_name = get_imagify_attachment_class_name( 'wp', $post->ID, 'attachment_submitbox_misc_actions' ); $attachment = new $class_name( $post->ID ); From fc1e6c6700d2a55655298fe25ac504467e1eeacb Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Mon, 17 Jul 2017 11:20:54 +0200 Subject: [PATCH 10/38] Allow to (de)select ALL thumbnail sizes at once in the settings page. --- assets/js/options.js | 67 ++++++++++++++++++++++++++++++++++++++++ assets/js/options.min.js | 2 +- inc/admin/ui/options.php | 51 ++++++++++++++++++++++-------- 3 files changed, 106 insertions(+), 14 deletions(-) diff --git a/assets/js/options.js b/assets/js/options.js index fca56ecb8..b2f376cdd 100755 --- a/assets/js/options.js +++ b/assets/js/options.js @@ -121,3 +121,70 @@ window.imagify = window.imagify || { } ); } )(jQuery, document, window); + + +// "Select all" checkboxes ========================================================================= +(function( w, d, $, undefined ) { + + var lastClicked = {}, + jqPropHookChecked = $.propHooks.checked; + + // Force `.prop()` to trigger a `change` event. + $.propHooks.checked = { + set: function( elem, value, name ) { + var ret; + + if ( undefined === jqPropHookChecked ) { + ret = ( elem[ name ] = value ); + } else { + ret = jqPropHookChecked( elem, value, name ); + } + + $( elem ).trigger( 'change.imagify' ); + + return ret; + } + }; + + // Check all checkboxes. + $( '.imagify-check-group .imagify-row-check' ).on( 'click', function( e ) { + var $group = $( this ).closest( '.imagify-check-group' ), + allChecked = 0 === $group.find( '.imagify-row-check' ).filter( ':visible:enabled' ).not( ':checked' ).length; + + // Toggle "check all" checkboxes. + $group.find( '.imagify-toggle-check' ).prop( 'checked', allChecked ); + } ) + .first().trigger( 'change.imagify' ); + + $( '.imagify-check-group .imagify-toggle-check' ).on( 'click.wp-toggle-checkboxes', function( e ) { + var $this = $( this ), + $wrap = $this.closest( '.imagify-check-group' ), + controlChecked = $this.prop( 'checked' ), + toggle = e.shiftKey || $this.data( 'wp-toggle' ); + + $wrap.find( '.imagify-toggle-check' ) + .prop( 'checked', function() { + var $this = $( this ); + + if ( $this.is( ':hidden,:disabled' ) ) { + return false; + } + + if ( toggle ) { + return ! $this.prop( 'checked' ); + } + + return controlChecked ? true : false; + } ); + + $wrap.find( '.imagify-row-check' ) + .prop( 'checked', function() { + if ( toggle ) { + return false; + } + + return controlChecked ? true : false; + } ); + } ); + +} )(window, document, jQuery); diff --git a/assets/js/options.min.js b/assets/js/options.min.js index e4020cf67..8a3aff59a 100755 --- a/assets/js/options.min.js +++ b/assets/js/options.min.js @@ -1 +1 @@ -window.imagify=window.imagify||{concat:ajaxurl.indexOf("?")>0?"&":"?",log:function(a){void 0!==console&&console.log(a)},info:function(a){void 0!==console&&console.info(a)}},function(a,b,c,d){var e=!1,f=!1;a("#imagify-settings #api_key").on("blur",function(){var b=a(this),c=b.val();return""!==a.trim(c)&&(a("#check_api_key").val()===c?(a("#imagify-check-api-container").html(' '+imagifyAdmin.labels.ValidApiKeyText),!1):(!0===e?f.abort():(a("#imagify-check-api-container").remove(),b.after(''+imagifyAdmin.labels.waitApiKeyCheckText+"")),e=!0,void(f=a.get(ajaxurl+imagify.concat+"action=imagify_check_api_key_validity&api_key="+b.val()+"&imagifycheckapikeynonce="+a("#imagifycheckapikeynonce").val()).done(function(b){b.success?(a("#imagify-check-api-container").remove(),swal({title:imagifyAdmin.labels.ApiKeyCheckSuccessTitle,html:imagifyAdmin.labels.ApiKeyCheckSuccessText,type:"success",customClass:"imagify-sweet-alert"}).then(function(){location.reload()})):a("#imagify-check-api-container").html(' '+b.data),e=!1}))))}),a(".imagify-options-line").css("cursor","pointer").on("click",function(b){if("INPUT"!==b.target.nodeName)return a('input[aria-describedby="'+a(this).attr("id")+'"]').trigger("click"),!1}),a(".imagify-settings th span").on("click",function(){var b=a(this).parent().next("td").find("input:checkbox");1===b.length&&b.trigger("click")}),a(".imagify-options-line").find("input").on("change focus",function(){var b=a(this).closest(".imagify-options-line").prev("label").prev("input");b[0].checked||b.prop("checked",!0)}),a(".imagify-settings-section").find("#backup").on("change",function(){var b=a(this);b.is(":checked")||swal({title:imagifyOptions.noBackupTitle,html:imagifyOptions.noBackupText,type:"warning",customClass:"imagify-sweet-alert",showCancelButton:!0,cancelButtonText:imagifyAdmin.labels.swalCancel,reverseButtons:!0}).then(function(){},function(){b.prop("checked",!0)})})}(jQuery,document,window); \ No newline at end of file +window.imagify=window.imagify||{concat:ajaxurl.indexOf("?")>0?"&":"?",log:function(a){void 0!==console&&console.log(a)},info:function(a){void 0!==console&&console.info(a)}},function(a,b,c,d){var e=!1,f=!1;a("#imagify-settings #api_key").on("blur",function(){var b=a(this),c=b.val();return""!==a.trim(c)&&(a("#check_api_key").val()===c?(a("#imagify-check-api-container").html(' '+imagifyAdmin.labels.ValidApiKeyText),!1):(!0===e?f.abort():(a("#imagify-check-api-container").remove(),b.after(''+imagifyAdmin.labels.waitApiKeyCheckText+"")),e=!0,void(f=a.get(ajaxurl+imagify.concat+"action=imagify_check_api_key_validity&api_key="+b.val()+"&imagifycheckapikeynonce="+a("#imagifycheckapikeynonce").val()).done(function(b){b.success?(a("#imagify-check-api-container").remove(),swal({title:imagifyAdmin.labels.ApiKeyCheckSuccessTitle,html:imagifyAdmin.labels.ApiKeyCheckSuccessText,type:"success",customClass:"imagify-sweet-alert"}).then(function(){location.reload()})):a("#imagify-check-api-container").html(' '+b.data),e=!1}))))}),a(".imagify-options-line").css("cursor","pointer").on("click",function(b){if("INPUT"!==b.target.nodeName)return a('input[aria-describedby="'+a(this).attr("id")+'"]').trigger("click"),!1}),a(".imagify-settings th span").on("click",function(){var b=a(this).parent().next("td").find("input:checkbox");1===b.length&&b.trigger("click")}),a(".imagify-options-line").find("input").on("change focus",function(){var b=a(this).closest(".imagify-options-line").prev("label").prev("input");b[0].checked||b.prop("checked",!0)}),a(".imagify-settings-section").find("#backup").on("change",function(){var b=a(this);b.is(":checked")||swal({title:imagifyOptions.noBackupTitle,html:imagifyOptions.noBackupText,type:"warning",customClass:"imagify-sweet-alert",showCancelButton:!0,cancelButtonText:imagifyAdmin.labels.swalCancel,reverseButtons:!0}).then(function(){},function(){b.prop("checked",!0)})})}(jQuery,document,window),function(a,b,c,d){var e=c.propHooks.checked;c.propHooks.checked={set:function(a,b,d){var f;return f=void 0===e?a[d]=b:e(a,b,d),c(a).trigger("change.imagify"),f}},c(".imagify-check-group .imagify-row-check").on("click",function(a){var b=c(this).closest(".imagify-check-group"),d=0===b.find(".imagify-row-check").filter(":visible:enabled").not(":checked").length;b.find(".imagify-toggle-check").prop("checked",d)}).first().trigger("change.imagify"),c(".imagify-check-group .imagify-toggle-check").on("click.wp-toggle-checkboxes",function(a){var b=c(this),d=b.closest(".imagify-check-group"),e=b.prop("checked"),f=a.shiftKey||b.data("wp-toggle");d.find(".imagify-toggle-check").prop("checked",function(){var a=c(this);return!a.is(":hidden,:disabled")&&(f?!a.prop("checked"):!!e)}),d.find(".imagify-row-check").prop("checked",function(){return!f&&!!e})})}(window,document,jQuery); \ No newline at end of file diff --git a/inc/admin/ui/options.php b/inc/admin/ui/options.php index d1dcc167c..f6f93b401 100755 --- a/inc/admin/ui/options.php +++ b/inc/admin/ui/options.php @@ -270,20 +270,45 @@ function _imagify_display_options_page() {
- $size_data ) { - $label = esc_html( stripslashes( $size_data['name'] ) ); - $label = sprintf( '%s - %d × %d', $label, $size_data['width'], $size_data['height'] ); - ?> - - /> - -
+
+ + $sizes = get_imagify_thumbnail_sizes(); + $select_all = count( $sizes ) > 3; + $disallowed = (array) get_imagify_option( 'disallowed-sizes', array() ); + + if ( $select_all ) { + $has_disallowed = ! empty( array_intersect_key( $disallowed, $sizes ) ); + ?> + + > + + +
+ $size_data ) { + $label = esc_html( stripslashes( $size_data['name'] ) ); + $label = sprintf( '%s - %d × %d', $label, $size_data['width'], $size_data['height'] ); + $checked = ! isset( $disallowed[ $size_key ] ); + ?> + + /> + +
+ + + > + + + +
From 8f5c3e35e8b238b375fb2aa32b9db100d8fed2a7 Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Mon, 17 Jul 2017 12:10:02 +0200 Subject: [PATCH 11/38] =?UTF-8?q?Hotfix:=20httpsify=20all=20the=20things?= =?UTF-8?q?=20(use=20https=20for=20our=20URLs).=20Also,=20introduced=20`im?= =?UTF-8?q?agify=5Fget=5Fwp=5Frocket=5Furl()`=20to=20standardize=20the=20W?= =?UTF-8?q?P=C2=A0Rocket's=20site=20URL=20among=20the=20plugin.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- imagify.php | 2 +- inc/admin/ui/notices.php | 23 +++-------------------- inc/admin/ui/options.php | 2 +- inc/functions/admin.php | 28 ++++++++++++++++++++++++++++ 4 files changed, 33 insertions(+), 22 deletions(-) diff --git a/imagify.php b/imagify.php index 44ed9f00a..5b1ca5c06 100644 --- a/imagify.php +++ b/imagify.php @@ -5,7 +5,7 @@ * Description: Dramaticaly reduce image file sizes without losing quality, make your website load faster, boost your SEO and save money on your bandwidth using Imagify, the new most advanced image optimization tool. * Version: 1.6.8 * Author: WP Media - * Author URI: http://wp-media.me + * Author URI: https://wp-media.me/ * Licence: GPLv2 * * Text Domain: imagify diff --git a/inc/admin/ui/notices.php b/inc/admin/ui/notices.php index 04520bb91..ee90c303a 100755 --- a/inc/admin/ui/notices.php +++ b/inc/admin/ui/notices.php @@ -334,28 +334,11 @@ function _imagify_rocket_notice() { $dismiss_url = get_imagify_admin_url( 'dismiss-notice', 'wp-rocket' ); $coupon_code = 'IMAGIFY20'; - $wprocket_url = 'http://wp-rocket.me/'; - - switch ( get_locale() ) { - case 'fr_FR' : - $wprocket_url = 'http://wp-rocket.me/fr/'; - break; - case 'es_ES' : - $wprocket_url = 'http://wp-rocket.me/es/'; - break; - case 'it_IT' : - $wprocket_url = 'http://wp-rocket.me/it/'; - break; - case 'de_DE' : - $wprocket_url = 'http://wp-rocket.me/de/'; - break; - } - - $wprocket_url .= '?utm_source=imagify-coupon&utm_medium=plugin&utm_campaign=imagify'; + $wprocket_url = imagify_get_wp_rocket_url(); ?>
- +

- +

diff --git a/inc/admin/ui/options.php b/inc/admin/ui/options.php index d1dcc167c..e807c0020 100755 --- a/inc/admin/ui/options.php +++ b/inc/admin/ui/options.php @@ -48,7 +48,7 @@ function _imagify_display_options_page() {

- +

diff --git a/inc/functions/admin.php b/inc/functions/admin.php index 722b35c45..bb58718cc 100755 --- a/inc/functions/admin.php +++ b/inc/functions/admin.php @@ -286,3 +286,31 @@ function imagify_get_wpdb_metas( $metas, $ids ) { return $metas; } + +/** + * Simple helper to get the WP Rocket's site URL. + * The URL is localized and contains some utm_*** parameters. + * + * @since 1.6.8 + * @author Grégory Viguier + * + * @return string The URL. + */ +function imagify_get_wp_rocket_url() { + $wprocket_url = 'https://wp-rocket.me/'; + $locale = get_locale(); + $suffixes = array( + 'fr_FR' => 'fr', + 'es_ES' => 'es', + 'it_IT' => 'it', + 'de_DE' => 'de', + ); + + if ( isset( $suffixes[ $locale ] ) ) { + $wprocket_url .= $suffixes[ $locale ] . '/'; + } + + $wprocket_url .= '?utm_source=imagify-coupon&utm_medium=plugin&utm_campaign=imagify'; + + return $wprocket_url; +} From fed4553e5f6d3c59fc30ab5e52ee1eb01b26ccdd Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Mon, 17 Jul 2017 12:11:05 +0200 Subject: [PATCH 12/38] =?UTF-8?q?Hotfix:=20added=20a=20`target=3D"=5Fblank?= =?UTF-8?q?"`=20attribute=20to=20links=20leading=20to=20WP=C2=A0Rocket's?= =?UTF-8?q?=20site.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- inc/admin/ui/notices.php | 2 +- inc/admin/ui/options.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/admin/ui/notices.php b/inc/admin/ui/notices.php index ee90c303a..72a2cd45f 100755 --- a/inc/admin/ui/notices.php +++ b/inc/admin/ui/notices.php @@ -338,7 +338,7 @@ function _imagify_rocket_notice() { ?>
- +

- +

From 40137fdbc54c41961b95751d78b342053d76c66b Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Mon, 17 Jul 2017 23:29:18 +0200 Subject: [PATCH 13/38] Display an error message under the "Backup original images" checkbox if the backup folder is not writable. --- assets/css/admin.css | 12 +++++++ assets/js/options.js | 25 +++++++++++-- inc/admin/ajax.php | 20 +++++++++++ inc/admin/ui/options.php | 18 +++++++++- inc/functions/attachments.php | 68 ++++++++++++++++++++++++++--------- 5 files changed, 124 insertions(+), 19 deletions(-) diff --git a/assets/css/admin.css b/assets/css/admin.css index 2acabe9e0..02f3b8f48 100755 --- a/assets/css/admin.css +++ b/assets/css/admin.css @@ -2398,6 +2398,18 @@ td.imagify-cell-filename { background: #D0021B; color: #FFF; } +.imagify-settings-section .imagify-error { + display: inline-block; + padding: 7px 10px; + margin: 10px 0 0 45px; + border-radius: 3px; +} +.imagify-settings-section .imagify-error code { + font-weight: normal; +} +.imagify-settings-section .imagify-error.hidden { + display: none; +} .imagify-warning, #wpadminbar .imagify-warning * { background: #f5a623; diff --git a/assets/js/options.js b/assets/js/options.js index fca56ecb8..6d22746a3 100755 --- a/assets/js/options.js +++ b/assets/js/options.js @@ -98,9 +98,26 @@ window.imagify = window.imagify || { * Imagify Backup alert. */ $( '.imagify-settings-section' ).find( '#backup' ).on( 'change', function() { - var $_this = $( this ); + var $_this = $( this ), + $backupMessage = $_this.siblings( '#backup-dir-is-writable' ), + params = { + 'action': 'imagify_check_backup_dir_is_writable', + '_wpnonce': $backupMessage.data( 'nonce' ) + }; if ( $_this.is( ':checked' ) ) { + $.getJSON( ajaxurl, params ) + .done( function( r ) { + if ( $.isPlainObject( r ) && r.success ) { + if ( r.data.is_writable ) { + // Hide the error message. + $backupMessage.addClass( 'hidden' ); + } else { + // Show the error message. + $backupMessage.removeClass( 'hidden' ); + } + } + } ); return; } @@ -113,8 +130,12 @@ window.imagify = window.imagify || { cancelButtonText: imagifyAdmin.labels.swalCancel, reverseButtons: true } ).then( - function() {}, function() { + // Leave it unchecked, hide the error message. + $backupMessage.addClass( 'hidden' ); + }, + function() { + // Re-check. $_this.prop( 'checked', true ); } ); diff --git a/inc/admin/ajax.php b/inc/admin/ajax.php index a0d0dfddb..2e0cc938d 100755 --- a/inc/admin/ajax.php +++ b/inc/admin/ajax.php @@ -442,6 +442,26 @@ function _do_wp_ajax_imagify_get_unoptimized_attachment_ids() { wp_send_json_success( $data ); } +add_action( 'wp_ajax_imagify_check_backup_dir_is_writable', '_do_wp_ajax_imagify_check_backup_dir_is_writable' ); +/** + * Check if the backup directory is writable. + * This is used to display an error message in the plugin's settings page. + * + * @since 1.6.8 + * @author Grégory Viguier + */ +function _do_wp_ajax_imagify_check_backup_dir_is_writable() { + check_ajax_referer( 'imagify_check_backup_dir_is_writable' ); + + if ( ! current_user_can( imagify_get_capacity() ) ) { + wp_send_json_error(); + } + + wp_send_json_success( array( + 'is_writable' => (int) imagify_backup_dir_is_writable(), + ) ); +} + /** --------------------------------------------------------------------------------------------- */ /** IMAGIFY ACCOUNT ============================================================================= */ /** --------------------------------------------------------------------------------------------- */ diff --git a/inc/admin/ui/options.php b/inc/admin/ui/options.php index 0380186b8..9d9eb2946 100755 --- a/inc/admin/ui/options.php +++ b/inc/admin/ui/options.php @@ -194,13 +194,29 @@ function _imagify_display_options_page() { - aria-describedby="describe-backup" /> + + aria-describedby="describe-backup" /> + +
+ $backup_path" ); + ?> + diff --git a/inc/functions/attachments.php b/inc/functions/attachments.php index 7d4de29c5..9583ce24a 100755 --- a/inc/functions/attachments.php +++ b/inc/functions/attachments.php @@ -44,6 +44,57 @@ function imagify_is_attachment_mime_type_supported( $attachment_id ) { return $is[ $attachment_id ]; } +/** + * Get the path to the backups directory. + * + * @since 1.6.8 + * @author Grégory Viguier + * + * @return string|bool Path to the backups directory. False on failure. + */ +function get_imagify_backup_dir_path() { + static $backup_dir; + + if ( isset( $backup_dir ) ) { + return $backup_dir; + } + + $upload_basedir = get_imagify_upload_basedir(); + + if ( ! $upload_basedir ) { + return false; + } + + $backup_dir = $upload_basedir . 'backup/'; + + /** + * Filter the backup directory path. + * + * @since 1.0 + * + * @param string $backup_dir The backup directory path. + */ + $backup_dir = apply_filters( 'imagify_backup_directory', $backup_dir ); + $backup_dir = trailingslashit( wp_normalize_path( $backup_dir ) ); + + return $backup_dir; +} + +/** + * Tell if the folder containing the backups is writable. + * + * @since 1.6.8 + * @author Grégory Viguier + * + * @return bool + */ +function imagify_backup_dir_is_writable() { + $filesystem = imagify_get_filesystem(); + $has_backup_dir = wp_mkdir_p( get_imagify_backup_dir_path() ); + + return $has_backup_dir && $filesystem->is_writable( get_imagify_backup_dir_path() ); +} + /** * Get the backup path of a specific attachement. * @@ -53,29 +104,14 @@ function imagify_is_attachment_mime_type_supported( $attachment_id ) { * @return string|bool The backup path. False on failure. */ function get_imagify_attachment_backup_path( $file_path ) { - static $backup_dir; - $file_path = wp_normalize_path( (string) $file_path ); $upload_basedir = get_imagify_upload_basedir(); + $backup_dir = get_imagify_backup_dir_path(); if ( ! $file_path || ! $upload_basedir ) { return false; } - if ( ! isset( $backup_dir ) ) { - $backup_dir = $upload_basedir . 'backup/'; - - /** - * Filter the backup directory path. - * - * @since 1.0 - * - * @param string $backup_dir The backup directory path. - */ - $backup_dir = apply_filters( 'imagify_backup_directory', $backup_dir ); - $backup_dir = trailingslashit( wp_normalize_path( $backup_dir ) ); - } - return str_replace( $upload_basedir, $backup_dir, $file_path ); } From 7a619b65dee778e5e816d618ea6d4bab3a8930a5 Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Tue, 18 Jul 2017 00:21:07 +0200 Subject: [PATCH 14/38] In `imagify_backup_dir_is_writable()`, make sure `get_imagify_backup_dir_path()` returns a valid value. --- inc/functions/attachments.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/inc/functions/attachments.php b/inc/functions/attachments.php index 9583ce24a..e97a5a58e 100755 --- a/inc/functions/attachments.php +++ b/inc/functions/attachments.php @@ -89,6 +89,10 @@ function get_imagify_backup_dir_path() { * @return bool */ function imagify_backup_dir_is_writable() { + if ( ! get_imagify_backup_dir_path() ) { + return false; + } + $filesystem = imagify_get_filesystem(); $has_backup_dir = wp_mkdir_p( get_imagify_backup_dir_path() ); From 2fd90e0d150505a38fb261de08c55fb661a6e72b Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Tue, 18 Jul 2017 12:51:40 +0200 Subject: [PATCH 15/38] Copy/paste drama I guess. --- inc/functions/attachments.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/functions/attachments.php b/inc/functions/attachments.php index e97a5a58e..4878f173f 100755 --- a/inc/functions/attachments.php +++ b/inc/functions/attachments.php @@ -104,8 +104,8 @@ function imagify_backup_dir_is_writable() { * * @since 1.0 * - * @param int $file_path The file path. - * @return string|bool The backup path. False on failure. + * @param string $file_path The file path. + * @return string|bool The backup path. False on failure. */ function get_imagify_attachment_backup_path( $file_path ) { $file_path = wp_normalize_path( (string) $file_path ); From 415dfe140120e30ce1d965735e5a3297950d6a6b Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Tue, 18 Jul 2017 12:55:36 +0200 Subject: [PATCH 16/38] Introduced `imagify_backup_file()` to... backup a file. Deprecated `Imagify_AS3CF_Attachment::maybe_backup()`. --- .../class-imagify-as3cf-attachment.php | 24 ++++----- .../classes/class-imagify-ngg-attachment.php | 14 ++--- inc/classes/class-imagify-attachment.php | 16 ++---- inc/functions/process.php | 54 ++++++++++++++++--- 4 files changed, 63 insertions(+), 45 deletions(-) diff --git a/inc/3rd-party/amazon-s3-and-cloudfront/inc/classes/class-imagify-as3cf-attachment.php b/inc/3rd-party/amazon-s3-and-cloudfront/inc/classes/class-imagify-as3cf-attachment.php index f4a4c845c..5899ad5db 100644 --- a/inc/3rd-party/amazon-s3-and-cloudfront/inc/classes/class-imagify-as3cf-attachment.php +++ b/inc/3rd-party/amazon-s3-and-cloudfront/inc/classes/class-imagify-as3cf-attachment.php @@ -519,9 +519,9 @@ protected function maybe_resize( $attachment_path ) { return false; } - $backed_up = $this->maybe_backup( $attachment_path ); + $backuped = imagify_backup_file( $attachment_path ); - if ( false === $backed_up ) { + if ( is_wp_error( $backuped ) ) { return false; } @@ -542,27 +542,23 @@ protected function maybe_resize( $attachment_path ) { * Maybe backup a file. * * @since 1.6.6 + * @since 1.6.8 Deprecated. * @author Grégory Viguier * * @param string $attachment_path The file path. * @return bool|null True on success. False on failure. Null if backup is not needed. */ protected function maybe_backup( $attachment_path ) { - if ( ! get_imagify_option( 'backup' ) ) { - return null; - } - - $filesystem = imagify_get_filesystem(); - $backup_path = get_imagify_attachment_backup_path( $attachment_path ); - $backup_path_info = pathinfo( $backup_path ); + $class_name = get_class( $this ); + _deprecated_function( $class_name . '::' . __FUNCTION__ . '()', '1.6.8', 'imagify_backup_file()' ); - wp_mkdir_p( $backup_path_info['dirname'] ); + $result = imagify_backup_file( $attachment_path ); - // TO DO - check and send a error message if the backup can't be created. - $filesystem->copy( $attachment_path, $backup_path, true ); - imagify_chmod_file( $backup_path ); + if ( false === $result ) { + return null; + } - return $filesystem->exists( $backup_path ); + return ! is_wp_error( $result ); } /** diff --git a/inc/3rd-party/nextgen-gallery/inc/classes/class-imagify-ngg-attachment.php b/inc/3rd-party/nextgen-gallery/inc/classes/class-imagify-ngg-attachment.php index 94c5420bc..aa9d93fe7 100644 --- a/inc/3rd-party/nextgen-gallery/inc/classes/class-imagify-ngg-attachment.php +++ b/inc/3rd-party/nextgen-gallery/inc/classes/class-imagify-ngg-attachment.php @@ -310,18 +310,10 @@ public function optimize( $optimization_level = null, $metadata = array() ) { $resized_attachment_path = $this->resize( $attachment_path, $attachment_size, $resize_width ); if ( ! is_wp_error( $resized_attachment_path ) ) { - $filesystem = imagify_get_filesystem(); - - if ( get_imagify_option( 'backup', false ) ) { - $backup_path = get_imagify_attachment_backup_path( $attachment_path ); - $backup_path_info = pathinfo( $backup_path ); - - wp_mkdir_p( $backup_path_info['dirname'] ); + // TODO (@Greg): Send an error message if the backup fails. + imagify_backup_file( $attachment_path ); - // TO DO - check and send a error message if the backup can't be created. - $filesystem->copy( $attachment_path, $backup_path, true ); - imagify_chmod_file( $backup_path ); - } + $filesystem = imagify_get_filesystem(); $filesystem->move( $resized_attachment_path, $attachment_path, true ); imagify_chmod_file( $attachment_path ); diff --git a/inc/classes/class-imagify-attachment.php b/inc/classes/class-imagify-attachment.php index 7856ba223..a76159ed4 100644 --- a/inc/classes/class-imagify-attachment.php +++ b/inc/classes/class-imagify-attachment.php @@ -241,7 +241,7 @@ public function optimize( $optimization_level = null, $metadata = array() ) { // Get the resize values for the original size. $resized = false; - $do_resize = get_imagify_option( 'resize_larger', false ); + $do_resize = get_imagify_option( 'resize_larger' ); $resize_width = get_imagify_option( 'resize_larger_w' ); $attachment_size = @getimagesize( $attachment_path ); @@ -249,18 +249,10 @@ public function optimize( $optimization_level = null, $metadata = array() ) { $resized_attachment_path = $this->resize( $attachment_path, $attachment_size, $resize_width ); if ( ! is_wp_error( $resized_attachment_path ) ) { - $filesystem = imagify_get_filesystem(); - - if ( get_imagify_option( 'backup', false ) ) { - $backup_path = get_imagify_attachment_backup_path( $attachment_path ); - $backup_path_info = pathinfo( $backup_path ); - - wp_mkdir_p( $backup_path_info['dirname'] ); + // TODO (@Greg): Send an error message if the backup fails. + imagify_backup_file( $attachment_path ); - // TO DO - check and send a error message if the backup can't be created. - $filesystem->copy( $attachment_path, $backup_path, true ); - imagify_chmod_file( $backup_path ); - } + $filesystem = imagify_get_filesystem(); $filesystem->move( $resized_attachment_path, $attachment_path, true ); imagify_chmod_file( $attachment_path ); diff --git a/inc/functions/process.php b/inc/functions/process.php index 96c958f86..9d475302c 100755 --- a/inc/functions/process.php +++ b/inc/functions/process.php @@ -107,14 +107,8 @@ function do_imagify( $file_path, $args = array() ) { // Create a backup file. if ( 'wp' === $args['context'] && $args['backup'] && ! $args['resized'] ) { - $backup_path = get_imagify_attachment_backup_path( $file_path ); - $backup_path_info = pathinfo( $backup_path ); - - wp_mkdir_p( $backup_path_info['dirname'] ); - - // TO DO - check and send a error message if the backup can't be created. - $filesystem->copy( $file_path, $backup_path, true ); - imagify_chmod_file( $backup_path ); + // TODO (@Greg): Send an error message if the backup fails. + imagify_backup_file( $file_path ); } if ( ! function_exists( 'download_url' ) ) { @@ -177,3 +171,47 @@ function imagify_do_async_job( $body ) { wp_remote_post( admin_url( 'admin-ajax.php' ), $args ); } + +/** + * Backup a file. + * + * @since 1.6.8 + * @author Grégory Viguier + * + * @param string $file_path The file path. + * @return bool|object True on success. False if the backup option is not enabled. A WP_Error object on failure. + */ +function imagify_backup_file( $file_path ) { + if ( ! get_imagify_option( 'backup' ) ) { + return false; + } + + if ( ! $file_path ) { + return new WP_Error( 'empty_path', __( 'The file path is empty.', 'imagify' ) ); + } + + if ( ! imagify_backup_dir_is_writable() ) { + return new WP_Error( 'backup_dir_not_writable', __( 'The backup directory is not writable.', 'imagify' ) ); + } + + $backup_path = get_imagify_attachment_backup_path( $file_path ); + + if ( ! $backup_path ) { + return new WP_Error( 'wp_upload_error', __( 'Error while retrieving the uploads directory path.', 'imagify' ) ); + } + + $filesystem = imagify_get_filesystem(); + + if ( ! empty( $filesystem->errors->errors ) ) { + return new WP_Error( 'filesystem_error', __( 'Filesystem error.', 'imagify' ), $filesystem->errors ); + } + + $filesystem->copy( $file_path, $backup_path, true ); + imagify_chmod_file( $backup_path ); + + if ( ! $filesystem->exists( $backup_path ) ) { + return new WP_Error( 'backup_doesnt_exist', __( 'The file could not be saved.', 'imagify' ) ); + } + + return true; +} From 951cbba1bec07e58d5e0bcad4bccb5467e36639d Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Tue, 18 Jul 2017 15:48:13 +0200 Subject: [PATCH 17/38] Display an admin notice if the backup folder is not writable. --- inc/admin/ui/notices.php | 69 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/inc/admin/ui/notices.php b/inc/admin/ui/notices.php index 72a2cd45f..c847a6067 100755 --- a/inc/admin/ui/notices.php +++ b/inc/admin/ui/notices.php @@ -9,13 +9,13 @@ * @author Jonathan Buttigieg */ function _imagify_warning_empty_api_key_notice() { - $current_screen = get_current_screen(); + $current_screen = get_current_screen(); if ( ! empty( $current_screen ) && ( 'settings_page_imagify' === $current_screen->base || 'settings_page_imagify-network' === $current_screen->base ) ) { return; } - if ( imagify_notice_is_dismissed( 'welcome-steps' ) || get_imagify_option( 'api_key', false ) || ! current_user_can( imagify_get_capacity() ) ) { + if ( imagify_notice_is_dismissed( 'welcome-steps' ) || get_imagify_option( 'api_key' ) || ! current_user_can( imagify_get_capacity() ) ) { return; } ?> @@ -121,7 +121,7 @@ function _imagify_warning_wrong_api_key_notice() { add_action( 'all_admin_notices', '_imagify_warning_plugins_to_deactivate_notice' ); /** - * This warning is displayed when some plugins may conflict with Imagify + * This warning is displayed when some plugins may conflict with Imagify. * * @since 1.0 * @author Jonathan Buttigieg @@ -314,6 +314,69 @@ function _imagify_warning_over_quota_notice() { 1, + 'settings_page_' . IMAGIFY_SLUG . '-network' => 1, + 'media_page_' . IMAGIFY_SLUG . '-bulk-optimization' => 1, + 'media_page_' . IMAGIFY_SLUG . '-ngg-bulk-optimization' => 1, + 'upload' => 1, + 'media' => 1, + 'attachment' => 1, + ); + + if ( ! $auto && empty( $bases[ $current_screen->id ] ) ) { + return; + } + + if ( ! $auto && 'attachment' === $current_screen->id && $post_id && ! imagify_is_attachment_mime_type_supported( $post_id ) ) { + return; + } + + if ( ! get_imagify_option( 'backup' ) || ! current_user_can( imagify_get_capacity( true ) ) ) { + return; + } + + $filesystem = imagify_get_filesystem(); + $has_backup_dir = wp_mkdir_p( get_imagify_backup_dir_path() ); + + if ( $has_backup_dir && $filesystem->is_writable( get_imagify_backup_dir_path() ) ) { + return; + } + + $backup_path = str_replace( wp_normalize_path( ABSPATH ), '', get_imagify_backup_dir_path() ); + ?> +
+
+ +
+

$backup_path" ); + ?>

+
+
+ Date: Wed, 19 Jul 2017 00:16:37 +0200 Subject: [PATCH 18/38] Improved translations in the bulk optimization page, mainly related to JavaScript. To note: - Used the keyword "Optimizing" instead of "Compressing". - Edited `imagify.js` to use a correct formatting: we use Bytes (not bits, because 1024), "Mega" is represented with a capital "M", a non-breaking space is used between the value and the unit. --- assets/js/bulk.js | 16 ++++++++-------- assets/js/imagify.js | 8 ++++---- assets/js/imagify.min.js | 2 +- inc/admin/ui/bulk.php | 14 ++++++++++---- inc/functions/i18n.php | 8 ++++++++ 5 files changed, 31 insertions(+), 17 deletions(-) diff --git a/assets/js/bulk.js b/assets/js/bulk.js index e83be714c..4cfe2edd9 100755 --- a/assets/js/bulk.js +++ b/assets/js/bulk.js @@ -181,7 +181,7 @@ window.imagify = window.imagify || { e.preventDefault(); - if ( optimizationLevel === undefined ) { + if ( undefined === optimizationLevel ) { optimizationLevel = -1; } @@ -262,20 +262,20 @@ window.imagify = window.imagify || { // Before the attachment optimization. Optimizer.before( function( data ) { - table.find( '.imagify-row-progress' ).after( '"' + data.filename + 'Compressing' ); + table.find( '.imagify-row-progress' ).after( '' + data.filename + '' + imagifyBulk.labels.optimizing + '' ); } ) // After the attachment optimization. .each( function( data ) { var $progress = $( '#imagify-progress-bar' ), errorClass = 'error', errorDashicon = 'dismiss', - errorMessage = 'Error'; + errorMessage = imagifyBulk.labels.error; $progress.css( { 'width': data.progress + '%' } ); $progress.find( '.percent' ).html( data.progress + '%' ); if ( data.success ) { - $( '#attachment-' + data.image + ' .imagify-cell-status' ).html( 'Complete' ); + $( '#attachment-' + data.image + ' .imagify-cell-status' ).html( '' + imagifyBulk.labels.complete + '' ); $( '#attachment-' + data.image + ' .imagify-cell-original' ).html( data.original_size_human ); $( '#attachment-' + data.image + ' .imagify-cell-optimized' ).html( data.new_size_human ); $( '#attachment-' + data.image + ' .imagify-cell-percentage' ).html( '' + data.percent + '%' ); @@ -285,7 +285,7 @@ window.imagify = window.imagify || { // The table footer total optimized files. files = files + data.thumbnails + 1; - $( '.imagify-cell-nb-files' ).html( files + ' file(s)' ); + $( '.imagify-cell-nb-files' ).html( imagifyBulk.labels.nbrFiles.replace( '%s', files ) ); // The table footer original size. original_overall_size = original_overall_size + data.original_overall_size; @@ -312,10 +312,10 @@ window.imagify = window.imagify || { if ( data.error.indexOf( 'This image is already compressed' ) >= 0 ) { errorClass = 'warning'; errorDashicon = 'warning'; - errorMessage = 'Notice'; + errorMessage = imagifyBulk.labels.notice; } else { errors++; - $( '.imagify-cell-errors' ).html( errors + ' error(s)' ); + $( '.imagify-cell-errors' ).html( imagifyBulk.labels.nbrErrors.replace( '%s', errors ) ); } $( '#attachment-' + data.image ).after( '' + data.error + '' ); @@ -356,7 +356,7 @@ window.imagify = window.imagify || { } } ) .error( function( id ) { - imagify.log( 'Can\'t optimize image with id ' + id ); + imagify.log( "Can't optimize image with id " + id + "." ); } ) .run(); } ) diff --git a/assets/js/imagify.js b/assets/js/imagify.js index 4e5848d48..dd084a149 100644 --- a/assets/js/imagify.js +++ b/assets/js/imagify.js @@ -2,7 +2,7 @@ * imagify-gulpjs - version 0.0.1 - 2016-04-07 * WP Media * - * Note: when updating this file, don't forget to replace `this.buffer_size = 1;` by `this.buffer_size = imagifyBulk.buffer_size;`. + * Note: when updating this file, don't forget to replace `this.buffer_size = 1;` by `this.buffer_size = imagifyBulk.buffer_size;`. Also, humanSize() has been edited to use a correct format. */ (function () { 'use strict'; @@ -94,13 +94,13 @@ window.ImagifyGulp = function () { key: 'humanSize', value: function humanSize( bytes ) { if ( 0 === bytes ) { - return '0kb'; + return '0 kB'; } - var sizes = [ 'b', 'kb', 'mb' ], + var sizes = [ 'B', 'kB', 'MB' ], i = parseInt( Math.floor( Math.log( bytes ) / Math.log( 1024 ) ) ); - return ( bytes / Math.pow( 1024, i ) ).toFixed( 2 ) + sizes[ i ]; + return ( bytes / Math.pow( 1024, i ) ).toFixed( 2 ) + ' ' + sizes[ i ]; } }, { key: 'run', diff --git a/assets/js/imagify.min.js b/assets/js/imagify.min.js index 29c3a5761..5f61aad72 100644 --- a/assets/js/imagify.min.js +++ b/assets/js/imagify.min.js @@ -1 +1 @@ -!function(){"use strict";function a(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}var b=function(){function a(a,b){for(var c=0;cthis.buffer_size?this.buffer_size:this.images_ids.length,b=0;bthis.buffer_size?this.buffer_size:this.images_ids.length,b=0;b - 0 - 0 - 0Mb - 0Mb + 0' ); + ?> + 0' ); + ?> + 0 kB + 0 kB diff --git a/inc/functions/i18n.php b/inc/functions/i18n.php index 9cf49a209..96ed0f635 100755 --- a/inc/functions/i18n.php +++ b/inc/functions/i18n.php @@ -99,6 +99,14 @@ function get_imagify_localize_script_translations( $context ) { 'totalUnoptimizedAttachments' => imagify_count_unoptimized_attachments(), 'totalErrorsAttachments' => imagify_count_error_attachments(), 'processing' => __( 'Imagify is still processing. Are you sure you want to leave this page?', 'imagify' ), + 'optimizing' => __( 'Optimizing', 'imagify' ), + 'complete' => _x( 'Complete', 'adjective', 'imagify' ), + 'error' => __( 'Error', 'imagify' ), + 'notice' => _x( 'Notice', 'noun', 'imagify' ), + /* translators: %s is a number. Don't use %d. */ + 'nbrFiles' => __( '%s file(s)', 'imagify' ), + /* translators: %s is a number. Don't use %d. */ + 'nbrErrors' => __( '%s error(s)', 'imagify' ), ), ); From 87a89f1ed9c51e91d76880b72177f0226c332398 Mon Sep 17 00:00:00 2001 From: Git I Hate You Date: Wed, 19 Jul 2017 00:20:20 +0200 Subject: [PATCH 19/38] Hotfix: added a HTML class "hide-if-no-js" to the payment modal. --- inc/functions/admin-ui.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/functions/admin-ui.php b/inc/functions/admin-ui.php index b43232946..570698427 100644 --- a/inc/functions/admin-ui.php +++ b/inc/functions/admin-ui.php @@ -329,7 +329,7 @@ function get_imagify_price_table_format( $value ) { */ function imagify_payment_modal() { ?> -