Compress JPEG & PNG images - Version 3.2.0

Version Description

  • Support for WP Retina 2x Pro.
  • More capability checks for extra security.
  • Less resource intensive AJAX requests.
  • Fixed CSS issues from Analytify plugin.
  • Removed legacy Enhanced Media Library compatibility.
Download this release

Release Info

Developer TinyPNG
Plugin Icon 128x128 Compress JPEG & PNG images
Version 3.2.0
Comparing to
See all releases

Code changes from version 3.1.0 to 3.2.0

.travis.yml CHANGED
@@ -6,75 +6,82 @@ php:
6
  - 7.0
7
  - 7.1
8
  - 7.2
 
9
  matrix:
10
  include:
11
  - dist: precise
12
  php: 5.3
13
  script: bin/unit-tests
14
  - dist: trusty
15
- php: hhvm
 
 
 
 
 
 
16
  - dist: trusty
17
- php: 7.0
18
  env: WORDPRESS_VERSION=49 INTEGRATION_TESTS=true
19
  script: bin/integration-tests
20
  - dist: trusty
21
- php: 7.0
22
  env: WORDPRESS_VERSION=48 INTEGRATION_TESTS=true
23
  script: bin/integration-tests
24
  - dist: trusty
25
- php: 7.0
26
  env: WORDPRESS_VERSION=47 INTEGRATION_TESTS=true
27
  script: bin/integration-tests
28
  - dist: trusty
29
- php: 7.0
30
  env: WORDPRESS_VERSION=46 INTEGRATION_TESTS=true
31
  script: bin/integration-tests
32
  - dist: trusty
33
- php: 7.0
34
  env: WORDPRESS_VERSION=45 INTEGRATION_TESTS=true
35
  script: bin/integration-tests
36
  - dist: trusty
37
- php: 7.0
38
  env: WORDPRESS_VERSION=44 INTEGRATION_TESTS=true
39
  script: bin/integration-tests
40
  - dist: trusty
41
- php: 7.0
42
  env: WORDPRESS_VERSION=43 INTEGRATION_TESTS=true
43
  script: bin/integration-tests
44
  - dist: trusty
45
- php: 7.0
46
  env: WORDPRESS_VERSION=42 INTEGRATION_TESTS=true
47
  script: bin/integration-tests
48
  - dist: trusty
49
- php: 7.0
50
  env: WORDPRESS_VERSION=41 INTEGRATION_TESTS=true
51
  script: bin/integration-tests
52
  - dist: trusty
53
- php: 7.0
54
  env: WORDPRESS_VERSION=40 INTEGRATION_TESTS=true
55
  script: bin/integration-tests
56
  - dist: trusty
57
- php: 7.0
58
  env: WORDPRESS_VERSION=39 INTEGRATION_TESTS=true
59
  script: bin/integration-tests
60
  - dist: trusty
61
- php: 7.0
62
  env: WORDPRESS_VERSION=38 INTEGRATION_TESTS=true
63
  script: bin/integration-tests
64
  - dist: trusty
65
- php: 7.0
66
  env: WORDPRESS_VERSION=37 INTEGRATION_TESTS=true
67
  script: bin/integration-tests
68
  - dist: trusty
69
- php: 7.0
70
  env: WORDPRESS_VERSION=36 INTEGRATION_TESTS=true
71
  script: bin/integration-tests
72
  - dist: trusty
73
- php: 7.0
74
  env: WORDPRESS_VERSION=35 INTEGRATION_TESTS=true
75
  script: bin/integration-tests
76
  - dist: trusty
77
- php: 7.0
78
  env: WORDPRESS_VERSION=34 INTEGRATION_TESTS=true
79
  script: bin/integration-tests
80
  install:
6
  - 7.0
7
  - 7.1
8
  - 7.2
9
+ - 7.3
10
  matrix:
11
  include:
12
  - dist: precise
13
  php: 5.3
14
  script: bin/unit-tests
15
  - dist: trusty
16
+ php: 7.3
17
+ env: WORDPRESS_VERSION=51 INTEGRATION_TESTS=true
18
+ script: bin/integration-tests
19
+ - dist: trusty
20
+ php: 7.3
21
+ env: WORDPRESS_VERSION=50 INTEGRATION_TESTS=true
22
+ script: bin/integration-tests
23
  - dist: trusty
24
+ php: 7.3
25
  env: WORDPRESS_VERSION=49 INTEGRATION_TESTS=true
26
  script: bin/integration-tests
27
  - dist: trusty
28
+ php: 7.3
29
  env: WORDPRESS_VERSION=48 INTEGRATION_TESTS=true
30
  script: bin/integration-tests
31
  - dist: trusty
32
+ php: 7.3
33
  env: WORDPRESS_VERSION=47 INTEGRATION_TESTS=true
34
  script: bin/integration-tests
35
  - dist: trusty
36
+ php: 7.3
37
  env: WORDPRESS_VERSION=46 INTEGRATION_TESTS=true
38
  script: bin/integration-tests
39
  - dist: trusty
40
+ php: 7.3
41
  env: WORDPRESS_VERSION=45 INTEGRATION_TESTS=true
42
  script: bin/integration-tests
43
  - dist: trusty
44
+ php: 7.3
45
  env: WORDPRESS_VERSION=44 INTEGRATION_TESTS=true
46
  script: bin/integration-tests
47
  - dist: trusty
48
+ php: 7.3
49
  env: WORDPRESS_VERSION=43 INTEGRATION_TESTS=true
50
  script: bin/integration-tests
51
  - dist: trusty
52
+ php: 7.3
53
  env: WORDPRESS_VERSION=42 INTEGRATION_TESTS=true
54
  script: bin/integration-tests
55
  - dist: trusty
56
+ php: 7.3
57
  env: WORDPRESS_VERSION=41 INTEGRATION_TESTS=true
58
  script: bin/integration-tests
59
  - dist: trusty
60
+ php: 7.3
61
  env: WORDPRESS_VERSION=40 INTEGRATION_TESTS=true
62
  script: bin/integration-tests
63
  - dist: trusty
64
+ php: 7.3
65
  env: WORDPRESS_VERSION=39 INTEGRATION_TESTS=true
66
  script: bin/integration-tests
67
  - dist: trusty
68
+ php: 7.3
69
  env: WORDPRESS_VERSION=38 INTEGRATION_TESTS=true
70
  script: bin/integration-tests
71
  - dist: trusty
72
+ php: 7.3
73
  env: WORDPRESS_VERSION=37 INTEGRATION_TESTS=true
74
  script: bin/integration-tests
75
  - dist: trusty
76
+ php: 7.3
77
  env: WORDPRESS_VERSION=36 INTEGRATION_TESTS=true
78
  script: bin/integration-tests
79
  - dist: trusty
80
+ php: 7.3
81
  env: WORDPRESS_VERSION=35 INTEGRATION_TESTS=true
82
  script: bin/integration-tests
83
  - dist: trusty
84
+ php: 7.3
85
  env: WORDPRESS_VERSION=34 INTEGRATION_TESTS=true
86
  script: bin/integration-tests
87
  install:
NOTES DELETED
@@ -1,9 +0,0 @@
1
- Note the following when making changes to the plugin:
2
-
3
- 1. XML-RPC
4
-
5
- Wordpress can either be used via the web interface or through the official
6
- Wordpress apps for mobile devices. Wordpress uses XML-RPC internally to
7
- communicate between the app and the Wordpress admin. Make sure therefore
8
- that when developing functionality that is linked to functionality available
9
- in the mobile app that it also works over XML-RPC.
 
 
 
 
 
 
 
 
 
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: TinyPNG
3
  Donate link: https://tinypng.com/
4
  Tags: optimize, compress, shrink, resize, faster, fit, scale, improve, images, picture, pictures, photo, photos, image, tinypng, tinyjpg, jpeg, jpg, png, lossy, jpegmini, crunch, minify, smush, save, bandwidth, website, speed, performance, panda, george, wordpress app, SEO, lossy, wp compress, sitespeed, shortpixel, kraken, PageRank, cheetaho, s3
5
  Requires at least: 3.4
6
- Tested up to: 5.0
7
- Stable tag: 3.1.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -26,8 +26,8 @@ Make your website faster by optimizing your JPEG and PNG images. This plugin aut
26
  * Supports compression of animated PNG.
27
  * Select which thumbnail sizes of an image may be optimized.
28
  * Multisite support with a single API key.
29
- * WPML compatible.
30
- * WooCommerce compatible.
31
  * WP Retina 2x compatible.
32
  * WP Offload S3 compatible.
33
  * See your usage on the settings page and during bulk optimization.
@@ -47,12 +47,16 @@ Install this plugin and follow the instructions to set up your account. With a r
47
 
48
  = Optimizing all your images =
49
 
50
- You can optimize your existing JPEG and PNG images all at once by going to *Media > Bulk Optimization*. Clicking on the big button will start optimizing all unoptimized images in your media library.
51
 
52
  = Multisite support =
53
 
54
  The plugin is fully multisite compatible and you can set the API key for all sites by defining the key in your *wp-config.php* file. View the installation instructions for more information.
55
 
 
 
 
 
56
  = Contact us =
57
 
58
  Got questions or feedback? Let us know! Contact us at support@tinypng.com or find us on [Twitter @tinypng](https://twitter.com/tinypng).
@@ -129,6 +133,13 @@ A: Yes! After installing the plugin, go to *Media > Bulk Optimization*, and clic
129
  A: You can upgrade to a paid account by adding your *Payment details* on your [account dashboard](https://tinypng.com/dashboard/api). Additional compressions above 500 will then be charged at the end of each month as a one-time fee.
130
 
131
  == Changelog ==
 
 
 
 
 
 
 
132
  = 3.1.0 =
133
  * Remaining free compressions shown in settings page.
134
  * Easier way to upgrade a free account.
3
  Donate link: https://tinypng.com/
4
  Tags: optimize, compress, shrink, resize, faster, fit, scale, improve, images, picture, pictures, photo, photos, image, tinypng, tinyjpg, jpeg, jpg, png, lossy, jpegmini, crunch, minify, smush, save, bandwidth, website, speed, performance, panda, george, wordpress app, SEO, lossy, wp compress, sitespeed, shortpixel, kraken, PageRank, cheetaho, s3
5
  Requires at least: 3.4
6
+ Tested up to: 5.1
7
+ Stable tag: 3.2.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
26
  * Supports compression of animated PNG.
27
  * Select which thumbnail sizes of an image may be optimized.
28
  * Multisite support with a single API key.
29
+ * [WPML](https://wpml.org/documentation/plugins-compatibility/optimize-wordpress-images-multilingual-sites/) compatible.
30
+ * WooCommerce compatible (see below).
31
  * WP Retina 2x compatible.
32
  * WP Offload S3 compatible.
33
  * See your usage on the settings page and during bulk optimization.
47
 
48
  = Optimizing all your images =
49
 
50
+ You can *bulk optimize* your existing JPEG and PNG images all at once by going to *Media > Bulk Optimization*. Clicking on the big button will start optimizing all unoptimized images in your media library.
51
 
52
  = Multisite support =
53
 
54
  The plugin is fully multisite compatible and you can set the API key for all sites by defining the key in your *wp-config.php* file. View the installation instructions for more information.
55
 
56
+ = WooCommerce compatibility =
57
+
58
+ This plugin is *fully compatible with WooCommerce*. However, we have discovered that WooCommerce may be trying to regenerate image attachment metadata over and over again on each page visit. If you are using WooCommerce please follow the tips from the [support section](https://wordpress.org/support/topic/woocommerce-conflict-25/). This may make your WooCommerce shop even faster than it was before.
59
+
60
  = Contact us =
61
 
62
  Got questions or feedback? Let us know! Contact us at support@tinypng.com or find us on [Twitter @tinypng](https://twitter.com/tinypng).
133
  A: You can upgrade to a paid account by adding your *Payment details* on your [account dashboard](https://tinypng.com/dashboard/api). Additional compressions above 500 will then be charged at the end of each month as a one-time fee.
134
 
135
  == Changelog ==
136
+ = 3.2.0 =
137
+ * Support for WP Retina 2x Pro.
138
+ * More capability checks for extra security.
139
+ * Less resource intensive AJAX requests.
140
+ * Fixed CSS issues from Analytify plugin.
141
+ * Removed legacy Enhanced Media Library compatibility.
142
+
143
  = 3.1.0 =
144
  * Remaining free compressions shown in settings page.
145
  * Easier way to upgrade a free account.
src/class-tiny-image.php CHANGED
@@ -132,8 +132,12 @@ class Tiny_Image {
132
  foreach ( $tiny_metadata as $size => $meta ) {
133
  if ( ! isset( $this->sizes[ $size ] ) ) {
134
  if ( self::is_retina( $size ) && Tiny_Settings::wr2x_active() ) {
 
 
 
 
135
  $retina_path = wr2x_get_retina(
136
- $this->sizes[ rtrim( $size, '_wr2x' ) ]->filename
137
  );
138
  $this->sizes[ $size ] = new Tiny_Image_Size( $retina_path );
139
  } else {
@@ -466,6 +470,6 @@ class Tiny_Image {
466
  }
467
 
468
  public static function is_retina( $size ) {
469
- return strrpos( $size, 'wr2x' ) === strlen( $size ) - strlen( 'wr2x' );
470
  }
471
  }
132
  foreach ( $tiny_metadata as $size => $meta ) {
133
  if ( ! isset( $this->sizes[ $size ] ) ) {
134
  if ( self::is_retina( $size ) && Tiny_Settings::wr2x_active() ) {
135
+ $size_name = rtrim( $size, '_wr2x' );
136
+ if ( 'original' === $size_name ) {
137
+ $size_name = '0';
138
+ }
139
  $retina_path = wr2x_get_retina(
140
+ $this->sizes[ $size_name ]->filename
141
  );
142
  $this->sizes[ $size ] = new Tiny_Image_Size( $retina_path );
143
  } else {
470
  }
471
 
472
  public static function is_retina( $size ) {
473
+ return strrpos( $size, 'wr2x' ) === strlen( $size ) - strlen( 'wr2x' );
474
  }
475
  }
src/class-tiny-notices.php CHANGED
@@ -22,6 +22,16 @@ class Tiny_Notices extends Tiny_WP_Base {
22
  private $notices;
23
  private $dismissals;
24
 
 
 
 
 
 
 
 
 
 
 
25
  private static function get_option_key() {
26
  return self::get_prefixed_name( 'admin_notices' );
27
  }
@@ -30,10 +40,14 @@ class Tiny_Notices extends Tiny_WP_Base {
30
  return self::get_prefixed_name( 'admin_notice_dismissals' );
31
  }
32
 
33
- public function admin_init() {
34
  add_action( 'wp_ajax_tiny_dismiss_notice', $this->get_method( 'dismiss' ) );
 
 
 
35
  if ( current_user_can( 'manage_options' ) ) {
36
  $this->show_stored();
 
37
  }
38
  }
39
 
@@ -85,6 +99,11 @@ class Tiny_Notices extends Tiny_WP_Base {
85
  }
86
  }
87
 
 
 
 
 
 
88
  public function add( $name, $message ) {
89
  $this->load_notices();
90
  $this->notices[ $name ] = $message;
@@ -138,7 +157,115 @@ class Tiny_Notices extends Tiny_WP_Base {
138
  );
139
  }
140
 
141
- public function show_incompatible_plugins( $incompatible_plugins ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  $notice = '<div class="error notice tiny-notice incompatible-plugins">';
143
  $notice .= '<h3>';
144
  $notice .= esc_html__( 'Compress JPEG & PNG images', 'tiny-compress-images' );
22
  private $notices;
23
  private $dismissals;
24
 
25
+ protected static $incompatible_plugins = array(
26
+ 'CheetahO Image Optimizer' => 'cheetaho-image-optimizer/cheetaho.php',
27
+ 'EWWW Image Optimizer' => 'ewww-image-optimizer/ewww-image-optimizer.php',
28
+ 'Imagify' => 'imagify/imagify.php',
29
+ 'Kraken Image Optimizer' => 'kraken-image-optimizer/kraken.php',
30
+ 'ShortPixel Image Optimizer' => 'shortpixel-image-optimiser/wp-shortpixel.php',
31
+ 'WP Smush' => 'wp-smushit/wp-smush.php',
32
+ 'WP Smush Pro' => 'wp-smush-pro/wp-smush.php',
33
+ );
34
+
35
  private static function get_option_key() {
36
  return self::get_prefixed_name( 'admin_notices' );
37
  }
40
  return self::get_prefixed_name( 'admin_notice_dismissals' );
41
  }
42
 
43
+ public function ajax_init() {
44
  add_action( 'wp_ajax_tiny_dismiss_notice', $this->get_method( 'dismiss' ) );
45
+ }
46
+
47
+ public function admin_init() {
48
  if ( current_user_can( 'manage_options' ) ) {
49
  $this->show_stored();
50
+ $this->show_notices();
51
  }
52
  }
53
 
99
  }
100
  }
101
 
102
+ public function show_notices() {
103
+ $this->incompatible_plugins_notice();
104
+ $this->outdated_platform_notice();
105
+ }
106
+
107
  public function add( $name, $message ) {
108
  $this->load_notices();
109
  $this->notices[ $name ] = $message;
157
  );
158
  }
159
 
160
+ public function api_key_missing_notice() {
161
+ $notice_class = 'error';
162
+ $notice = esc_html__(
163
+ 'Please register or provide an API key to start compressing images.',
164
+ 'tiny-compress-images'
165
+ );
166
+ $link = sprintf(
167
+ '<a href="options-general.php?page=tinify">%s</a>', $notice
168
+ );
169
+ $this->show( 'setting', $link, $notice_class, false );
170
+ }
171
+
172
+ public function get_api_key_pending_notice() {
173
+ $notice_class = 'notice-warning';
174
+ $notice = esc_html__(
175
+ 'Please activate your account to start compressing images.',
176
+ 'tiny-compress-images'
177
+ );
178
+ $link = sprintf(
179
+ '<a href="options-general.php?page=tinify">%s</a>', $notice
180
+ );
181
+ $this->show( 'setting', $link, $notice_class, false );
182
+ }
183
+
184
+ public function add_limit_reached_notice( $email ) {
185
+ $encoded_email = str_replace( '%20', '%2B', rawurlencode( $email ) );
186
+ $url = 'https://tinypng.com/dashboard/api?type=upgrade&mail=' . $encoded_email;
187
+ $link = '<a href="' . $url . '" target="_blank">' .
188
+ esc_html__( 'TinyPNG API account', 'tiny-compress-images' ) . '</a>';
189
+
190
+ $this->add('limit-reached',
191
+ esc_html__(
192
+ 'You have reached your free limit this month.',
193
+ 'tiny-compress-images'
194
+ ) . ' ' .
195
+ sprintf(
196
+ /* translators: %s: link saying TinyPNG API account */
197
+ esc_html__(
198
+ 'Upgrade your %s if you like to compress more images.',
199
+ 'tiny-compress-images'
200
+ ),
201
+ $link
202
+ )
203
+ );
204
+ }
205
+
206
+ public function outdated_platform_notice() {
207
+ if ( ! Tiny_PHP::client_supported() ) {
208
+ if ( ! Tiny_PHP::has_fully_supported_php() ) {
209
+ $details = 'PHP ' . PHP_VERSION;
210
+ if ( Tiny_PHP::curl_available() ) {
211
+ $curlinfo = curl_version();
212
+ $details .= ' ' . sprintf(
213
+ /* translators: %s: curl version */
214
+ esc_html__( 'with curl %s', 'tiny-compress-images' ), $curlinfo['version']
215
+ );
216
+ } else {
217
+ $details .= ' ' . esc_html__( 'without curl', 'tiny-compress-images' );
218
+ }
219
+ if ( Tiny_PHP::curl_exec_disabled() ) {
220
+ $details .= ' ' .
221
+ esc_html__( 'and curl_exec disabled', 'tiny-compress-images' );
222
+ }
223
+ $message = sprintf(
224
+ /* translators: %s: details of outdated platform */
225
+ esc_html__(
226
+ 'You are using an outdated platform (%s).',
227
+ 'tiny-compress-images'
228
+ ), $details
229
+ );
230
+ } elseif ( ! Tiny_PHP::curl_available() ) {
231
+ $message = esc_html__(
232
+ 'We noticed that cURL is not available. For the best experience we recommend to make sure cURL is available.', // WPCS: Needed for proper translation.
233
+ 'tiny-compress-images'
234
+ );
235
+ } elseif ( Tiny_PHP::curl_exec_disabled() ) {
236
+ $message = esc_html__(
237
+ 'We noticed that curl_exec is disabled in your PHP configuration. Please update this setting for the best experience.', // WPCS: Needed for proper translation.
238
+ 'tiny-compress-images'
239
+ );
240
+ }
241
+ $this->show( 'deprecated', $message, 'notice-warning', false );
242
+ } // End if().
243
+ }
244
+
245
+ public function show_offload_s3_notice() {
246
+ $message = esc_html__(
247
+ 'Removing files from the server is incompatible with background compressions. Images will still be automatically compressed, but no longer in the background.', // WPCS: Needed for proper translation.
248
+ 'tiny-compress-images'
249
+ );
250
+ $this->show( 'offload-s3', $message, 'notice-error', false );
251
+ }
252
+
253
+ public function old_offload_s3_version_notice() {
254
+ $message = esc_html__(
255
+ 'Background compressions are not compatible with the version of WP Offload S3 you have installed. Please update to version 0.7.2 at least.', // WPCS: Needed for proper translation.
256
+ 'tiny-compress-images'
257
+ );
258
+ $this->show( 'old-offload-s3-version', $message, 'notice-error', false );
259
+ }
260
+
261
+ public function incompatible_plugins_notice() {
262
+ $incompatible_plugins = array_filter( self::$incompatible_plugins, 'is_plugin_active' );
263
+ if ( count( $incompatible_plugins ) > 0 ) {
264
+ $this->show_incompatible_plugins( $incompatible_plugins );
265
+ }
266
+ }
267
+
268
+ private function show_incompatible_plugins( $incompatible_plugins ) {
269
  $notice = '<div class="error notice tiny-notice incompatible-plugins">';
270
  $notice .= '<h3>';
271
  $notice .= esc_html__( 'Compress JPEG & PNG images', 'tiny-compress-images' );
src/class-tiny-plugin.php CHANGED
@@ -18,7 +18,7 @@
18
  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
  */
20
  class Tiny_Plugin extends Tiny_WP_Base {
21
- const VERSION = '3.1.0';
22
  const MEDIA_COLUMN = self::NAME;
23
  const DATETIME_FORMAT = 'Y-m-d G:i:s';
24
 
@@ -39,7 +39,6 @@ class Tiny_Plugin extends Tiny_WP_Base {
39
 
40
  public function __construct() {
41
  parent::__construct();
42
-
43
  $this->settings = new Tiny_Settings();
44
  }
45
 
@@ -61,15 +60,54 @@ class Tiny_Plugin extends Tiny_WP_Base {
61
  10, 2
62
  );
63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  /* When touching any functionality linked to image compressions when
65
- uploading images make sure it also works with XML-RPC. See NOTES. */
66
  add_filter( 'wp_ajax_nopriv_tiny_rpc',
67
  $this->get_method( 'process_rpc_request' )
68
  );
69
 
70
- load_plugin_textdomain( self::NAME, false,
71
- dirname( plugin_basename( __FILE__ ) ) . '/languages'
72
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  }
74
 
75
  public function admin_init() {
@@ -102,26 +140,6 @@ class Tiny_Plugin extends Tiny_WP_Base {
102
  $this->get_method( 'show_media_info' )
103
  );
104
 
105
- add_filter( 'wp_ajax_tiny_async_optimize_upload_new_media',
106
- $this->get_method( 'compress_on_upload' )
107
- );
108
-
109
- add_action( 'wp_ajax_tiny_compress_image_from_library',
110
- $this->get_method( 'compress_image_from_library' )
111
- );
112
-
113
- add_action( 'wp_ajax_tiny_compress_image_for_bulk',
114
- $this->get_method( 'compress_image_for_bulk' )
115
- );
116
-
117
- add_action( 'wp_ajax_tiny_get_optimization_statistics',
118
- $this->get_method( 'ajax_optimization_statistics' )
119
- );
120
-
121
- add_action( 'wp_ajax_tiny_get_compression_status',
122
- $this->get_method( 'ajax_compression_status' )
123
- );
124
-
125
  $plugin = plugin_basename(
126
  dirname( dirname( __FILE__ ) ) . '/tiny-compress-images.php'
127
  );
@@ -130,16 +148,6 @@ class Tiny_Plugin extends Tiny_WP_Base {
130
  $this->get_method( 'add_plugin_links' )
131
  );
132
 
133
- add_action( 'wr2x_retina_file_added',
134
- $this->get_method( 'compress_retina_image' ),
135
- 10, 3
136
- );
137
-
138
- add_action( 'wr2x_retina_file_removed',
139
- $this->get_method( 'remove_retina_image' ),
140
- 10, 2
141
- );
142
-
143
  $this->tiny_compatibility();
144
 
145
  add_thickbox();
@@ -175,11 +183,14 @@ class Tiny_Plugin extends Tiny_WP_Base {
175
  }
176
  }
177
 
 
 
 
 
 
178
  public function compress_retina_image( $attachment_id, $path, $size_name ) {
179
- if ( $this->settings->compress_wr2x_images() ) {
180
- $tiny_image = new Tiny_Image( $this->settings, $attachment_id );
181
- $tiny_image->compress_retina( $size_name . '_wr2x', $path );
182
- }
183
  }
184
 
185
  public function remove_retina_image( $attachment_id, $path ) {
@@ -194,7 +205,7 @@ class Tiny_Plugin extends Tiny_WP_Base {
194
  );
195
 
196
  wp_enqueue_style( self::NAME . '_chart',
197
- plugins_url( '/css/chart.css', __FILE__ ),
198
  array(), self::version()
199
  );
200
 
@@ -238,7 +249,7 @@ class Tiny_Plugin extends Tiny_WP_Base {
238
  );
239
 
240
  wp_enqueue_style( self::NAME . '_chart',
241
- plugins_url( '/css/chart.css', __FILE__ ),
242
  array(), self::version()
243
  );
244
 
@@ -354,16 +365,18 @@ class Tiny_Plugin extends Tiny_WP_Base {
354
  }
355
 
356
  public function compress_on_upload() {
357
- $attachment_id = intval( $_POST['attachment_id'] );
358
- $metadata = $_POST['metadata'];
359
- if ( is_array( $metadata ) ) {
360
- $tiny_image = new Tiny_Image( $this->settings, $attachment_id, $metadata );
361
- $result = $tiny_image->compress( $this->settings );
362
- // The wp_update_attachment_metadata call is thrown because the
363
- // dimensions of the original image can change. This will then
364
- // trigger other plugins and can result in unexpected behaviour and
365
- // further changes to the image. This may require another approach.
366
- wp_update_attachment_metadata( $attachment_id, $tiny_image->get_wp_metadata() );
 
 
367
  }
368
  exit();
369
  }
@@ -497,11 +510,10 @@ class Tiny_Plugin extends Tiny_WP_Base {
497
  }
498
 
499
  public function ajax_optimization_statistics() {
500
- if ( ! $this->check_ajax_referer() ) {
501
- exit();
 
502
  }
503
- $stats = Tiny_Bulk_Optimization::get_optimization_statistics( $this->settings );
504
- echo json_encode( $stats );
505
  exit();
506
  }
507
 
@@ -509,7 +521,9 @@ class Tiny_Plugin extends Tiny_WP_Base {
509
  if ( ! $this->check_ajax_referer() ) {
510
  exit();
511
  }
512
-
 
 
513
  if ( empty( $_POST['id'] ) ) {
514
  $message = esc_html__(
515
  'Not a valid media file.',
@@ -625,7 +639,7 @@ class Tiny_Plugin extends Tiny_WP_Base {
625
 
626
  public function add_dashboard_widget() {
627
  wp_enqueue_style( self::NAME . '_chart',
628
- plugins_url( '/css/chart.css', __FILE__ ),
629
  array(), self::version()
630
  );
631
 
18
  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
  */
20
  class Tiny_Plugin extends Tiny_WP_Base {
21
+ const VERSION = '3.2.0';
22
  const MEDIA_COLUMN = self::NAME;
23
  const DATETIME_FORMAT = 'Y-m-d G:i:s';
24
 
39
 
40
  public function __construct() {
41
  parent::__construct();
 
42
  $this->settings = new Tiny_Settings();
43
  }
44
 
60
  10, 2
61
  );
62
 
63
+ load_plugin_textdomain( self::NAME, false,
64
+ dirname( plugin_basename( __FILE__ ) ) . '/languages'
65
+ );
66
+ }
67
+
68
+ public function ajax_init() {
69
+ add_filter( 'wp_ajax_tiny_async_optimize_upload_new_media',
70
+ $this->get_method( 'compress_on_upload' )
71
+ );
72
+
73
+ add_action( 'wp_ajax_tiny_compress_image_from_library',
74
+ $this->get_method( 'compress_image_from_library' )
75
+ );
76
+
77
+ add_action( 'wp_ajax_tiny_compress_image_for_bulk',
78
+ $this->get_method( 'compress_image_for_bulk' )
79
+ );
80
+
81
+ add_action( 'wp_ajax_tiny_get_optimization_statistics',
82
+ $this->get_method( 'ajax_optimization_statistics' )
83
+ );
84
+
85
+ add_action( 'wp_ajax_tiny_get_compression_status',
86
+ $this->get_method( 'ajax_compression_status' )
87
+ );
88
+
89
  /* When touching any functionality linked to image compressions when
90
+ uploading images make sure it also works with XML-RPC. See README. */
91
  add_filter( 'wp_ajax_nopriv_tiny_rpc',
92
  $this->get_method( 'process_rpc_request' )
93
  );
94
 
95
+ if ( $this->settings->compress_wr2x_images() ) {
96
+ add_action( 'wr2x_upload_retina',
97
+ $this->get_method( 'compress_original_retina_image' ),
98
+ 10, 2
99
+ );
100
+
101
+ add_action( 'wr2x_retina_file_added',
102
+ $this->get_method( 'compress_retina_image' ),
103
+ 10, 3
104
+ );
105
+
106
+ add_action( 'wr2x_retina_file_removed',
107
+ $this->get_method( 'remove_retina_image' ),
108
+ 10, 2
109
+ );
110
+ }
111
  }
112
 
113
  public function admin_init() {
140
  $this->get_method( 'show_media_info' )
141
  );
142
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  $plugin = plugin_basename(
144
  dirname( dirname( __FILE__ ) ) . '/tiny-compress-images.php'
145
  );
148
  $this->get_method( 'add_plugin_links' )
149
  );
150
 
 
 
 
 
 
 
 
 
 
 
151
  $this->tiny_compatibility();
152
 
153
  add_thickbox();
183
  }
184
  }
185
 
186
+ public function compress_original_retina_image( $attachment_id, $path ) {
187
+ $tiny_image = new Tiny_Image( $this->settings, $attachment_id );
188
+ $tiny_image->compress_retina( 'original_wr2x', $path );
189
+ }
190
+
191
  public function compress_retina_image( $attachment_id, $path, $size_name ) {
192
+ $tiny_image = new Tiny_Image( $this->settings, $attachment_id );
193
+ $tiny_image->compress_retina( $size_name . '_wr2x', $path );
 
 
194
  }
195
 
196
  public function remove_retina_image( $attachment_id, $path ) {
205
  );
206
 
207
  wp_enqueue_style( self::NAME . '_chart',
208
+ plugins_url( '/css/optimization-chart.css', __FILE__ ),
209
  array(), self::version()
210
  );
211
 
249
  );
250
 
251
  wp_enqueue_style( self::NAME . '_chart',
252
+ plugins_url( '/css/optimization-chart.css', __FILE__ ),
253
  array(), self::version()
254
  );
255
 
365
  }
366
 
367
  public function compress_on_upload() {
368
+ if ( current_user_can( 'upload_files' ) ) {
369
+ $attachment_id = intval( $_POST['attachment_id'] );
370
+ $metadata = $_POST['metadata'];
371
+ if ( is_array( $metadata ) ) {
372
+ $tiny_image = new Tiny_Image( $this->settings, $attachment_id, $metadata );
373
+ $result = $tiny_image->compress( $this->settings );
374
+ // The wp_update_attachment_metadata call is thrown because the
375
+ // dimensions of the original image can change. This will then
376
+ // trigger other plugins and can result in unexpected behaviour and
377
+ // further changes to the image. This may require another approach.
378
+ wp_update_attachment_metadata( $attachment_id, $tiny_image->get_wp_metadata() );
379
+ }
380
  }
381
  exit();
382
  }
510
  }
511
 
512
  public function ajax_optimization_statistics() {
513
+ if ( $this->check_ajax_referer() && current_user_can( 'upload_files' ) ) {
514
+ $stats = Tiny_Bulk_Optimization::get_optimization_statistics( $this->settings );
515
+ echo json_encode( $stats );
516
  }
 
 
517
  exit();
518
  }
519
 
521
  if ( ! $this->check_ajax_referer() ) {
522
  exit();
523
  }
524
+ if ( ! current_user_can( 'upload_files' ) ) {
525
+ exit();
526
+ }
527
  if ( empty( $_POST['id'] ) ) {
528
  $message = esc_html__(
529
  'Not a valid media file.',
639
 
640
  public function add_dashboard_widget() {
641
  wp_enqueue_style( self::NAME . '_chart',
642
+ plugins_url( '/css/optimization-chart.css', __FILE__ ),
643
  array(), self::version()
644
  );
645
 
src/class-tiny-settings.php CHANGED
@@ -25,22 +25,11 @@ class Tiny_Settings extends Tiny_WP_Base {
25
  private $compressor;
26
  private $notices;
27
 
28
- protected static $incompatible_plugins = array(
29
- 'CheetahO Image Optimizer' => 'cheetaho-image-optimizer/cheetaho.php',
30
- 'EWWW Image Optimizer' => 'ewww-image-optimizer/ewww-image-optimizer.php',
31
- 'Imagify' => 'imagify/imagify.php',
32
- 'Kraken Image Optimizer' => 'kraken-image-optimizer/kraken.php',
33
- 'ShortPixel Image Optimizer' => 'shortpixel-image-optimiser/wp-shortpixel.php',
34
- 'WP Smush' => 'wp-smushit/wp-smush.php',
35
- 'WP Smush Pro' => 'wp-smush-pro/wp-smush.php',
36
- );
37
-
38
  protected static $offload_s3_plugin = 'amazon-s3-and-cloudfront/wordpress-s3.php';
39
 
40
  public function __construct() {
41
  parent::__construct();
42
  $this->notices = new Tiny_Notices();
43
- add_action( 'admin_menu', array( $this, 'add_menu' ) );
44
  }
45
 
46
  private function init_compressor() {
@@ -61,21 +50,34 @@ class Tiny_Settings extends Tiny_WP_Base {
61
  }
62
  }
63
 
64
- public function add_menu() {
65
- add_options_page(
66
- __( 'Compress JPEG & PNG images', 'tiny-compress-images' ),
67
- esc_html__( 'Compress JPEG & PNG images', 'tiny-compress-images' ),
68
- 'manage_options',
69
- 'tinify',
70
- array( $this, 'add_options_to_page' )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  );
72
  }
73
 
74
  public function admin_init() {
75
- if ( current_user_can( 'manage_options' ) ) {
76
- $this->render_notices();
77
- }
78
-
79
  try {
80
  $this->init_compressor();
81
  } catch ( Tiny_Exception $e ) {
@@ -86,11 +88,10 @@ class Tiny_Settings extends Tiny_WP_Base {
86
  );
87
  }
88
 
89
- /* Create link to new settings page from media settings page. */
90
- add_settings_section( 'section_end', '',
91
- $this->get_method( 'render_settings_link' ),
92
- 'media'
93
- );
94
 
95
  $field = self::get_prefixed_name( 'api_key' );
96
  register_setting( 'tinify', $field );
@@ -109,25 +110,21 @@ class Tiny_Settings extends Tiny_WP_Base {
109
 
110
  $field = self::get_prefixed_name( 'preserve_data' );
111
  register_setting( 'tinify', $field );
 
112
 
113
- add_action(
114
- 'wp_ajax_tiny_image_sizes_notice',
115
- $this->get_method( 'image_sizes_notice' )
116
- );
117
-
118
- add_action(
119
- 'wp_ajax_tiny_account_status',
120
- $this->get_method( 'account_status' )
121
- );
122
-
123
- add_action(
124
- 'wp_ajax_tiny_settings_create_api_key',
125
- $this->get_method( 'create_api_key' )
126
  );
127
 
128
- add_action(
129
- 'wp_ajax_tiny_settings_update_api_key',
130
- $this->get_method( 'update_api_key' )
 
 
 
131
  );
132
  }
133
 
@@ -136,16 +133,20 @@ class Tiny_Settings extends Tiny_WP_Base {
136
  }
137
 
138
  public function image_sizes_notice() {
139
- $this->render_image_sizes_notice(
140
- $_GET['image_sizes_selected'],
141
- isset( $_GET['resize_original'] ),
142
- isset( $_GET['compress_wr2x'] )
143
- );
 
 
144
  exit();
145
  }
146
 
147
  public function account_status() {
148
- $this->render_account_status();
 
 
149
  exit();
150
  }
151
 
@@ -401,83 +402,15 @@ class Tiny_Settings extends Tiny_WP_Base {
401
  return sizeof( $options ) >= 2 ? $options : false;
402
  }
403
 
404
- public function render_notices() {
405
- $this->render_setup_incomplete_notice();
406
- $this->render_outdated_platform_notice();
407
- $this->render_incompatible_plugins_notice();
408
- $this->render_offload_s3_notices();
409
- }
410
-
411
- public function render_setup_incomplete_notice() {
412
  if ( ! $this->get_api_key() ) {
413
- $notice_class = 'error';
414
- $notice = esc_html__(
415
- 'Please register or provide an API key to start compressing images.',
416
- 'tiny-compress-images'
417
- );
418
  } elseif ( $this->get_api_key_pending() ) {
419
- $notice_class = 'notice-warning';
420
- $notice = esc_html__(
421
- 'Please activate your account to start compressing images.',
422
- 'tiny-compress-images'
423
- );
424
- }
425
-
426
- if ( isset( $notice ) && $notice ) {
427
- $link = sprintf(
428
- '<a href="options-general.php?page=tinify">%s</a>', $notice
429
- );
430
- $this->notices->show( 'setting', $link, $notice_class, false );
431
- }
432
- }
433
-
434
- public function render_outdated_platform_notice() {
435
- if ( ! Tiny_PHP::client_supported() ) {
436
- if ( ! Tiny_PHP::has_fully_supported_php() ) {
437
- $details = 'PHP ' . PHP_VERSION;
438
- if ( Tiny_PHP::curl_available() ) {
439
- $curlinfo = curl_version();
440
- $details .= ' ' . sprintf(
441
- /* translators: %s: curl version */
442
- esc_html__( 'with curl %s', 'tiny-compress-images' ), $curlinfo['version']
443
- );
444
- } else {
445
- $details .= ' ' . esc_html__( 'without curl', 'tiny-compress-images' );
446
- }
447
- if ( Tiny_PHP::curl_exec_disabled() ) {
448
- $details .= ' ' .
449
- esc_html__( 'and curl_exec disabled', 'tiny-compress-images' );
450
- }
451
- $message = sprintf(
452
- /* translators: %s: details of outdated platform */
453
- esc_html__(
454
- 'You are using an outdated platform (%s).',
455
- 'tiny-compress-images'
456
- ), $details
457
- );
458
- } elseif ( ! Tiny_PHP::curl_available() ) {
459
- $message = esc_html__(
460
- 'We noticed that cURL is not available. For the best experience we recommend to make sure cURL is available.', // WPCS: Needed for proper translation.
461
- 'tiny-compress-images'
462
- );
463
- } elseif ( Tiny_PHP::curl_exec_disabled() ) {
464
- $message = esc_html__(
465
- 'We noticed that curl_exec is disabled in your PHP configuration. Please update this setting for the best experience.', // WPCS: Needed for proper translation.
466
- 'tiny-compress-images'
467
- );
468
- }
469
- $this->notices->show( 'deprecated', $message, 'notice-warning', false );
470
- } // End if().
471
- }
472
-
473
- public function render_incompatible_plugins_notice() {
474
- $incompatible_plugins = array_filter( self::$incompatible_plugins, 'is_plugin_active' );
475
- if ( count( $incompatible_plugins ) > 0 ) {
476
- $this->notices->show_incompatible_plugins( $incompatible_plugins );
477
  }
478
  }
479
 
480
- public function render_settings_link() {
481
  echo '<div class="tinify-settings"><h3>';
482
  esc_html_e( 'Compress JPEG & PNG images', 'tiny-compress-images' );
483
  echo '</h3>';
@@ -500,25 +433,16 @@ class Tiny_Settings extends Tiny_WP_Base {
500
  echo '</div>';
501
  }
502
 
503
- public function render_offload_s3_notices() {
504
  if ( $this->remove_local_files_setting_enabled() &&
505
  'background' === $this->get_compression_timing() ) {
506
- $message = esc_html__(
507
- 'Removing files from the server is incompatible with background compressions. Images will still be automatically compressed, but no longer in the background.', // WPCS: Needed for proper translation.
508
- 'tiny-compress-images'
509
- );
510
- $this->notices->show( 'offload-s3', $message, 'notice-error', false );
511
  update_option( self::get_prefixed_name( 'compression_timing' ), 'auto' );
 
512
  }
513
-
514
  if ( $this->old_offload_s3_version_installed() &&
515
  'background' === $this->get_compression_timing() ) {
516
- $message = esc_html__(
517
- 'Background compressions are not compatible with the version of WP Offload S3 you have installed. Please update to version 0.7.2 at least.', // WPCS: Needed for proper translation.
518
- 'tiny-compress-images'
519
- );
520
- $this->notices->show( 'old-offload-s3-version', $message, 'notice-error', false );
521
  update_option( self::get_prefixed_name( 'compression_timing' ), 'auto' );
 
522
  }
523
  }
524
 
@@ -604,15 +528,15 @@ class Tiny_Settings extends Tiny_WP_Base {
604
  self::get_prefixed_name( 'sizes[' . self::DUMMY_SIZE . ']' ) . '" value="on"/>';
605
 
606
  foreach ( $this->get_sizes() as $size => $option ) {
607
- $this->render_size_checkbox( $size, $option );
608
  }
609
  if ( self::wr2x_active() ) {
610
- $this->render_size_checkbox( 'wr2x', $this->get_wr2x_option() );
611
  }
612
  echo '<br>';
613
  echo '<div id="tiny-image-sizes-notice">';
614
 
615
- $this->render_image_sizes_notice(
616
  count( self::get_active_tinify_sizes() ),
617
  self::get_resize_enabled(),
618
  self::compress_wr2x_images()
@@ -621,7 +545,7 @@ class Tiny_Settings extends Tiny_WP_Base {
621
  echo '</div>';
622
  }
623
 
624
- private function render_size_checkbox( $size, $option ) {
625
  $id = self::get_prefixed_name( "sizes_$size" );
626
  $name = self::get_prefixed_name( 'sizes[' . $size . ']' );
627
  $checked = ( $option['tinify'] ? ' checked="checked"' : '' );
@@ -654,7 +578,7 @@ class Tiny_Settings extends Tiny_WP_Base {
654
  echo '</p>';
655
  }
656
 
657
- public function render_image_sizes_notice(
658
  $active_sizes_count, $resize_original_enabled, $compress_wr2x ) {
659
  echo '<p>';
660
  esc_html_e(
@@ -885,25 +809,7 @@ class Tiny_Settings extends Tiny_WP_Base {
885
  update_option( $field, $email_address );
886
  }
887
  if ( $compressor->limit_reached() ) {
888
- $encoded_email = str_replace( '%20', '%2B', rawurlencode( $email_address ) );
889
- $url = 'https://tinypng.com/dashboard/api?type=upgrade&mail=' . $encoded_email;
890
- $link = '<a href="' . $url . '" target="_blank">' .
891
- esc_html__( 'TinyPNG API account', 'tiny-compress-images' ) . '</a>';
892
-
893
- $this->notices->add('limit-reached',
894
- esc_html__(
895
- 'You have reached your free limit this month.',
896
- 'tiny-compress-images'
897
- ) . ' ' .
898
- sprintf(
899
- /* translators: %s: link saying TinyPNG API account */
900
- esc_html__(
901
- 'Upgrade your %s if you like to compress more images.',
902
- 'tiny-compress-images'
903
- ),
904
- $link
905
- )
906
- );
907
  } else {
908
  $this->notices->remove( 'limit-reached' );
909
  }
@@ -930,7 +836,7 @@ class Tiny_Settings extends Tiny_WP_Base {
930
  $status->ok = true;
931
  $status->pending = true;
932
  $status->message = (
933
- 'An email has been sent with a link to activate your account'
934
  );
935
  }
936
  }
@@ -954,7 +860,12 @@ class Tiny_Settings extends Tiny_WP_Base {
954
 
955
  public function create_api_key() {
956
  $compressor = $this->get_compressor();
957
- if ( $compressor->can_create_key() ) {
 
 
 
 
 
958
  if ( ! isset( $_POST['name'] ) || ! $_POST['name'] ) {
959
  $status = (object) array(
960
  'ok' => false,
@@ -1015,7 +926,12 @@ class Tiny_Settings extends Tiny_WP_Base {
1015
 
1016
  public function update_api_key() {
1017
  $key = $_POST['key'];
1018
- if ( empty( $key ) ) {
 
 
 
 
 
1019
  /* Always save if key is blank, so the key can be deleted. */
1020
  $status = (object) array(
1021
  'ok' => true,
@@ -1033,7 +949,7 @@ class Tiny_Settings extends Tiny_WP_Base {
1033
  }
1034
 
1035
  public static function wr2x_active() {
1036
- return is_plugin_active( 'wp-retina-2x/wp-retina-2x.php' );
1037
  }
1038
 
1039
  public function get_wr2x_option() {
25
  private $compressor;
26
  private $notices;
27
 
 
 
 
 
 
 
 
 
 
 
28
  protected static $offload_s3_plugin = 'amazon-s3-and-cloudfront/wordpress-s3.php';
29
 
30
  public function __construct() {
31
  parent::__construct();
32
  $this->notices = new Tiny_Notices();
 
33
  }
34
 
35
  private function init_compressor() {
50
  }
51
  }
52
 
53
+ public function ajax_init() {
54
+ try {
55
+ $this->init_compressor();
56
+ } catch ( Tiny_Exception $e ) {
57
+ }
58
+
59
+ add_action(
60
+ 'wp_ajax_tiny_image_sizes_notice',
61
+ $this->get_method( 'image_sizes_notice' )
62
+ );
63
+
64
+ add_action(
65
+ 'wp_ajax_tiny_account_status',
66
+ $this->get_method( 'account_status' )
67
+ );
68
+
69
+ add_action(
70
+ 'wp_ajax_tiny_settings_create_api_key',
71
+ $this->get_method( 'create_api_key' )
72
+ );
73
+
74
+ add_action(
75
+ 'wp_ajax_tiny_settings_update_api_key',
76
+ $this->get_method( 'update_api_key' )
77
  );
78
  }
79
 
80
  public function admin_init() {
 
 
 
 
81
  try {
82
  $this->init_compressor();
83
  } catch ( Tiny_Exception $e ) {
88
  );
89
  }
90
 
91
+ if ( current_user_can( 'manage_options' ) ) {
92
+ $this->setup_incomplete_checks();
93
+ $this->offload_s3_checks();
94
+ }
 
95
 
96
  $field = self::get_prefixed_name( 'api_key' );
97
  register_setting( 'tinify', $field );
110
 
111
  $field = self::get_prefixed_name( 'preserve_data' );
112
  register_setting( 'tinify', $field );
113
+ }
114
 
115
+ public function admin_menu() {
116
+ /* Create link to new settings page from media settings page. */
117
+ add_settings_section( 'section_end', '',
118
+ $this->get_method( 'render_settings_moved' ),
119
+ 'media'
 
 
 
 
 
 
 
 
120
  );
121
 
122
+ add_options_page(
123
+ __( 'Compress JPEG & PNG images', 'tiny-compress-images' ),
124
+ esc_html__( 'Compress JPEG & PNG images', 'tiny-compress-images' ),
125
+ 'manage_options',
126
+ 'tinify',
127
+ array( $this, 'add_options_to_page' )
128
  );
129
  }
130
 
133
  }
134
 
135
  public function image_sizes_notice() {
136
+ if ( current_user_can( 'manage_options' ) ) {
137
+ $this->render_size_checkboxes_description(
138
+ $_GET['image_sizes_selected'],
139
+ isset( $_GET['resize_original'] ),
140
+ isset( $_GET['compress_wr2x'] )
141
+ );
142
+ }
143
  exit();
144
  }
145
 
146
  public function account_status() {
147
+ if ( current_user_can( 'manage_options' ) ) {
148
+ $this->render_account_status();
149
+ }
150
  exit();
151
  }
152
 
402
  return sizeof( $options ) >= 2 ? $options : false;
403
  }
404
 
405
+ private function setup_incomplete_checks() {
 
 
 
 
 
 
 
406
  if ( ! $this->get_api_key() ) {
407
+ $this->notices->api_key_missing_notice();
 
 
 
 
408
  } elseif ( $this->get_api_key_pending() ) {
409
+ $this->notices->get_api_key_pending_notice();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
410
  }
411
  }
412
 
413
+ public function render_settings_moved() {
414
  echo '<div class="tinify-settings"><h3>';
415
  esc_html_e( 'Compress JPEG & PNG images', 'tiny-compress-images' );
416
  echo '</h3>';
433
  echo '</div>';
434
  }
435
 
436
+ private function offload_s3_checks() {
437
  if ( $this->remove_local_files_setting_enabled() &&
438
  'background' === $this->get_compression_timing() ) {
 
 
 
 
 
439
  update_option( self::get_prefixed_name( 'compression_timing' ), 'auto' );
440
+ $this->notices->show_offload_s3_notice();
441
  }
 
442
  if ( $this->old_offload_s3_version_installed() &&
443
  'background' === $this->get_compression_timing() ) {
 
 
 
 
 
444
  update_option( self::get_prefixed_name( 'compression_timing' ), 'auto' );
445
+ $this->notices->old_offload_s3_version_notice();
446
  }
447
  }
448
 
528
  self::get_prefixed_name( 'sizes[' . self::DUMMY_SIZE . ']' ) . '" value="on"/>';
529
 
530
  foreach ( $this->get_sizes() as $size => $option ) {
531
+ $this->render_size_checkboxes( $size, $option );
532
  }
533
  if ( self::wr2x_active() ) {
534
+ $this->render_size_checkboxes( 'wr2x', $this->get_wr2x_option() );
535
  }
536
  echo '<br>';
537
  echo '<div id="tiny-image-sizes-notice">';
538
 
539
+ $this->render_size_checkboxes_description(
540
  count( self::get_active_tinify_sizes() ),
541
  self::get_resize_enabled(),
542
  self::compress_wr2x_images()
545
  echo '</div>';
546
  }
547
 
548
+ private function render_size_checkboxes( $size, $option ) {
549
  $id = self::get_prefixed_name( "sizes_$size" );
550
  $name = self::get_prefixed_name( 'sizes[' . $size . ']' );
551
  $checked = ( $option['tinify'] ? ' checked="checked"' : '' );
578
  echo '</p>';
579
  }
580
 
581
+ public function render_size_checkboxes_description(
582
  $active_sizes_count, $resize_original_enabled, $compress_wr2x ) {
583
  echo '<p>';
584
  esc_html_e(
809
  update_option( $field, $email_address );
810
  }
811
  if ( $compressor->limit_reached() ) {
812
+ $this->notices->add_limit_reached_notice( $email_address );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
813
  } else {
814
  $this->notices->remove( 'limit-reached' );
815
  }
836
  $status->ok = true;
837
  $status->pending = true;
838
  $status->message = (
839
+ 'An email has been sent to activate your account'
840
  );
841
  }
842
  }
860
 
861
  public function create_api_key() {
862
  $compressor = $this->get_compressor();
863
+ if ( ! current_user_can( 'manage_options' ) ) {
864
+ $status = (object) array(
865
+ 'ok' => false,
866
+ 'message' => 'This feature requires certain user capabilities',
867
+ );
868
+ } elseif ( $compressor->can_create_key() ) {
869
  if ( ! isset( $_POST['name'] ) || ! $_POST['name'] ) {
870
  $status = (object) array(
871
  'ok' => false,
926
 
927
  public function update_api_key() {
928
  $key = $_POST['key'];
929
+ if ( ! current_user_can( 'manage_options' ) ) {
930
+ $status = (object) array(
931
+ 'ok' => false,
932
+ 'message' => 'This feature requires certain user capabilities',
933
+ );
934
+ } elseif ( empty( $key ) ) {
935
  /* Always save if key is blank, so the key can be deleted. */
936
  $status = (object) array(
937
  'ok' => true,
949
  }
950
 
951
  public static function wr2x_active() {
952
+ return function_exists( 'wr2x_get_retina' );
953
  }
954
 
955
  public function get_wr2x_option() {
src/class-tiny-wp-base.php CHANGED
@@ -45,6 +45,10 @@ abstract class Tiny_WP_Base {
45
  return defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST;
46
  }
47
 
 
 
 
 
48
  protected static function get_prefixed_name( $name ) {
49
  return self::PREFIX . $name;
50
  }
@@ -53,6 +57,8 @@ abstract class Tiny_WP_Base {
53
  add_action( 'init', $this->get_method( 'init' ) );
54
  if ( self::is_xmlrpc_request() ) {
55
  add_action( 'init', $this->get_method( 'xmlrpc_init' ) );
 
 
56
  } elseif ( is_admin() ) {
57
  add_action( 'admin_init', $this->get_method( 'admin_init' ) );
58
  add_action( 'admin_menu', $this->get_method( 'admin_menu' ) );
@@ -81,6 +87,9 @@ abstract class Tiny_WP_Base {
81
  public function xmlrpc_init() {
82
  }
83
 
 
 
 
84
  public function admin_init() {
85
  }
86
 
45
  return defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST;
46
  }
47
 
48
+ protected function doing_ajax_request() {
49
+ return defined( 'DOING_AJAX' ) && DOING_AJAX;
50
+ }
51
+
52
  protected static function get_prefixed_name( $name ) {
53
  return self::PREFIX . $name;
54
  }
57
  add_action( 'init', $this->get_method( 'init' ) );
58
  if ( self::is_xmlrpc_request() ) {
59
  add_action( 'init', $this->get_method( 'xmlrpc_init' ) );
60
+ } elseif ( self::doing_ajax_request() ) {
61
+ add_action( 'admin_init', $this->get_method( 'ajax_init' ) );
62
  } elseif ( is_admin() ) {
63
  add_action( 'admin_init', $this->get_method( 'admin_init' ) );
64
  add_action( 'admin_menu', $this->get_method( 'admin_menu' ) );
87
  public function xmlrpc_init() {
88
  }
89
 
90
+ public function ajax_init() {
91
+ }
92
+
93
  public function admin_init() {
94
  }
95
 
src/css/admin.css CHANGED
@@ -7,7 +7,7 @@ div.misc-pub-section.tiny-compress-images {
7
  div.tiny-account-status {
8
  box-sizing: border-box;
9
  display: table-cell;
10
- width: 500px;
11
  border: 1px solid #e1e1e1;
12
  background-color: white;
13
  }
@@ -20,10 +20,46 @@ div.tiny-account-status {
20
 
21
  div.tiny-account-status div.status {
22
  box-sizing: border-box;
23
- padding: 22px 28px 22px 56px;
24
  position: relative;
25
  }
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  div.tiny-account-status p.status span {
28
  position: relative;
29
  margin-right: 30px;
@@ -40,10 +76,29 @@ div.tiny-account-status p.status span:after {
40
  font-style: normal;
41
  }
42
 
43
- div.tiny-account-status div.status-success,
44
- div.tiny-account-status div.status-failure,
45
- div.tiny-account-status div.status-pending {
46
- padding-left: 28px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  }
48
 
49
  div.tiny-account-status div.status-success p {
@@ -67,80 +122,56 @@ div.tiny-account-status div.status-failure p.status span:after {
67
  }
68
 
69
  div.tiny-account-status div.status-pending p.status span:after {
70
- right: -24px;
71
- top: -11px;
72
  color: #0086ba;
73
  font-size: 24px;
74
  content: "\f466";
75
  }
76
 
77
- div.tiny-account-status p.status a {
78
- text-decoration: none;
79
- font-weight: 400;
80
  }
81
 
82
- div.tiny-account-status div.status-loading:before {
83
- position: absolute;
84
- left: 26px;
85
- top: 22px;
86
- height: 20px;
87
- width: 20px;
88
- background: url("../images/spinner.gif") no-repeat center;
89
- background-size: 20px 20px;
90
- content: "";
91
- }
92
-
93
- @media (-webkit-min-device-pixel-ratio: 1.25), (min-resolution: 120dpi) {
94
- div.tiny-account-status div.status-loading:before {
95
- background-image: url("../images/spinner-2x.gif");
96
- }
97
- }
98
-
99
- div.tiny-account-status h4 {
100
- margin-top: 0;
101
- line-height: 1.5;
102
- }
103
-
104
- div.tiny-account-status p {
105
- margin-top: 0;
106
- margin-bottom: 4px;
107
- }
108
-
109
- div.tiny-account-status button + p {
110
- margin-top: 8px;
111
  }
112
 
113
- div.tiny-account-status p:last-child {
114
- margin-bottom: 0;
115
  }
116
 
117
- div.tiny-account-status p.introduction {
118
- margin-bottom: 12px;
119
  }
120
 
121
- div.tiny-account-status p.status {
122
- font-weight: bold;
 
123
  }
124
 
125
  div.tiny-account-status div.upgrade {
126
- display: flex;
127
  padding: 22px 28px;
128
- background-color: #F5F9FA;
129
  }
130
 
131
  div.tiny-account-status div.upgrade p {
132
- width: 400px;
133
- margin-right: 20px;
134
  }
135
 
136
- @media only screen and (max-width: 800px) {
137
- div.tiny-account-status div.upgrade p {
138
- width: auto;
139
- }
140
  }
141
 
142
- div.tiny-account-status div.upgrade div.button-container {
143
- display: inline-block;
 
 
 
 
144
  }
145
 
146
  div.tiny-account-status.wide {
@@ -148,19 +179,6 @@ div.tiny-account-status.wide {
148
  max-width: 700px;
149
  }
150
 
151
- div.tiny-account-status div.failure input {
152
- border: 1px solid #d54e21;
153
- }
154
-
155
- div.tiny-account-status div.failure p.message {
156
- color: #d54e21;
157
- }
158
-
159
- div.tiny-account-status div.update {
160
- width: 380px;
161
- padding: 22px 28px;
162
- }
163
-
164
  div.tiny-account-status.wide div.create {
165
  box-sizing: border-box;
166
  display: table-cell;
@@ -202,7 +220,7 @@ div.tiny-account-status.wide div.create button,
202
  div.tiny-account-status.wide div.update button {
203
  width: 100%;
204
  margin-top: 4px;
205
- margin-bottom: 4px;
206
  }
207
 
208
  div.tiny-account-status.wide div.create button.loading,
7
  div.tiny-account-status {
8
  box-sizing: border-box;
9
  display: table-cell;
10
+ width: 570px;
11
  border: 1px solid #e1e1e1;
12
  background-color: white;
13
  }
20
 
21
  div.tiny-account-status div.status {
22
  box-sizing: border-box;
23
+ padding: 22px 28px 14px 28px;
24
  position: relative;
25
  }
26
 
27
+ div.tiny-account-status h4 {
28
+ margin-top: 0;
29
+ margin-bottom: 9px;
30
+ line-height: 1.5;
31
+ }
32
+
33
+ div.tiny-account-status p {
34
+ margin-top: 0;
35
+ margin-bottom: 8px;
36
+ }
37
+
38
+ div.tiny-account-status button + p {
39
+ margin-top: 8px;
40
+ }
41
+
42
+ div.tiny-account-status p:first-child {
43
+ margin-bottom: 10px;
44
+ }
45
+
46
+ div.tiny-account-status p:last-child {
47
+ margin-bottom: 0;
48
+ }
49
+
50
+ div.tiny-account-status p.introduction {
51
+ margin-bottom: 12px;
52
+ }
53
+
54
+ div.tiny-account-status p.status {
55
+ font-weight: bold;
56
+ }
57
+
58
+ div.tiny-account-status p.status a {
59
+ text-decoration: none;
60
+ font-weight: normal;
61
+ }
62
+
63
  div.tiny-account-status p.status span {
64
  position: relative;
65
  margin-right: 30px;
76
  font-style: normal;
77
  }
78
 
79
+ div.tiny-account-status div.status-loading {
80
+ padding-left: 56px;
81
+ }
82
+
83
+ div.tiny-account-status div.status-loading:before {
84
+ position: absolute;
85
+ left: 26px;
86
+ top: 22px;
87
+ height: 20px;
88
+ width: 20px;
89
+ background: url("../images/spinner.gif") no-repeat center;
90
+ background-size: 20px 20px;
91
+ content: "";
92
+ }
93
+
94
+ div.tiny-account-status div.status-loading p {
95
+ margin-bottom: 10px;
96
+ }
97
+
98
+ @media (-webkit-min-device-pixel-ratio: 1.25), (min-resolution: 120dpi) {
99
+ div.tiny-account-status div.status-loading:before {
100
+ background-image: url("../images/spinner-2x.gif");
101
+ }
102
  }
103
 
104
  div.tiny-account-status div.status-success p {
122
  }
123
 
124
  div.tiny-account-status div.status-pending p.status span:after {
125
+ right: -26px;
126
+ top: -9px;
127
  color: #0086ba;
128
  font-size: 24px;
129
  content: "\f466";
130
  }
131
 
132
+ div.tiny-account-status div.status-pending p.status span {
133
+ margin-right: 38px;
 
134
  }
135
 
136
+ div.tiny-account-status div.failure input {
137
+ border-color: #dc3232;
138
+ background-color: #fdf1f1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  }
140
 
141
+ div.tiny-account-status div.failure p.message {
142
+ color: #dc3232;
143
  }
144
 
145
+ div.tiny-account-status div.update {
146
+ padding: 22px 28px;
147
  }
148
 
149
+ div.tiny-account-status div.update input {
150
+ padding-top: 5px;
151
+ padding-bottom: 5px;
152
  }
153
 
154
  div.tiny-account-status div.upgrade {
 
155
  padding: 22px 28px;
156
+ background-color: #f5f9fa;
157
  }
158
 
159
  div.tiny-account-status div.upgrade p {
160
+ margin-bottom: 0;
 
161
  }
162
 
163
+ div.tiny-account-status div.upgrade div.button-container {
164
+ float: right;
165
+ margin-left: 20px;
166
+ margin-bottom: 5px;
167
  }
168
 
169
+ @media only screen and (max-width: 400px) {
170
+ div.tiny-account-status div.upgrade div.button-container {
171
+ float: none;
172
+ margin-left: 0;
173
+ margin-bottom: 10px;
174
+ }
175
  }
176
 
177
  div.tiny-account-status.wide {
179
  max-width: 700px;
180
  }
181
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
  div.tiny-account-status.wide div.create {
183
  box-sizing: border-box;
184
  display: table-cell;
220
  div.tiny-account-status.wide div.update button {
221
  width: 100%;
222
  margin-top: 4px;
223
+ margin-bottom: 6px;
224
  }
225
 
226
  div.tiny-account-status.wide div.create button.loading,
src/css/{chart.css → optimization-chart.css} RENAMED
@@ -1,25 +1,25 @@
1
- #optimization-chart {
2
  float: left;
3
  position: relative;
4
  width: 50%;
5
  text-align: center;
6
  }
7
 
8
- .ie8 #optimization-chart {
9
  margin: 0;
10
  }
11
 
12
- #optimization-chart svg circle.main {
13
  fill: #ebebeb;
14
  animation: shwoosh 2s ease;
15
  transition: stroke-dasharray 1s ease;
16
  }
17
 
18
- #optimization-chart svg circle.inner {
19
  fill: #fff;
20
  }
21
 
22
- #optimization-chart div.value {
23
  position: absolute;
24
  top: 0;
25
  left: 0;
@@ -27,7 +27,7 @@
27
  text-align: center;
28
  }
29
 
30
- #optimization-chart div.value div.percentage {
31
  width: 50%;
32
  margin-left: auto;
33
  margin-right: auto;
@@ -36,7 +36,7 @@
36
  line-height: 1em;
37
  }
38
 
39
- #optimization-chart div.value div.label {
40
  width: 50%;
41
  margin-left: auto;
42
  margin-right: auto;
@@ -45,7 +45,7 @@
45
  }
46
 
47
  @media only screen and (max-width: 400px) {
48
- div.tiny-bulk-optimization #optimization-chart {
49
  float: none;
50
  width: 100%;
51
  }
1
+ div.tiny-optimization-chart {
2
  float: left;
3
  position: relative;
4
  width: 50%;
5
  text-align: center;
6
  }
7
 
8
+ .ie8 div.tiny-optimization-chart {
9
  margin: 0;
10
  }
11
 
12
+ div.tiny-optimization-chart svg circle.main {
13
  fill: #ebebeb;
14
  animation: shwoosh 2s ease;
15
  transition: stroke-dasharray 1s ease;
16
  }
17
 
18
+ div.tiny-optimization-chart svg circle.inner {
19
  fill: #fff;
20
  }
21
 
22
+ div.tiny-optimization-chart div.value {
23
  position: absolute;
24
  top: 0;
25
  left: 0;
27
  text-align: center;
28
  }
29
 
30
+ div.tiny-optimization-chart div.value div.percentage {
31
  width: 50%;
32
  margin-left: auto;
33
  margin-right: auto;
36
  line-height: 1em;
37
  }
38
 
39
+ div.tiny-optimization-chart div.value div.label {
40
  width: 50%;
41
  margin-left: auto;
42
  margin-right: auto;
45
  }
46
 
47
  @media only screen and (max-width: 400px) {
48
+ div.tiny-bulk-optimization div.tiny-optimization-chart {
49
  float: none;
50
  width: 100%;
51
  }
src/js/admin.js CHANGED
@@ -243,9 +243,7 @@
243
  case 'post-php':
244
  eventOn('click', 'button.tiny-compress', compressImage);
245
  break;
246
- case 'options-media-php':
247
  case 'settings_page_tinify':
248
- case 'settings_page_media': // Enhanced Media Library plugin
249
  changeEnterKeyTarget('div.tiny-account-status create', '[data-tiny-action=create-key]');
250
  changeEnterKeyTarget('div.tiny-account-status update', '[data-tiny-action=update-key]');
251
 
243
  case 'post-php':
244
  eventOn('click', 'button.tiny-compress', compressImage);
245
  break;
 
246
  case 'settings_page_tinify':
 
247
  changeEnterKeyTarget('div.tiny-account-status create', '[data-tiny-action=create-key]');
248
  changeEnterKeyTarget('div.tiny-account-status update', '[data-tiny-action=update-key]');
249
 
src/js/dashboard-widget.js CHANGED
@@ -54,11 +54,13 @@
54
 
55
  function renderWidget(data) {
56
  var stats = jQuery.parseJSON(data);
57
- var savings = stats['display-percentage'];
58
- var libraryOptimized = optimizedPercentage(stats);
59
- renderContent(libraryOptimized, stats, savings);
60
- renderChart(savings);
61
- jQuery('#optimization-chart').show();
 
 
62
  jQuery('#widget-spinner').attr('class', 'hidden');
63
  }
64
 
54
 
55
  function renderWidget(data) {
56
  var stats = jQuery.parseJSON(data);
57
+ if (stats !== null) {
58
+ var savings = stats['display-percentage'];
59
+ var libraryOptimized = optimizedPercentage(stats);
60
+ renderContent(libraryOptimized, stats, savings);
61
+ renderChart(savings);
62
+ jQuery('#optimization-chart').show();
63
+ }
64
  jQuery('#widget-spinner').attr('class', 'hidden');
65
  }
66
 
src/views/account-status-connected.php CHANGED
@@ -4,23 +4,18 @@
4
  if ( $status->ok ) {
5
  if ( isset( $status->message ) ) {
6
  echo esc_html( $status->message, 'tiny-compress-images' );
7
- echo '</span>';
8
  } else {
9
- echo esc_html__( 'Your account is connected', 'tiny-compress-images' );
10
- if ( ! defined( 'TINY_API_KEY' ) ) {
11
- echo '</span><a href="#" id="change-key">';
12
- echo esc_html__( 'change key', 'tiny-compress-images' );
13
- echo '</a>';
14
- }
15
  }
16
  } else {
17
- echo esc_html__( 'Connection unsuccessful', 'tiny-compress-images' );
18
- echo '</span>';
19
- if ( ! defined( 'TINY_API_KEY' ) ) {
20
- echo '<a href="#" id="change-key">';
21
- echo esc_html__( 'change key', 'tiny-compress-images' );
22
- echo '</a>';
23
- }
 
24
  }
25
  ?></p>
26
  <p><?php
@@ -48,7 +43,7 @@
48
  echo esc_html__( 'Error', 'tiny-compress-images' ) . ': ';
49
  echo esc_html( $status->message, 'tiny-compress-images' );
50
  } else {
51
- esc_html__(
52
  'API status could not be checked, enable cURL for more information',
53
  'tiny-compress-images'
54
  );
@@ -67,7 +62,7 @@
67
  </div>
68
 
69
  <div class="update" style="display: none">
70
- <h4><?php echo esc_html__( 'Change your API key', 'tiny-compress-images' ); ?></h4>
71
  <p class="introduction"><?php
72
  $link = sprintf( '<a href="https://tinypng.com/dashboard/api" target="_blank">%s</a>',
73
  esc_html__( 'API dashboard', 'tiny-compress-images' )
@@ -78,37 +73,34 @@
78
  'tiny-compress-images'
79
  ), $link );
80
  ?></p>
81
-
82
  <input type="text" id="tinypng_api_key"
83
  name="tinypng_api_key" size="35" spellcheck="false"
84
  value="<?php echo esc_attr( $key ); ?>">
85
-
86
  <button class="button button-primary" data-tiny-action="update-key"><?php
87
- echo esc_html__( 'Save' );
88
  ?></button>
89
-
90
  <p class="message"></p>
 
 
 
 
91
 
92
- <p><a href="#" id="cancel-change-key"><?php
93
- echo esc_html__( 'Cancel' );
94
- ?></a></p>
95
- </div><?php
96
- if ( self::is_on_free_plan() ) { ?>
97
  <div class="upgrade">
98
- <p>
99
- <?php echo esc_html__(
100
- 'Remove all limitations? Visit your TinyPNG dashboard to upgrade your account.',
101
- 'tiny-compress-images'
102
- ); ?>
103
- </p>
104
  <div class="button-container">
105
  <div class="box">
106
  <?php $encoded_email = str_replace( '%20', '%2B', rawurlencode( self::get_email_address() ) ); ?>
107
  <a href="https://tinypng.com/dashboard/api?type=upgrade&mail=<?php echo $encoded_email; ?>" target="_blank" class="button button-primary upgrade-account">
108
- <?php echo esc_html__( 'Upgrade account', 'tiny-compress-images' ); ?>
109
  </a>
110
  </div>
111
  </div>
 
 
 
 
 
 
112
  </div>
113
  <?php } ?>
114
  </div>
4
  if ( $status->ok ) {
5
  if ( isset( $status->message ) ) {
6
  echo esc_html( $status->message, 'tiny-compress-images' );
 
7
  } else {
8
+ esc_html_e( 'Your account is connected', 'tiny-compress-images' );
 
 
 
 
 
9
  }
10
  } else {
11
+ esc_html_e( 'Connection unsuccessful', 'tiny-compress-images' );
12
+ }
13
+ ?></span>
14
+ <?php
15
+ if ( ! defined( 'TINY_API_KEY' ) ) {
16
+ echo '<a href="#" id="change-key">';
17
+ esc_html_e( 'Change API key', 'tiny-compress-images' );
18
+ echo '</a>';
19
  }
20
  ?></p>
21
  <p><?php
43
  echo esc_html__( 'Error', 'tiny-compress-images' ) . ': ';
44
  echo esc_html( $status->message, 'tiny-compress-images' );
45
  } else {
46
+ esc_html_e(
47
  'API status could not be checked, enable cURL for more information',
48
  'tiny-compress-images'
49
  );
62
  </div>
63
 
64
  <div class="update" style="display: none">
65
+ <h4><?php esc_html_e( 'Change your API key', 'tiny-compress-images' ); ?></h4>
66
  <p class="introduction"><?php
67
  $link = sprintf( '<a href="https://tinypng.com/dashboard/api" target="_blank">%s</a>',
68
  esc_html__( 'API dashboard', 'tiny-compress-images' )
73
  'tiny-compress-images'
74
  ), $link );
75
  ?></p>
 
76
  <input type="text" id="tinypng_api_key"
77
  name="tinypng_api_key" size="35" spellcheck="false"
78
  value="<?php echo esc_attr( $key ); ?>">
 
79
  <button class="button button-primary" data-tiny-action="update-key"><?php
80
+ esc_html_e( 'Save' );
81
  ?></button>
 
82
  <p class="message"></p>
83
+ <p>
84
+ <a href="#" id="cancel-change-key"><?php esc_html_e( 'Cancel' ); ?></a>
85
+ </p>
86
+ </div>
87
 
88
+ <?php if ( self::is_on_free_plan() ) { ?>
 
 
 
 
89
  <div class="upgrade">
 
 
 
 
 
 
90
  <div class="button-container">
91
  <div class="box">
92
  <?php $encoded_email = str_replace( '%20', '%2B', rawurlencode( self::get_email_address() ) ); ?>
93
  <a href="https://tinypng.com/dashboard/api?type=upgrade&mail=<?php echo $encoded_email; ?>" target="_blank" class="button button-primary upgrade-account">
94
+ <?php esc_html_e( 'Upgrade account', 'tiny-compress-images' ); ?>
95
  </a>
96
  </div>
97
  </div>
98
+ <p>
99
+ <?php esc_html_e(
100
+ 'Remove all limitations? Visit your TinyPNG dashboard to upgrade your account.',
101
+ 'tiny-compress-images'
102
+ ); ?>
103
+ </p>
104
  </div>
105
  <?php } ?>
106
  </div>
src/views/account-status-create-advanced.php CHANGED
@@ -11,7 +11,7 @@ $email = trim( $user->user_email );
11
  ?></h4>
12
 
13
  <p class="introduction" class="description"><?php
14
- echo esc_html__(
15
  'Provide your name and email address to start optimizing images.',
16
  'tiny-compress-images'
17
  );
@@ -26,13 +26,13 @@ $email = trim( $user->user_email );
26
  <p class="message"></p>
27
 
28
  <button class="button button-primary" data-tiny-action="create-key">
29
- <?php echo esc_html__( 'Register Account', 'tiny-compress-images' ) ?>
30
  </button>
31
  </div>
32
 
33
  <div class="update">
34
  <h4><?php
35
- echo esc_html__( 'Already have an account?', 'tiny-compress-images' );
36
  ?></h4>
37
 
38
  <p class="introduction"><?php
@@ -52,7 +52,7 @@ $email = trim( $user->user_email );
52
  <p class="message"></p>
53
 
54
  <button class="button button-primary" data-tiny-action="update-key">
55
- <?php echo esc_html__( 'Save' ); ?>
56
  </button>
57
  </div>
58
  </div>
11
  ?></h4>
12
 
13
  <p class="introduction" class="description"><?php
14
+ esc_html_e(
15
  'Provide your name and email address to start optimizing images.',
16
  'tiny-compress-images'
17
  );
26
  <p class="message"></p>
27
 
28
  <button class="button button-primary" data-tiny-action="create-key">
29
+ <?php esc_html_e( 'Register Account', 'tiny-compress-images' ) ?>
30
  </button>
31
  </div>
32
 
33
  <div class="update">
34
  <h4><?php
35
+ esc_html_e( 'Already have an account?', 'tiny-compress-images' );
36
  ?></h4>
37
 
38
  <p class="introduction"><?php
52
  <p class="message"></p>
53
 
54
  <button class="button button-primary" data-tiny-action="update-key">
55
+ <?php esc_html_e( 'Save' ); ?>
56
  </button>
57
  </div>
58
  </div>
src/views/account-status-create-simple.php CHANGED
@@ -1,12 +1,12 @@
1
  <div class="tiny-account-status" id="tiny-account-status" data-state="missing">
2
  <div class="update">
3
- <h4><?php echo esc_html__( 'Configure your account', 'tiny-compress-images' ); ?></h4>
4
  <p class="introduction"><?php
5
  $link = sprintf( '<a href="https://tinypng.com/developers" target="_blank">%s</a>',
6
  esc_html__( 'TinyPNG developer section', 'tiny-compress-images' )
7
  );
8
 
9
- echo esc_html__( 'Enter your API key.', 'tiny-compress-images' );
10
  echo ' ';
11
 
12
  /* translators: %s: link saying TinyPNG developer section */
@@ -21,7 +21,7 @@
21
  value="<?php echo esc_attr( $key ); ?>">
22
 
23
  <button class="button button-primary" data-tiny-action="update-key"><?php
24
- echo esc_html__( 'Save', 'tiny-compress-images' );
25
  ?></button>
26
 
27
  <p class="message"></p>
1
  <div class="tiny-account-status" id="tiny-account-status" data-state="missing">
2
  <div class="update">
3
+ <h4><?php esc_html_e( 'Configure your account', 'tiny-compress-images' ); ?></h4>
4
  <p class="introduction"><?php
5
  $link = sprintf( '<a href="https://tinypng.com/developers" target="_blank">%s</a>',
6
  esc_html__( 'TinyPNG developer section', 'tiny-compress-images' )
7
  );
8
 
9
+ esc_html_e( 'Enter your API key.', 'tiny-compress-images' );
10
  echo ' ';
11
 
12
  /* translators: %s: link saying TinyPNG developer section */
21
  value="<?php echo esc_attr( $key ); ?>">
22
 
23
  <button class="button button-primary" data-tiny-action="update-key"><?php
24
+ esc_html_e( 'Save', 'tiny-compress-images' );
25
  ?></button>
26
 
27
  <p class="message"></p>
src/views/account-status-loading.php CHANGED
@@ -1,9 +1,8 @@
1
  <div class="tiny-account-status" id="tiny-account-status" data-state="pending">
2
  <div class="status status-loading">
3
- <p class="status"><?php echo esc_html__(
4
- 'Retrieving account status',
5
- 'tiny-compress-images'
6
- ); ?></p>
7
 
8
  <input type="hidden" id="<?php echo esc_attr( self::get_prefixed_name( 'api_key' ) ); ?>"
9
  name="<?php echo esc_attr( self::get_prefixed_name( 'api_key' ) ); ?>" size="35" spellcheck="false"
1
  <div class="tiny-account-status" id="tiny-account-status" data-state="pending">
2
  <div class="status status-loading">
3
+ <p class="status">
4
+ <?php esc_html_e( 'Retrieving account status', 'tiny-compress-images' ); ?>
5
+ </p>
 
6
 
7
  <input type="hidden" id="<?php echo esc_attr( self::get_prefixed_name( 'api_key' ) ); ?>"
8
  name="<?php echo esc_attr( self::get_prefixed_name( 'api_key' ) ); ?>" size="35" spellcheck="false"
src/views/bulk-optimization-upgrade-notice.php CHANGED
@@ -1,31 +1,35 @@
1
  <div class="upgrade-account-notice">
2
  <div class="introduction">
3
- <p><?php
4
- $strong = array(
5
- 'strong' => array(),
6
- );
7
- /* translators: %s: number of remaining credits */
8
- printf( wp_kses( __(
9
- 'You are on a <strong>free plan</strong> with <strong>%s compressions left</strong> this month.', // WPCS: Needed for proper translation.
10
- 'tiny-compress-images'
11
- ), $strong ), $remaining_credits );
12
- ?></p>
13
- <p><?php
14
- echo esc_html__(
15
- 'Upgrade your account now to compress your entire media library.',
16
- 'tiny-compress-images'
17
- );
18
- ?></p>
 
 
 
 
19
  </div>
20
  <?php $encoded_email = str_replace( '%20', '%2B', rawurlencode( $email_address ) ); ?>
21
  <a href="https://tinypng.com/dashboard/api?type=upgrade&mail=<?php echo $encoded_email; ?>" target="_blank" class="button button-primary button-hero upgrade-account">
22
- <?php echo esc_html__( 'Upgrade account', 'tiny-compress-images' ); ?>
23
- </a><?php
24
- if ( $remaining_credits > 0 ) { ?>
25
- <p>
26
- <a id="hide-warning" href="#">
27
- <?php echo esc_html__( 'No thanks, continue anyway', 'tiny-compress-images' ); ?>
28
- </a>
29
- </p><?php
30
- } ?>
31
  </div>
1
  <div class="upgrade-account-notice">
2
  <div class="introduction">
3
+ <p>
4
+ <?php
5
+ $strong = array(
6
+ 'strong' => array(),
7
+ );
8
+ /* translators: %s: number of remaining credits */
9
+ printf( wp_kses( __(
10
+ 'You are on a <strong>free plan</strong> with <strong>%s compressions left</strong> this month.', // WPCS: Needed for proper translation.
11
+ 'tiny-compress-images'
12
+ ), $strong ), $remaining_credits );
13
+ ?>
14
+ </p>
15
+ <p>
16
+ <?php
17
+ esc_html_e(
18
+ 'Upgrade your account now to compress your entire media library.',
19
+ 'tiny-compress-images'
20
+ );
21
+ ?>
22
+ </p>
23
  </div>
24
  <?php $encoded_email = str_replace( '%20', '%2B', rawurlencode( $email_address ) ); ?>
25
  <a href="https://tinypng.com/dashboard/api?type=upgrade&mail=<?php echo $encoded_email; ?>" target="_blank" class="button button-primary button-hero upgrade-account">
26
+ <?php esc_html_e( 'Upgrade account', 'tiny-compress-images' ); ?>
27
+ </a>
28
+ <?php if ( $remaining_credits > 0 ) { ?>
29
+ <p>
30
+ <a id="hide-warning" href="#">
31
+ <?php esc_html_e( 'No thanks, continue anyway', 'tiny-compress-images' ); ?>
32
+ </a>
33
+ </p>
34
+ <?php } ?>
35
  </div>
src/views/bulk-optimization.php CHANGED
@@ -5,10 +5,10 @@
5
  div.tiny-bulk-optimization div.available div.tooltip span.dashicons {
6
  color: <?php echo $admin_colors[3] ?>;
7
  }
8
- div.tiny-bulk-optimization div.savings div.chart div.value {
9
  color: <?php echo $admin_colors[2] ?>;
10
  }
11
- div.tiny-bulk-optimization div.savings div.chart svg circle.main {
12
  stroke: <?php echo $admin_colors[2] ?>;
13
  }
14
  div.tiny-bulk-optimization div.savings table td.emphasize {
@@ -193,7 +193,7 @@ div.tiny-bulk-optimization div.dashboard div.optimize div.progressbar div.progre
193
  <?php esc_html_e( 'Statistics based on all available JPEG and PNG images in your media library.', 'tiny-compress-images' ); ?>
194
  </p>
195
  <?php
196
- require_once dirname( __FILE__ ) . '/bulk-optimization-chart.php';
197
  ?>
198
  <div class="legend">
199
  <table>
5
  div.tiny-bulk-optimization div.available div.tooltip span.dashicons {
6
  color: <?php echo $admin_colors[3] ?>;
7
  }
8
+ div.tiny-bulk-optimization div.savings div.tiny-optimization-chart div.value {
9
  color: <?php echo $admin_colors[2] ?>;
10
  }
11
+ div.tiny-bulk-optimization div.savings div.tiny-optimization-chart svg circle.main {
12
  stroke: <?php echo $admin_colors[2] ?>;
13
  }
14
  div.tiny-bulk-optimization div.savings table td.emphasize {
193
  <?php esc_html_e( 'Statistics based on all available JPEG and PNG images in your media library.', 'tiny-compress-images' ); ?>
194
  </p>
195
  <?php
196
+ require_once dirname( __FILE__ ) . '/optimization-chart.php';
197
  ?>
198
  <div class="legend">
199
  <table>
src/views/dashboard-widget.php CHANGED
@@ -73,4 +73,4 @@ div#tinypng_dashboard_widget div#optimization-chart svg circle.main {
73
  </p>
74
  </div>
75
 
76
- <?php require_once dirname( __FILE__ ) . '/bulk-optimization-chart.php'; ?>
73
  </p>
74
  </div>
75
 
76
+ <?php require_once dirname( __FILE__ ) . '/optimization-chart.php'; ?>
src/views/{bulk-optimization-chart.php → optimization-chart.php} RENAMED
@@ -21,12 +21,12 @@ $chart['dash-array-size'] = $chart['percentage'] / 100 * $chart['circle-size'];
21
  ?>
22
  <style>
23
 
24
- #optimization-chart svg circle.main {
25
  stroke-width: <?php echo $chart['dash-stroke'] ?>;
26
  stroke-dasharray: <?php echo $chart['dash-array-size'] . ' ' . $chart['circle-size'] ?>;
27
  }
28
 
29
- #optimization-chart div.chart div.value {
30
  min-width: <?php echo $chart['size'] ?>px;
31
  }
32
 
@@ -43,13 +43,13 @@ $chart['dash-array-size'] = $chart['percentage'] / 100 * $chart['circle-size'];
43
 
44
  </style>
45
 
46
- <div id="optimization-chart" class="chart" data-full-circle-size="<?php echo $chart['circle-size'] ?>" data-percentage-factor="<?php echo $chart['main-radius'] ?>" >
47
  <svg width="<?php echo $chart['size'] ?>" height="<?php echo $chart['size'] ?>">
48
  <circle class="main" transform="rotate(-90, <?php echo $chart['center'] ?>, <?php echo $chart['center'] ?>)" r="<?php echo $chart['main-radius'] ?>" cx="<?php echo $chart['center'] ?>" cy="<?php echo $chart['center'] ?>"/>
49
  <circle class="inner" r="<?php echo $chart['inner-radius'] ?>" cx="<?php echo $chart['center'] ?>" cy="<?php echo $chart['center'] ?>" />
50
  </svg>
51
  <div class="value">
52
  <div class="percentage" id="savings-percentage"><span><?php echo $chart['percentage'] ?></span>%</div>
53
- <div class="label" ><?php echo esc_html__( 'savings', 'tiny-compress-images' ); ?></div>
54
  </div>
55
  </div>
21
  ?>
22
  <style>
23
 
24
+ div.tiny-optimization-chart svg circle.main {
25
  stroke-width: <?php echo $chart['dash-stroke'] ?>;
26
  stroke-dasharray: <?php echo $chart['dash-array-size'] . ' ' . $chart['circle-size'] ?>;
27
  }
28
 
29
+ div.tiny-optimization-chart div.value {
30
  min-width: <?php echo $chart['size'] ?>px;
31
  }
32
 
43
 
44
  </style>
45
 
46
+ <div id="optimization-chart" class="tiny-optimization-chart" data-full-circle-size="<?php echo $chart['circle-size'] ?>" data-percentage-factor="<?php echo $chart['main-radius'] ?>" >
47
  <svg width="<?php echo $chart['size'] ?>" height="<?php echo $chart['size'] ?>">
48
  <circle class="main" transform="rotate(-90, <?php echo $chart['center'] ?>, <?php echo $chart['center'] ?>)" r="<?php echo $chart['main-radius'] ?>" cx="<?php echo $chart['center'] ?>" cy="<?php echo $chart['center'] ?>"/>
49
  <circle class="inner" r="<?php echo $chart['inner-radius'] ?>" cx="<?php echo $chart['center'] ?>" cy="<?php echo $chart['center'] ?>" />
50
  </svg>
51
  <div class="value">
52
  <div class="percentage" id="savings-percentage"><span><?php echo $chart['percentage'] ?></span>%</div>
53
+ <div class="label" ><?php esc_html_e( 'savings', 'tiny-compress-images' ); ?></div>
54
  </div>
55
  </div>
tiny-compress-images.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  * Plugin Name: Compress JPEG & PNG images
4
  * Description: Speed up your website. Optimize your JPEG and PNG images automatically with TinyPNG.
5
- * Version: 3.1.0
6
  * Author: TinyPNG
7
  * Author URI: https://tinypng.com
8
  * Text Domain: tiny-compress-images
2
  /**
3
  * Plugin Name: Compress JPEG & PNG images
4
  * Description: Speed up your website. Optimize your JPEG and PNG images automatically with TinyPNG.
5
+ * Version: 3.2.0
6
  * Author: TinyPNG
7
  * Author URI: https://tinypng.com
8
  * Text Domain: tiny-compress-images