Optimus – WordPress Image Optimizer - Version 1.4.9

Version Description

  • Formatting updates
Download this release

Release Info

Developer keycdn
Plugin Icon 128x128 Optimus – WordPress Image Optimizer
Version 1.4.9
Comparing to
See all releases

Code changes from version 1.4.8 to 1.4.9

inc/optimus.class.php CHANGED
@@ -15,384 +15,384 @@ class Optimus
15
  {
16
 
17
 
18
- /**
19
- * Pseudo-Konstruktor der Klasse
20
- *
21
- * @since 0.0.1
22
- * @change 0.0.1
23
- */
24
-
25
- public static function instance()
26
- {
27
- new self();
28
- }
29
-
30
-
31
- /**
32
- * Konstruktor der Klasse
33
- *
34
- * @since 0.0.1
35
- * @change 1.4.6
36
- */
37
-
38
- public function __construct()
39
- {
40
- /* Get plugin options */
41
- $options = Optimus::get_options();
42
-
43
- /* Check if manual optimization is enabled */
44
- if ( ! $options['manual_optimize'] ) {
45
- /* Fire! */
46
- add_filter(
47
- 'wp_generate_attachment_metadata',
48
- array(
49
- 'Optimus_Request',
50
- 'optimize_upload_images'
51
- ),
52
- 10,
53
- 2
54
- );
55
- }
56
-
57
- /* Remove converted files */
58
- add_filter(
59
- 'wp_delete_file',
60
- array(
61
- 'Optimus_Request',
62
- 'delete_converted_file'
63
- )
64
- );
65
-
66
- /* WP Retina 2x compatibility (existing images) */
67
- add_action(
68
- 'wr2x_retina_file_added',
69
- array(
70
- 'Optimus_Request',
71
- 'optimize_wr2x_image'
72
- ),
73
- 10,
74
- 2
75
- );
76
-
77
- /* Filter */
78
- if ( (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) OR (defined('DOING_CRON') && DOING_CRON) OR (defined('DOING_AJAX') && DOING_AJAX) OR (defined('XMLRPC_REQUEST') && XMLRPC_REQUEST) ) {
79
- return;
80
- }
81
-
82
- /* BE only */
83
- if ( ! is_admin() ) {
84
- return;
85
- }
86
-
87
- /* Hooks */
88
- add_action(
89
- 'admin_enqueue_scripts',
90
- array(
91
- __CLASS__,
92
- 'add_js_css'
93
- )
94
- );
95
- add_filter(
96
- 'manage_media_columns',
97
- array(
98
- 'Optimus_Media',
99
- 'manage_columns'
100
- )
101
- );
102
- add_action(
103
- 'manage_media_custom_column',
104
- array(
105
- 'Optimus_Media',
106
- 'manage_column'
107
- ),
108
- 10,
109
- 2
110
- );
111
- add_filter(
112
- 'plugin_row_meta',
113
- array(
114
- __CLASS__,
115
- 'add_row_meta'
116
- ),
117
- 10,
118
- 2
119
- );
120
- add_filter(
121
- 'plugin_action_links_' .OPTIMUS_BASE,
122
- array(
123
- __CLASS__,
124
- 'add_action_link'
125
- )
126
- );
127
- add_action(
128
- 'after_plugin_row_' .OPTIMUS_BASE,
129
- array(
130
- 'Optimus_HQ',
131
- 'display_key_input'
132
- )
133
- );
134
- add_action(
135
- 'admin_init',
136
- array(
137
- 'Optimus_HQ',
138
- 'verify_key_input'
139
- )
140
- );
141
- add_action(
142
- 'admin_init',
143
- array(
144
- 'Optimus_Settings',
145
- 'register_settings'
146
- )
147
- );
148
-
149
- add_action(
150
- 'admin_menu',
151
- array(
152
- 'Optimus_Settings',
153
- 'add_page'
154
- )
155
- );
156
- add_action(
157
- 'admin_menu',
158
- array(
159
- 'Optimus_Management',
160
- 'add_bulk_optimizer_page'
161
- )
162
- );
163
-
164
- /* Admin notices */
165
- add_action(
166
- 'all_admin_notices',
167
- array(
168
- __CLASS__,
169
- 'optimus_requirements_check'
170
- )
171
- );
172
- add_action(
173
- 'all_admin_notices',
174
- array(
175
- 'Optimus_HQ',
176
- 'optimus_hq_notice'
177
- )
178
- );
179
-
180
- }
181
-
182
-
183
-
184
- /**
185
- * Hinzufügen der Action-Links
186
- *
187
- * @since 1.1.2
188
- * @change 1.1.2
189
- *
190
- * @param array $data Bereits existente Links
191
- * @return array $data Erweitertes Array mit Links
192
- */
193
-
194
- public static function add_action_link($data)
195
- {
196
- /* Rechte? */
197
- if ( ! current_user_can('manage_options') ) {
198
- return $data;
199
- }
200
-
201
- return array_merge(
202
- $data,
203
- array(
204
- sprintf(
205
- '<a href="%s">%s</a>',
206
- add_query_arg(
207
- array(
208
- 'page' => 'optimus'
209
- ),
210
- admin_url('options-general.php')
211
- ),
212
- __("Settings")
213
- )
214
- )
215
- );
216
- }
217
-
218
-
219
- /**
220
- * Hinzufügen der Meta-Informationen
221
- *
222
- * @since 0.0.1
223
- * @change 1.1.8
224
- *
225
- * @param array $rows Array mit Links
226
- * @param string $file Name des Plugins
227
- * @return array Array mit erweitertem Link
228
- */
229
-
230
- public static function add_row_meta($rows, $file)
231
- {
232
- /* Restliche Plugins? */
233
- if ( $file !== OPTIMUS_BASE ) {
234
- return $rows;
235
- }
236
-
237
- /* Keine Rechte? */
238
- if ( ! current_user_can('manage_options') ) {
239
- return $rows;
240
- }
241
-
242
- /* Add new key link */
243
- $rows = array_merge(
244
- $rows,
245
- array(
246
- sprintf(
247
- '<a href="%s">%s</a>',
248
- add_query_arg(
249
- array(
250
- '_optimus_action' => 'rekey'
251
- ),
252
- network_admin_url('plugins.php#_optimus_key')
253
- ),
254
- ( Optimus_HQ::get_key() ? __("Enter a different Optimus HQ license key", "optimus") : '<span style="color:#dd3d36">'.__("Activate Optimus HQ", "optimus").'</span>' )
255
- )
256
- )
257
- );
258
-
259
- /* Add expiration date */
260
- if ( Optimus_HQ::is_unlocked() ) {
261
- $rows = array_merge(
262
- $rows,
263
- array(
264
- sprintf(
265
- __("Optimus HQ expiry date: %s", "optimus"),
266
- date( 'd.m.Y', Optimus_HQ::best_before() )
267
- )
268
- )
269
- );
270
- }
271
-
272
- return $rows;
273
- }
274
-
275
-
276
- /**
277
- * Run uninstall hook
278
- *
279
- * @since 1.1.0
280
- * @change 1.1.8
281
- */
282
-
283
- public static function handle_uninstall_hook()
284
- {
285
- delete_option('optimus');
286
- delete_site_option('optimus_key');
287
- delete_site_option('optimus_purchase_time');
288
- }
289
-
290
-
291
- /**
292
- * Run activation hook
293
- *
294
- * @since 1.2.0
295
- * @change 1.2.0
296
- */
297
-
298
- public static function handle_activation_hook() {
299
- set_transient(
300
- 'optimus_activation_hook_in_use',
301
- 1,
302
- MINUTE_IN_SECONDS
303
- );
304
- }
305
-
306
-
307
- /**
308
- * Check plugin requirements
309
- *
310
- * @since 1.3.1
311
- * @change 1.3.1
312
- */
313
-
314
- public static function optimus_requirements_check() {
315
- /* WordPress version check */
316
- if ( version_compare($GLOBALS['wp_version'], OPTIMUS_MIN_WP.'alpha', '<') ) {
317
- show_message(
318
- sprintf(
319
- '<div class="error"><p>%s</p></div>',
320
- sprintf(
321
- __("Optimus is optimized for WordPress %s. Please disable the plugin or upgrade your WordPress installation (recommended).", "optimus"),
322
- OPTIMUS_MIN_WP
323
- )
324
- )
325
- );
326
- }
327
-
328
- /* cURL check */
329
- if ( ! WP_Http_Curl::test() ) {
330
- show_message(
331
- sprintf(
332
- '<div class="error"><p>%s</p></div>',
333
- sprintf(
334
- __("Optimus requires the <a href=\"%s\" target=\"_blank\">cURL-Library</a>. Please contact your hosting provider to get cURL installed.", "optimus"),
335
- 'https://php.net/manual/en/intro.curl.php'
336
- )
337
- )
338
- );
339
- }
340
- }
341
-
342
-
343
- /**
344
- * Return plugin options
345
- *
346
- * @since 1.1.2
347
- * @change 1.4.0
348
- *
349
- * @return array $diff Data pairs
350
- */
351
-
352
- public static function get_options()
353
- {
354
- return wp_parse_args(
355
- get_option('optimus'),
356
- array(
357
- 'copy_markers' => 0,
358
- 'webp_convert' => 0,
359
- 'keep_original' => 0,
360
- 'secure_transport' => 0,
361
- 'manual_optimize' => 0
362
- )
363
- );
364
- }
365
-
366
-
367
- /**
368
- * Hinzufügen von JavaScript und Styles
369
- *
370
- * @since 1.3.8
371
- * @change 1.3.8
372
- */
373
- public static function add_js_css()
374
- {
375
- wp_register_style(
376
- 'optimus-styles',
377
- plugins_url(
378
- 'css/styles.css',
379
- OPTIMUS_FILE
380
- )
381
- );
382
- wp_enqueue_style('optimus-styles');
383
-
384
- $handle = 'optimus-scripts';
385
-
386
- wp_register_script( $handle, plugins_url('js/scripts.js', OPTIMUS_FILE), array('jquery'), '2', TRUE );
387
- wp_localize_script($handle, 'optimusOptimize', array(
388
- 'nonce' => wp_create_nonce('optimus-optimize'),
389
- 'bulkDone' => __("All images have been optimized.", "optimus"),
390
- 'bulkAction' => __("Optimize images", "optimus"),
391
- 'optimizing' => __("Optimizing", "optimus"),
392
- 'optimized' => __("optimized", "optimus"),
393
- 'internalError' => __("Internal error", "optimus"),
394
- 'waiting' => __("Waiting", "optimus"),
395
- ));
396
- wp_enqueue_script($handle);
397
- }
398
  }
15
  {
16
 
17
 
18
+ /**
19
+ * Pseudo-Konstruktor der Klasse
20
+ *
21
+ * @since 0.0.1
22
+ * @change 0.0.1
23
+ */
24
+
25
+ public static function instance()
26
+ {
27
+ new self();
28
+ }
29
+
30
+
31
+ /**
32
+ * Konstruktor der Klasse
33
+ *
34
+ * @since 0.0.1
35
+ * @change 1.4.6
36
+ */
37
+
38
+ public function __construct()
39
+ {
40
+ /* Get plugin options */
41
+ $options = Optimus::get_options();
42
+
43
+ /* Check if manual optimization is enabled */
44
+ if ( ! $options['manual_optimize'] ) {
45
+ /* Fire! */
46
+ add_filter(
47
+ 'wp_generate_attachment_metadata',
48
+ array(
49
+ 'Optimus_Request',
50
+ 'optimize_upload_images'
51
+ ),
52
+ 10,
53
+ 2
54
+ );
55
+ }
56
+
57
+ /* Remove converted files */
58
+ add_filter(
59
+ 'wp_delete_file',
60
+ array(
61
+ 'Optimus_Request',
62
+ 'delete_converted_file'
63
+ )
64
+ );
65
+
66
+ /* WP Retina 2x compatibility (existing images) */
67
+ add_action(
68
+ 'wr2x_retina_file_added',
69
+ array(
70
+ 'Optimus_Request',
71
+ 'optimize_wr2x_image'
72
+ ),
73
+ 10,
74
+ 2
75
+ );
76
+
77
+ /* Filter */
78
+ if ( (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) OR (defined('DOING_CRON') && DOING_CRON) OR (defined('DOING_AJAX') && DOING_AJAX) OR (defined('XMLRPC_REQUEST') && XMLRPC_REQUEST) ) {
79
+ return;
80
+ }
81
+
82
+ /* BE only */
83
+ if ( ! is_admin() ) {
84
+ return;
85
+ }
86
+
87
+ /* Hooks */
88
+ add_action(
89
+ 'admin_enqueue_scripts',
90
+ array(
91
+ __CLASS__,
92
+ 'add_js_css'
93
+ )
94
+ );
95
+ add_filter(
96
+ 'manage_media_columns',
97
+ array(
98
+ 'Optimus_Media',
99
+ 'manage_columns'
100
+ )
101
+ );
102
+ add_action(
103
+ 'manage_media_custom_column',
104
+ array(
105
+ 'Optimus_Media',
106
+ 'manage_column'
107
+ ),
108
+ 10,
109
+ 2
110
+ );
111
+ add_filter(
112
+ 'plugin_row_meta',
113
+ array(
114
+ __CLASS__,
115
+ 'add_row_meta'
116
+ ),
117
+ 10,
118
+ 2
119
+ );
120
+ add_filter(
121
+ 'plugin_action_links_' .OPTIMUS_BASE,
122
+ array(
123
+ __CLASS__,
124
+ 'add_action_link'
125
+ )
126
+ );
127
+ add_action(
128
+ 'after_plugin_row_' .OPTIMUS_BASE,
129
+ array(
130
+ 'Optimus_HQ',
131
+ 'display_key_input'
132
+ )
133
+ );
134
+ add_action(
135
+ 'admin_init',
136
+ array(
137
+ 'Optimus_HQ',
138
+ 'verify_key_input'
139
+ )
140
+ );
141
+ add_action(
142
+ 'admin_init',
143
+ array(
144
+ 'Optimus_Settings',
145
+ 'register_settings'
146
+ )
147
+ );
148
+
149
+ add_action(
150
+ 'admin_menu',
151
+ array(
152
+ 'Optimus_Settings',
153
+ 'add_page'
154
+ )
155
+ );
156
+ add_action(
157
+ 'admin_menu',
158
+ array(
159
+ 'Optimus_Management',
160
+ 'add_bulk_optimizer_page'
161
+ )
162
+ );
163
+
164
+ /* Admin notices */
165
+ add_action(
166
+ 'all_admin_notices',
167
+ array(
168
+ __CLASS__,
169
+ 'optimus_requirements_check'
170
+ )
171
+ );
172
+ add_action(
173
+ 'all_admin_notices',
174
+ array(
175
+ 'Optimus_HQ',
176
+ 'optimus_hq_notice'
177
+ )
178
+ );
179
+
180
+ }
181
+
182
+
183
+
184
+ /**
185
+ * Hinzufügen der Action-Links
186
+ *
187
+ * @since 1.1.2
188
+ * @change 1.1.2
189
+ *
190
+ * @param array $data Bereits existente Links
191
+ * @return array $data Erweitertes Array mit Links
192
+ */
193
+
194
+ public static function add_action_link($data)
195
+ {
196
+ /* Rechte? */
197
+ if ( ! current_user_can('manage_options') ) {
198
+ return $data;
199
+ }
200
+
201
+ return array_merge(
202
+ $data,
203
+ array(
204
+ sprintf(
205
+ '<a href="%s">%s</a>',
206
+ add_query_arg(
207
+ array(
208
+ 'page' => 'optimus'
209
+ ),
210
+ admin_url('options-general.php')
211
+ ),
212
+ __("Settings")
213
+ )
214
+ )
215
+ );
216
+ }
217
+
218
+
219
+ /**
220
+ * Hinzufügen der Meta-Informationen
221
+ *
222
+ * @since 0.0.1
223
+ * @change 1.1.8
224
+ *
225
+ * @param array $rows Array mit Links
226
+ * @param string $file Name des Plugins
227
+ * @return array Array mit erweitertem Link
228
+ */
229
+
230
+ public static function add_row_meta($rows, $file)
231
+ {
232
+ /* Restliche Plugins? */
233
+ if ( $file !== OPTIMUS_BASE ) {
234
+ return $rows;
235
+ }
236
+
237
+ /* Keine Rechte? */
238
+ if ( ! current_user_can('manage_options') ) {
239
+ return $rows;
240
+ }
241
+
242
+ /* Add new key link */
243
+ $rows = array_merge(
244
+ $rows,
245
+ array(
246
+ sprintf(
247
+ '<a href="%s">%s</a>',
248
+ add_query_arg(
249
+ array(
250
+ '_optimus_action' => 'rekey'
251
+ ),
252
+ network_admin_url('plugins.php#_optimus_key')
253
+ ),
254
+ ( Optimus_HQ::get_key() ? __("Enter a different Optimus HQ license key", "optimus") : '<span style="color:#dd3d36">'.__("Activate Optimus HQ", "optimus").'</span>' )
255
+ )
256
+ )
257
+ );
258
+
259
+ /* Add expiration date */
260
+ if ( Optimus_HQ::is_unlocked() ) {
261
+ $rows = array_merge(
262
+ $rows,
263
+ array(
264
+ sprintf(
265
+ __("Optimus HQ expiry date: %s", "optimus"),
266
+ date( 'd.m.Y', Optimus_HQ::best_before() )
267
+ )
268
+ )
269
+ );
270
+ }
271
+
272
+ return $rows;
273
+ }
274
+
275
+
276
+ /**
277
+ * Run uninstall hook
278
+ *
279
+ * @since 1.1.0
280
+ * @change 1.1.8
281
+ */
282
+
283
+ public static function handle_uninstall_hook()
284
+ {
285
+ delete_option('optimus');
286
+ delete_site_option('optimus_key');
287
+ delete_site_option('optimus_purchase_time');
288
+ }
289
+
290
+
291
+ /**
292
+ * Run activation hook
293
+ *
294
+ * @since 1.2.0
295
+ * @change 1.2.0
296
+ */
297
+
298
+ public static function handle_activation_hook() {
299
+ set_transient(
300
+ 'optimus_activation_hook_in_use',
301
+ 1,
302
+ MINUTE_IN_SECONDS
303
+ );
304
+ }
305
+
306
+
307
+ /**
308
+ * Check plugin requirements
309
+ *
310
+ * @since 1.3.1
311
+ * @change 1.3.1
312
+ */
313
+
314
+ public static function optimus_requirements_check() {
315
+ /* WordPress version check */
316
+ if ( version_compare($GLOBALS['wp_version'], OPTIMUS_MIN_WP.'alpha', '<') ) {
317
+ show_message(
318
+ sprintf(
319
+ '<div class="error"><p>%s</p></div>',
320
+ sprintf(
321
+ __("Optimus is optimized for WordPress %s. Please disable the plugin or upgrade your WordPress installation (recommended).", "optimus"),
322
+ OPTIMUS_MIN_WP
323
+ )
324
+ )
325
+ );
326
+ }
327
+
328
+ /* cURL check */
329
+ if ( ! WP_Http_Curl::test() ) {
330
+ show_message(
331
+ sprintf(
332
+ '<div class="error"><p>%s</p></div>',
333
+ sprintf(
334
+ __("Optimus requires the <a href=\"%s\" target=\"_blank\">cURL-Library</a>. Please contact your hosting provider to get cURL installed.", "optimus"),
335
+ 'https://php.net/manual/en/intro.curl.php'
336
+ )
337
+ )
338
+ );
339
+ }
340
+ }
341
+
342
+
343
+ /**
344
+ * Return plugin options
345
+ *
346
+ * @since 1.1.2
347
+ * @change 1.4.0
348
+ *
349
+ * @return array $diff Data pairs
350
+ */
351
+
352
+ public static function get_options()
353
+ {
354
+ return wp_parse_args(
355
+ get_option('optimus'),
356
+ array(
357
+ 'copy_markers' => 0,
358
+ 'webp_convert' => 0,
359
+ 'keep_original' => 0,
360
+ 'secure_transport' => 0,
361
+ 'manual_optimize' => 0
362
+ )
363
+ );
364
+ }
365
+
366
+
367
+ /**
368
+ * Hinzufügen von JavaScript und Styles
369
+ *
370
+ * @since 1.3.8
371
+ * @change 1.3.8
372
+ */
373
+ public static function add_js_css()
374
+ {
375
+ wp_register_style(
376
+ 'optimus-styles',
377
+ plugins_url(
378
+ 'css/styles.css',
379
+ OPTIMUS_FILE
380
+ )
381
+ );
382
+ wp_enqueue_style('optimus-styles');
383
+
384
+ $handle = 'optimus-scripts';
385
+
386
+ wp_register_script( $handle, plugins_url('js/scripts.js', OPTIMUS_FILE), array('jquery'), '2', TRUE );
387
+ wp_localize_script($handle, 'optimusOptimize', array(
388
+ 'nonce' => wp_create_nonce('optimus-optimize'),
389
+ 'bulkDone' => __("All images have been optimized.", "optimus"),
390
+ 'bulkAction' => __("Optimize images", "optimus"),
391
+ 'optimizing' => __("Optimizing", "optimus"),
392
+ 'optimized' => __("optimized", "optimus"),
393
+ 'internalError' => __("Internal error", "optimus"),
394
+ 'waiting' => __("Waiting", "optimus"),
395
+ ));
396
+ wp_enqueue_script($handle);
397
+ }
398
  }
inc/optimus_hq.class.php CHANGED
@@ -15,386 +15,386 @@ class Optimus_HQ
15
  {
16
 
17
 
18
- /* Private vars */
19
- private static $_is_locked = NULL;
20
- private static $_is_unlocked = NULL;
21
-
22
-
23
- /**
24
- * Interne Prüfung auf Optimus HQ
25
- * P.S. Manipulation bringt nichts, da serverseitige Prüfung. Peace!
26
- *
27
- * @since 1.1.9
28
- * @change 1.1.9
29
- *
30
- * @return boolean TRUE wenn Optimus HQ nicht freigeschaltet
31
- */
32
-
33
- public static function is_locked()
34
- {
35
- if ( self::$_is_locked !== NULL ) {
36
- return self::$_is_locked;
37
- }
38
-
39
- $is_locked = ! (bool)self::best_before();
40
-
41
- self::$_is_locked = $is_locked;
42
- self::$_is_unlocked = ! $is_locked;
43
-
44
- return $is_locked;
45
- }
46
-
47
-
48
- /**
49
- * Interne Prüfung auf Optimus HQ
50
- * P.S. Manipulation bringt nichts, da serverseitige Prüfung. Peace!
51
- *
52
- * @since 1.1.9
53
- * @change 1.1.9
54
- *
55
- * @return boolean TRUE wenn Optimus HQ freigeschaltet
56
- */
57
-
58
- public static function is_unlocked()
59
- {
60
- if ( self::$_is_unlocked !== NULL ) {
61
- return self::$_is_unlocked;
62
- }
63
-
64
- return ! self::is_locked();
65
- }
66
-
67
-
68
- /**
69
- * Ablaufdatum von Optimus HQ
70
- * P.S. Manipulation bringt nichts, da serverseitige Prüfung. Peace!
71
- *
72
- * @since 1.1.9
73
- * @change 1.1.9
74
- *
75
- * @return mixed FALSE/Date Datum im Erfolgsfall
76
- */
77
-
78
- public static function best_before()
79
- {
80
- /* Key exists? */
81
- if ( ! $key = self::get_key() ) {
82
- return false;
83
- }
84
-
85
- /* Timestamp from cache */
86
- if ( ! $purchase_time = self::get_purchase_time() ) {
87
- $response = wp_safe_remote_get(
88
- sprintf(
89
- '%s/%s',
90
- 'https://verify.optimus.io',
91
- $key
92
- )
93
- );
94
-
95
- /* Exit on error */
96
- if ( is_wp_error($response) ) {
97
- wp_die( $response->get_error_message() );
98
- }
99
-
100
- /* Initial state */
101
- $purchase_time = -1;
102
-
103
- /* Set the timestamp */
104
- if ( wp_remote_retrieve_response_code($response) === 200 ) {
105
- $purchase_time = (int) wp_remote_retrieve_body($response);
106
- }
107
-
108
- /* Store as option */
109
- self::_update_purchase_time($purchase_time);
110
- }
111
-
112
- /* Invalid purchase time? */
113
- if ( (int)$purchase_time <= 0 ) {
114
- self::_delete_key();
115
-
116
- return false;
117
- }
118
-
119
- /* Set expiration time */
120
- $expiration_time = strtotime(
121
- '+1 year',
122
- $purchase_time
123
- );
124
-
125
- /* Expired time? */
126
- if ( $expiration_time < time() ) {
127
- self::_delete_key();
128
-
129
- return false;
130
- }
131
-
132
- return $expiration_time;
133
- }
134
-
135
-
136
- /**
137
- * Return the license key
138
- *
139
- * @since 1.1.0
140
- * @change 1.1.9
141
- *
142
- * @return string Optimus HQ Key
143
- */
144
-
145
- public static function get_key()
146
- {
147
- return get_site_option('optimus_key');
148
- }
149
-
150
-
151
- /**
152
- * Update the license key
153
- *
154
- * @since 1.1.0
155
- * @change 1.1.9
156
- *
157
- * @return mixed $value Optimus HQ Key value
158
- */
159
-
160
- private static function _update_key($value)
161
- {
162
- update_site_option(
163
- 'optimus_key',
164
- $value
165
- );
166
- }
167
-
168
-
169
- /**
170
- * Delete the license key
171
- *
172
- * @since 1.1.9
173
- * @change 1.1.9
174
- */
175
-
176
- private static function _delete_key()
177
- {
178
- delete_site_option('optimus_key');
179
- }
180
-
181
-
182
- /**
183
- * Return the purchase timestamp
184
- *
185
- * @since 1.1.9
186
- * @change 1.1.9
187
- *
188
- * @return string Optimus HQ purchase timestamp
189
- */
190
-
191
- public static function get_purchase_time()
192
- {
193
- return get_site_option('optimus_purchase_time');
194
- }
195
-
196
-
197
- /**
198
- * Update the purchase timestamp
199
- *
200
- * @since 1.1.9
201
- * @change 1.1.9
202
- *
203
- * @return integer $value Purchase time as a timestamp
204
- */
205
-
206
- private static function _update_purchase_time($value)
207
- {
208
- update_site_option(
209
- 'optimus_purchase_time',
210
- $value
211
- );
212
- }
213
-
214
-
215
- /**
216
- * Delete the purchase timestamp
217
- *
218
- * @since 1.1.9
219
- * @change 1.1.9
220
- */
221
-
222
- private static function _delete_purchase_time()
223
- {
224
- delete_site_option('optimus_purchase_time');
225
- }
226
-
227
-
228
- /**
229
- * Ausgabe des Eingabefeldes für den Optimus HQ Key
230
- *
231
- * @since 1.1.0
232
- * @change 1.3.2
233
- */
234
-
235
- public static function display_key_input()
236
- {
237
- /* Plausibility check */
238
- if ( empty($_GET['_optimus_action']) OR $_GET['_optimus_action'] !== 'rekey' ) {
239
- return;
240
- }
241
-
242
- /* Capability check */
243
- if ( ! current_user_can('manage_options') ) {
244
- return;
245
- } ?>
246
-
247
- <tr class="plugin-update-tr">
248
- <td colspan="3" class="plugin-update">
249
- <div class="update-message">
250
- <form action="<?php echo network_admin_url('plugins.php') ?>" method="post">
251
- <input type="hidden" name="_optimus_action" value="verify" />
252
- <?php wp_nonce_field('_optimus__key_nonce') ?>
253
-
254
- <label for="_optimus_key">
255
- Optimus HQ Key:
256
- <input type="text" name="_optimus_key" id="_optimus_key" maxlength="24" pattern="[A-Z0-9]{17,24}" />
257
- </label>
258
-
259
- <input type="submit" name="submit" value="<?php _e("Activate", "optimus"); ?>" class="button button-primary regular" />
260
- <a href="<?php echo network_admin_url('plugins.php') ?>" class="button"><?php _e("Cancel", "optimus"); ?></a>
261
- </form>
262
- </div>
263
- </td>
264
- </tr>
265
-
266
- <style>
267
- #optimus + .plugin-update-tr .update-message {
268
- margin-top: 12px;
269
- }
270
- #optimus + .plugin-update-tr .update-message::before {
271
- display: none;
272
- }
273
- #optimus + .plugin-update-tr label {
274
- line-height: 30px;
275
- vertical-align: top;
276
- }
277
- #optimus + .plugin-update-tr input[type="text"] {
278
- width: 300px;
279
- margin-left: 10px;
280
- }
281
- </style>
282
- <?php }
283
-
284
-
285
- /**
286
- * Verify und store the Optimus HQ key
287
- *
288
- * @since 1.1.0
289
- * @change 1.3.2
290
- */
291
-
292
- public static function verify_key_input()
293
- {
294
- /* Action check */
295
- if ( empty($_POST['_optimus_action']) OR $_POST['_optimus_action'] !== 'verify' ) {
296
- return;
297
- }
298
-
299
- /* Empty input? */
300
- if ( empty($_POST['_optimus_key']) ) {
301
- return;
302
- }
303
-
304
- /* Nonce check */
305
- check_admin_referer('_optimus__key_nonce');
306
-
307
- /* Capability check */
308
- if ( ! current_user_can('manage_options') ) {
309
- return;
310
- }
311
-
312
- /* Sanitize input */
313
- $optimus_key = sanitize_text_field($_POST['_optimus_key']);
314
-
315
- /* Advanced check */
316
- if ( ! preg_match('/^[A-Z0-9]{17,24}$/', $optimus_key) ) {
317
- return;
318
- }
319
-
320
- /* Delete purchase_time */
321
- self::_delete_purchase_time();
322
-
323
- /* Store current key */
324
- self::_update_key($optimus_key);
325
-
326
- /* Redirect */
327
- wp_safe_redirect(
328
- add_query_arg(
329
- array(
330
- '_optimus_notice' => ( self::is_locked() ? 'locked' : 'unlocked' )
331
- ),
332
- network_admin_url('plugins.php')
333
- )
334
- );
335
-
336
- die();
337
- }
338
-
339
-
340
- /**
341
- * Steuerung der Ausgabe von Admin-Notizen
342
- *
343
- * @since 1.1.0
344
- * @change 1.2.0
345
- */
346
-
347
- public static function optimus_hq_notice()
348
- {
349
- /* Check admin pages */
350
- if ( ! in_array($GLOBALS['pagenow'], array('plugins.php', 'index.php') ) ) {
351
- return;
352
- }
353
-
354
- /* Get message type */
355
- if ( ! empty($_GET['_optimus_notice']) && $_GET['_optimus_notice'] === 'unlocked' ) {
356
- $type = 'unlocked';
357
- } else if ( self::is_locked() ) {
358
- if ( self::get_purchase_time() ) {
359
- $type = 'expired';
360
- } else if ( get_transient('optimus_activation_hook_in_use') ) {
361
- $type = 'locked';
362
- }
363
- }
364
-
365
- /* Empty? */
366
- if ( empty($type) ) {
367
- return;
368
- }
369
-
370
- /* Matching */
371
- switch( $type ) {
372
- case 'unlocked':
373
- $msg = __("<p>Thank you for using <strong>Optimus HQ</strong>. Follow us on <a href=\"https://twitter.com/optimusHQ\" target=\"_blank\">Twitter</a> to get the latest news and updates.</p>", "optimus");
374
- $class = 'updated';
375
- break;
376
-
377
- case 'locked':
378
- $msg = __("<p><strong>Optimus</strong> is free of charge, the functionality is limited to the essential features.</p><p><strong>Optimus HQ</strong> (Premium) on the other hand can handle several image formats, compress larger files and connects through HTTPS. <span class=\"no-break\">More details on <a href=\"https://optimus.io\" target=\"_blank\">optimus.io</a></span><br /><br /><em>This information is displayed for 60 seconds and will not appear again.</em></p>", "optimus");
379
- $class = 'error';
380
- break;
381
-
382
- case 'expired':
383
- $msg = __("<p><strong>Optimus HQ license key</strong> has expired. Get a new Optimus HQ license key on <a href=\"https://optimus.io/en/\" target=\"_blank\">optimus.io</a>. Thank you!", "optimus");
384
- $class = 'error';
385
- break;
386
-
387
- default:
388
- return;
389
- }
390
-
391
- /* Output */
392
- show_message(
393
- sprintf(
394
- '<div class="%s">%s</div>',
395
- $class,
396
- $msg
397
- )
398
- );
399
- }
400
  }
15
  {
16
 
17
 
18
+ /* Private vars */
19
+ private static $_is_locked = NULL;
20
+ private static $_is_unlocked = NULL;
21
+
22
+
23
+ /**
24
+ * Interne Prüfung auf Optimus HQ
25
+ * P.S. Manipulation bringt nichts, da serverseitige Prüfung. Peace!
26
+ *
27
+ * @since 1.1.9
28
+ * @change 1.1.9
29
+ *
30
+ * @return boolean TRUE wenn Optimus HQ nicht freigeschaltet
31
+ */
32
+
33
+ public static function is_locked()
34
+ {
35
+ if ( self::$_is_locked !== NULL ) {
36
+ return self::$_is_locked;
37
+ }
38
+
39
+ $is_locked = ! (bool)self::best_before();
40
+
41
+ self::$_is_locked = $is_locked;
42
+ self::$_is_unlocked = ! $is_locked;
43
+
44
+ return $is_locked;
45
+ }
46
+
47
+
48
+ /**
49
+ * Interne Prüfung auf Optimus HQ
50
+ * P.S. Manipulation bringt nichts, da serverseitige Prüfung. Peace!
51
+ *
52
+ * @since 1.1.9
53
+ * @change 1.1.9
54
+ *
55
+ * @return boolean TRUE wenn Optimus HQ freigeschaltet
56
+ */
57
+
58
+ public static function is_unlocked()
59
+ {
60
+ if ( self::$_is_unlocked !== NULL ) {
61
+ return self::$_is_unlocked;
62
+ }
63
+
64
+ return ! self::is_locked();
65
+ }
66
+
67
+
68
+ /**
69
+ * Ablaufdatum von Optimus HQ
70
+ * P.S. Manipulation bringt nichts, da serverseitige Prüfung. Peace!
71
+ *
72
+ * @since 1.1.9
73
+ * @change 1.1.9
74
+ *
75
+ * @return mixed FALSE/Date Datum im Erfolgsfall
76
+ */
77
+
78
+ public static function best_before()
79
+ {
80
+ /* Key exists? */
81
+ if ( ! $key = self::get_key() ) {
82
+ return false;
83
+ }
84
+
85
+ /* Timestamp from cache */
86
+ if ( ! $purchase_time = self::get_purchase_time() ) {
87
+ $response = wp_safe_remote_get(
88
+ sprintf(
89
+ '%s/%s',
90
+ 'https://verify.optimus.io',
91
+ $key
92
+ )
93
+ );
94
+
95
+ /* Exit on error */
96
+ if ( is_wp_error($response) ) {
97
+ wp_die( $response->get_error_message() );
98
+ }
99
+
100
+ /* Initial state */
101
+ $purchase_time = -1;
102
+
103
+ /* Set the timestamp */
104
+ if ( wp_remote_retrieve_response_code($response) === 200 ) {
105
+ $purchase_time = (int) wp_remote_retrieve_body($response);
106
+ }
107
+
108
+ /* Store as option */
109
+ self::_update_purchase_time($purchase_time);
110
+ }
111
+
112
+ /* Invalid purchase time? */
113
+ if ( (int)$purchase_time <= 0 ) {
114
+ self::_delete_key();
115
+
116
+ return false;
117
+ }
118
+
119
+ /* Set expiration time */
120
+ $expiration_time = strtotime(
121
+ '+1 year',
122
+ $purchase_time
123
+ );
124
+
125
+ /* Expired time? */
126
+ if ( $expiration_time < time() ) {
127
+ self::_delete_key();
128
+
129
+ return false;
130
+ }
131
+
132
+ return $expiration_time;
133
+ }
134
+
135
+
136
+ /**
137
+ * Return the license key
138
+ *
139
+ * @since 1.1.0
140
+ * @change 1.1.9
141
+ *
142
+ * @return string Optimus HQ Key
143
+ */
144
+
145
+ public static function get_key()
146
+ {
147
+ return get_site_option('optimus_key');
148
+ }
149
+
150
+
151
+ /**
152
+ * Update the license key
153
+ *
154
+ * @since 1.1.0
155
+ * @change 1.1.9
156
+ *
157
+ * @return mixed $value Optimus HQ Key value
158
+ */
159
+
160
+ private static function _update_key($value)
161
+ {
162
+ update_site_option(
163
+ 'optimus_key',
164
+ $value
165
+ );
166
+ }
167
+
168
+
169
+ /**
170
+ * Delete the license key
171
+ *
172
+ * @since 1.1.9
173
+ * @change 1.1.9
174
+ */
175
+
176
+ private static function _delete_key()
177
+ {
178
+ delete_site_option('optimus_key');
179
+ }
180
+
181
+
182
+ /**
183
+ * Return the purchase timestamp
184
+ *
185
+ * @since 1.1.9
186
+ * @change 1.1.9
187
+ *
188
+ * @return string Optimus HQ purchase timestamp
189
+ */
190
+
191
+ public static function get_purchase_time()
192
+ {
193
+ return get_site_option('optimus_purchase_time');
194
+ }
195
+
196
+
197
+ /**
198
+ * Update the purchase timestamp
199
+ *
200
+ * @since 1.1.9
201
+ * @change 1.1.9
202
+ *
203
+ * @return integer $value Purchase time as a timestamp
204
+ */
205
+
206
+ private static function _update_purchase_time($value)
207
+ {
208
+ update_site_option(
209
+ 'optimus_purchase_time',
210
+ $value
211
+ );
212
+ }
213
+
214
+
215
+ /**
216
+ * Delete the purchase timestamp
217
+ *
218
+ * @since 1.1.9
219
+ * @change 1.1.9
220
+ */
221
+
222
+ private static function _delete_purchase_time()
223
+ {
224
+ delete_site_option('optimus_purchase_time');
225
+ }
226
+
227
+
228
+ /**
229
+ * Ausgabe des Eingabefeldes für den Optimus HQ Key
230
+ *
231
+ * @since 1.1.0
232
+ * @change 1.3.2
233
+ */
234
+
235
+ public static function display_key_input()
236
+ {
237
+ /* Plausibility check */
238
+ if ( empty($_GET['_optimus_action']) OR $_GET['_optimus_action'] !== 'rekey' ) {
239
+ return;
240
+ }
241
+
242
+ /* Capability check */
243
+ if ( ! current_user_can('manage_options') ) {
244
+ return;
245
+ } ?>
246
+
247
+ <tr class="plugin-update-tr">
248
+ <td colspan="3" class="plugin-update">
249
+ <div class="update-message">
250
+ <form action="<?php echo network_admin_url('plugins.php') ?>" method="post">
251
+ <input type="hidden" name="_optimus_action" value="verify" />
252
+ <?php wp_nonce_field('_optimus__key_nonce') ?>
253
+
254
+ <label for="_optimus_key">
255
+ Optimus HQ Key:
256
+ <input type="text" name="_optimus_key" id="_optimus_key" maxlength="24" pattern="[A-Z0-9]{17,24}" />
257
+ </label>
258
+
259
+ <input type="submit" name="submit" value="<?php _e("Activate", "optimus"); ?>" class="button button-primary regular" />
260
+ <a href="<?php echo network_admin_url('plugins.php') ?>" class="button"><?php _e("Cancel", "optimus"); ?></a>
261
+ </form>
262
+ </div>
263
+ </td>
264
+ </tr>
265
+
266
+ <style>
267
+ #optimus + .plugin-update-tr .update-message {
268
+ margin-top: 12px;
269
+ }
270
+ #optimus + .plugin-update-tr .update-message::before {
271
+ display: none;
272
+ }
273
+ #optimus + .plugin-update-tr label {
274
+ line-height: 30px;
275
+ vertical-align: top;
276
+ }
277
+ #optimus + .plugin-update-tr input[type="text"] {
278
+ width: 300px;
279
+ margin-left: 10px;
280
+ }
281
+ </style>
282
+ <?php }
283
+
284
+
285
+ /**
286
+ * Verify und store the Optimus HQ key
287
+ *
288
+ * @since 1.1.0
289
+ * @change 1.3.2
290
+ */
291
+
292
+ public static function verify_key_input()
293
+ {
294
+ /* Action check */
295
+ if ( empty($_POST['_optimus_action']) OR $_POST['_optimus_action'] !== 'verify' ) {
296
+ return;
297
+ }
298
+
299
+ /* Empty input? */
300
+ if ( empty($_POST['_optimus_key']) ) {
301
+ return;
302
+ }
303
+
304
+ /* Nonce check */
305
+ check_admin_referer('_optimus__key_nonce');
306
+
307
+ /* Capability check */
308
+ if ( ! current_user_can('manage_options') ) {
309
+ return;
310
+ }
311
+
312
+ /* Sanitize input */
313
+ $optimus_key = sanitize_text_field($_POST['_optimus_key']);
314
+
315
+ /* Advanced check */
316
+ if ( ! preg_match('/^[A-Z0-9]{17,24}$/', $optimus_key) ) {
317
+ return;
318
+ }
319
+
320
+ /* Delete purchase_time */
321
+ self::_delete_purchase_time();
322
+
323
+ /* Store current key */
324
+ self::_update_key($optimus_key);
325
+
326
+ /* Redirect */
327
+ wp_safe_redirect(
328
+ add_query_arg(
329
+ array(
330
+ '_optimus_notice' => ( self::is_locked() ? 'locked' : 'unlocked' )
331
+ ),
332
+ network_admin_url('plugins.php')
333
+ )
334
+ );
335
+
336
+ die();
337
+ }
338
+
339
+
340
+ /**
341
+ * Steuerung der Ausgabe von Admin-Notizen
342
+ *
343
+ * @since 1.1.0
344
+ * @change 1.2.0
345
+ */
346
+
347
+ public static function optimus_hq_notice()
348
+ {
349
+ /* Check admin pages */
350
+ if ( ! in_array($GLOBALS['pagenow'], array('plugins.php', 'index.php') ) ) {
351
+ return;
352
+ }
353
+
354
+ /* Get message type */
355
+ if ( ! empty($_GET['_optimus_notice']) && $_GET['_optimus_notice'] === 'unlocked' ) {
356
+ $type = 'unlocked';
357
+ } else if ( self::is_locked() ) {
358
+ if ( self::get_purchase_time() ) {
359
+ $type = 'expired';
360
+ } else if ( get_transient('optimus_activation_hook_in_use') ) {
361
+ $type = 'locked';
362
+ }
363
+ }
364
+
365
+ /* Empty? */
366
+ if ( empty($type) ) {
367
+ return;
368
+ }
369
+
370
+ /* Matching */
371
+ switch( $type ) {
372
+ case 'unlocked':
373
+ $msg = __("<p>Thank you for using <strong>Optimus HQ</strong>. Follow us on <a href=\"https://twitter.com/optimusHQ\" target=\"_blank\">Twitter</a> to get the latest news and updates.</p>", "optimus");
374
+ $class = 'updated';
375
+ break;
376
+
377
+ case 'locked':
378
+ $msg = __("<p><strong>Optimus</strong> is free of charge, the functionality is limited to the essential features.</p><p><strong>Optimus HQ</strong> (Premium) on the other hand can handle several image formats, compress larger files and connects through HTTPS. <span class=\"no-break\">More details on <a href=\"https://optimus.io\" target=\"_blank\">optimus.io</a></span><br /><br /><em>This information is displayed for 60 seconds and will not appear again.</em></p>", "optimus");
379
+ $class = 'error';
380
+ break;
381
+
382
+ case 'expired':
383
+ $msg = __("<p><strong>Optimus HQ license key</strong> has expired. Get a new Optimus HQ license key on <a href=\"https://optimus.io/en/\" target=\"_blank\">optimus.io</a>. Thank you!", "optimus");
384
+ $class = 'error';
385
+ break;
386
+
387
+ default:
388
+ return;
389
+ }
390
+
391
+ /* Output */
392
+ show_message(
393
+ sprintf(
394
+ '<div class="%s">%s</div>',
395
+ $class,
396
+ $msg
397
+ )
398
+ );
399
+ }
400
  }
inc/optimus_management.class.php CHANGED
@@ -16,11 +16,11 @@ class Optimus_Management
16
 
17
 
18
  /**
19
- * Bulk optimizer media
20
- *
21
- * @since 1.3.8
22
- * @change 1.4.4
23
- */
24
 
25
  public static function bulk_optimizer_media() {
26
  check_admin_referer('bulk-media');
@@ -39,42 +39,42 @@ class Optimus_Management
39
  }
40
 
41
 
42
- /**
43
- * Add bulk optimizer page
44
- *
45
- * @since 1.3.8
46
- * @change 1.3.8
47
- */
48
-
49
- public static function add_bulk_optimizer_page()
50
- {
51
  /* Management page */
52
- add_management_page(
53
  __("Optimus Bulk Optimizer", "optimus"),
54
  __("Optimize all images", "optimus"),
55
  'upload_files',
56
  'optimus-bulk-optimizer',
57
  array(
58
- __CLASS__,
59
- 'bulk_optimizer_page'
60
- )
61
  );
62
- }
63
 
64
 
65
  /**
66
- * Bulk optimizer page
67
- *
68
- * @since 1.3.8
69
- * @change 1.4.8
70
- *
71
- */
72
 
73
- public static function bulk_optimizer_page() {
74
- global $wpdb;
75
 
76
  /* Get plugin options */
77
- $options = Optimus::get_options();
78
 
79
  /* Check if images are already optimized */
80
  if ( $options['webp_convert'] ) {
@@ -105,32 +105,32 @@ class Optimus_Management
105
  $assets = $wpdb->get_results($query, ARRAY_A);
106
  $count = count($assets);
107
 
108
- echo '<div class="wrap" id="optimus-bulk-optimizer">';
109
- echo '<h2>' . __("Optimus Bulk Optimizer", "optimus") . '</h2>';
110
- if (empty($_POST['optimus-bulk-optimizer']) && empty($_GET['ids'])) {
111
- echo '<p>' . __("The Optimus bulk optimizer compresses all images that have not yet been compressed in your WordPress media library.", "optimus") . '</p>';
112
 
113
  if ( Optimus_HQ::is_locked() ) {
114
  echo '<p>' . __("It is recommended to run the bulk image optimization with an Optimus HQ activated version due to the size limitation of the free version.", "optimus") . '</p>';
115
- }
116
 
117
  echo '<p><em>' . sprintf(__("Optimus found <strong>%d images</strong> in your WordPress media library that can be optimized.", "optimus"), $count) . '</em></p>';
118
- echo '<form method="POST" action="?page=optimus-bulk-optimizer">';
119
- echo '<input type="hidden" name="_wpnonce" value="' . wp_create_nonce('optimus-bulk-optimizer') . '">';
120
- echo '<input type="hidden" name="optimus-bulk-optimizer" value="1">';
121
- echo '<p><input type="submit" name="submit" id="submit" class="button button-primary" value="'.__("Optimize all images", "optimus").'"></p>';
122
- echo '</form>';
123
- } else {
124
- check_admin_referer('optimus-bulk-optimizer');
125
- echo '<p>' . __("It might take a while until all images are optimized. This depends on the amount and size of the images.", "optimus") . '</p>';
126
- echo '<p><em>' . __("Note: Do not close this tab during the optimization process.", "optimus") . '</em></p>';
127
-
128
- echo '<div id="optimus-progress"><p>' . __("Completed", "optimus") . ' <span>0</span> / ' . sprintf(' %d </p></div>', $count);
129
- echo '<div id="media-items"></div>';
130
-
131
- echo '<script type="text/javascript">jQuery(function() { optimusBulkOptimizer('. json_encode($assets) . ')})</script>';
132
- }
133
-
134
- echo '</div>';
135
- }
136
  }
16
 
17
 
18
  /**
19
+ * Bulk optimizer media
20
+ *
21
+ * @since 1.3.8
22
+ * @change 1.4.4
23
+ */
24
 
25
  public static function bulk_optimizer_media() {
26
  check_admin_referer('bulk-media');
39
  }
40
 
41
 
42
+ /**
43
+ * Add bulk optimizer page
44
+ *
45
+ * @since 1.3.8
46
+ * @change 1.3.8
47
+ */
48
+
49
+ public static function add_bulk_optimizer_page()
50
+ {
51
  /* Management page */
52
+ add_management_page(
53
  __("Optimus Bulk Optimizer", "optimus"),
54
  __("Optimize all images", "optimus"),
55
  'upload_files',
56
  'optimus-bulk-optimizer',
57
  array(
58
+ __CLASS__,
59
+ 'bulk_optimizer_page'
60
+ )
61
  );
62
+ }
63
 
64
 
65
  /**
66
+ * Bulk optimizer page
67
+ *
68
+ * @since 1.3.8
69
+ * @change 1.4.8
70
+ *
71
+ */
72
 
73
+ public static function bulk_optimizer_page() {
74
+ global $wpdb;
75
 
76
  /* Get plugin options */
77
+ $options = Optimus::get_options();
78
 
79
  /* Check if images are already optimized */
80
  if ( $options['webp_convert'] ) {
105
  $assets = $wpdb->get_results($query, ARRAY_A);
106
  $count = count($assets);
107
 
108
+ echo '<div class="wrap" id="optimus-bulk-optimizer">';
109
+ echo '<h2>' . __("Optimus Bulk Optimizer", "optimus") . '</h2>';
110
+ if (empty($_POST['optimus-bulk-optimizer']) && empty($_GET['ids'])) {
111
+ echo '<p>' . __("The Optimus bulk optimizer compresses all images that have not yet been compressed in your WordPress media library.", "optimus") . '</p>';
112
 
113
  if ( Optimus_HQ::is_locked() ) {
114
  echo '<p>' . __("It is recommended to run the bulk image optimization with an Optimus HQ activated version due to the size limitation of the free version.", "optimus") . '</p>';
115
+ }
116
 
117
  echo '<p><em>' . sprintf(__("Optimus found <strong>%d images</strong> in your WordPress media library that can be optimized.", "optimus"), $count) . '</em></p>';
118
+ echo '<form method="POST" action="?page=optimus-bulk-optimizer">';
119
+ echo '<input type="hidden" name="_wpnonce" value="' . wp_create_nonce('optimus-bulk-optimizer') . '">';
120
+ echo '<input type="hidden" name="optimus-bulk-optimizer" value="1">';
121
+ echo '<p><input type="submit" name="submit" id="submit" class="button button-primary" value="'.__("Optimize all images", "optimus").'"></p>';
122
+ echo '</form>';
123
+ } else {
124
+ check_admin_referer('optimus-bulk-optimizer');
125
+ echo '<p>' . __("It might take a while until all images are optimized. This depends on the amount and size of the images.", "optimus") . '</p>';
126
+ echo '<p><em>' . __("Note: Do not close this tab during the optimization process.", "optimus") . '</em></p>';
127
+
128
+ echo '<div id="optimus-progress"><p>' . __("Completed", "optimus") . ' <span>0</span> / ' . sprintf(' %d </p></div>', $count);
129
+ echo '<div id="media-items"></div>';
130
+
131
+ echo '<script type="text/javascript">jQuery(function() { optimusBulkOptimizer('. json_encode($assets) . ')})</script>';
132
+ }
133
+
134
+ echo '</div>';
135
+ }
136
  }
inc/optimus_media.class.php CHANGED
@@ -15,116 +15,116 @@ class Optimus_Media
15
  {
16
 
17
 
18
- /**
19
- * Media column output
20
- *
21
- * @since 0.0.1
22
- * @change 1.3.0
23
- *
24
- * @param array $columns Available columns
25
- * @return array Renewed columns
26
- */
27
-
28
- public static function manage_columns($columns)
29
- {
30
- return array_merge(
31
- $columns,
32
- array(
33
- 'optimus' => 'Optimus'
34
- )
35
- );
36
- }
37
-
38
-
39
- /**
40
- * Print Optimus values as column
41
- *
42
- * @since 0.0.1
43
- * @change 1.3.0
44
- *
45
- * @param string $column Column name
46
- * @param integer $id Current object ID
47
- */
48
-
49
- public static function manage_column($column, $id)
50
- {
51
- /* Falsche Spalte? */
52
- if ( $column !== 'optimus' ) {
53
- return;
54
- }
55
-
56
- echo self::_column_html($id);
57
- }
58
-
59
-
60
- /**
61
- * Returns the formatted column as HTML
62
- *
63
- * @since 0.0.1
64
- * @change 1.3.0
65
- *
66
- * @param intval $id Object ID
67
- * @return string Column HTML
68
- */
69
-
70
- private static function _column_html($id)
71
- {
72
- /* Attachment metadata */
73
- $data = (array)wp_get_attachment_metadata($id);
74
-
75
- /* Data exists? */
76
- if ( empty($data['optimus']) OR ! is_array($data['optimus']) ) {
77
- return;
78
- }
79
-
80
- /* Array init */
81
- $optimus = $data['optimus'];
82
-
83
- /* Metadata exists? */
84
- if ( ! isset($optimus['quantity']) OR ! isset($optimus['profit']) ) {
85
- return;
86
- }
87
-
88
- return sprintf(
89
- '<div class="%s"><p>%d%%</p></div>',
90
- self::_pie_class(
91
- $optimus['quantity']
92
- ),
93
- $optimus['profit']
94
- );
95
- }
96
-
97
-
98
- /**
99
- * Specifies the CSS class depending on the amount of compressed files
100
- *
101
- * @since 0.0.8
102
- * @change 1.3.0
103
- *
104
- * @param intval $quantity File quantity
105
- * @return string Optimus CSS class
106
- */
107
-
108
- private static function _pie_class($quantity)
109
- {
110
- /* Init */
111
- $quantity = (int)$quantity;
112
-
113
- /* Leer? */
114
- if ( empty($quantity) ) {
115
- return '';
116
- }
117
-
118
- /* Loop */
119
- switch(true) {
120
- case ($quantity == 100):
121
- return 'four';
122
- case ($quantity <= 25):
123
- return 'one';
124
- case ($quantity <= 50):
125
- return 'two';
126
- default:
127
- return 'three';
128
- }
129
- }
130
  }
15
  {
16
 
17
 
18
+ /**
19
+ * Media column output
20
+ *
21
+ * @since 0.0.1
22
+ * @change 1.3.0
23
+ *
24
+ * @param array $columns Available columns
25
+ * @return array Renewed columns
26
+ */
27
+
28
+ public static function manage_columns($columns)
29
+ {
30
+ return array_merge(
31
+ $columns,
32
+ array(
33
+ 'optimus' => 'Optimus'
34
+ )
35
+ );
36
+ }
37
+
38
+
39
+ /**
40
+ * Print Optimus values as column
41
+ *
42
+ * @since 0.0.1
43
+ * @change 1.3.0
44
+ *
45
+ * @param string $column Column name
46
+ * @param integer $id Current object ID
47
+ */
48
+
49
+ public static function manage_column($column, $id)
50
+ {
51
+ /* Falsche Spalte? */
52
+ if ( $column !== 'optimus' ) {
53
+ return;
54
+ }
55
+
56
+ echo self::_column_html($id);
57
+ }
58
+
59
+
60
+ /**
61
+ * Returns the formatted column as HTML
62
+ *
63
+ * @since 0.0.1
64
+ * @change 1.3.0
65
+ *
66
+ * @param intval $id Object ID
67
+ * @return string Column HTML
68
+ */
69
+
70
+ private static function _column_html($id)
71
+ {
72
+ /* Attachment metadata */
73
+ $data = (array)wp_get_attachment_metadata($id);
74
+
75
+ /* Data exists? */
76
+ if ( empty($data['optimus']) OR ! is_array($data['optimus']) ) {
77
+ return;
78
+ }
79
+
80
+ /* Array init */
81
+ $optimus = $data['optimus'];
82
+
83
+ /* Metadata exists? */
84
+ if ( ! isset($optimus['quantity']) OR ! isset($optimus['profit']) ) {
85
+ return;
86
+ }
87
+
88
+ return sprintf(
89
+ '<div class="%s"><p>%d%%</p></div>',
90
+ self::_pie_class(
91
+ $optimus['quantity']
92
+ ),
93
+ $optimus['profit']
94
+ );
95
+ }
96
+
97
+
98
+ /**
99
+ * Specifies the CSS class depending on the amount of compressed files
100
+ *
101
+ * @since 0.0.8
102
+ * @change 1.3.0
103
+ *
104
+ * @param intval $quantity File quantity
105
+ * @return string Optimus CSS class
106
+ */
107
+
108
+ private static function _pie_class($quantity)
109
+ {
110
+ /* Init */
111
+ $quantity = (int)$quantity;
112
+
113
+ /* Leer? */
114
+ if ( empty($quantity) ) {
115
+ return '';
116
+ }
117
+
118
+ /* Loop */
119
+ switch(true) {
120
+ case ($quantity == 100):
121
+ return 'four';
122
+ case ($quantity <= 25):
123
+ return 'one';
124
+ case ($quantity <= 50):
125
+ return 'two';
126
+ default:
127
+ return 'three';
128
+ }
129
+ }
130
  }
inc/optimus_request.class.php CHANGED
@@ -15,664 +15,664 @@ class Optimus_Request
15
  {
16
 
17
 
18
- /**
19
- * Optimize image
20
- *
21
- * @var string
22
- */
23
-
24
- private static $_remote_scheme = 'http';
25
-
26
-
27
- /**
28
- * Image optimization post process (ajax)
29
- *
30
- * @since 1.3.8
31
- * @change 1.4.2
32
- *
33
- * @return json $metadata Update metadata information
34
- */
35
-
36
- public static function optimize_image() {
37
- if (!check_ajax_referer('optimus-optimize', '_nonce', false)) {
38
- exit();
39
- }
40
-
41
- /* check if valid request */
42
- if (empty($_POST['id'])) {
43
- $message = __("Invalid request", "optimus");
44
- echo json_encode(array('error' => $message));
45
- exit();
46
- }
47
- $id = intval($_POST['id']);
48
-
49
- /* check user permission */
50
- if (!current_user_can('upload_files')) {
51
- $message = __("Permission missing (upload_files)", "optimus");
52
- echo json_encode(array('error' => $message));
53
- exit();
54
- }
55
-
56
- /* get metadata */
57
- $metadata = wp_get_attachment_metadata($id);
58
- if (!is_array($metadata)) {
59
- $message = __("Metadata missing", "optimus");
60
- echo json_encode(array('error' => $message));
61
- exit;
62
- }
63
-
64
- /* optimize image */
65
- $optimus_metadata = self::optimize_upload_images($metadata, $id);
66
-
67
- if ( !empty($optimus_metadata['optimus']['error']) ) {
68
- echo json_encode(array('error' => $optimus_metadata['optimus']['error']));
69
- exit;
70
- }
71
-
72
- /* check if optimus array empty */
73
- if ( empty($optimus_metadata['optimus']) ) {
74
- echo json_encode(array('error' => __("Internal error", "optimus")));
75
- exit;
76
- }
77
-
78
- /* update metadata */
79
- update_post_meta($id, '_wp_attachment_metadata', $optimus_metadata);
80
-
81
- echo json_encode($optimus_metadata);
82
- exit;
83
- }
84
-
85
- /**
86
- * Image optimization for wp retina 2x
87
- *
88
- * @since 1.4.6
89
- * @change 1.4.7
90
- *
91
- * @param integer $attachment_id Attachment ID
92
- * @param string $upload_path_file_retina Retina file path
93
- */
94
-
95
- public static function optimize_wr2x_image($attachment_id, $upload_path_file_retina) {
96
- // get file size
97
- $upload_filesize = (int)filesize($upload_path_file_retina);
98
-
99
- /* Get the attachment */
100
- $attachment = get_post($attachment_id);
101
-
102
- // get mime type
103
- $mime_type = get_post_mime_type($attachment);
104
-
105
- // check mime type and size
106
- if ( self::_allowed_mime_type($mime_type) && self::_allowed_file_size($mime_type, $upload_filesize) ) {
107
- // get optimus plugin options
108
- $options = Optimus::get_options();
109
-
110
- // set https scheme
111
- if ( $options['secure_transport'] && Optimus_HQ::is_unlocked() ) {
112
- self::$_remote_scheme = 'https';
113
- }
114
-
115
- // request: optimize retina image
116
- self::_do_image_action(
117
- $upload_path_file_retina,
118
- array(
119
- 'file' => null,
120
- 'copy' => $options['copy_markers']
121
- )
122
- );
123
-
124
- // request: webp convert
125
- if ( $options['webp_convert'] && Optimus_HQ::is_unlocked() ) {
126
- self::_do_image_action(
127
- $upload_path_file_retina,
128
- array(
129
- 'file' => null,
130
- 'webp' => true
131
- )
132
- );
133
- }
134
- }
135
- }
136
-
137
-
138
- /**
139
- * Build optimization for a upload image including previews
140
- *
141
- * @since 0.0.1
142
- * @change 1.4.8
143
- *
144
- * @param array $upload_data Incoming upload information
145
- * @param integer $attachment_id Attachment ID
146
- * @return array $upload_data Renewed upload information
147
- */
148
-
149
- public static function optimize_upload_images($upload_data, $attachment_id) {
150
- /* Get plugin options */
151
- $options = Optimus::get_options();
152
-
153
- /* Already optimized? */
154
- if ( ( ! empty($upload_data['optimus']) && $options['webp_convert'] == 0 ) || ( ! empty($upload_data['optimus']['webp']) && $upload_data['optimus']['webp'] == 1 ) ) {
155
- return $upload_data;
156
- }
157
-
158
- /* Only images, please */
159
- if ( empty($upload_data['file']) ) {
160
- return $upload_data;
161
- }
162
-
163
- /* Skip regenerating */
164
- if ( ! empty($_POST['action']) && $_POST['action'] === 'regeneratethumbnail' ) {
165
- return $upload_data;
166
- }
167
-
168
- /* cURL only */
169
- if ( ! WP_Http_Curl::test() ) {
170
- return $upload_data;
171
- }
172
-
173
- /* WP upload folder */
174
- $upload_dir = wp_upload_dir();
175
-
176
- /* Upload dir workaround */
177
- if ( empty($upload_dir['subdir']) ) {
178
- $upload_path = $upload_dir['path'];
179
- $upload_url = $upload_dir['url'];
180
- $upload_file = $upload_data['file'];
181
- } else {
182
- $file_info = pathinfo($upload_data['file']);
183
- $upload_path = path_join($upload_dir['basedir'], $file_info['dirname']);
184
- $upload_url = path_join($upload_dir['baseurl'], $file_info['dirname']);
185
- $upload_file = $file_info['basename'];
186
- }
187
-
188
- /* Simple regex check */
189
- if ( ! preg_match('/^[^\?\%]+\.(?:jpe?g|png)$/i', $upload_file) ) {
190
- $upload_data['optimus']['error'] = __("Format not supported", "optimus");
191
- return $upload_data;
192
- }
193
-
194
- /* Get the attachment */
195
- $attachment = get_post($attachment_id);
196
-
197
- /* Attachment mime type */
198
- $mime_type = get_post_mime_type($attachment);
199
-
200
- /* Mime type check */
201
- if ( ! self::_allowed_mime_type($mime_type) ) {
202
- $upload_data['optimus']['error'] = __("Mime type not supported", "optimus");
203
- return $upload_data;
204
- }
205
-
206
- /* Init arrays */
207
- $todo_files = array();
208
- $diff_filesizes = array();
209
-
210
- /* Keep the master */
211
- if ( ! $options['keep_original'] ) {
212
- array_push(
213
- $todo_files,
214
- $upload_file
215
- );
216
- }
217
-
218
- /* Set https scheme */
219
- if ( $options['secure_transport'] && Optimus_HQ::is_unlocked() ) {
220
- self::$_remote_scheme = 'https';
221
- }
222
-
223
- /* Search for thumbs */
224
- if ( ! empty($upload_data['sizes']) ) {
225
- foreach( $upload_data['sizes'] as $thumb ) {
226
- if ( $thumb['file'] && ( empty($thumb['mime-type']) || self::_allowed_mime_type($thumb['mime-type']) ) ) {
227
- array_push(
228
- $todo_files,
229
- $thumb['file']
230
- );
231
- }
232
- }
233
-
234
- /* Reverse files array */
235
- $todo_files = array_reverse(
236
- array_unique($todo_files)
237
- );
238
- }
239
-
240
- /* No images to process */
241
- if ( empty($todo_files) ) {
242
- return $upload_data;
243
- }
244
-
245
- /* Loop todo files */
246
- foreach ($todo_files as $file) {
247
- /* Merge path & file */
248
- $upload_url_file = path_join($upload_url, $file);
249
- $upload_path_file = path_join($upload_path, $file);
250
-
251
- /* Get file size */
252
- $upload_filesize = (int)filesize($upload_path_file);
253
-
254
- /* Too big? */
255
- if ( ! self::_allowed_file_size($mime_type, $upload_filesize) ) {
256
- continue;
257
- }
258
-
259
- /* Encoded url */
260
- $upload_url_file_encoded = urlencode(
261
- esc_url_raw(
262
- $upload_url_file,
263
- array('http', 'https')
264
- )
265
- );
266
-
267
- /* Request: Optimize image */
268
- $action_response = self::_do_image_action(
269
- $upload_path_file,
270
- array(
271
- 'file' => $upload_url_file_encoded,
272
- 'copy' => $options['copy_markers']
273
- )
274
- );
275
-
276
- /* Get retina image [WP Retina 2x] */
277
- if ( function_exists( 'wr2x_get_retina' ) ) {
278
- $upload_path_file_retina = wr2x_get_retina( $upload_path_file );
279
- } else {
280
- $upload_path_file_retina = false;
281
- }
282
-
283
- /* Request: Optimize retina image [WP Retina 2x] */
284
- if ( ! empty($upload_path_file_retina) ) {
285
- self::_do_image_action(
286
- $upload_path_file_retina,
287
- array(
288
- 'file' => $upload_url_file_encoded,
289
- 'copy' => $options['copy_markers']
290
- )
291
- );
292
- }
293
-
294
- /* Evaluate response */
295
- if ( is_numeric($action_response) ) {
296
- // keep the size if nothing was optimized
297
- if ($action_response === 0) {
298
- $response_filesize = $upload_filesize;
299
- } else {
300
- $response_filesize = $action_response;
301
- }
302
- } else {
303
- // return error message
304
- $upload_data['optimus']['error'] = $action_response;
305
- return $upload_data;
306
- }
307
-
308
- /* Request: WebP convert */
309
- if ( $options['webp_convert'] && Optimus_HQ::is_unlocked() && self::_allowed_file_size($mime_type, $response_filesize) ) {
310
- self::_do_image_action(
311
- $upload_path_file,
312
- array(
313
- 'file' => $upload_url_file_encoded,
314
- 'webp' => true
315
- )
316
- );
317
-
318
- /* Convert retina image to webp [WP Retina 2x] */
319
- if ( ! empty($upload_path_file_retina) ) {
320
- self::_do_image_action(
321
- $upload_path_file_retina,
322
- array(
323
- 'file' => $upload_url_file_encoded,
324
- 'webp' => true
325
- )
326
- );
327
- }
328
- }
329
-
330
- /* File size difference */
331
- array_push(
332
- $diff_filesizes,
333
- self::_calculate_diff_filesize(
334
- $upload_filesize,
335
- $response_filesize
336
- )
337
- );
338
- }
339
-
340
- /* Count files */
341
- $ordered = count($todo_files);
342
- $received = count($diff_filesizes);
343
-
344
- /* Average values */
345
- if ( $received ) {
346
-
347
- /* Reallocate optimization results */
348
- if ( !empty($upload_data['optimus']['profit']) and ( $upload_data['optimus']['profit'] > max($diff_filesizes) ) ) {
349
- $profit = $upload_data['optimus']['profit'];
350
- $quantity = $upload_data['optimus']['quantity'];
351
- } else {
352
- $profit = max($diff_filesizes);
353
- $quantity = round( $received * 100 / $ordered );
354
- }
355
-
356
- $upload_data['optimus'] = array(
357
- 'profit' => $profit,
358
- 'quantity' => $quantity,
359
- 'webp' => $options['webp_convert']
360
- );
361
- }
362
-
363
- return $upload_data;
364
- }
365
-
366
-
367
- /**
368
- * Handle image actions
369
- *
370
- * @since 1.1.4
371
- * @change 1.4.8
372
- *
373
- * @param string $file Image file
374
- * @param array $args Request arguments
375
- * @return array Request failed with an error code
376
- * @return false An error has occurred
377
- * @return null Empty response with 204 status code
378
- * @return intval Response content length
379
- */
380
-
381
- private static function _do_image_action($file, $args)
382
- {
383
- /* Start request */
384
- $response = self::_do_api_request($file, $args);
385
-
386
- /* Response status code */
387
- $response_code = (int)wp_remote_retrieve_response_code($response);
388
-
389
- /* No content? return 0 */
390
- if ( $response_code === 204 ) {
391
- return 0;
392
- }
393
-
394
- /* Not success status code? $response->get_error_message() */
395
- if ( $response_code !== 200 ) {
396
- return 'code '.$response_code;
397
- }
398
-
399
- /* Response error? */
400
- if ( is_wp_error($response) ) {
401
- return get_error_message($response);
402
- }
403
-
404
- /* Response properties */
405
- $response_body = wp_remote_retrieve_body($response);
406
- $response_type = wp_remote_retrieve_header($response, 'content-type');
407
- $response_length = (int)wp_remote_retrieve_header($response, 'content-length');
408
-
409
- /* Empty file? */
410
- if ( empty($response_body) OR empty($response_type) OR empty($response_length) ) {
411
- return __("File empty", "optimus");
412
- }
413
-
414
- /* Mime type check */
415
- if ( ! self::_allowed_mime_type($response_type) ) {
416
- return __("Mime type not supported", "optimus");
417
- }
418
-
419
- /* Extension replace for WebP */
420
- if ( isset($args['webp']) ) {
421
- $file = self::_replace_file_extension(
422
- $file,
423
- 'webp'
424
- );
425
- }
426
-
427
- /* Rewrite image file */
428
- if ( ! file_put_contents($file, $response_body) ) {
429
- return __("Write operation failed", "optimus");
430
- }
431
-
432
- return $response_length;
433
- }
434
-
435
-
436
- /**
437
- * Optimus API request
438
- *
439
- * @since 1.1.4
440
- * @change 1.4.3
441
- *
442
- * @param string $file Image file
443
- * @param array $args Request arguments
444
- * @return array Response data
445
- */
446
-
447
- private static function _do_api_request($file, $args)
448
- {
449
- return wp_safe_remote_post(
450
- sprintf(
451
- '%s://%s.%s/%s?%s',
452
- self::$_remote_scheme,
453
  'magic',
454
  'optimus.io',
455
- Optimus_HQ::get_key(),
456
- self::_curl_optimus_task($args)
457
- ),
458
- array(
459
- 'body' => file_get_contents($file),
460
- 'timeout' => 180,
461
- 'headers' => array(
462
- 'Accept' => 'image/*'
463
- )
464
- )
465
- );
466
- }
467
-
468
-
469
- /**
470
- * Get optimus task depending on $args array
471
- *
472
- * @since 1.1.9
473
- * @change 1.1.9
474
- *
475
- * @param array $args Array mit arguments
476
- * @return string Current optimus task
477
- */
478
-
479
- private static function _curl_optimus_task($args)
480
- {
481
- if ( ! empty($args['copy']) ) {
482
- return 'clean';
483
- }
484
- if ( ! empty($args['webp']) ) {
485
- return 'webp';
486
- }
487
-
488
- return 'optimize';
489
- }
490
-
491
-
492
- /**
493
- * Adjustment of the file extension
494
- *
495
- * @since 1.1.4
496
- * @change 1.3.0
497
- *
498
- * @param string $file File path
499
- * @param string $extension Target extension
500
- * @return string Renewed file path
501
- */
502
-
503
- private static function _replace_file_extension($file, $extension)
504
- {
505
- return substr_replace(
506
- $file,
507
- $extension,
508
- strlen(pathinfo($file, PATHINFO_EXTENSION)) * -1
509
- );
510
- }
511
-
512
-
513
- /**
514
- * Prüfung des erlaubten Bildtyps pro Datei
515
- *
516
- * @since 1.1.0
517
- * @change 1.1.7
518
- *
519
- * @param string $mime_type Mime Type
520
- * @return boolean TRUE bei bestehender Prüfung
521
- */
522
-
523
- private static function _allowed_mime_type($mime_type)
524
- {
525
- /* Leer? */
526
- if ( empty($mime_type) ) {
527
- return false;
528
- }
529
-
530
- /* Quota-Prüfung */
531
- return array_key_exists(
532
- $mime_type,
533
- self::_get_request_quota()
534
- );
535
- }
536
-
537
-
538
- /**
539
- * Prüfung der erlaubten Bildgröße pro Dateityp
540
- *
541
- * @since 1.1.0
542
- * @change 1.1.7
543
- *
544
- * @param string $mime_type Mime Type
545
- * @param integer $file_size Bild-Größe
546
- * @return boolean TRUE bei bestehender Prüfung
547
- */
548
-
549
- private static function _allowed_file_size($mime_type, $file_size)
550
- {
551
- /* Leer? */
552
- if ( empty($file_size) ) {
553
- return false;
554
- }
555
-
556
- /* Quota */
557
- $request_quota = self::_get_request_quota();
558
-
559
- /* Zu groß? */
560
- if ( $file_size > $request_quota[$mime_type] ) {
561
- return false;
562
- }
563
-
564
- return true;
565
- }
566
-
567
-
568
- /**
569
- * Return Optimus quota for a plugin type
570
- *
571
- * @since 1.1.0
572
- * @change 1.4.0
573
- *
574
- * @return array Optimus quota
575
- */
576
-
577
- private static function _get_request_quota()
578
- {
579
- /* Quota */
580
- $quota = array(
581
- /* Optimus */
582
- false => array(
583
- 'image/jpeg' => 100 * 1024,
584
- 'image/png' => 100 * 1024
585
- ),
586
-
587
- /* Optimus HQ */
588
- true => array(
589
- 'image/jpeg' => 5000 * 1024,
590
- 'image/webp' => 5000 * 1024,
591
- 'image/png' => 5000 * 1024
592
- )
593
- );
594
-
595
- return $quota[ Optimus_HQ::is_unlocked() ];
596
- }
597
-
598
-
599
- /**
600
- * Löscht erzeugte WebP-Dateien
601
- *
602
- * @since 1.1.4
603
- * @change 1.4.6
604
- *
605
- * @param string $file Zu löschende Original-Datei
606
- * @return string $file Zu löschende Original-Datei
607
- */
608
-
609
- public static function delete_converted_file($file) {
610
- /* Plugin options */
611
- $options = Optimus::get_options();
612
-
613
- /* Nicht aktiv? */
614
- if ( ! $options['webp_convert'] OR Optimus_HQ::is_locked() ) {
615
- return $file;
616
- }
617
-
618
- /* Upload path */
619
- $upload_path = wp_upload_dir();
620
- $base_dir = $upload_path['basedir'];
621
-
622
- /* Init converted file */
623
- $converted_file = $file;
624
-
625
- /* Check for upload path */
626
- if ( strpos($converted_file, $base_dir) === false ) {
627
- $converted_file = path_join($base_dir, $converted_file);
628
- }
629
-
630
- /* Remove retina image if exists [WP Retina 2x] */
631
- $converted_file_retina = substr_replace(
632
- $converted_file,
633
- '@2x.webp',
634
- (strlen(pathinfo($file, PATHINFO_EXTENSION)) * -1 - 1)
635
- );
636
-
637
- if ( file_exists($converted_file_retina) ) {
638
- @unlink($converted_file_retina);
639
- }
640
-
641
- /* Replace to webp extension */
642
- $converted_file = self::_replace_file_extension(
643
- $converted_file,
644
- 'webp'
645
- );
646
-
647
- /* Remove if exists */
648
- if ( file_exists($converted_file) ) {
649
- @unlink($converted_file);
650
- }
651
-
652
- return $file;
653
- }
654
-
655
-
656
- /**
657
- * Ermittelt die Differenz der Dateigröße
658
- *
659
- * @since 0.0.1
660
- * @change 1.1.7
661
- *
662
- * @param intval $before Größe vor der Optimierung in Bytes
663
- * @param intval $after Größe nach der Optimierung in Bytes
664
- * @return intval Ermittelte Differenz
665
- */
666
-
667
- private static function _calculate_diff_filesize($before, $after)
668
- {
669
- /* Konvertieren */
670
- $before = (int)$before;
671
- $after = (int)$after;
672
-
673
- return sprintf(
674
- '%d',
675
- ceil( ($before - $after) * 100 / $before )
676
- );
677
- }
678
  }
15
  {
16
 
17
 
18
+ /**
19
+ * Optimize image
20
+ *
21
+ * @var string
22
+ */
23
+
24
+ private static $_remote_scheme = 'http';
25
+
26
+
27
+ /**
28
+ * Image optimization post process (ajax)
29
+ *
30
+ * @since 1.3.8
31
+ * @change 1.4.2
32
+ *
33
+ * @return json $metadata Update metadata information
34
+ */
35
+
36
+ public static function optimize_image() {
37
+ if (!check_ajax_referer('optimus-optimize', '_nonce', false)) {
38
+ exit();
39
+ }
40
+
41
+ /* check if valid request */
42
+ if (empty($_POST['id'])) {
43
+ $message = __("Invalid request", "optimus");
44
+ echo json_encode(array('error' => $message));
45
+ exit();
46
+ }
47
+ $id = intval($_POST['id']);
48
+
49
+ /* check user permission */
50
+ if (!current_user_can('upload_files')) {
51
+ $message = __("Permission missing (upload_files)", "optimus");
52
+ echo json_encode(array('error' => $message));
53
+ exit();
54
+ }
55
+
56
+ /* get metadata */
57
+ $metadata = wp_get_attachment_metadata($id);
58
+ if (!is_array($metadata)) {
59
+ $message = __("Metadata missing", "optimus");
60
+ echo json_encode(array('error' => $message));
61
+ exit;
62
+ }
63
+
64
+ /* optimize image */
65
+ $optimus_metadata = self::optimize_upload_images($metadata, $id);
66
+
67
+ if ( !empty($optimus_metadata['optimus']['error']) ) {
68
+ echo json_encode(array('error' => $optimus_metadata['optimus']['error']));
69
+ exit;
70
+ }
71
+
72
+ /* check if optimus array empty */
73
+ if ( empty($optimus_metadata['optimus']) ) {
74
+ echo json_encode(array('error' => __("Internal error", "optimus")));
75
+ exit;
76
+ }
77
+
78
+ /* update metadata */
79
+ update_post_meta($id, '_wp_attachment_metadata', $optimus_metadata);
80
+
81
+ echo json_encode($optimus_metadata);
82
+ exit;
83
+ }
84
+
85
+ /**
86
+ * Image optimization for wp retina 2x
87
+ *
88
+ * @since 1.4.6
89
+ * @change 1.4.7
90
+ *
91
+ * @param integer $attachment_id Attachment ID
92
+ * @param string $upload_path_file_retina Retina file path
93
+ */
94
+
95
+ public static function optimize_wr2x_image($attachment_id, $upload_path_file_retina) {
96
+ // get file size
97
+ $upload_filesize = (int)filesize($upload_path_file_retina);
98
+
99
+ /* Get the attachment */
100
+ $attachment = get_post($attachment_id);
101
+
102
+ // get mime type
103
+ $mime_type = get_post_mime_type($attachment);
104
+
105
+ // check mime type and size
106
+ if ( self::_allowed_mime_type($mime_type) && self::_allowed_file_size($mime_type, $upload_filesize) ) {
107
+ // get optimus plugin options
108
+ $options = Optimus::get_options();
109
+
110
+ // set https scheme
111
+ if ( $options['secure_transport'] && Optimus_HQ::is_unlocked() ) {
112
+ self::$_remote_scheme = 'https';
113
+ }
114
+
115
+ // request: optimize retina image
116
+ self::_do_image_action(
117
+ $upload_path_file_retina,
118
+ array(
119
+ 'file' => null,
120
+ 'copy' => $options['copy_markers']
121
+ )
122
+ );
123
+
124
+ // request: webp convert
125
+ if ( $options['webp_convert'] && Optimus_HQ::is_unlocked() ) {
126
+ self::_do_image_action(
127
+ $upload_path_file_retina,
128
+ array(
129
+ 'file' => null,
130
+ 'webp' => true
131
+ )
132
+ );
133
+ }
134
+ }
135
+ }
136
+
137
+
138
+ /**
139
+ * Build optimization for a upload image including previews
140
+ *
141
+ * @since 0.0.1
142
+ * @change 1.4.8
143
+ *
144
+ * @param array $upload_data Incoming upload information
145
+ * @param integer $attachment_id Attachment ID
146
+ * @return array $upload_data Renewed upload information
147
+ */
148
+
149
+ public static function optimize_upload_images($upload_data, $attachment_id) {
150
+ /* Get plugin options */
151
+ $options = Optimus::get_options();
152
+
153
+ /* Already optimized? */
154
+ if ( ( ! empty($upload_data['optimus']) && $options['webp_convert'] == 0 ) || ( ! empty($upload_data['optimus']['webp']) && $upload_data['optimus']['webp'] == 1 ) ) {
155
+ return $upload_data;
156
+ }
157
+
158
+ /* Only images, please */
159
+ if ( empty($upload_data['file']) ) {
160
+ return $upload_data;
161
+ }
162
+
163
+ /* Skip regenerating */
164
+ if ( ! empty($_POST['action']) && $_POST['action'] === 'regeneratethumbnail' ) {
165
+ return $upload_data;
166
+ }
167
+
168
+ /* cURL only */
169
+ if ( ! WP_Http_Curl::test() ) {
170
+ return $upload_data;
171
+ }
172
+
173
+ /* WP upload folder */
174
+ $upload_dir = wp_upload_dir();
175
+
176
+ /* Upload dir workaround */
177
+ if ( empty($upload_dir['subdir']) ) {
178
+ $upload_path = $upload_dir['path'];
179
+ $upload_url = $upload_dir['url'];
180
+ $upload_file = $upload_data['file'];
181
+ } else {
182
+ $file_info = pathinfo($upload_data['file']);
183
+ $upload_path = path_join($upload_dir['basedir'], $file_info['dirname']);
184
+ $upload_url = path_join($upload_dir['baseurl'], $file_info['dirname']);
185
+ $upload_file = $file_info['basename'];
186
+ }
187
+
188
+ /* Simple regex check */
189
+ if ( ! preg_match('/^[^\?\%]+\.(?:jpe?g|png)$/i', $upload_file) ) {
190
+ $upload_data['optimus']['error'] = __("Format not supported", "optimus");
191
+ return $upload_data;
192
+ }
193
+
194
+ /* Get the attachment */
195
+ $attachment = get_post($attachment_id);
196
+
197
+ /* Attachment mime type */
198
+ $mime_type = get_post_mime_type($attachment);
199
+
200
+ /* Mime type check */
201
+ if ( ! self::_allowed_mime_type($mime_type) ) {
202
+ $upload_data['optimus']['error'] = __("Mime type not supported", "optimus");
203
+ return $upload_data;
204
+ }
205
+
206
+ /* Init arrays */
207
+ $todo_files = array();
208
+ $diff_filesizes = array();
209
+
210
+ /* Keep the master */
211
+ if ( ! $options['keep_original'] ) {
212
+ array_push(
213
+ $todo_files,
214
+ $upload_file
215
+ );
216
+ }
217
+
218
+ /* Set https scheme */
219
+ if ( $options['secure_transport'] && Optimus_HQ::is_unlocked() ) {
220
+ self::$_remote_scheme = 'https';
221
+ }
222
+
223
+ /* Search for thumbs */
224
+ if ( ! empty($upload_data['sizes']) ) {
225
+ foreach( $upload_data['sizes'] as $thumb ) {
226
+ if ( $thumb['file'] && ( empty($thumb['mime-type']) || self::_allowed_mime_type($thumb['mime-type']) ) ) {
227
+ array_push(
228
+ $todo_files,
229
+ $thumb['file']
230
+ );
231
+ }
232
+ }
233
+
234
+ /* Reverse files array */
235
+ $todo_files = array_reverse(
236
+ array_unique($todo_files)
237
+ );
238
+ }
239
+
240
+ /* No images to process */
241
+ if ( empty($todo_files) ) {
242
+ return $upload_data;
243
+ }
244
+
245
+ /* Loop todo files */
246
+ foreach ($todo_files as $file) {
247
+ /* Merge path & file */
248
+ $upload_url_file = path_join($upload_url, $file);
249
+ $upload_path_file = path_join($upload_path, $file);
250
+
251
+ /* Get file size */
252
+ $upload_filesize = (int)filesize($upload_path_file);
253
+
254
+ /* Too big? */
255
+ if ( ! self::_allowed_file_size($mime_type, $upload_filesize) ) {
256
+ continue;
257
+ }
258
+
259
+ /* Encoded url */
260
+ $upload_url_file_encoded = urlencode(
261
+ esc_url_raw(
262
+ $upload_url_file,
263
+ array('http', 'https')
264
+ )
265
+ );
266
+
267
+ /* Request: Optimize image */
268
+ $action_response = self::_do_image_action(
269
+ $upload_path_file,
270
+ array(
271
+ 'file' => $upload_url_file_encoded,
272
+ 'copy' => $options['copy_markers']
273
+ )
274
+ );
275
+
276
+ /* Get retina image [WP Retina 2x] */
277
+ if ( function_exists( 'wr2x_get_retina' ) ) {
278
+ $upload_path_file_retina = wr2x_get_retina( $upload_path_file );
279
+ } else {
280
+ $upload_path_file_retina = false;
281
+ }
282
+
283
+ /* Request: Optimize retina image [WP Retina 2x] */
284
+ if ( ! empty($upload_path_file_retina) ) {
285
+ self::_do_image_action(
286
+ $upload_path_file_retina,
287
+ array(
288
+ 'file' => $upload_url_file_encoded,
289
+ 'copy' => $options['copy_markers']
290
+ )
291
+ );
292
+ }
293
+
294
+ /* Evaluate response */
295
+ if ( is_numeric($action_response) ) {
296
+ // keep the size if nothing was optimized
297
+ if ($action_response === 0) {
298
+ $response_filesize = $upload_filesize;
299
+ } else {
300
+ $response_filesize = $action_response;
301
+ }
302
+ } else {
303
+ // return error message
304
+ $upload_data['optimus']['error'] = $action_response;
305
+ return $upload_data;
306
+ }
307
+
308
+ /* Request: WebP convert */
309
+ if ( $options['webp_convert'] && Optimus_HQ::is_unlocked() && self::_allowed_file_size($mime_type, $response_filesize) ) {
310
+ self::_do_image_action(
311
+ $upload_path_file,
312
+ array(
313
+ 'file' => $upload_url_file_encoded,
314
+ 'webp' => true
315
+ )
316
+ );
317
+
318
+ /* Convert retina image to webp [WP Retina 2x] */
319
+ if ( ! empty($upload_path_file_retina) ) {
320
+ self::_do_image_action(
321
+ $upload_path_file_retina,
322
+ array(
323
+ 'file' => $upload_url_file_encoded,
324
+ 'webp' => true
325
+ )
326
+ );
327
+ }
328
+ }
329
+
330
+ /* File size difference */
331
+ array_push(
332
+ $diff_filesizes,
333
+ self::_calculate_diff_filesize(
334
+ $upload_filesize,
335
+ $response_filesize
336
+ )
337
+ );
338
+ }
339
+
340
+ /* Count files */
341
+ $ordered = count($todo_files);
342
+ $received = count($diff_filesizes);
343
+
344
+ /* Average values */
345
+ if ( $received ) {
346
+
347
+ /* Reallocate optimization results */
348
+ if ( !empty($upload_data['optimus']['profit']) and ( $upload_data['optimus']['profit'] > max($diff_filesizes) ) ) {
349
+ $profit = $upload_data['optimus']['profit'];
350
+ $quantity = $upload_data['optimus']['quantity'];
351
+ } else {
352
+ $profit = max($diff_filesizes);
353
+ $quantity = round( $received * 100 / $ordered );
354
+ }
355
+
356
+ $upload_data['optimus'] = array(
357
+ 'profit' => $profit,
358
+ 'quantity' => $quantity,
359
+ 'webp' => $options['webp_convert']
360
+ );
361
+ }
362
+
363
+ return $upload_data;
364
+ }
365
+
366
+
367
+ /**
368
+ * Handle image actions
369
+ *
370
+ * @since 1.1.4
371
+ * @change 1.4.8
372
+ *
373
+ * @param string $file Image file
374
+ * @param array $args Request arguments
375
+ * @return array Request failed with an error code
376
+ * @return false An error has occurred
377
+ * @return null Empty response with 204 status code
378
+ * @return intval Response content length
379
+ */
380
+
381
+ private static function _do_image_action($file, $args)
382
+ {
383
+ /* Start request */
384
+ $response = self::_do_api_request($file, $args);
385
+
386
+ /* Response status code */
387
+ $response_code = (int)wp_remote_retrieve_response_code($response);
388
+
389
+ /* No content? return 0 */
390
+ if ( $response_code === 204 ) {
391
+ return 0;
392
+ }
393
+
394
+ /* Not success status code? $response->get_error_message() */
395
+ if ( $response_code !== 200 ) {
396
+ return 'code '.$response_code;
397
+ }
398
+
399
+ /* Response error? */
400
+ if ( is_wp_error($response) ) {
401
+ return get_error_message($response);
402
+ }
403
+
404
+ /* Response properties */
405
+ $response_body = wp_remote_retrieve_body($response);
406
+ $response_type = wp_remote_retrieve_header($response, 'content-type');
407
+ $response_length = (int)wp_remote_retrieve_header($response, 'content-length');
408
+
409
+ /* Empty file? */
410
+ if ( empty($response_body) OR empty($response_type) OR empty($response_length) ) {
411
+ return __("File empty", "optimus");
412
+ }
413
+
414
+ /* Mime type check */
415
+ if ( ! self::_allowed_mime_type($response_type) ) {
416
+ return __("Mime type not supported", "optimus");
417
+ }
418
+
419
+ /* Extension replace for WebP */
420
+ if ( isset($args['webp']) ) {
421
+ $file = self::_replace_file_extension(
422
+ $file,
423
+ 'webp'
424
+ );
425
+ }
426
+
427
+ /* Rewrite image file */
428
+ if ( ! file_put_contents($file, $response_body) ) {
429
+ return __("Write operation failed", "optimus");
430
+ }
431
+
432
+ return $response_length;
433
+ }
434
+
435
+
436
+ /**
437
+ * Optimus API request
438
+ *
439
+ * @since 1.1.4
440
+ * @change 1.4.3
441
+ *
442
+ * @param string $file Image file
443
+ * @param array $args Request arguments
444
+ * @return array Response data
445
+ */
446
+
447
+ private static function _do_api_request($file, $args)
448
+ {
449
+ return wp_safe_remote_post(
450
+ sprintf(
451
+ '%s://%s.%s/%s?%s',
452
+ self::$_remote_scheme,
453
  'magic',
454
  'optimus.io',
455
+ Optimus_HQ::get_key(),
456
+ self::_curl_optimus_task($args)
457
+ ),
458
+ array(
459
+ 'body' => file_get_contents($file),
460
+ 'timeout' => 180,
461
+ 'headers' => array(
462
+ 'Accept' => 'image/*'
463
+ )
464
+ )
465
+ );
466
+ }
467
+
468
+
469
+ /**
470
+ * Get optimus task depending on $args array
471
+ *
472
+ * @since 1.1.9
473
+ * @change 1.1.9
474
+ *
475
+ * @param array $args Array mit arguments
476
+ * @return string Current optimus task
477
+ */
478
+
479
+ private static function _curl_optimus_task($args)
480
+ {
481
+ if ( ! empty($args['copy']) ) {
482
+ return 'clean';
483
+ }
484
+ if ( ! empty($args['webp']) ) {
485
+ return 'webp';
486
+ }
487
+
488
+ return 'optimize';
489
+ }
490
+
491
+
492
+ /**
493
+ * Adjustment of the file extension
494
+ *
495
+ * @since 1.1.4
496
+ * @change 1.3.0
497
+ *
498
+ * @param string $file File path
499
+ * @param string $extension Target extension
500
+ * @return string Renewed file path
501
+ */
502
+
503
+ private static function _replace_file_extension($file, $extension)
504
+ {
505
+ return substr_replace(
506
+ $file,
507
+ $extension,
508
+ strlen(pathinfo($file, PATHINFO_EXTENSION)) * -1
509
+ );
510
+ }
511
+
512
+
513
+ /**
514
+ * Prüfung des erlaubten Bildtyps pro Datei
515
+ *
516
+ * @since 1.1.0
517
+ * @change 1.1.7
518
+ *
519
+ * @param string $mime_type Mime Type
520
+ * @return boolean TRUE bei bestehender Prüfung
521
+ */
522
+
523
+ private static function _allowed_mime_type($mime_type)
524
+ {
525
+ /* Leer? */
526
+ if ( empty($mime_type) ) {
527
+ return false;
528
+ }
529
+
530
+ /* Quota-Prüfung */
531
+ return array_key_exists(
532
+ $mime_type,
533
+ self::_get_request_quota()
534
+ );
535
+ }
536
+
537
+
538
+ /**
539
+ * Prüfung der erlaubten Bildgröße pro Dateityp
540
+ *
541
+ * @since 1.1.0
542
+ * @change 1.1.7
543
+ *
544
+ * @param string $mime_type Mime Type
545
+ * @param integer $file_size Bild-Größe
546
+ * @return boolean TRUE bei bestehender Prüfung
547
+ */
548
+
549
+ private static function _allowed_file_size($mime_type, $file_size)
550
+ {
551
+ /* Leer? */
552
+ if ( empty($file_size) ) {
553
+ return false;
554
+ }
555
+
556
+ /* Quota */
557
+ $request_quota = self::_get_request_quota();
558
+
559
+ /* Zu groß? */
560
+ if ( $file_size > $request_quota[$mime_type] ) {
561
+ return false;
562
+ }
563
+
564
+ return true;
565
+ }
566
+
567
+
568
+ /**
569
+ * Return Optimus quota for a plugin type
570
+ *
571
+ * @since 1.1.0
572
+ * @change 1.4.0
573
+ *
574
+ * @return array Optimus quota
575
+ */
576
+
577
+ private static function _get_request_quota()
578
+ {
579
+ /* Quota */
580
+ $quota = array(
581
+ /* Optimus */
582
+ false => array(
583
+ 'image/jpeg' => 100 * 1024,
584
+ 'image/png' => 100 * 1024
585
+ ),
586
+
587
+ /* Optimus HQ */
588
+ true => array(
589
+ 'image/jpeg' => 5000 * 1024,
590
+ 'image/webp' => 5000 * 1024,
591
+ 'image/png' => 5000 * 1024
592
+ )
593
+ );
594
+
595
+ return $quota[ Optimus_HQ::is_unlocked() ];
596
+ }
597
+
598
+
599
+ /**
600
+ * Löscht erzeugte WebP-Dateien
601
+ *
602
+ * @since 1.1.4
603
+ * @change 1.4.6
604
+ *
605
+ * @param string $file Zu löschende Original-Datei
606
+ * @return string $file Zu löschende Original-Datei
607
+ */
608
+
609
+ public static function delete_converted_file($file) {
610
+ /* Plugin options */
611
+ $options = Optimus::get_options();
612
+
613
+ /* Nicht aktiv? */
614
+ if ( ! $options['webp_convert'] OR Optimus_HQ::is_locked() ) {
615
+ return $file;
616
+ }
617
+
618
+ /* Upload path */
619
+ $upload_path = wp_upload_dir();
620
+ $base_dir = $upload_path['basedir'];
621
+
622
+ /* Init converted file */
623
+ $converted_file = $file;
624
+
625
+ /* Check for upload path */
626
+ if ( strpos($converted_file, $base_dir) === false ) {
627
+ $converted_file = path_join($base_dir, $converted_file);
628
+ }
629
+
630
+ /* Remove retina image if exists [WP Retina 2x] */
631
+ $converted_file_retina = substr_replace(
632
+ $converted_file,
633
+ '@2x.webp',
634
+ (strlen(pathinfo($file, PATHINFO_EXTENSION)) * -1 - 1)
635
+ );
636
+
637
+ if ( file_exists($converted_file_retina) ) {
638
+ @unlink($converted_file_retina);
639
+ }
640
+
641
+ /* Replace to webp extension */
642
+ $converted_file = self::_replace_file_extension(
643
+ $converted_file,
644
+ 'webp'
645
+ );
646
+
647
+ /* Remove if exists */
648
+ if ( file_exists($converted_file) ) {
649
+ @unlink($converted_file);
650
+ }
651
+
652
+ return $file;
653
+ }
654
+
655
+
656
+ /**
657
+ * Ermittelt die Differenz der Dateigröße
658
+ *
659
+ * @since 0.0.1
660
+ * @change 1.1.7
661
+ *
662
+ * @param intval $before Größe vor der Optimierung in Bytes
663
+ * @param intval $after Größe nach der Optimierung in Bytes
664
+ * @return intval Ermittelte Differenz
665
+ */
666
+
667
+ private static function _calculate_diff_filesize($before, $after)
668
+ {
669
+ /* Konvertieren */
670
+ $before = (int)$before;
671
+ $after = (int)$after;
672
+
673
+ return sprintf(
674
+ '%d',
675
+ ceil( ($before - $after) * 100 / $before )
676
+ );
677
+ }
678
  }
inc/optimus_settings.class.php CHANGED
@@ -15,208 +15,208 @@ class Optimus_Settings
15
  {
16
 
17
 
18
- /**
19
- * Registrierung der Settings
20
- *
21
- * @since 1.0.0
22
- * @change 1.3.1
23
- */
24
-
25
- public static function register_settings()
26
- {
27
- register_setting(
28
- 'optimus',
29
- 'optimus',
30
- array(
31
- __CLASS__,
32
- 'validate_settings'
33
- )
34
- );
35
- }
36
-
37
-
38
- /**
39
- * Valisierung der Optionsseite
40
- *
41
- * @since 1.0.0
42
- * @change 1.4.0
43
- *
44
- * @param array $data Array mit Formularwerten
45
- * @return array Array mit geprüften Werten
46
- */
47
-
48
- public static function validate_settings($data)
49
- {
50
- return array(
51
- 'copy_markers' => (int)(!empty($data['copy_markers'])),
52
- 'webp_convert' => (int)(!empty($data['webp_convert'])),
53
- 'keep_original' => (int)(!empty($data['keep_original'])),
54
- 'secure_transport' => (int)(!empty($data['secure_transport'])),
55
- 'manual_optimize' => (int)(!empty($data['manual_optimize']))
56
- );
57
- }
58
-
59
-
60
- /**
61
- * Einfügen der Optionsseite
62
- *
63
- * @since 1.0.0
64
- * @change 1.3.1
65
- */
66
-
67
- public static function add_page()
68
- {
69
- $page = add_options_page(
70
- 'Optimus',
71
- 'Optimus',
72
- 'manage_options',
73
- 'optimus',
74
- array(
75
- __CLASS__,
76
- 'settings_page'
77
- )
78
- );
79
- }
80
-
81
-
82
- /**
83
- * Darstellung der Optionsseite
84
- *
85
- * @since 1.0.0
86
- * @change 1.4.0
87
- *
88
- * @return void
89
- */
90
-
91
- public static function settings_page()
92
- { ?>
93
- <div class="wrap">
94
- <h2>
95
- <?php _e("Optimus Settings", "optimus"); ?>
96
- </h2>
97
-
98
- <div class="updated"><p><?php _e("Need to optimize all your existing images? Use the <strong><a href=\"".admin_url('tools.php?page=optimus-bulk-optimizer')."\">Optimus Bulk Optimizer</a></strong>.", "optimus"); ?></p></div>
99
-
100
- <form method="post" action="options.php">
101
- <?php settings_fields('optimus') ?>
102
-
103
- <?php $options = Optimus::get_options() ?>
104
-
105
- <table class="form-table">
106
- <?php if ( $sizes = get_intermediate_image_sizes() ) { ?>
107
- <tr valign="top">
108
- <th scope="row">
109
- <?php _e("Image sizes", "optimus"); ?>
110
- </th>
111
- <td>
112
- <p>
113
- <?php echo implode( ', ', array_values($sizes) ) ?>
114
- </p>
115
-
116
- <p class="description">
117
- <?php _e("In addition to the original image, Optimus compresses the registered image sizes in WordPress. [<a href=\"https://optimus.keycdn.com/support/optimus-settings/#compression-thumbnail-images\" target=\"_blank\">Details</a>]", "optimus"); ?>
118
- </p>
119
- <br>
120
- <p class="description">
121
- <?php if ( Optimus_HQ::is_locked() ) { _e("The size limit of the free version of Optimus is <strong>100 KB</strong>. Do you want to compress larger images? Get a license for <a href=\"https://optimus.io\" target=\"_blank\">Optimus HQ</a>.", "optimus"); } ?>
122
- </p>
123
- </td>
124
- </tr>
125
- <?php } ?>
126
-
127
- <tr valign="top">
128
- <th scope="row">
129
- <?php _e("Original images", "optimus"); ?>
130
- </th>
131
- <td>
132
- <fieldset>
133
- <label for="optimus_keep_original">
134
- <input type="checkbox" name="optimus[keep_original]" id="optimus_keep_original" value="1" <?php checked(1, $options['keep_original']) ?> />
135
- <?php _e("No optimization of original images", "optimus"); ?>
136
- </label>
137
-
138
- <p class="description">
139
- <?php _e("Optimus only compresses preview images (Thumbnails). Original images uploaded to WordPress are not affected. [<a href=\"https://optimus.keycdn.com/support/optimus-settings/#optimization-original-images\" target=\"_blank\">Details</a>]", "optimus"); ?>
140
- </p>
141
- </fieldset>
142
- </td>
143
- </tr>
144
-
145
- <tr valign="top">
146
- <th scope="row">
147
- <?php _e("Image metadata", "optimus"); ?>
148
- </th>
149
- <td>
150
- <fieldset>
151
- <label for="optimus_copy_markers">
152
- <input type="checkbox" name="optimus[copy_markers]" id="optimus_copy_markers" value="1" <?php checked(1, $options['copy_markers']) ?> />
153
- <?php _e("No deletion of image metadata", "optimus"); ?>
154
- </label>
155
-
156
- <p class="description">
157
- <?php _e("Only <a href=\"https://optimus.io\" target=\"_blank\">Optimus HQ</a>. Active option keeps EXIF-, copyright and photo creation information in images. Size reduction is less significant. [<a href=\"https://optimus.keycdn.com/support/optimus-settings/#remove-metadata\" target=\"_blank\">Details</a>]", "optimus"); ?>
158
- </p>
159
- </fieldset>
160
- </td>
161
- </tr>
162
-
163
- <tr valign="top">
164
- <th scope="row">
165
- <?php _e("WebP files", "optimus"); ?>
166
- </th>
167
- <td>
168
- <fieldset>
169
- <label for="optimus_webp_convert">
170
- <input type="checkbox" name="optimus[webp_convert]" id="optimus_webp_convert" value="1" <?php checked(1, $options['webp_convert']) ?> />
171
- <?php _e("Creation of WebP files", "optimus"); ?>
172
- </label>
173
-
174
- <p class="description">
175
- <?php _e("Only <a href=\"https://optimus.io\" target=\"_blank\">Optimus HQ</a>. It is recommended to use the <a href=\"https://wordpress.org/plugins/cache-enabler/\">Cache Enabler plugin</a> to integrate the WebP images. [<a href=\"https://optimus.keycdn.com/support/optimus-settings/#convert-to-webp\" target=\"_blank\">Details</a>]", "optimus"); ?>
176
- </p>
177
- </fieldset>
178
- </td>
179
- </tr>
180
-
181
- <tr valign="top">
182
- <th scope="row">
183
- <?php _e("HTTPS connection", "optimus"); ?>
184
- </th>
185
- <td>
186
- <fieldset>
187
- <label for="optimus_secure_transport">
188
- <input type="checkbox" name="optimus[secure_transport]" id="optimus_secure_transport" value="1" <?php checked(1, $options['secure_transport']) ?> />
189
- <?php _e("Transfer images using TLS encryption", "optimus"); ?>
190
- </label>
191
-
192
- <p class="description">
193
- <?php _e("Only <a href=\"https://optimus.io\" target=\"_blank\">Optimus HQ</a>. Communication with the Optimus server is conducted through an HTTPS connection. Slightly slows down the optimization process.", "optimus"); ?>
194
- </p>
195
- </fieldset>
196
- </td>
197
- </tr>
198
-
199
- <tr valign="top">
200
- <th scope="row">
201
- <?php _e("Optimize during upload", "optimus"); ?>
202
- </th>
203
- <td>
204
- <fieldset>
205
- <label for="optimus_manual_optimize">
206
- <input type="checkbox" name="optimus[manual_optimize]" id="optimus_manual_optimize" value="1" <?php checked(1, $options['manual_optimize']) ?> />
207
- <?php _e("No optimization of images during the upload process", "optimus"); ?>
208
- </label>
209
-
210
- <p class="description">
211
- <?php _e("This setting prevents the automatic optimization during the upload process. Images need to be optimized via the Media Library later on. [<a href=\"https://optimus.keycdn.com/support/image-bulk-optimization/\" target=\"_blank\">Details</a>]", "optimus"); ?>
212
- </p>
213
- </fieldset>
214
- </td>
215
- </tr>
216
- </table>
217
-
218
- <?php submit_button() ?>
219
- </form>
220
- </div><?php
221
- }
222
  }
15
  {
16
 
17
 
18
+ /**
19
+ * Registrierung der Settings
20
+ *
21
+ * @since 1.0.0
22
+ * @change 1.3.1
23
+ */
24
+
25
+ public static function register_settings()
26
+ {
27
+ register_setting(
28
+ 'optimus',
29
+ 'optimus',
30
+ array(
31
+ __CLASS__,
32
+ 'validate_settings'
33
+ )
34
+ );
35
+ }
36
+
37
+
38
+ /**
39
+ * Valisierung der Optionsseite
40
+ *
41
+ * @since 1.0.0
42
+ * @change 1.4.0
43
+ *
44
+ * @param array $data Array mit Formularwerten
45
+ * @return array Array mit geprüften Werten
46
+ */
47
+
48
+ public static function validate_settings($data)
49
+ {
50
+ return array(
51
+ 'copy_markers' => (int)(!empty($data['copy_markers'])),
52
+ 'webp_convert' => (int)(!empty($data['webp_convert'])),
53
+ 'keep_original' => (int)(!empty($data['keep_original'])),
54
+ 'secure_transport' => (int)(!empty($data['secure_transport'])),
55
+ 'manual_optimize' => (int)(!empty($data['manual_optimize']))
56
+ );
57
+ }
58
+
59
+
60
+ /**
61
+ * Einfügen der Optionsseite
62
+ *
63
+ * @since 1.0.0
64
+ * @change 1.3.1
65
+ */
66
+
67
+ public static function add_page()
68
+ {
69
+ $page = add_options_page(
70
+ 'Optimus',
71
+ 'Optimus',
72
+ 'manage_options',
73
+ 'optimus',
74
+ array(
75
+ __CLASS__,
76
+ 'settings_page'
77
+ )
78
+ );
79
+ }
80
+
81
+
82
+ /**
83
+ * Darstellung der Optionsseite
84
+ *
85
+ * @since 1.0.0
86
+ * @change 1.4.0
87
+ *
88
+ * @return void
89
+ */
90
+
91
+ public static function settings_page()
92
+ { ?>
93
+ <div class="wrap">
94
+ <h2>
95
+ <?php _e("Optimus Settings", "optimus"); ?>
96
+ </h2>
97
+
98
+ <div class="updated"><p><?php _e("Need to optimize all your existing images? Use the <strong><a href=\"".admin_url('tools.php?page=optimus-bulk-optimizer')."\">Optimus Bulk Optimizer</a></strong>.", "optimus"); ?></p></div>
99
+
100
+ <form method="post" action="options.php">
101
+ <?php settings_fields('optimus') ?>
102
+
103
+ <?php $options = Optimus::get_options() ?>
104
+
105
+ <table class="form-table">
106
+ <?php if ( $sizes = get_intermediate_image_sizes() ) { ?>
107
+ <tr valign="top">
108
+ <th scope="row">
109
+ <?php _e("Image sizes", "optimus"); ?>
110
+ </th>
111
+ <td>
112
+ <p>
113
+ <?php echo implode( ', ', array_values($sizes) ) ?>
114
+ </p>
115
+
116
+ <p class="description">
117
+ <?php _e("In addition to the original image, Optimus compresses the registered image sizes in WordPress. [<a href=\"https://optimus.keycdn.com/support/optimus-settings/#compression-thumbnail-images\" target=\"_blank\">Details</a>]", "optimus"); ?>
118
+ </p>
119
+ <br>
120
+ <p class="description">
121
+ <?php if ( Optimus_HQ::is_locked() ) { _e("The size limit of the free version of Optimus is <strong>100 KB</strong>. Do you want to compress larger images? Get a license for <a href=\"https://optimus.io\" target=\"_blank\">Optimus HQ</a>.", "optimus"); } ?>
122
+ </p>
123
+ </td>
124
+ </tr>
125
+ <?php } ?>
126
+
127
+ <tr valign="top">
128
+ <th scope="row">
129
+ <?php _e("Original images", "optimus"); ?>
130
+ </th>
131
+ <td>
132
+ <fieldset>
133
+ <label for="optimus_keep_original">
134
+ <input type="checkbox" name="optimus[keep_original]" id="optimus_keep_original" value="1" <?php checked(1, $options['keep_original']) ?> />
135
+ <?php _e("No optimization of original images", "optimus"); ?>
136
+ </label>
137
+
138
+ <p class="description">
139
+ <?php _e("Optimus only compresses preview images (Thumbnails). Original images uploaded to WordPress are not affected. [<a href=\"https://optimus.keycdn.com/support/optimus-settings/#optimization-original-images\" target=\"_blank\">Details</a>]", "optimus"); ?>
140
+ </p>
141
+ </fieldset>
142
+ </td>
143
+ </tr>
144
+
145
+ <tr valign="top">
146
+ <th scope="row">
147
+ <?php _e("Image metadata", "optimus"); ?>
148
+ </th>
149
+ <td>
150
+ <fieldset>
151
+ <label for="optimus_copy_markers">
152
+ <input type="checkbox" name="optimus[copy_markers]" id="optimus_copy_markers" value="1" <?php checked(1, $options['copy_markers']) ?> />
153
+ <?php _e("No deletion of image metadata", "optimus"); ?>
154
+ </label>
155
+
156
+ <p class="description">
157
+ <?php _e("Only <a href=\"https://optimus.io\" target=\"_blank\">Optimus HQ</a>. Active option keeps EXIF-, copyright and photo creation information in images. Size reduction is less significant. [<a href=\"https://optimus.keycdn.com/support/optimus-settings/#remove-metadata\" target=\"_blank\">Details</a>]", "optimus"); ?>
158
+ </p>
159
+ </fieldset>
160
+ </td>
161
+ </tr>
162
+
163
+ <tr valign="top">
164
+ <th scope="row">
165
+ <?php _e("WebP files", "optimus"); ?>
166
+ </th>
167
+ <td>
168
+ <fieldset>
169
+ <label for="optimus_webp_convert">
170
+ <input type="checkbox" name="optimus[webp_convert]" id="optimus_webp_convert" value="1" <?php checked(1, $options['webp_convert']) ?> />
171
+ <?php _e("Creation of WebP files", "optimus"); ?>
172
+ </label>
173
+
174
+ <p class="description">
175
+ <?php _e("Only <a href=\"https://optimus.io\" target=\"_blank\">Optimus HQ</a>. It is recommended to use the <a href=\"https://wordpress.org/plugins/cache-enabler/\">Cache Enabler plugin</a> to integrate the WebP images. [<a href=\"https://optimus.keycdn.com/support/optimus-settings/#convert-to-webp\" target=\"_blank\">Details</a>]", "optimus"); ?>
176
+ </p>
177
+ </fieldset>
178
+ </td>
179
+ </tr>
180
+
181
+ <tr valign="top">
182
+ <th scope="row">
183
+ <?php _e("HTTPS connection", "optimus"); ?>
184
+ </th>
185
+ <td>
186
+ <fieldset>
187
+ <label for="optimus_secure_transport">
188
+ <input type="checkbox" name="optimus[secure_transport]" id="optimus_secure_transport" value="1" <?php checked(1, $options['secure_transport']) ?> />
189
+ <?php _e("Transfer images using TLS encryption", "optimus"); ?>
190
+ </label>
191
+
192
+ <p class="description">
193
+ <?php _e("Only <a href=\"https://optimus.io\" target=\"_blank\">Optimus HQ</a>. Communication with the Optimus server is conducted through an HTTPS connection. Slightly slows down the optimization process.", "optimus"); ?>
194
+ </p>
195
+ </fieldset>
196
+ </td>
197
+ </tr>
198
+
199
+ <tr valign="top">
200
+ <th scope="row">
201
+ <?php _e("Optimize during upload", "optimus"); ?>
202
+ </th>
203
+ <td>
204
+ <fieldset>
205
+ <label for="optimus_manual_optimize">
206
+ <input type="checkbox" name="optimus[manual_optimize]" id="optimus_manual_optimize" value="1" <?php checked(1, $options['manual_optimize']) ?> />
207
+ <?php _e("No optimization of images during the upload process", "optimus"); ?>
208
+ </label>
209
+
210
+ <p class="description">
211
+ <?php _e("This setting prevents the automatic optimization during the upload process. Images need to be optimized via the Media Library later on. [<a href=\"https://optimus.keycdn.com/support/image-bulk-optimization/\" target=\"_blank\">Details</a>]", "optimus"); ?>
212
+ </p>
213
+ </fieldset>
214
+ </td>
215
+ </tr>
216
+ </table>
217
+
218
+ <?php submit_button() ?>
219
+ </form>
220
+ </div><?php
221
+ }
222
  }
optimus.php CHANGED
@@ -2,12 +2,12 @@
2
  /*
3
  Plugin Name: Optimus
4
  Text Domain: optimus
5
- Description: Lossless compression and optimization of uploaded images in WordPress. Automatic, reliable, effective.
6
  Author: KeyCDN
7
  Author URI: https://www.keycdn.com
8
  Plugin URI: https://optimus.io
9
  License: GPLv2 or later
10
- Version: 1.4.8
11
  */
12
 
13
  /*
@@ -44,56 +44,56 @@ define('OPTIMUS_MIN_WP', '3.8');
44
  add_action('init', 'optimus_admin_init');
45
  function optimus_admin_init()
46
  {
47
- if (is_admin()) {
48
- load_plugin_textdomain( 'optimus', false, dirname( plugin_basename(__FILE__) ) . '/lang/' );
49
-
50
- add_action(
51
- 'wp_ajax_optimus_optimize_image',
52
- array(
53
- 'Optimus_Request',
54
- 'optimize_image'
55
- )
56
- );
57
- add_action(
58
- 'admin_action_optimus_bulk_optimizer',
59
- array(
60
- 'Optimus_Management',
61
- 'bulk_optimizer_media'
62
- )
63
- );
64
- }
65
  }
66
 
67
 
68
  /* Admin & XMLRPC only */
69
  if ( is_admin() OR (defined('XMLRPC_REQUEST') && XMLRPC_REQUEST) ) {
70
- add_action(
71
- 'plugins_loaded',
72
- array(
73
- 'Optimus',
74
- 'instance'
75
- )
76
- );
77
  }
78
 
79
 
80
  /* Uninstall */
81
  register_uninstall_hook(
82
- __FILE__,
83
- array(
84
- 'Optimus',
85
- 'handle_uninstall_hook'
86
- )
87
  );
88
 
89
 
90
  /* Activation */
91
  register_activation_hook(
92
- __FILE__,
93
- array(
94
- 'Optimus',
95
- 'handle_activation_hook'
96
- )
97
  );
98
 
99
 
@@ -102,13 +102,13 @@ spl_autoload_register('optimus_autoload');
102
 
103
  /* Autoload Funktion */
104
  function optimus_autoload($class) {
105
- if ( in_array($class, array('Optimus', 'Optimus_HQ', 'Optimus_Management', 'Optimus_Settings', 'Optimus_Media', 'Optimus_Request')) ) {
106
- require_once(
107
- sprintf(
108
- '%s/inc/%s.class.php',
109
- OPTIMUS_DIR,
110
- strtolower($class)
111
- )
112
- );
113
- }
114
  }
2
  /*
3
  Plugin Name: Optimus
4
  Text Domain: optimus
5
+ Description: Smart compression and optimization of uploaded images in WordPress. Automatic, reliable, effective.
6
  Author: KeyCDN
7
  Author URI: https://www.keycdn.com
8
  Plugin URI: https://optimus.io
9
  License: GPLv2 or later
10
+ Version: 1.4.9
11
  */
12
 
13
  /*
44
  add_action('init', 'optimus_admin_init');
45
  function optimus_admin_init()
46
  {
47
+ if (is_admin()) {
48
+ load_plugin_textdomain( 'optimus', false, dirname( plugin_basename(__FILE__) ) . '/lang/' );
49
+
50
+ add_action(
51
+ 'wp_ajax_optimus_optimize_image',
52
+ array(
53
+ 'Optimus_Request',
54
+ 'optimize_image'
55
+ )
56
+ );
57
+ add_action(
58
+ 'admin_action_optimus_bulk_optimizer',
59
+ array(
60
+ 'Optimus_Management',
61
+ 'bulk_optimizer_media'
62
+ )
63
+ );
64
+ }
65
  }
66
 
67
 
68
  /* Admin & XMLRPC only */
69
  if ( is_admin() OR (defined('XMLRPC_REQUEST') && XMLRPC_REQUEST) ) {
70
+ add_action(
71
+ 'plugins_loaded',
72
+ array(
73
+ 'Optimus',
74
+ 'instance'
75
+ )
76
+ );
77
  }
78
 
79
 
80
  /* Uninstall */
81
  register_uninstall_hook(
82
+ __FILE__,
83
+ array(
84
+ 'Optimus',
85
+ 'handle_uninstall_hook'
86
+ )
87
  );
88
 
89
 
90
  /* Activation */
91
  register_activation_hook(
92
+ __FILE__,
93
+ array(
94
+ 'Optimus',
95
+ 'handle_activation_hook'
96
+ )
97
  );
98
 
99
 
102
 
103
  /* Autoload Funktion */
104
  function optimus_autoload($class) {
105
+ if ( in_array($class, array('Optimus', 'Optimus_HQ', 'Optimus_Management', 'Optimus_Settings', 'Optimus_Media', 'Optimus_Request')) ) {
106
+ require_once(
107
+ sprintf(
108
+ '%s/inc/%s.class.php',
109
+ OPTIMUS_DIR,
110
+ strtolower($class)
111
+ )
112
+ );
113
+ }
114
  }
readme.txt CHANGED
@@ -1,22 +1,22 @@
1
  === Optimus - WordPress Image Optimizer ===
2
  Contributors: keycdn
3
  Tags: images, optimize, compress, progressive, performance, png, jpeg, webp, image optimizer, wordpress image optimizer, optimize image, optimize jpg, optimize jpeg, optimize png, compress image, progressive jpeg, progressive jpg
4
- Requires at least: 3.8
5
- Tested up to: 4.7
6
  Stable tag: trunk
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
10
 
11
 
12
- Effective image compression and optimization during the upload process. Automatic and without loss of quality.
13
 
14
 
15
 
16
  == Description ==
17
 
18
  = WordPress Image Optimizer =
19
- Optimus reduces the file size of uploaded media files *lossless*. Depending on the image and format, reductions in size of up to 70% are possible. Several kilobytes can be saved per image—these savings contribute positively to the performance of the blog website. What’s most impressive about the compression technology: the quality of the images is maintained—guaranteed.
20
 
21
 
22
  > #### There are three different versions of Optimus:
@@ -32,7 +32,7 @@ During the uploading process of images to the media library, the *Optimus* plugi
32
 
33
  The optimization of images - *including thumbnails* - is conducted in the background and outside of the view of the user. The image compression gains per file are displayed by Optimus within the media library in form of a percentage value, see [screenshot](https://wordpress.org/plugins/optimus/screenshots/).
34
 
35
- Differently from common optimization tools, this WordPress image optimization plugin never alters the quality of images. Instead, superfluous information that is saved by image processing programs and is not even necessary for displaying the image is extracted from image files. This way, the quality of the graphics remains intact while the image size can be reduced significantly. If you wish, Optimus keeps all author, EXIF and copyright information contained within the photos — the compressional gains will be correspondingly lower.
36
 
37
  Optimus supports the conversion of images to the new [*WebP* image format](https://www.keycdn.com/blog/convert-to-webp-the-successor-of-jpeg/).
38
 
@@ -40,7 +40,7 @@ Optimus supports the conversion of images to the new [*WebP* image format](https
40
 
41
  = Features =
42
  * [Progressive JPEGs](https://optimus.keycdn.com/support/progressive-jpeg/)
43
- * Reduction of file size *without loss in quality*
44
  * Optimization of all preview images of a photo
45
  * No adjustments to code necessary
46
  * Optional: no removal of EXIF and IPTC metadata
@@ -67,8 +67,8 @@ Optimus supports the conversion of images to the new [*WebP* image format](https
67
 
68
 
69
  = System Requirements =
70
- * PHP >=5.2.4
71
- * WordPress >=3.8
72
  * Allow outbound connections
73
 
74
 
@@ -88,6 +88,9 @@ Optimus supports the conversion of images to the new [*WebP* image format](https
88
 
89
  == Changelog ==
90
 
 
 
 
91
  = 1.4.8 =
92
  * Improved the handling of 204 errors
93
  * Removed language files
1
  === Optimus - WordPress Image Optimizer ===
2
  Contributors: keycdn
3
  Tags: images, optimize, compress, progressive, performance, png, jpeg, webp, image optimizer, wordpress image optimizer, optimize image, optimize jpg, optimize jpeg, optimize png, compress image, progressive jpeg, progressive jpg
4
+ Requires at least: 4.6
5
+ Tested up to: 4.8
6
  Stable tag: trunk
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
10
 
11
 
12
+ Effective image compression and optimization during the upload process. Smart, automatic and reliable.
13
 
14
 
15
 
16
  == Description ==
17
 
18
  = WordPress Image Optimizer =
19
+ Optimus reduces the file size of uploaded media files automatically. Depending on the image and format, reductions in size of up to 70% are possible. Several kilobytes can be saved per image—these savings contribute positively to the performance of the blog website. What’s most impressive about the compression technology: the quality of the images is maintained.
20
 
21
 
22
  > #### There are three different versions of Optimus:
32
 
33
  The optimization of images - *including thumbnails* - is conducted in the background and outside of the view of the user. The image compression gains per file are displayed by Optimus within the media library in form of a percentage value, see [screenshot](https://wordpress.org/plugins/optimus/screenshots/).
34
 
35
+ Superfluous information that is saved by image processing programs and is not even necessary for displaying the image is extracted from image files. This way, the quality of the graphics remains intact while the image size can be reduced significantly. If you wish, Optimus keeps all author, EXIF and copyright information contained within the photos — the compressional gains will be correspondingly lower.
36
 
37
  Optimus supports the conversion of images to the new [*WebP* image format](https://www.keycdn.com/blog/convert-to-webp-the-successor-of-jpeg/).
38
 
40
 
41
  = Features =
42
  * [Progressive JPEGs](https://optimus.keycdn.com/support/progressive-jpeg/)
43
+ * Reduction of file size during the upload
44
  * Optimization of all preview images of a photo
45
  * No adjustments to code necessary
46
  * Optional: no removal of EXIF and IPTC metadata
67
 
68
 
69
  = System Requirements =
70
+ * PHP >=5.6
71
+ * WordPress >=4.6
72
  * Allow outbound connections
73
 
74
 
88
 
89
  == Changelog ==
90
 
91
+ = 1.4.9 =
92
+ * Formatting updates
93
+
94
  = 1.4.8 =
95
  * Improved the handling of 204 errors
96
  * Removed language files