Optimus – WordPress Image Optimizer - Version 1.3.1

Version Description

  • Anpassung fr WordPress 3.9: Sicherstellung der Bildoptimierung im WordPress-Editor
Download this release

Release Info

Developer sergej.mueller
Plugin Icon 128x128 Optimus – WordPress Image Optimizer
Version 1.3.1
Comparing to
See all releases

Version 1.3.1

css/styles.css ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* @group Media */
2
+
3
+ .manage-column.column-optimus {
4
+ width: 5em;
5
+ }
6
+
7
+ .optimus.column-optimus div {
8
+ width: 32px;
9
+ height: 32px;
10
+ position: relative;
11
+ background: #bbb;
12
+ margin-left: 11px;
13
+ border-radius: 16px;
14
+ }
15
+
16
+ .optimus.column-optimus p {
17
+ top: 0;
18
+ left: 0;
19
+ color: #fff;
20
+ width: 32px;
21
+ height: 32px;
22
+ margin: 0;
23
+ z-index: 99;
24
+ position: absolute;
25
+ text-align: center;
26
+ font-size: 10px;
27
+ line-height: 32px;
28
+ }
29
+ .optimus.column-optimus p:before {
30
+ top: 0;
31
+ left: 0;
32
+ border: 16px solid transparent;
33
+ z-index: -99;
34
+ content: '';
35
+ position: absolute;
36
+ border-radius: 16px;
37
+
38
+ transform: rotate(-45deg);
39
+ -o-transform: rotate(-45deg);
40
+ -ms-transform: rotate(-45deg);
41
+ -moz-transform: rotate(-45deg);
42
+ -webkit-transform: rotate(-45deg);
43
+ }
44
+
45
+ .optimus.column-optimus .one p:before {
46
+ border-right-color: #7ad03a;
47
+ }
48
+ .optimus.column-optimus .two p:before {
49
+ border-right-color: #7ad03a;
50
+ border-bottom-color: #7ad03a;
51
+ }
52
+ .optimus.column-optimus .three p:before {
53
+ border-left-color: #7ad03a;
54
+ border-right-color: #7ad03a;
55
+ border-bottom-color: #7ad03a;
56
+ }
57
+ .optimus.column-optimus .four p:before {
58
+ border-color: #7ad03a;
59
+ }
60
+
61
+ /* @end group */
css/styles.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .manage-column.column-optimus{width:5em;}.optimus.column-optimus div{width:32px;height:32px;position:relative;background:#bbb;margin-left:11px;border-radius:16px;}.optimus.column-optimus p{top:0;left:0;color:#fff;width:32px;height:32px;margin:0;z-index:99;position:absolute;text-align:center;font-size:10px;line-height:32px;}.optimus.column-optimus p:before{top:0;left:0;border:16px solid transparent;z-index:-99;content:'';position:absolute;border-radius:16px;transform:rotate(-45deg);-o-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-webkit-transform:rotate(-45deg);}.optimus.column-optimus .one p:before{border-right-color:#7ad03a;}.optimus.column-optimus .two p:before{border-right-color:#7ad03a;border-bottom-color:#7ad03a;}.optimus.column-optimus .three p:before{border-left-color:#7ad03a;border-right-color:#7ad03a;border-bottom-color:#7ad03a;}.optimus.column-optimus .four p:before{border-color:#7ad03a;}
inc/optimus.class.php ADDED
@@ -0,0 +1,349 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ /* Quit */
5
+ defined('ABSPATH') OR exit;
6
+
7
+
8
+ /**
9
+ * Optimus
10
+ *
11
+ * @since 0.0.1
12
+ */
13
+
14
+ 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.3.1
36
+ */
37
+
38
+ public function __construct()
39
+ {
40
+ /* Fire! */
41
+ add_filter(
42
+ 'wp_generate_attachment_metadata',
43
+ array(
44
+ 'Optimus_Request',
45
+ 'optimize_upload_images'
46
+ ),
47
+ 10,
48
+ 2
49
+ );
50
+
51
+ /* Filter */
52
+ if ( (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) OR (defined('DOING_CRON') && DOING_CRON) OR (defined('DOING_AJAX') && DOING_AJAX) ) {
53
+ return;
54
+ }
55
+
56
+ /* BE only */
57
+ if ( ! is_admin() ) {
58
+ return;
59
+ }
60
+
61
+ /* Hooks */
62
+ add_action(
63
+ 'admin_print_styles-upload.php',
64
+ array(
65
+ 'Optimus_Media',
66
+ 'add_css'
67
+ )
68
+ );
69
+ add_filter(
70
+ 'manage_media_columns',
71
+ array(
72
+ 'Optimus_Media',
73
+ 'manage_columns'
74
+ )
75
+ );
76
+ add_action(
77
+ 'manage_media_custom_column',
78
+ array(
79
+ 'Optimus_Media',
80
+ 'manage_column'
81
+ ),
82
+ 10,
83
+ 2
84
+ );
85
+
86
+ add_filter(
87
+ 'plugin_row_meta',
88
+ array(
89
+ __CLASS__,
90
+ 'add_row_meta'
91
+ ),
92
+ 10,
93
+ 2
94
+ );
95
+ add_filter(
96
+ 'plugin_action_links_' .OPTIMUS_BASE,
97
+ array(
98
+ __CLASS__,
99
+ 'add_action_link'
100
+ )
101
+ );
102
+ add_action(
103
+ 'after_plugin_row_' .OPTIMUS_BASE,
104
+ array(
105
+ 'Optimus_HQ',
106
+ 'display_key_input'
107
+ )
108
+ );
109
+ add_action(
110
+ 'admin_init',
111
+ array(
112
+ 'Optimus_HQ',
113
+ 'verify_key_input'
114
+ )
115
+ );
116
+ add_action(
117
+ 'admin_init',
118
+ array(
119
+ 'Optimus_Settings',
120
+ 'register_settings'
121
+ )
122
+ );
123
+ add_action(
124
+ 'admin_menu',
125
+ array(
126
+ 'Optimus_Settings',
127
+ 'add_page'
128
+ )
129
+ );
130
+ add_filter(
131
+ 'wp_delete_file',
132
+ array(
133
+ 'Optimus_Request',
134
+ 'delete_converted_file'
135
+ )
136
+ );
137
+
138
+ add_action(
139
+ 'network_admin_notices',
140
+ array(
141
+ __CLASS__,
142
+ 'optimus_requirements_check'
143
+ )
144
+ );
145
+ add_action(
146
+ 'admin_notices',
147
+ array(
148
+ __CLASS__,
149
+ 'optimus_requirements_check'
150
+ )
151
+ );
152
+
153
+ add_action(
154
+ 'network_admin_notices',
155
+ array(
156
+ 'Optimus_HQ',
157
+ 'optimus_hq_notice'
158
+ )
159
+ );
160
+ add_action(
161
+ 'admin_notices',
162
+ array(
163
+ 'Optimus_HQ',
164
+ 'optimus_hq_notice'
165
+ )
166
+ );
167
+ }
168
+
169
+
170
+ /**
171
+ * Hinzufügen der Action-Links
172
+ *
173
+ * @since 1.1.2
174
+ * @change 1.1.2
175
+ *
176
+ * @param array $data Bereits existente Links
177
+ * @return array $data Erweitertes Array mit Links
178
+ */
179
+
180
+ public static function add_action_link($data)
181
+ {
182
+ /* Rechte? */
183
+ if ( ! current_user_can('manage_options') ) {
184
+ return $data;
185
+ }
186
+
187
+ return array_merge(
188
+ $data,
189
+ array(
190
+ sprintf(
191
+ '<a href="%s">%s</a>',
192
+ add_query_arg(
193
+ array(
194
+ 'page' => 'optimus'
195
+ ),
196
+ admin_url('options-general.php')
197
+ ),
198
+ __('Settings')
199
+ )
200
+ )
201
+ );
202
+ }
203
+
204
+
205
+ /**
206
+ * Hinzufügen der Meta-Informationen
207
+ *
208
+ * @since 0.0.1
209
+ * @change 1.1.8
210
+ *
211
+ * @param array $rows Array mit Links
212
+ * @param string $file Name des Plugins
213
+ * @return array Array mit erweitertem Link
214
+ */
215
+
216
+ public static function add_row_meta($rows, $file)
217
+ {
218
+ /* Restliche Plugins? */
219
+ if ( $file !== OPTIMUS_BASE ) {
220
+ return $rows;
221
+ }
222
+
223
+ /* Keine Rechte? */
224
+ if ( ! current_user_can('manage_options') ) {
225
+ return $rows;
226
+ }
227
+
228
+ /* Add new key link */
229
+ $rows = array_merge(
230
+ $rows,
231
+ array(
232
+ sprintf(
233
+ '<a href="%s">%s</a>',
234
+ add_query_arg(
235
+ array(
236
+ '_optimus_action' => 'rekey'
237
+ ),
238
+ network_admin_url('plugins.php#optimus')
239
+ ),
240
+ ( Optimus_HQ::get_key() ? 'Anderen Optimus HQ Key eingeben' : 'Optimus HQ aktivieren' )
241
+ )
242
+ )
243
+ );
244
+
245
+ /* Add expiration date */
246
+ if ( Optimus_HQ::is_unlocked() ) {
247
+ $rows = array_merge(
248
+ $rows,
249
+ array(
250
+ sprintf(
251
+ 'Optimus HQ Ablaufdatum: %s',
252
+ date( 'd.m.Y', Optimus_HQ::best_before() )
253
+ )
254
+ )
255
+ );
256
+ }
257
+
258
+ return $rows;
259
+ }
260
+
261
+
262
+ /**
263
+ * Run uninstall hook
264
+ *
265
+ * @since 1.1.0
266
+ * @change 1.1.8
267
+ */
268
+
269
+ public static function handle_uninstall_hook()
270
+ {
271
+ delete_option('optimus');
272
+ delete_site_option('optimus_key');
273
+ delete_site_option('optimus_purchase_time');
274
+ }
275
+
276
+
277
+ /**
278
+ * Run activation hook
279
+ *
280
+ * @since 1.2.0
281
+ * @change 1.2.0
282
+ */
283
+
284
+ public static function handle_activation_hook() {
285
+ set_transient(
286
+ 'optimus_activation_hook_in_use',
287
+ 1,
288
+ MINUTE_IN_SECONDS
289
+ );
290
+ }
291
+
292
+
293
+ /**
294
+ * Check plugin requirements
295
+ *
296
+ * @since 1.3.1
297
+ * @change 1.3.1
298
+ */
299
+
300
+ public static function optimus_requirements_check() {
301
+ /* WordPress version check */
302
+ if ( version_compare($GLOBALS['wp_version'], OPTIMUS_MIN_WP.'alpha', '<') ) {
303
+ show_message(
304
+ sprintf(
305
+ '<div class="error"><p>%s</p></div>',
306
+ sprintf(
307
+ 'Optimus ist für WordPress %s optimiert. Bitte das Plugin deaktivieren oder WordPress aktualisieren (empfohlen).',
308
+ OPTIMUS_MIN_WP
309
+ )
310
+ )
311
+ );
312
+ }
313
+
314
+ /* cURL check */
315
+ if ( ! WP_Http_Curl::test() ) {
316
+ show_message(
317
+ sprintf(
318
+ '<div class="error"><p>%s</p></div>',
319
+ sprintf(
320
+ 'Optimus setzt <a href="%s" target="_blank">cURL-Bibliothek</a> voraus (sollte auf keinem Server fehlen). Bitte beim Hoster anfragen.',
321
+ 'http://www.php.net/manual/de/intro.curl.php'
322
+ )
323
+ )
324
+ );
325
+ }
326
+ }
327
+
328
+
329
+ /**
330
+ * Return plugin options
331
+ *
332
+ * @since 1.1.2
333
+ * @change 1.3.0
334
+ *
335
+ * @return array $diff Data pairs
336
+ */
337
+
338
+ public static function get_options()
339
+ {
340
+ return wp_parse_args(
341
+ get_option('optimus'),
342
+ array(
343
+ 'copy_markers' => 0,
344
+ 'webp_convert' => 0,
345
+ 'secure_transport' => 0
346
+ )
347
+ );
348
+ }
349
+ }
inc/optimus_hq.class.php ADDED
@@ -0,0 +1,394 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ /* Quit */
5
+ defined('ABSPATH') OR exit;
6
+
7
+
8
+ /**
9
+ * Optimus_HQ
10
+ *
11
+ * @since 1.1.0
12
+ */
13
+
14
+ 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
+ /* Set the timestamp */
96
+ if ( is_wp_error($response) ) {
97
+ $purchase_time = -1;
98
+ } else {
99
+ $purchase_time = wp_remote_retrieve_body($response);
100
+ }
101
+
102
+ /* Validate the timestamp */
103
+ if ( ! ( is_numeric($purchase_time) && $purchase_time <= PHP_INT_MAX && $purchase_time >= ~PHP_INT_MAX ) ) {
104
+ $purchase_time = -1;
105
+ }
106
+
107
+ /* Store as option */
108
+ self::_update_purchase_time($purchase_time);
109
+ }
110
+
111
+ /* Invalid purchase time? */
112
+ if ( (int)$purchase_time <= 0 ) {
113
+ self::_delete_key();
114
+
115
+ return false;
116
+ }
117
+
118
+ /* Set expiration time */
119
+ $expiration_time = strtotime(
120
+ '+1 year',
121
+ $purchase_time
122
+ );
123
+
124
+ /* Expired time? */
125
+ if ( $expiration_time < time() ) {
126
+ self::_delete_key();
127
+
128
+ return false;
129
+ }
130
+
131
+ return $expiration_time;
132
+ }
133
+
134
+
135
+ /**
136
+ * Return the license key
137
+ *
138
+ * @since 1.1.0
139
+ * @change 1.1.9
140
+ *
141
+ * @return string Optimus HQ Key
142
+ */
143
+
144
+ public static function get_key()
145
+ {
146
+ return get_site_option('optimus_key');
147
+ }
148
+
149
+
150
+ /**
151
+ * Update the license key
152
+ *
153
+ * @since 1.1.0
154
+ * @change 1.1.9
155
+ *
156
+ * @return mixed $value Optimus HQ Key value
157
+ */
158
+
159
+ private static function _update_key($value)
160
+ {
161
+ update_site_option(
162
+ 'optimus_key',
163
+ $value
164
+ );
165
+ }
166
+
167
+
168
+ /**
169
+ * Delete the license key
170
+ *
171
+ * @since 1.1.9
172
+ * @change 1.1.9
173
+ */
174
+
175
+ private static function _delete_key()
176
+ {
177
+ delete_site_option('optimus_key');
178
+ }
179
+
180
+
181
+ /**
182
+ * Return the purchase timestamp
183
+ *
184
+ * @since 1.1.9
185
+ * @change 1.1.9
186
+ *
187
+ * @return string Optimus HQ purchase timestamp
188
+ */
189
+
190
+ public static function get_purchase_time()
191
+ {
192
+ return get_site_option('optimus_purchase_time');
193
+ }
194
+
195
+
196
+ /**
197
+ * Update the purchase timestamp
198
+ *
199
+ * @since 1.1.9
200
+ * @change 1.1.9
201
+ *
202
+ * @return integer $value Purchase time as a timestamp
203
+ */
204
+
205
+ private static function _update_purchase_time($value)
206
+ {
207
+ update_site_option(
208
+ 'optimus_purchase_time',
209
+ $value
210
+ );
211
+ }
212
+
213
+
214
+ /**
215
+ * Delete the purchase timestamp
216
+ *
217
+ * @since 1.1.9
218
+ * @change 1.1.9
219
+ */
220
+
221
+ private static function _delete_purchase_time()
222
+ {
223
+ delete_site_option('optimus_purchase_time');
224
+ }
225
+
226
+
227
+ /**
228
+ * Ausgabe des Eingabefeldes für den Optimus HQ Key
229
+ *
230
+ * @since 1.1.0
231
+ * @change 1.3.2
232
+ */
233
+
234
+ public static function display_key_input()
235
+ {
236
+ /* Keine Rechte? */
237
+ if ( ! current_user_can('manage_options') ) {
238
+ return;
239
+ }
240
+
241
+ /* Überspringen? */
242
+ if ( empty($_GET['_optimus_action']) OR $_GET['_optimus_action'] !== 'rekey' ) {
243
+ return;
244
+ } ?>
245
+
246
+ <tr class="plugin-update-tr">
247
+ <td colspan="3" class="plugin-update">
248
+ <div class="update-message">
249
+ <form action="<?php echo network_admin_url('plugins.php') ?>" method="post">
250
+ <input type="hidden" name="_optimus_action" value="verify" />
251
+ <?php wp_nonce_field('_optimus_nonce') ?>
252
+
253
+ <label for="_optimus_key">
254
+ Optimus HQ Key:
255
+ <input type="text" name="_optimus_key" id="_optimus_key" maxlength="17" pattern="[A-Z0-9]{17}" />
256
+ </label>
257
+
258
+ <input type="submit" name="submit" value="Aktivieren" class="button button-primary regular" />
259
+ <a href="<?php echo network_admin_url('plugins.php') ?>" class="button">Abbrechen</a>
260
+ </form>
261
+ </div>
262
+ </td>
263
+ </tr>
264
+
265
+ <style>
266
+ #optimus + .plugin-update-tr .update-message {
267
+ margin-top: 12px;
268
+ }
269
+ #optimus + .plugin-update-tr .update-message::before {
270
+ display: none;
271
+ }
272
+ #optimus + .plugin-update-tr label {
273
+ line-height: 30px;
274
+ vertical-align: top;
275
+ }
276
+ #optimus + .plugin-update-tr input[type="text"] {
277
+ width: 300px;
278
+ margin-left: 10px;
279
+ }
280
+ </style>
281
+ <?php }
282
+
283
+
284
+ /**
285
+ * Verify und store the Optimus HQ key
286
+ *
287
+ * @since 1.1.0
288
+ * @change 1.3.2
289
+ */
290
+
291
+ public static function verify_key_input()
292
+ {
293
+ /* Action check */
294
+ if ( empty($_POST['_optimus_action']) OR $_POST['_optimus_action'] !== 'verify' ) {
295
+ return;
296
+ }
297
+
298
+ /* Empty input? */
299
+ if ( empty($_POST['_optimus_key']) ) {
300
+ return;
301
+ }
302
+
303
+ /* Sanitize input */
304
+ $optimus_key = sanitize_text_field($_POST['_optimus_key']);
305
+
306
+ /* Advanced check */
307
+ if ( ! preg_match('/^[A-Z0-9]{17}$/', $optimus_key) ) {
308
+ return;
309
+ }
310
+
311
+ /* Security */
312
+ check_admin_referer('_optimus_nonce');
313
+
314
+ /* Delete purchase_time */
315
+ self::_delete_purchase_time();
316
+
317
+ /* Store current key */
318
+ self::_update_key($optimus_key);
319
+
320
+ /* Redirect */
321
+ wp_safe_redirect(
322
+ add_query_arg(
323
+ array(
324
+ '_optimus_notice' => ( self::is_locked() ? 'locked' : 'unlocked' )
325
+ ),
326
+ network_admin_url('plugins.php')
327
+ )
328
+ );
329
+
330
+ die();
331
+ }
332
+
333
+
334
+ /**
335
+ * Steuerung der Ausgabe von Admin-Notizen
336
+ *
337
+ * @since 1.1.0
338
+ * @change 1.2.0
339
+ */
340
+
341
+ public static function optimus_hq_notice()
342
+ {
343
+ /* Check admin pages */
344
+ if ( ! in_array($GLOBALS['pagenow'], array('plugins.php', 'index.php') ) ) {
345
+ return;
346
+ }
347
+
348
+ /* Get message type */
349
+ if ( ! empty($_GET['_optimus_notice']) && $_GET['_optimus_notice'] === 'unlocked' ) {
350
+ $type = 'unlocked';
351
+ } else if ( self::is_locked() ) {
352
+ if ( self::get_purchase_time() ) {
353
+ $type = 'expired';
354
+ } else if ( get_transient('optimus_activation_hook_in_use') ) {
355
+ $type = 'locked';
356
+ }
357
+ }
358
+
359
+ /* Empty? */
360
+ if ( empty($type) ) {
361
+ return;
362
+ }
363
+
364
+ /* Matching */
365
+ switch( $type ) {
366
+ case 'unlocked':
367
+ $msg = 'Vielen Dank für die Nutzung von <strong>Optimus HQ</strong>. Wissenswertes und Aktualisierungen rund um das Plugin auf <a href="https://plus.google.com/b/114450218898660299759/114450218898660299759/posts" target="_blank">Google+</a>.';
368
+ $class = 'updated';
369
+ break;
370
+
371
+ case 'locked':
372
+ $msg = 'Optimus ist aktuell nur eingeschränkt nutzbar.<br /><strong>Optimus HQ</strong> beherrscht mehr Bildformate, komprimiert größere Dateien und erlaubt Anfragen von im Ausland gehosteten Blogs. Weitere Details auf <a href="http://optimus.io" target="_blank">optimus.io</a><br /><br /><em>Dieser Hinweis hat eine Lebensdauer von 60 Sekunden und erscheint nicht erneut.</em>';
373
+ $class = 'error';
374
+ break;
375
+
376
+ case 'expired':
377
+ $msg = '<strong>Optimus HQ Key</strong> ist abgelaufen. Ein neuer Optimus HQ Key kann auf <a href="http://optimus.io" target="_blank">optimus.io</a> erworben werden. Vielen Dank!';
378
+ $class = 'error';
379
+ break;
380
+
381
+ default:
382
+ return;
383
+ }
384
+
385
+ /* Output */
386
+ show_message(
387
+ sprintf(
388
+ '<div class="%s"><p>%s</p></div>',
389
+ $class,
390
+ $msg
391
+ )
392
+ );
393
+ }
394
+ }
inc/optimus_media.class.php ADDED
@@ -0,0 +1,151 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ /* Quit */
5
+ defined('ABSPATH') OR exit;
6
+
7
+
8
+ /**
9
+ * Optimus_Media
10
+ *
11
+ * @since 1.1.2
12
+ */
13
+
14
+ class Optimus_Media
15
+ {
16
+
17
+
18
+ /**
19
+ * Add media column css
20
+ *
21
+ * @since 0.0.2
22
+ * @change 1.3.0
23
+ */
24
+
25
+ public static function add_css()
26
+ {
27
+ wp_register_style(
28
+ 'optimus-media',
29
+ plugins_url(
30
+ 'css/styles.min.css',
31
+ OPTIMUS_FILE
32
+ )
33
+ );
34
+
35
+ wp_enqueue_style('optimus-media');
36
+ }
37
+
38
+
39
+ /**
40
+ * Media column output
41
+ *
42
+ * @since 0.0.1
43
+ * @change 1.3.0
44
+ *
45
+ * @param array $columns Available columns
46
+ * @return array Renewed columns
47
+ */
48
+
49
+ public static function manage_columns($columns)
50
+ {
51
+ return array_merge(
52
+ $columns,
53
+ array(
54
+ 'optimus' => 'Optimus'
55
+ )
56
+ );
57
+ }
58
+
59
+
60
+ /**
61
+ * Print Optimus values as column
62
+ *
63
+ * @since 0.0.1
64
+ * @change 1.3.0
65
+ *
66
+ * @param string $column Column name
67
+ * @param integer $id Current object ID
68
+ */
69
+
70
+ public static function manage_column($column, $id)
71
+ {
72
+ /* Falsche Spalte? */
73
+ if ( $column !== 'optimus' ) {
74
+ return;
75
+ }
76
+
77
+ echo self::_column_html($id);
78
+ }
79
+
80
+
81
+ /**
82
+ * Returns the formatted column as HTML
83
+ *
84
+ * @since 0.0.1
85
+ * @change 1.3.0
86
+ *
87
+ * @param intval $id Object ID
88
+ * @return string Column HTML
89
+ */
90
+
91
+ private static function _column_html($id)
92
+ {
93
+ /* Attachment metadata */
94
+ $data = (array)wp_get_attachment_metadata($id);
95
+
96
+ /* Data exists? */
97
+ if ( empty($data['optimus']) OR ! is_array($data['optimus']) ) {
98
+ return;
99
+ }
100
+
101
+ /* Array init */
102
+ $optimus = $data['optimus'];
103
+
104
+ /* Metadata exists? */
105
+ if ( ! isset($optimus['quantity']) OR ! isset($optimus['profit']) ) {
106
+ return;
107
+ }
108
+
109
+ return sprintf(
110
+ '<div class="%s"><p>%d%%</p></div>',
111
+ self::_pie_class(
112
+ $optimus['quantity']
113
+ ),
114
+ $optimus['profit']
115
+ );
116
+ }
117
+
118
+
119
+ /**
120
+ * Specifies the CSS class depending on the amount of compressed files
121
+ *
122
+ * @since 0.0.8
123
+ * @change 1.3.0
124
+ *
125
+ * @param intval $quantity File quantity
126
+ * @return string Optimus CSS class
127
+ */
128
+
129
+ private static function _pie_class($quantity)
130
+ {
131
+ /* Init */
132
+ $quantity = (int)$quantity;
133
+
134
+ /* Leer? */
135
+ if ( empty($quantity) ) {
136
+ return '';
137
+ }
138
+
139
+ /* Loop */
140
+ switch(true) {
141
+ case ($quantity == 100):
142
+ return 'four';
143
+ case ($quantity <= 25):
144
+ return 'one';
145
+ case ($quantity <= 50):
146
+ return 'two';
147
+ default:
148
+ return 'three';
149
+ }
150
+ }
151
+ }
inc/optimus_request.class.php ADDED
@@ -0,0 +1,533 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ /* Quit */
5
+ defined('ABSPATH') OR exit;
6
+
7
+
8
+ /**
9
+ * Optimus_Request
10
+ *
11
+ * @since 1.1.7
12
+ */
13
+
14
+ class Optimus_Request
15
+ {
16
+
17
+
18
+ /**
19
+ * cURL is available
20
+ *
21
+ * @var boolean
22
+ */
23
+
24
+ private static $_use_curl = false;
25
+
26
+
27
+ /**
28
+ * Default remote scheme
29
+ *
30
+ * @var string
31
+ */
32
+
33
+ private static $_remote_scheme = 'http';
34
+
35
+
36
+ /**
37
+ * Build optimization for a upload image including previews
38
+ *
39
+ * @since 0.0.1
40
+ * @change 1.3.0
41
+ *
42
+ * @param array $upload_data Incoming upload information
43
+ * @param integer $attachment_id Attachment ID
44
+ * @return array $upload_data Renewed upload information
45
+ */
46
+
47
+ public static function optimize_upload_images($upload_data, $attachment_id) {
48
+ /* Already optimized? */
49
+ if ( ! empty($upload_data['optimus']) ) {
50
+ return $upload_data;
51
+ }
52
+
53
+ /* WP upload folder */
54
+ $upload_dir = wp_upload_dir();
55
+
56
+ /* Upload dir workaround */
57
+ if ( empty($upload_dir['subdir']) ) {
58
+ $upload_path = $upload_dir['path'];
59
+ $upload_url = $upload_dir['url'];
60
+ $upload_file = $upload_data['file'];
61
+ } else {
62
+ $file_info = pathinfo($upload_data['file']);
63
+ $upload_path = path_join($upload_dir['basedir'], $file_info['dirname']);
64
+ $upload_url = path_join($upload_dir['baseurl'], $file_info['dirname']);
65
+ $upload_file = $file_info['basename'];
66
+ }
67
+
68
+ /* Simple regex check */
69
+ if ( ! preg_match('/^[^\?\%]+\.(?:jpe?g|png)$/i', $upload_file) ) {
70
+ return $upload_data;
71
+ }
72
+
73
+ /* Get the attachment */
74
+ $attachment = get_post($attachment_id);
75
+
76
+ /* Attachment mime type */
77
+ $mime_type = get_post_mime_type($attachment);
78
+
79
+ /* Mime type check */
80
+ if ( ! self::_allowed_mime_type($mime_type) ) {
81
+ return $upload_data;
82
+ }
83
+
84
+ /* Get plugin options */
85
+ $options = Optimus::get_options();
86
+
87
+ /* Todo files array */
88
+ $todo_files = array($upload_file);
89
+
90
+ /* Diff file sizes */
91
+ $diff_filesizes = array();
92
+
93
+ /* Set cURL options */
94
+ if ( self::$_use_curl = WP_Http_Curl::test() ) {
95
+ add_action(
96
+ 'http_api_curl',
97
+ array(
98
+ __CLASS__,
99
+ 'set_curl_options'
100
+ )
101
+ );
102
+ }
103
+
104
+ /* Set https scheme */
105
+ if ( $options['secure_transport'] && Optimus_HQ::is_unlocked() ) {
106
+ self::$_remote_scheme = 'https';
107
+ }
108
+
109
+ /* Search for thumbs */
110
+ if ( ! empty($upload_data['sizes']) ) {
111
+ foreach( $upload_data['sizes'] as $thumb ) {
112
+ if ( $thumb['file'] && self::_allowed_mime_type($thumb['mime-type']) ) {
113
+ array_push(
114
+ $todo_files,
115
+ $thumb['file']
116
+ );
117
+ }
118
+ }
119
+
120
+ /* Reverse files array */
121
+ $todo_files = array_reverse(
122
+ array_unique($todo_files)
123
+ );
124
+ }
125
+
126
+ /* Loop todo files */
127
+ foreach ($todo_files as $file) {
128
+ /* Merge path & file */
129
+ $upload_url_file = path_join($upload_url, $file);
130
+ $upload_path_file = path_join($upload_path, $file);
131
+
132
+ /* Get file size */
133
+ $upload_filesize = (int)filesize($upload_path_file);
134
+
135
+ /* Too big? */
136
+ if ( ! self::_allowed_file_size($mime_type, $upload_filesize) ) {
137
+ continue;
138
+ }
139
+
140
+ /* Encoded url */
141
+ $upload_url_file_encoded = urlencode(
142
+ esc_url_raw(
143
+ $upload_url_file,
144
+ array('http', 'https')
145
+ )
146
+ );
147
+
148
+ /* Request: Optimize image */
149
+ $action_response = self::_do_image_action(
150
+ $upload_path_file,
151
+ array(
152
+ 'file' => $upload_url_file_encoded,
153
+ 'copy' => $options['copy_markers']
154
+ )
155
+ );
156
+
157
+ /* Evaluate response */
158
+ if ( is_numeric($action_response) ) {
159
+ $response_filesize = $action_response;
160
+ } else {
161
+ return $upload_data;
162
+ }
163
+
164
+ /* Request: WebP convert */
165
+ if ( $options['webp_convert'] && Optimus_HQ::is_unlocked() ) {
166
+ self::_do_image_action(
167
+ $upload_path_file,
168
+ array(
169
+ 'file' => $upload_url_file_encoded,
170
+ 'webp' => true
171
+ )
172
+ );
173
+ }
174
+
175
+ /* File size difference */
176
+ array_push(
177
+ $diff_filesizes,
178
+ self::_calculate_diff_filesize(
179
+ $upload_filesize,
180
+ $response_filesize
181
+ )
182
+ );
183
+ }
184
+
185
+ /* Count files */
186
+ $ordered = count($todo_files);
187
+ $received = count($diff_filesizes);
188
+
189
+ /* Average values */
190
+ if ( $received ) {
191
+ $upload_data['optimus'] = array(
192
+ 'profit' => max($diff_filesizes),
193
+ 'quantity' => round( $received * 100 / $ordered )
194
+ );
195
+ }
196
+
197
+ return $upload_data;
198
+ }
199
+
200
+
201
+ /**
202
+ * Handle image actions
203
+ *
204
+ * @since 1.1.4
205
+ * @change 1.3.0
206
+ *
207
+ * @param string $file Image file
208
+ * @param array $args Request arguments
209
+ * @return array Request failed with an error code
210
+ * @return false An error has occurred
211
+ * @return null Empty response with 204 status code
212
+ * @return intval Response content length
213
+ */
214
+
215
+ private static function _do_image_action($file, $args)
216
+ {
217
+ /* Start request */
218
+ $response = self::_do_api_request($file, $args);
219
+
220
+ /* Response status code */
221
+ $response_code = (int)wp_remote_retrieve_response_code($response);
222
+
223
+ /* Not success status code? */
224
+ if ( $response_code !== 200 ) {
225
+ return false;
226
+ }
227
+
228
+ /* Response error? */
229
+ if ( is_wp_error($response) ) {
230
+ return false;
231
+ }
232
+
233
+ /* Response properties */
234
+ $response_body = wp_remote_retrieve_body($response);
235
+ $response_type = wp_remote_retrieve_header($response, 'content-type');
236
+ $response_length = (int)wp_remote_retrieve_header($response, 'content-length');
237
+
238
+ /* Empty file? */
239
+ if ( empty($response_body) OR empty($response_type) OR empty($response_length) ) {
240
+ return false;
241
+ }
242
+
243
+ /* Mime type check */
244
+ if ( ! self::_allowed_mime_type($response_type) ) {
245
+ return false;
246
+ }
247
+
248
+ /* Extension replace for WebP */
249
+ if ( isset($args['webp']) ) {
250
+ $file = self::_replace_file_extension(
251
+ $file,
252
+ 'webp'
253
+ );
254
+ }
255
+
256
+ /* Rewrite image file */
257
+ if ( ! file_put_contents($file, $response_body) ) {
258
+ return false;
259
+ }
260
+
261
+ return $response_length;
262
+ }
263
+
264
+
265
+ /**
266
+ * Optimus API request
267
+ *
268
+ * @since 1.1.4
269
+ * @change 1.3.0
270
+ *
271
+ * @param string $file Image file
272
+ * @param array $args Request arguments
273
+ * @return array Response data
274
+ */
275
+
276
+ private static function _do_api_request($file, $args)
277
+ {
278
+ /* cURL Request */
279
+ if ( self::$_use_curl ) {
280
+ return wp_safe_remote_post(
281
+ sprintf(
282
+ '%s://magic.optimus.io/%s?%s',
283
+ self::$_remote_scheme,
284
+ Optimus_HQ::get_key(),
285
+ self::_curl_optimus_task($args)
286
+ ),
287
+ array(
288
+ 'body' => file_get_contents($file),
289
+ 'timeout' => 10
290
+ )
291
+ );
292
+ }
293
+
294
+ /* Fallback request */
295
+ return wp_safe_remote_post(
296
+ sprintf(
297
+ '%s://api.optimus.io/%s',
298
+ self::$_remote_scheme,
299
+ Optimus_HQ::get_key()
300
+ ),
301
+ array(
302
+ 'body' => $args,
303
+ 'timeout' => 10
304
+ )
305
+ );
306
+ }
307
+
308
+
309
+ /**
310
+ * Set cURL request options
311
+ *
312
+ * @since 1.1.9
313
+ * @change 1.3.0
314
+ *
315
+ * @param object $handle cURL handle with default options
316
+ * @return object $handle cURL handle with added options
317
+ */
318
+
319
+ public static function set_curl_options(&$handle)
320
+ {
321
+ curl_setopt(
322
+ $handle,
323
+ CURLOPT_BINARYTRANSFER,
324
+ true
325
+ );
326
+ curl_setopt(
327
+ $handle,
328
+ CURLOPT_HTTPHEADER,
329
+ array(
330
+ 'Accept: image/jpeg,image/webp,image/png'
331
+ )
332
+ );
333
+ }
334
+
335
+
336
+ /**
337
+ * Get optimus task depending on $args array
338
+ *
339
+ * @since 1.1.9
340
+ * @change 1.1.9
341
+ *
342
+ * @param array $args Array mit arguments
343
+ * @return string Current optimus task
344
+ */
345
+
346
+ private static function _curl_optimus_task($args)
347
+ {
348
+ if ( ! empty($args['copy']) ) {
349
+ return 'clean';
350
+ }
351
+ if ( ! empty($args['webp']) ) {
352
+ return 'webp';
353
+ }
354
+
355
+ return 'optimize';
356
+ }
357
+
358
+
359
+ /**
360
+ * Adjustment of the file extension
361
+ *
362
+ * @since 1.1.4
363
+ * @change 1.3.0
364
+ *
365
+ * @param string $file File path
366
+ * @param string $extension Target extension
367
+ * @return string Renewed file path
368
+ */
369
+
370
+ private static function _replace_file_extension($file, $extension)
371
+ {
372
+ return substr_replace(
373
+ $file,
374
+ $extension,
375
+ strlen(pathinfo($file, PATHINFO_EXTENSION)) * -1
376
+ );
377
+ }
378
+
379
+
380
+ /**
381
+ * Prüfung des erlaubten Bildtyps pro Datei
382
+ *
383
+ * @since 1.1.0
384
+ * @change 1.1.7
385
+ *
386
+ * @param string $mime_type Mime Type
387
+ * @return boolean TRUE bei bestehender Prüfung
388
+ */
389
+
390
+ private static function _allowed_mime_type($mime_type)
391
+ {
392
+ /* Leer? */
393
+ if ( empty($mime_type) ) {
394
+ return false;
395
+ }
396
+
397
+ /* Quota-Prüfung */
398
+ return array_key_exists(
399
+ $mime_type,
400
+ self::_get_request_quota()
401
+ );
402
+ }
403
+
404
+
405
+ /**
406
+ * Prüfung der erlaubten Bildgröße pro Dateityp
407
+ *
408
+ * @since 1.1.0
409
+ * @change 1.1.7
410
+ *
411
+ * @param string $mime_type Mime Type
412
+ * @param integer $file_size Bild-Größe
413
+ * @return boolean TRUE bei bestehender Prüfung
414
+ */
415
+
416
+ private static function _allowed_file_size($mime_type, $file_size)
417
+ {
418
+ /* Leer? */
419
+ if ( empty($file_size) ) {
420
+ return false;
421
+ }
422
+
423
+ /* Quota */
424
+ $request_quota = self::_get_request_quota();
425
+
426
+ /* Zu groß? */
427
+ if ( $file_size > $request_quota[$mime_type] ) {
428
+ return false;
429
+ }
430
+
431
+ return true;
432
+ }
433
+
434
+
435
+ /**
436
+ * Return Optimus quota for a plugin type
437
+ *
438
+ * @since 1.1.0
439
+ * @change 1.3.0
440
+ *
441
+ * @return array Optimus quota
442
+ */
443
+
444
+ private static function _get_request_quota()
445
+ {
446
+ /* Quota */
447
+ $quota = array(
448
+ /* FREE */
449
+ false => array(
450
+ 'image/jpeg' => 20 * 1024
451
+ ),
452
+
453
+ /* HQ */
454
+ true => array(
455
+ 'image/jpeg' => 1000 * 1024,
456
+ 'image/webp' => 1000 * 1024,
457
+ 'image/png' => 200 * 1024
458
+ )
459
+ );
460
+
461
+ return $quota[ Optimus_HQ::is_unlocked() ];
462
+ }
463
+
464
+
465
+ /**
466
+ * Löscht erzeugte WebP-Dateien
467
+ *
468
+ * @since 1.1.4
469
+ * @change 1.1.7
470
+ *
471
+ * @param string $file Zu löschende Original-Datei
472
+ * @return string $file Zu löschende Original-Datei
473
+ */
474
+
475
+ public static function delete_converted_file($file) {
476
+ /* Plugin options */
477
+ $options = Optimus::get_options();
478
+
479
+ /* Nicht aktiv? */
480
+ if ( ! $options['webp_convert'] OR Optimus_HQ::is_locked() ) {
481
+ return $file;
482
+ }
483
+
484
+ /* Upload path */
485
+ $upload_path = wp_upload_dir();
486
+ $base_dir = $upload_path['basedir'];
487
+
488
+ /* Init converted file */
489
+ $converted_file = $file;
490
+
491
+ /* Check for upload path */
492
+ if ( strpos($converted_file, $base_dir) === false ) {
493
+ $converted_file = path_join($base_dir, $converted_file);
494
+ }
495
+
496
+ /* Replace to webp extension */
497
+ $converted_file = self::_replace_file_extension(
498
+ $converted_file,
499
+ 'webp'
500
+ );
501
+
502
+ /* Remove if exists */
503
+ if ( file_exists($converted_file) ) {
504
+ @unlink($converted_file);
505
+ }
506
+
507
+ return $file;
508
+ }
509
+
510
+
511
+ /**
512
+ * Ermittelt die Differenz der Dateigröße
513
+ *
514
+ * @since 0.0.1
515
+ * @change 1.1.7
516
+ *
517
+ * @param intval $before Größe vor der Optimierung in Bytes
518
+ * @param intval $after Größe nach der Optimierung in Bytes
519
+ * @return intval Ermittelte Differenz
520
+ */
521
+
522
+ private static function _calculate_diff_filesize($before, $after)
523
+ {
524
+ /* Konvertieren */
525
+ $before = (int)$before;
526
+ $after = (int)$after;
527
+
528
+ return sprintf(
529
+ '%d',
530
+ ceil( ($before - $after) * 100 / $before )
531
+ );
532
+ }
533
+ }
inc/optimus_settings.class.php ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ /* Quit */
5
+ defined('ABSPATH') OR exit;
6
+
7
+
8
+ /**
9
+ * Optimus_Settings
10
+ *
11
+ * @since 1.1.2
12
+ */
13
+
14
+ 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.3.1
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
+ 'secure_transport' => (int)(!empty($data['secure_transport']))
54
+ );
55
+ }
56
+
57
+
58
+ /**
59
+ * Einfügen der Optionsseite
60
+ *
61
+ * @since 1.0.0
62
+ * @change 1.3.1
63
+ */
64
+
65
+ public static function add_page()
66
+ {
67
+ $page = add_options_page(
68
+ 'Optimus',
69
+ 'Optimus',
70
+ 'manage_options',
71
+ 'optimus',
72
+ array(
73
+ __CLASS__,
74
+ 'settings_page'
75
+ )
76
+ );
77
+ }
78
+
79
+
80
+ /**
81
+ * Darstellung der Optionsseite
82
+ *
83
+ * @since 1.0.0
84
+ * @change 1.3.1
85
+ */
86
+
87
+ public static function settings_page()
88
+ { ?>
89
+ <div class="wrap">
90
+ <h2>
91
+ Optimus
92
+ </h2>
93
+
94
+ <form method="post" action="options.php">
95
+ <?php settings_fields('optimus') ?>
96
+
97
+ <?php $options = Optimus::get_options() ?>
98
+
99
+ <table class="form-table">
100
+ <tr valign="top">
101
+ <th scope="row">
102
+ Bild-Metadaten
103
+ </th>
104
+ <td>
105
+ <fieldset>
106
+ <label for="optimus_copy_markers">
107
+ <input type="checkbox" name="optimus[copy_markers]" id="optimus_copy_markers" value="1" <?php checked(1, $options['copy_markers']) ?> />
108
+ Keine Löschung der Bild-Metadaten
109
+ </label>
110
+
111
+ <p class="description">
112
+ Aktive Option behält EXIF- und IPTC-Daten bzw. Copyright- und Fotoaufnahme-Parameter in Bildern. Die Größenreduzierung fällt geringer aus. [<a href="https://plus.google.com/b/114450218898660299759/114450218898660299759/posts/Wwz7uFHBzFF" target="_blank">Details</a>]
113
+ </p>
114
+ </fieldset>
115
+ </td>
116
+ </tr>
117
+
118
+ <tr valign="top">
119
+ <th scope="row">
120
+ WebP-Dateien
121
+ </th>
122
+ <td>
123
+ <fieldset>
124
+ <label for="optimus_webp_convert">
125
+ <input type="checkbox" name="optimus[webp_convert]" id="optimus_webp_convert" value="1" <?php checked(1, $options['webp_convert']) ?> onclick='if ( this.checked ) return confirm("Nur für erfahrene Nutzer, da Anpassung der Server-Konfigurationsdatei und Qualitätskontrolle notwendig.\n\nOption aktivieren?")' />
126
+ Anfertigung der WebP-Dateien
127
+ </label>
128
+
129
+ <p class="description">
130
+ Nur Optimus HQ. Modifizierung der Server-Konfigurationsdatei und Überprüfung der Ausgabe erforderlich. Verlangsamt den Optimierungsprozess. [<a href="https://plus.google.com/114450218898660299759/posts/3emb7o4368X" target="_blank">Details</a>]
131
+ </p>
132
+ </fieldset>
133
+ </td>
134
+ </tr>
135
+
136
+ <tr valign="top">
137
+ <th scope="row">
138
+ HTTPS-Verbindung
139
+ </th>
140
+ <td>
141
+ <fieldset>
142
+ <label for="optimus_secure_transport">
143
+ <input type="checkbox" name="optimus[secure_transport]" id="optimus_secure_transport" value="1" <?php checked(1, $options['secure_transport']) ?> />
144
+ Bilder TLS-verschlüsselt übertragen
145
+ </label>
146
+
147
+ <p class="description">
148
+ Nur Optimus HQ. Die Kommunikation zum Optimus-Server erfolgt über eine HTTPS-Verbindung. Verlangsamt den Optimierungsprozess. [<a href="https://plus.google.com/b/114450218898660299759/114450218898660299759/posts/5f2f9XKXb4F" target="_blank">Details</a>]
149
+ </p>
150
+ </fieldset>
151
+ </td>
152
+ </tr>
153
+ </table>
154
+
155
+ <?php submit_button() ?>
156
+ </form>
157
+ </div><?php
158
+ }
159
+ }
optimus.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Plugin Name: Optimus
4
+ Description: Reduzierung der Dateigröße während des Uploads der Bilder in die Mediathek. Effektive und geschwinde Komprimierung ohne Qualitätsverlust.
5
+ Author: Sergej M&uuml;ller
6
+ Author URI: http://wpcoder.de
7
+ Plugin URI: https://optimus.io
8
+ Version: 1.3.1
9
+ */
10
+
11
+
12
+ /* Check & Quit */
13
+ defined('ABSPATH') OR exit;
14
+
15
+
16
+ /* Konstanten */
17
+ define('OPTIMUS_FILE', __FILE__);
18
+ define('OPTIMUS_BASE', plugin_basename(__FILE__));
19
+ define('OPTIMUS_MIN_WP', '3.8');
20
+
21
+
22
+ /* Admin & XMLRPC only */
23
+ if ( is_admin() OR (defined('XMLRPC_REQUEST') && XMLRPC_REQUEST) ) {
24
+ add_action(
25
+ 'plugins_loaded',
26
+ array(
27
+ 'Optimus',
28
+ 'instance'
29
+ )
30
+ );
31
+ }
32
+
33
+
34
+ /* Uninstall */
35
+ register_uninstall_hook(
36
+ __FILE__,
37
+ array(
38
+ 'Optimus',
39
+ 'handle_uninstall_hook'
40
+ )
41
+ );
42
+
43
+
44
+ /* Activation */
45
+ register_activation_hook(
46
+ __FILE__,
47
+ array(
48
+ 'Optimus',
49
+ 'handle_activation_hook'
50
+ )
51
+ );
52
+
53
+
54
+ /* Autoload Init */
55
+ spl_autoload_register('optimus_autoload');
56
+
57
+ /* Autoload Funktion */
58
+ function optimus_autoload($class) {
59
+ if ( in_array($class, array('Optimus', 'Optimus_HQ', 'Optimus_Settings', 'Optimus_Media', 'Optimus_Request')) ) {
60
+ require_once(
61
+ sprintf(
62
+ '%s/inc/%s.class.php',
63
+ dirname(__FILE__),
64
+ strtolower($class)
65
+ )
66
+ );
67
+ }
68
+ }
readme.txt ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Optimus ===
2
+ Contributors: sergej.mueller
3
+ Tags: images, optimize, compress, progressive, performance, png, jpeg, webp
4
+ Requires at least: 3.8
5
+ Tested up to: 3.9
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
+ Effektive Komprimierung der Bilder während des Upload-Vorgangs. Automatisch und ohne Qualitätsverlust.
13
+
14
+
15
+
16
+ == Description ==
17
+
18
+ = (Fast) Magie =
19
+ *Optimus* verkleinert die Dateigröße hochgeladener Medien. Abhängig vom Bild und Format ist eine Reduzierung der Größe um bis zu 70 Prozent möglich. Pro Bild lassen sich mehrere Kilobytes einsparen, die der Blogseiten-Performance positiv beitragen. Das Beeindruckende an der Kompressionstechnologie: Die Qualität der Bilder bleibt garantiert erhalten.
20
+
21
+
22
+ > #### Optimus HQ mit PREMIUM-Funktionen
23
+ > *Optimus* existiert in zwei Varianten:
24
+ > 1. Die kostenlos erhältliche Grundversion mit einigen Einschränkungen.
25
+ > 2. *Optimus HQ* mit erweitertem Funktionsumgang und unlimitiertem Traffic.
26
+ >
27
+ > Alle Informationen zum Produkt auf [optimus.io](https://optimus.io)
28
+
29
+
30
+ = Das Prinzip =
31
+ Während der Übertragung der Bilder in die Mediathek schickt das *Optimus*-Plugin die jeweiligen Bilder parallel an den *Optimus*-Server, der das eingegangene Material bearbeitet und in optimierter Form zurückgibt. Daraufhin speichert das *Optimus*-Plugin die in der Größe reduzierte Version eines Bildes in der Mediathek ab.
32
+
33
+ Die Optimierung der Bilder (samt Thumbnails) erfolgt im Hintergrund und ist für Nutzer optisch nahezu nicht wahrzunehmen. Den Kompressionsgewinn pro Datei stellt *Optimus* innerhalb der Mediathek in Form eines Prozentwertes dar, siehe [Screenshot](https://wordpress.org/plugins/optimus/screenshots/).
34
+
35
+ Anders als andere Tools rührt *Optimus* die Qualität der Fotos niemals an. Stattdessen werden aus Bilddateien überflüssige Informationen extrahiert, die von Bildprogrammen (mit)gespeichert werden und zur Darstellung überhaupt nicht notwendig sind. Auf diese Art bleibt die Qualität der Grafiken erhalten, die Dateigröße kann um ein Vielfaches verkleinert werden. Auf Wunsch behält *Optimus* alle Autor-, EXIF- und Copyright-Informationen innerhalb der Fotos - der Kompressionsgewinn fällt entsprechend kleiner aus.
36
+
37
+ NEU für Optimus HQ: Optionale [Konvertierung](https://plus.google.com/b/114450218898660299759/114450218898660299759/posts/3emb7o4368X) der Bilder ins sparsame [WebP-Bildformat](http://cup.wpcoder.de/webp-jpeg-alternative/).
38
+
39
+
40
+ = Pluspunkte =
41
+ * [Progressive JPEGs](https://plus.google.com/114450218898660299759/posts/RPW48vHbwoM)
42
+ * Verkleinerung der Dateigröße ohne Verlust der Qualität
43
+ * Optimierung aller Vorschauvarianten eines Bildes
44
+ * Keine Code-Anpassungen notwendig
45
+ * Option: Keine Entfernung von EXIF- und IPTC-Metadaten
46
+ * Option: HTTPS-Verbindung für die Bildübertragung (Optimus HQ)
47
+ * Option: Konvertierung ins WebP-Bildformat (Optimus HQ)
48
+ * Optimiert für WordPress Mobile Apps und Windows Live Writer
49
+ * Vorteilhafterer PageSpeed als Ranking-Faktor
50
+ * Geringere Ladezeit der Blogseiten
51
+ * WordPress Multisite-fähig
52
+
53
+
54
+ = Datenschutz =
55
+ * Nach der Optimierung und Auslieferung der Bilder löscht der *Optimus*-Server die temporär angelegten Dateien unverzüglich. Keine Aufbewahrung!
56
+ * Der Server-Standort ist Deutschland beim Hoster domainFACTORY.
57
+
58
+
59
+ = Tipps =
60
+ * Fotos stets als JPEGs statt PNGs speichern. Das PNG-Format ist sinnvoll für Illustrationen, JPEG ist dagegen genau das Richtige für Fotoaufnahmen. Weiterer Grund: Die Größenreduzierung geht bei JPEGs flotter vonstatten.
61
+ * Zahlreiche Blogger optimieren ihre Bilder vor dem Upload mit Desktop-Tools wie [ImageOptim](http://playground.ebiene.de/png-bilder-optimieren/). *Optimus* hat den gravierenden Vorteil, dass von WordPress (Theme & Plugins) erstellte Thumbnails (= Vorschaubilder) von *Optimus* ebenfalls behandelt und minimiert werden. Schliesslich sind im Theme fast immer Thumbnails eingebunden und nur selten das Originalbild.
62
+
63
+
64
+ = Systemanforderungen =
65
+ * PHP ab 5.2.4
66
+ * WordPress ab 3.8
67
+ * Ausgehende Serververbindung
68
+
69
+
70
+ = Website =
71
+ * [optimus.io](https://optimus.io)
72
+
73
+
74
+ = Autor =
75
+ * [Twitter](https://twitter.com/wpSEO)
76
+ * [Google+](https://plus.google.com/110569673423509816572 "Google+")
77
+ * [Plugins](http://wpcoder.de "Plugins")
78
+
79
+
80
+
81
+ == Changelog ==
82
+
83
+ = 1.3.1 =
84
+ * Anpassung für WordPress 3.9: Sicherstellung der Bildoptimierung im WordPress-Editor
85
+
86
+ = 1.3.0 =
87
+ * Überarbeitung der Kommunikation via cURL
88
+ * Implementierung von HTTPS (Optimus HQ)
89
+ * Zusätzliche Checks beim Versand und Empfang der Daten
90
+ * Vereinfachung der Feedback-Ausgabe in grünen Kreisen
91
+ * Kein Abgleich der Davor-Danach-Bildgrößen für 204-Header
92
+ * Connection-Timeout auf 10 Sekunden
93
+ * Tiefgehende Code-Revision
94
+
95
+ = 1.2.0 =
96
+ * Optimierungen am Plugin-Rechtemanagement
97
+ * Überarbeitung der Plugin-Hinweise
98
+ * [Ausführlich auf Google+](https://plus.google.com/b/114450218898660299759/114450218898660299759/posts/2eynLwEsedi)
99
+
100
+ = 1.1.9 =
101
+ * Optimus HQ: Umbau der Lizenzverifizierung wegen einem [Bug](https://www.google.de/search?q=w3+total+cache+transient) im W3 Total Cache Plugin
102
+ * Ausbau der Schnittstelle für binäre Datenübertragung
103
+
104
+ = 1.1.8 =
105
+ * Anzeige des Optimus HQ Ablaufdatums
106
+ * Admin-Hinweis bei abgelaufener Optimus HQ Lizenz
107
+ * [Ausführlich auf Google+](https://plus.google.com/b/114450218898660299759/114450218898660299759/posts/9UGqj6UPjLv)
108
+
109
+ = 1.1.7 =
110
+ * Christmas-Edition (Code- & Performance-Optimierungen)
111
+
112
+ = 1.1.6 =
113
+ * Optimiert für WordPress 3.8
114
+
115
+ = 1.1.5 =
116
+ * Optimus HQ: Eingabe eines neuen Lizenzschlüssels möglich
117
+ * Selbstprüfung auf Erreichbarkeit der Upload-Bilder (Zugriffsschutz, etc.)
118
+ * Performance-Optimierungen
119
+ * [Ausführlich auf Google+](https://plus.google.com/114450218898660299759/posts/6nyJ3kPnFPu)
120
+
121
+ = 1.1.4 =
122
+ * Optimus HQ: Erhöhung des Limits für PNGs auf 200 KB
123
+ * Optimus HQ: Konvertierung der Bilder ins [WebP-Format](https://plus.google.com/b/114450218898660299759/114450218898660299759/posts/3emb7o4368X)
124
+
125
+ = 1.1.3 =
126
+ * Unterstützung für WordPress Apps und Windows Live Writer / [Ausführlich auf Google+](https://plus.google.com/114450218898660299759/posts/CDAc5FoDioN)
127
+
128
+ = 1.1.2 =
129
+ * Option: Bild-Metadaten nicht entfernen / [Ausführlich auf Google+](https://plus.google.com/114450218898660299759/posts/Nu8SLUwvNSS)
130
+
131
+ = 1.1.1 =
132
+ * Interne Umstellung auf Mime-Type
133
+ * Code-Optimierungen
134
+
135
+ = 1.1.0 =
136
+ * Umstellung auf Freemium Modell / [Offizielles Statement](https://plus.google.com/110569673423509816572/posts/XEoHhEi5uJw)
137
+ * Plugin Website: [optimus.io](https://optimus.io)
138
+
139
+ = 1.0.0 =
140
+ * Code-Freeze
141
+ * Vervollständigung der FAQ
142
+ * Filter für lokale Installationen
143
+
144
+ = 0.0.9 =
145
+ * Support für PNGs
146
+
147
+ = 0.0.8 =
148
+ * Beschränkung auf JPEGs (da fast keine PNG/GIF-Nutzung)
149
+ * Menge der optimierten Thumbnails als Diagramm
150
+ * Überarbeitung diverser Code-Fragmente
151
+
152
+ = 0.0.7 =
153
+ * Verbesserte Fehlerausgabe an den Nutzer
154
+
155
+ = 0.0.6 =
156
+ * Erweiterung der FAQ
157
+ * Unterstützung für WordPress 3.5
158
+ * Erhöhung des max. Limits auf 300 KB
159
+
160
+ = 0.0.5 =
161
+ * Zusatzabfrage für (korrupte) Bild-URLs
162
+ * Weiterer [Screenshot](https://wordpress.org/plugins/optimus/screenshots/)
163
+
164
+ = 0.0.4 =
165
+ * Diverse Code-Optimierungen
166
+ * Reduzierung der Max-Größe
167
+
168
+ = 0.0.3 =
169
+ * Unterstützung für PHP 5.2.4
170
+
171
+ = 0.0.2 =
172
+ * Überarbeitung der GUI
173
+
174
+ = 0.0.1 =
175
+ * Init release
176
+
177
+
178
+
179
+ == Upgrade Notice ==
180
+
181
+ = 1.1.0 =
182
+ *Optimus* wurde auf Freemium Modell umgestellt. [Offizielles Statement](https://plus.google.com/110569673423509816572/posts/XEoHhEi5uJw).
183
+
184
+
185
+
186
+ == Screenshots ==
187
+
188
+ 1. Anzeige der Komprimierung und der Bildmenge als Kreis
189
+ 2. Bild samt Thumbnails ohne (oben) und mit Optimus Optimierung