Image optimization & Lazy Load by Optimole - Version 2.2.7

Version Description

Download this release

Release Info

Developer optimole
Plugin Icon 128x128 Image optimization & Lazy Load by Optimole
Version 2.2.7
Comparing to
See all releases

Code changes from version 2.2.6 to 2.2.7

CHANGELOG.md CHANGED
@@ -1,3 +1,22 @@
1
#### [Version 2.2.6](https://github.com/Codeinwp/optimole-wp/compare/v2.2.5...v2.2.6) (2019-12-02)
2
3
* **Bug Fixes**
1
+ #### [Version 2.2.7](https://github.com/Codeinwp/optimole-wp/compare/v2.2.6...v2.2.7) (2019-12-17)
2
+
3
+ * **Bug Fixes**
4
+ * blur remaining outside of an image after it gets lazyloaded ([0df2633](https://github.com/Codeinwp/optimole-wp/commit/0df2633))
5
+ * blur remaining outside of an image after it gets lazyloaded, references Codeinwp/optimole_js_lib[#55](https://github.com/Codeinwp/optimole-wp/issues/55) ([001bfe5](https://github.com/Codeinwp/optimole-wp/commit/001bfe5))
6
+ * edge case lazyload replacement when noscript images are present ([c788c3f](https://github.com/Codeinwp/optimole-wp/commit/c788c3f))
7
+ * improve compatibility with Divi builder ([7d1c469](https://github.com/Codeinwp/optimole-wp/commit/7d1c469))
8
+ * improve compatibility with W3TC minification system ([bf9f058](https://github.com/Codeinwp/optimole-wp/commit/bf9f058))
9
+ * improve compatibility with WP Migrate DB ([02df077](https://github.com/Codeinwp/optimole-wp/commit/02df077))
10
+ * improve lazyload and replacement on json strings ([b7f67fd](https://github.com/Codeinwp/optimole-wp/commit/b7f67fd))
11
+ * removed blur from lazyload placeholders ([2c7d66d](https://github.com/Codeinwp/optimole-wp/commit/2c7d66d))
12
+ * safari blur problem ([5e31ec3](https://github.com/Codeinwp/optimole-wp/commit/5e31ec3))
13
+ * safari blur problem ([2ea1d82](https://github.com/Codeinwp/optimole-wp/commit/2ea1d82))
14
+
15
+ * **Features**
16
+ * adds compatibility for schemaless and relative image URLs ([e3886eb](https://github.com/Codeinwp/optimole-wp/commit/e3886eb))
17
+ * hide Optimole menu via constant [#196](https://github.com/Codeinwp/optimole-wp/issues/196) ([e0268fa](https://github.com/Codeinwp/optimole-wp/commit/e0268fa))
18
+ * skip lazyload on images with skip-lazy flag ([4d9219f](https://github.com/Codeinwp/optimole-wp/commit/4d9219f))
19
+
20
#### [Version 2.2.6](https://github.com/Codeinwp/optimole-wp/compare/v2.2.5...v2.2.6) (2019-12-02)
21
22
* **Bug Fixes**
README.md CHANGED
@@ -89,6 +89,27 @@ Premium users will be able to optimize images for more than 25k monthly active u
89
90
## Changelog ##
91
92
#### [Version 2.2.6](https://github.com/Codeinwp/optimole-wp/compare/v2.2.5...v2.2.6) (2019-12-02)
93
94
* **Bug Fixes**
89
90
## Changelog ##
91
92
+ #### [Version 2.2.7](https://github.com/Codeinwp/optimole-wp/compare/v2.2.6...v2.2.7) (2019-12-17)
93
+
94
+ * **Bug Fixes**
95
+ * blur remaining outside of an image after it gets lazyloaded ([0df2633](https://github.com/Codeinwp/optimole-wp/commit/0df2633))
96
+ * blur remaining outside of an image after it gets lazyloaded, references Codeinwp/optimole_js_lib[#55](https://github.com/Codeinwp/optimole-wp/issues/55) ([001bfe5](https://github.com/Codeinwp/optimole-wp/commit/001bfe5))
97
+ * edge case lazyload replacement when noscript images are present ([c788c3f](https://github.com/Codeinwp/optimole-wp/commit/c788c3f))
98
+ * improve compatibility with Divi builder ([7d1c469](https://github.com/Codeinwp/optimole-wp/commit/7d1c469))
99
+ * improve compatibility with W3TC minification system ([bf9f058](https://github.com/Codeinwp/optimole-wp/commit/bf9f058))
100
+ * improve compatibility with WP Migrate DB ([02df077](https://github.com/Codeinwp/optimole-wp/commit/02df077))
101
+ * improve lazyload and replacement on json strings ([b7f67fd](https://github.com/Codeinwp/optimole-wp/commit/b7f67fd))
102
+ * removed blur from lazyload placeholders ([2c7d66d](https://github.com/Codeinwp/optimole-wp/commit/2c7d66d))
103
+ * safari blur problem ([5e31ec3](https://github.com/Codeinwp/optimole-wp/commit/5e31ec3))
104
+ * safari blur problem ([2ea1d82](https://github.com/Codeinwp/optimole-wp/commit/2ea1d82))
105
+
106
+ * **Features**
107
+ * adds compatibility for schemaless and relative image URLs ([e3886eb](https://github.com/Codeinwp/optimole-wp/commit/e3886eb))
108
+ * hide Optimole menu via constant [#196](https://github.com/Codeinwp/optimole-wp/issues/196) ([e0268fa](https://github.com/Codeinwp/optimole-wp/commit/e0268fa))
109
+ * skip lazyload on images with skip-lazy flag ([4d9219f](https://github.com/Codeinwp/optimole-wp/commit/4d9219f))
110
+
111
+
112
+
113
#### [Version 2.2.6](https://github.com/Codeinwp/optimole-wp/compare/v2.2.5...v2.2.6) (2019-12-02)
114
115
* **Bug Fixes**
inc/admin.php CHANGED
@@ -60,6 +60,7 @@ class Optml_Admin {
60
* Adds script for lazyload/js replacement.
61
*/
62
public function inline_bootstrap_script() {
63
$domain = 'https://' . OPTML_JS_CDN;
64
65
$min = ! OPTML_DEBUG ? '.min' : '';
@@ -85,7 +86,6 @@ class Optml_Admin {
85
}
86
img[data-opt-src]:not([data-opt-lazy-loaded]) {
87
opacity: .75;
88
- filter: blur(5px);
89
}
90
91
</style>
@@ -439,6 +439,9 @@ class Optml_Admin {
439
* Add the dashboard page.
440
*/
441
public function add_dashboard_page() {
442
add_media_page( 'Optimole', 'Optimole', 'manage_options', 'optimole', array( $this, 'render_dashboard_page' ) );
443
}
444
60
* Adds script for lazyload/js replacement.
61
*/
62
public function inline_bootstrap_script() {
63
+
64
$domain = 'https://' . OPTML_JS_CDN;
65
66
$min = ! OPTML_DEBUG ? '.min' : '';
86
}
87
img[data-opt-src]:not([data-opt-lazy-loaded]) {
88
opacity: .75;
89
}
90
91
</style>
439
* Add the dashboard page.
440
*/
441
public function add_dashboard_page() {
442
+ if ( defined( 'OPTIOMLE_HIDE_ADMIN_AREA' ) && OPTIOMLE_HIDE_ADMIN_AREA ) {
443
+ return;
444
+ }
445
add_media_page( 'Optimole', 'Optimole', 'manage_options', 'optimole', array( $this, 'render_dashboard_page' ) );
446
}
447
inc/app_replacer.php CHANGED
@@ -130,7 +130,7 @@ abstract class Optml_App_Replacer {
130
return self::$ignore_lazyload_strings;
131
}
132
133
- self::$possible_src_attributes = apply_filters( 'optml_possible_lazyload_flags', [] );
134
135
return array_merge( self::$possible_src_attributes, [ '<noscript' ] );
136
}
@@ -271,10 +271,11 @@ abstract class Optml_App_Replacer {
271
self::$filters = $this->settings->get_filters();
272
add_filter(
273
'optml_possible_lazyload_flags',
274
- function( $strings = array() ) {
275
foreach ( self::$filters[ Optml_Settings::FILTER_TYPE_LAZYLOAD ][ Optml_Settings::FILTER_CLASS ] as $rule_flag => $status ) {
276
$strings[] = $rule_flag;
277
}
278
return $strings;
279
},
280
10,
@@ -310,9 +311,6 @@ abstract class Optml_App_Replacer {
310
'secret' => $service_data['cdn_secret'],
311
)
312
);
313
- $this->site_mappings['//i0.wp.com/'] = '//';
314
- $this->site_mappings['//i1.wp.com/'] = '//';
315
- $this->site_mappings['//i2.wp.com/'] = '//';
316
317
if ( defined( 'OPTML_SITE_MIRROR' ) && constant( 'OPTML_SITE_MIRROR' ) ) {
318
$this->site_mappings[ rtrim( get_home_url(), '/' ) ] = rtrim( constant( 'OPTML_SITE_MIRROR' ), '/' );
@@ -326,9 +324,12 @@ abstract class Optml_App_Replacer {
326
)
327
);
328
329
- $this->allowed_sources = $this->extract_domain_from_urls( $service_data['whitelist'] );
330
-
331
- $this->is_allowed_site = count( array_diff_key( $this->possible_sources, $this->allowed_sources ) ) > 0;
332
333
$this->max_height = $this->settings->get( 'max_height' );
334
$this->max_width = $this->settings->get( 'max_width' );
@@ -342,6 +343,15 @@ abstract class Optml_App_Replacer {
342
);
343
}
344
345
/**
346
* List to resizes and save the crop for later re-use.
347
*
130
return self::$ignore_lazyload_strings;
131
}
132
133
+ self::$possible_src_attributes = apply_filters( 'optml_possible_lazyload_flags', [ 'skip-lazy' ] );
134
135
return array_merge( self::$possible_src_attributes, [ '<noscript' ] );
136
}
271
self::$filters = $this->settings->get_filters();
272
add_filter(
273
'optml_possible_lazyload_flags',
274
+ function ( $strings = array() ) {
275
foreach ( self::$filters[ Optml_Settings::FILTER_TYPE_LAZYLOAD ][ Optml_Settings::FILTER_CLASS ] as $rule_flag => $status ) {
276
$strings[] = $rule_flag;
277
}
278
+
279
return $strings;
280
},
281
10,
311
'secret' => $service_data['cdn_secret'],
312
)
313
);
314
315
if ( defined( 'OPTML_SITE_MIRROR' ) && constant( 'OPTML_SITE_MIRROR' ) ) {
316
$this->site_mappings[ rtrim( get_home_url(), '/' ) ] = rtrim( constant( 'OPTML_SITE_MIRROR' ), '/' );
324
)
325
);
326
327
+ $this->allowed_sources = $this->extract_domain_from_urls( $service_data['whitelist'] );
328
+ // Allways allow Photon urls.
329
+ $this->allowed_sources['i0.wp.com'] = true;
330
+ $this->allowed_sources['i1.wp.com'] = true;
331
+ $this->allowed_sources['i2.wp.com'] = true;
332
+ $this->is_allowed_site = count( array_diff_key( $this->possible_sources, $this->allowed_sources ) ) > 0;
333
334
$this->max_height = $this->settings->get( 'max_height' );
335
$this->max_width = $this->settings->get( 'max_width' );
343
);
344
}
345
346
+ /**
347
+ * Method to expose upload resource property.
348
+ *
349
+ * @return null
350
+ */
351
+ public function get_upload_resource() {
352
+ return $this->upload_resource;
353
+ }
354
+
355
/**
356
* List to resizes and save the crop for later re-use.
357
*
inc/compatibilities/divi_builder.php CHANGED
@@ -30,7 +30,7 @@ class Optml_divi_builder extends Optml_compatibility {
30
$all_watchers[] = '.et_pb_slides > .et_pb_slide';
31
$all_watchers[] = '.et_parallax_bg';
32
$all_watchers[] = '.et_pb_video_overlay';
33
- $all_watchers[] = '.et_pb_module';
34
$all_watchers[] = '.et_pb_row';
35
$all_watchers[] = '.et_pb_with_background';
36
return $all_watchers;
30
$all_watchers[] = '.et_pb_slides > .et_pb_slide';
31
$all_watchers[] = '.et_parallax_bg';
32
$all_watchers[] = '.et_pb_video_overlay';
33
+ $all_watchers[] = '.et_pb_module:not(.et_pb_blog_grid_wrapper)';
34
$all_watchers[] = '.et_pb_row';
35
$all_watchers[] = '.et_pb_with_background';
36
return $all_watchers;
inc/config.php CHANGED
@@ -26,7 +26,8 @@ class Optml_Config {
26
*
27
* @var string
28
*/
29
- public static $chars = '@%A-Za-z-ÁÀȦÂÄǞǍĂĀÃÅǺǼǢĆĊĈČĎḌḐḒÉÈĖÊËĚĔĒẼE̊ẸǴĠĜǦĞG̃ĢĤḤáàȧâäǟǎăāãåǻǽǣćċĉčďḍḑḓéèėêëěĕēẽe̊ẹǵġĝǧğg̃ģĥḥÍÌİÎÏǏĬĪĨỊĴĶǨĹĻĽĿḼM̂M̄ʼNŃN̂ṄN̈ŇN̄ÑŅṊÓÒȮȰÔÖȪǑŎŌÕȬŐỌǾƠíìiîïǐĭīĩịĵķǩĺļľŀḽm̂m̄ʼnńn̂ṅn̈ňn̄ñņṋóòôȯȱöȫǒŏōõȭőọǿơP̄ŔŘŖŚŜṠŠȘṢŤȚṬṰÚÙÛÜǓŬŪŨŰŮỤẂẀŴẄÝỲŶŸȲỸŹŻŽẒǮp̄ŕřŗśŝṡšşṣťțṭṱúùûüǔŭūũűůụẃẁŵẅýỳŷÿȳỹźżžẓǯßœŒçÇ';
30
31
/**
32
* Service api key.
26
*
27
* @var string
28
*/
29
+
30
+ public static $chars = '\/:,\\\\.\-\d_@%A-Za-z-ÁÀȦÂÄǞǍĂĀÃÅǺǼǢĆĊĈČĎḌḐḒÉÈĖÊËĚĔĒẼE̊ẸǴĠĜǦĞG̃ĢĤḤáàȧâäǟǎăāãåǻǽǣćċĉčďḍḑḓéèėêëěĕēẽe̊ẹǵġĝǧğg̃ģĥḥÍÌİÎÏǏĬĪĨỊĴĶǨĹĻĽĿḼM̂M̄ʼNŃN̂ṄN̈ŇN̄ÑŅṊÓÒȮȰÔÖȪǑŎŌÕȬŐỌǾƠíìiîïǐĭīĩịĵķǩĺļľŀḽm̂m̄ʼnńn̂ṅn̈ňn̄ñņṋóòôȯȱöȫǒŏōõȭőọǿơP̄ŔŘŖŚŜṠŠȘṢŤȚṬṰÚÙÛÜǓŬŪŨŰŮỤẂẀŴẄÝỲŶŸȲỸŹŻŽẒǮp̄ŕřŗśŝṡšşṣťțṭṱúùûüǔŭūũűůụẃẁŵẅýỳŷÿȳỹźżžẓǯßœŒçÇ';
31
32
/**
33
* Service api key.
inc/conflicts/divi.php ADDED
@@ -0,0 +1,60 @@
1
+ <?php
2
+
3
+ /**
4
+ * Class Optml_Divi
5
+ *
6
+ * An example of a conflict.
7
+ */
8
+ class Optml_Divi extends Optml_abstract_conflict {
9
+
10
+ /**
11
+ * Optml_Divi constructor.
12
+ */
13
+ public function __construct() {
14
+ $this->priority = 2;
15
+ $this->severity = self::SEVERITY_HIGH;
16
+ parent::__construct();
17
+ }
18
+
19
+ /**
20
+ * Set the message property
21
+ *
22
+ * @since 2.2.6
23
+ * @access public
24
+ */
25
+ public function define_message() {
26
+ $this->message = sprintf( __( 'It seems your are using %1$sDivi%2$s right now. %3$s In order for Optimole to replace the images in your Divi pages, you will need to go to %4$sDivi -> Theme Options -> Builder -> Advanced -> Static CSS File Generations%5$s and click on Clear for the images to be processed. ', 'optimole-wp' ), '<b>', '</b>', '<br/>', '<a target="_blank" href="' . admin_url( 'admin.php?page=et_divi_options' ) . '">', '</a>' );
27
+ }
28
+
29
+
30
+ /**
31
+ * Determine if conflict is applicable.
32
+ *
33
+ * @return bool
34
+ * @since 2.2.6
35
+ * @access public
36
+ */
37
+ public function is_conflict_valid() {
38
+ if ( ! is_plugin_active( 'divi-builder/divi-builder.php' ) ) {
39
+ return false;
40
+ }
41
+
42
+ $theme = wp_get_theme();
43
+ // No divi, no child theme.
44
+ if ( strcmp( $theme->get( 'Name' ), 'Divi' ) !== 0 && $theme->parent() === false ) {
45
+ return false;
46
+ }
47
+ // Child theme, no parent divi.
48
+ if ( $theme->parent() !== false && strcmp( $theme->parent()->get( 'Name' ), 'Divi' ) !== 0 ) {
49
+ return false;
50
+ }
51
+ if ( ! function_exists( 'et_get_option' ) ) {
52
+ return false;
53
+ }
54
+ if ( 'off' === et_get_option( 'et_pb_static_css_file', 'on' ) ) {
55
+ return false;
56
+ }
57
+
58
+ return true;
59
+ }
60
+ }
inc/lazyload_replacer.php CHANGED
@@ -183,7 +183,7 @@ final class Optml_Lazyload_Replacer extends Optml_App_Replacer {
183
if ( ! self::$is_lazyload_placeholder && ! $should_ignore_rescale ) {
184
$optml_args['quality'] = 'eco';
185
$optml_args['resize'] = [];
186
- $low_url = apply_filters( 'optml_content_url', $is_slashed ? stripslashes( $original_url ) : $original_url, $optml_args );
187
$low_url = $is_slashed ? addcslashes( $low_url, '/' ) : $low_url;
188
} else {
189
$low_url = $this->get_svg_for(
@@ -221,12 +221,12 @@ final class Optml_Lazyload_Replacer extends Optml_App_Replacer {
221
);
222
$new_tag = preg_replace(
223
[
224
- '/( src(?>=|"|\'|\s|\\\\)*)' . preg_quote( $original_url, '/' ) . '/m',
225
- '/ src=/m',
226
],
227
[
228
"$1$low_url",
229
- $opt_src . ' src=',
230
],
231
$new_tag,
232
1
183
if ( ! self::$is_lazyload_placeholder && ! $should_ignore_rescale ) {
184
$optml_args['quality'] = 'eco';
185
$optml_args['resize'] = [];
186
+ $low_url = apply_filters( 'optml_content_url', $original_url, $optml_args );
187
$low_url = $is_slashed ? addcslashes( $low_url, '/' ) : $low_url;
188
} else {
189
$low_url = $this->get_svg_for(
221
);
222
$new_tag = preg_replace(
223
[
224
+ '/((?:\s|\'|"){1,}src(?>=|"|\'|\s|\\\\)*)' . preg_quote( $original_url, '/' ) . '/m',
225
+ '/<img/im',
226
],
227
[
228
"$1$low_url",
229
+ '<img' . $opt_src,
230
],
231
$new_tag,
232
1
inc/main.php CHANGED
@@ -97,6 +97,7 @@ final class Optml_Main {
97
'Optml_Jetpack_Photon',
98
'Optml_Jetpack_Lazyload',
99
'Optml_Wprocket',
100
)
101
);
102
97
'Optml_Jetpack_Photon',
98
'Optml_Jetpack_Lazyload',
99
'Optml_Wprocket',
100
+ 'Optml_Divi',
101
)
102
);
103
inc/manager.php CHANGED
@@ -200,6 +200,9 @@ final class Optml_Manager {
200
if ( ! wp_doing_ajax() ) {
201
return false;
202
}
203
204
return true;
205
}
@@ -257,101 +260,13 @@ final class Optml_Manager {
257
return $metadata;
258
}
259
260
- return $this->process_urls_from_json( $current_meta );
261
}
262
263
// Return original if the check does not pass
264
return $metadata;
265
}
266
267
- /**
268
- * Process json string.
269
- *
270
- * @param string $json Json string.
271
- *
272
- * @return string Processed string.
273
- */
274
- public function process_urls_from_json( $json ) {
275
-
276
- $extracted_urls = $this->extract_urls_from_json( $json );
277
-
278
- return $this->do_url_replacement( $json, $extracted_urls );
279
- }
280
-
281
- /**
282
- * Extract urls used as values in json string, i.e not prefixed by =("|') char.
283
- *
284
- * @param string $content Raw json string.
285
- *
286
- * @return array array of urls.
287
- */
288
- public function extract_urls_from_json( $content ) {
289
- $regex = '/(?<!(=|\\\\)(?:"|\'|"))(?:http(?:s?):)(?:[\/\\\\|.|\w|\s|@|%|-])*\.(?:' . implode( '|', array_keys( Optml_Config::$extensions ) ) . ')(?:\??[\w|=|&|\-|\.|:]*)/';
290
- preg_match_all(
291
- $regex,
292
- $content,
293
- $urls
294
- );
295
-
296
- return $this->normalize_urls( $urls[0] );
297
- }
298
-
299
- /**
300
- * Normalize extracted urls.
301
- *
302
- * @param array $urls Raw urls extracted.
303
- *
304
- * @return array Normalized array.
305
- */
306
- private function normalize_urls( $urls ) {
307
-
308
- $urls = array_map(
309
- function ( $value ) {
310
- $value = str_replace( '&quot;', '', $value );
311
-
312
- return rtrim( $value, '\\";\'' );
313
- },
314
- $urls
315
- );
316
- $urls = array_unique( $urls );
317
-
318
- return array_values( $urls );
319
- }
320
-
321
- /**
322
- * Process string content and replace possible urls.
323
- *
324
- * @param string $html String content.
325
- * @param array $extracted_urls Urls to check.
326
- *
327
- * @return string Processed html.
328
- */
329
- private function do_url_replacement( $html, $extracted_urls ) {
330
- $extracted_urls = apply_filters( 'optml_extracted_urls', $extracted_urls );
331
-
332
- if ( empty( $extracted_urls ) ) {
333
- return $html;
334
- }
335
-
336
- $urls = array_combine( $extracted_urls, $extracted_urls );
337
- $urls = array_map(
338
- function ( $url ) {
339
- $is_slashed = strpos( $url, '\/' ) !== false;
340
- $url = html_entity_decode( $url );
341
- $new_url = apply_filters( 'optml_content_url', $url );
342
-
343
- return $is_slashed ? addcslashes( $new_url, '/' ) : $new_url;
344
- },
345
- $urls
346
- );
347
-
348
- foreach ( $urls as $origin => $replace ) {
349
- $html = preg_replace( '/(?<!\/)' . preg_quote( $origin, '/' ) . '/m', $replace, $html );
350
- }
351
-
352
- return $html;
353
- }
354
-
355
/**
356
* Filter raw HTML content for urls.
357
*
@@ -434,8 +349,9 @@ final class Optml_Manager {
434
$header_start = $matches[0][1];
435
$header_end = $header_start + strlen( $matches[0][0] );
436
}
437
438
- if ( preg_match_all( '/(?:<a[^>]+?href=["|\'](?P<link_url>[^\s]+?)["|\'][^>]*?>\s*)?(?P<img_tag>(?:<noscript\s*>\s*)?<img[^>]*?\s+?(?:' . implode( '|', array_merge( [ 'src' ], Optml_Tag_Replacer::possible_src_attributes() ) ) . ')=\\\\?["|\'](?P<img_url>[^\s]+?)["|\'].*?>(?:<\/noscript\s*>)?){1}(?:\s*<\/a>)?/ism', $content, $images, PREG_OFFSET_CAPTURE ) ) {
439
440
foreach ( $images as $key => $unused ) {
441
// Simplify the output as much as possible, mostly for confirming test results.
@@ -495,14 +411,88 @@ final class Optml_Manager {
495
* @return array
496
*/
497
public function extract_image_urls_from_content( $content ) {
498
- $regex = '/(?:http(?:s?):)(?:[\/\\\\|.|\w|\s|-])*(?:[' . Optml_Config::$chars . '])*\.(?:' . implode( '|', array_keys( Optml_Config::$extensions ) ) . ')(?:\?{1}[\w|=|&|\-|\.|:|;]*)?/';
499
preg_match_all(
500
$regex,
501
$content,
502
$urls
503
);
504
505
- return $this->normalize_urls( $urls[0] );
506
}
507
508
/**
200
if ( ! wp_doing_ajax() ) {
201
return false;
202
}
203
+ if ( isset( $_REQUEST['action'] ) && strpos( $_REQUEST['action'], 'wpmdb' ) !== false ) {
204
+ return false;
205
+ }
206
207
return true;
208
}
260
return $metadata;
261
}
262
263
+ return $this->replace_content( $current_meta );
264
}
265
266
// Return original if the check does not pass
267
return $metadata;
268
}
269
270
/**
271
* Filter raw HTML content for urls.
272
*
349
$header_start = $matches[0][1];
350
$header_end = $header_start + strlen( $matches[0][0] );
351
}
352
+ $regex = '/(?:<a[^>]+?href=["|\'](?P<link_url>[^\s]+?)["|\'][^>]*?>\s*)?(?P<img_tag>(?:<noscript\s*>\s*)?<img[^>]*?\s?(?:' . implode( '|', array_merge( [ 'src' ], Optml_Tag_Replacer::possible_src_attributes() ) ) . ')=["\'\\\\]*?(?P<img_url>[' . Optml_Config::$chars . ']{10,}).*?>(?:\s*<\/noscript\s*>)?){1}(?:\s*<\/a>)?/ism';
353
354
+ if ( preg_match_all( $regex, $content, $images, PREG_OFFSET_CAPTURE ) ) {
355
356
foreach ( $images as $key => $unused ) {
357
// Simplify the output as much as possible, mostly for confirming test results.
411
* @return array
412
*/
413
public function extract_image_urls_from_content( $content ) {
414
+
415
+ $regex = '/(?:[(|\s\';",=])((?:http|\/|\\\\){1}(?:[' . Optml_Config::$chars . ']{10,}\.(?:' . implode( '|', array_keys( Optml_Config::$extensions ) ) . ')))(?=(?:|\?|"|&|,|\s|\'|\)|\||\\\\|}))/U';
416
preg_match_all(
417
$regex,
418
$content,
419
$urls
420
);
421
422
+ return $this->normalize_urls( $urls[1] );
423
+ }
424
+
425
+ /**
426
+ * Normalize extracted urls.
427
+ *
428
+ * @param array $urls Raw urls extracted.
429
+ *
430
+ * @return array Normalized array.
431
+ */
432
+ private function normalize_urls( $urls ) {
433
+
434
+ $urls = array_map(
435
+ function ( $value ) {
436
+ $value = str_replace( '&quot;', '', $value );
437
+
438
+ return rtrim( $value, '\\";\'' );
439
+ },
440
+ $urls
441
+ );
442
+ $urls = array_unique( $urls );
443
+
444
+ return array_values( $urls );
445
+ }
446
+
447
+ /**
448
+ * Process string content and replace possible urls.
449
+ *
450
+ * @param string $html String content.
451
+ * @param array $extracted_urls Urls to check.
452
+ *
453
+ * @return string Processed html.
454
+ */
455
+ private function do_url_replacement( $html, $extracted_urls ) {
456
+ $extracted_urls = apply_filters( 'optml_extracted_urls', $extracted_urls );
457
+
458
+ if ( empty( $extracted_urls ) ) {
459
+ return $html;
460
+ }
461
+ $slashed_config = addcslashes( Optml_Config::$service_url, '/' );
462
+
463
+ $extracted_urls = array_filter(
464
+ $extracted_urls,
465
+ function ( $value ) use ( $slashed_config ) {
466
+ return strpos( $value, Optml_Config::$service_url ) === false && strpos( $value, $slashed_config ) === false;
467
+ }
468
+ );
469
+ $upload_resource = $this->tag_replacer->get_upload_resource();
470
+ $urls = array_combine( $extracted_urls, $extracted_urls );
471
+
472
+ $urls = array_map(
473
+ function ( $url ) use ( $upload_resource ) {
474
+ $is_slashed = strpos( $url, '\/' ) !== false;
475
+ $is_relative = strpos(
476
+ $url,
477
+ $is_slashed ?
478
+ addcslashes( $upload_resource['content_path'], '/' ) :
479
+ $upload_resource['content_path']
480
+ ) === 0;
481
+ if ( $is_relative ) {
482
+ $url = $upload_resource['content_host'] . $url;
483
+ }
484
+ $new_url = apply_filters( 'optml_content_url', $url );
485
+
486
+ return $new_url;
487
+ },
488
+ $urls
489
+ );
490
+
491
+ foreach ( $urls as $origin => $replace ) {
492
+ $html = preg_replace( '/(?<![\/|:|\\w])' . preg_quote( $origin, '/' ) . '/m', $replace, $html );
493
+ }
494
+
495
+ return $html;
496
}
497
498
/**
inc/tag_replacer.php CHANGED
@@ -143,7 +143,7 @@ final class Optml_Tag_Replacer extends Optml_App_Replacer {
143
144
$is_slashed = strpos( $images['img_url'][ $index ], '\/' ) !== false;
145
146
- $src = $tmp = $is_slashed ? stripslashes( $images['img_url'][ $index ] ) : $images['img_url'][ $index ];
147
148
if ( strpos( $src, $this->upload_resource['content_path'] ) === 0 ) {
149
$src = $tmp = untrailingslashit( $this->upload_resource['content_host'] ) . $src;
143
144
$is_slashed = strpos( $images['img_url'][ $index ], '\/' ) !== false;
145
146
+ $src = $tmp = $is_slashed ? $this->strip_slashes( $images['img_url'][ $index ] ) : $images['img_url'][ $index ];
147
148
if ( strpos( $src, $this->upload_resource['content_path'] ) === 0 ) {
149
$src = $tmp = untrailingslashit( $this->upload_resource['content_host'] ) . $src;
inc/traits/normalizer.php CHANGED
@@ -27,6 +27,16 @@ trait Optml_Normalizer {
27
return boolval( $value );
28
}
29
30
/**
31
* Normalize value to an integer within bounds.
32
*
27
return boolval( $value );
28
}
29
30
+ /**
31
+ * Strip slashes on unicode encoded strings.
32
+ *
33
+ * @param string $string Input string.
34
+ *
35
+ * @return string Decoded string.
36
+ */
37
+ public function strip_slashes( $string ) {
38
+ return html_entity_decode( stripslashes( preg_replace( '/\\\u([\da-fA-F]{4})/', '&#x\1;', $string ) ) );
39
+ }
40
/**
41
* Normalize value to an integer within bounds.
42
*
inc/url_replacer.php CHANGED
@@ -118,8 +118,7 @@ final class Optml_Url_Replacer extends Optml_App_Replacer {
118
119
// We do a little hack here, for json unicode chars we first replace them with html special chars,
120
// we then strip slashes to normalize the URL and last we convert html special chars back to get a clean URL
121
- $url = $is_slashed ? html_entity_decode( stripslashes( preg_replace( '/\\\u([\da-fA-F]{4})/', '&#x\1;', $url ) ) ) : $url;
122
-
123
if ( strpos( $url, Optml_Config::$service_url ) !== false ) {
124
return $original_url;
125
}
118
119
// We do a little hack here, for json unicode chars we first replace them with html special chars,
120
// we then strip slashes to normalize the URL and last we convert html special chars back to get a clean URL
121
+ $url = $is_slashed ? html_entity_decode( stripslashes( preg_replace( '/\\\u([\da-fA-F]{4})/', '&#x\1;', $url ) ) ) : ( $url );
122
if ( strpos( $url, Optml_Config::$service_url ) !== false ) {
123
return $original_url;
124
}
optimole-wp.php CHANGED
@@ -2,7 +2,7 @@
2
/**
3
* Plugin Name: Image optimization service by Optimole
4
* Description: Complete handling of your website images.
5
- * Version: 2.2.6
6
* Author: Optimole
7
* Author URI: https://optimole.com
8
* License: GPL-2.0+
@@ -75,7 +75,7 @@ function optml() {
75
define( 'OPTML_URL', plugin_dir_url( __FILE__ ) );
76
define( 'OPTML_JS_CDN', 'd5jmkjjpb7yfg.cloudfront.net' );
77
define( 'OPTML_PATH', plugin_dir_path( __FILE__ ) );
78
- define( 'OPTML_VERSION', '2.2.6' );
79
define( 'OPTML_NAMESPACE', 'optml' );
80
define( 'OPTML_BASEFILE', __FILE__ );
81
// Fallback for old PHP versions when this constant is not defined.
2
/**
3
* Plugin Name: Image optimization service by Optimole
4
* Description: Complete handling of your website images.
5
+ * Version: 2.2.7
6
* Author: Optimole
7
* Author URI: https://optimole.com
8
* License: GPL-2.0+
75
define( 'OPTML_URL', plugin_dir_url( __FILE__ ) );
76
define( 'OPTML_JS_CDN', 'd5jmkjjpb7yfg.cloudfront.net' );
77
define( 'OPTML_PATH', plugin_dir_path( __FILE__ ) );
78
+ define( 'OPTML_VERSION', '2.2.7' );
79
define( 'OPTML_NAMESPACE', 'optml' );
80
define( 'OPTML_BASEFILE', __FILE__ );
81
// Fallback for old PHP versions when this constant is not defined.
readme.txt CHANGED
@@ -89,6 +89,27 @@ Premium users will be able to optimize images for more than 25k monthly active u
89
90
== Changelog ==
91
92
#### [Version 2.2.6](https://github.com/Codeinwp/optimole-wp/compare/v2.2.5...v2.2.6) (2019-12-02)
93
94
* **Bug Fixes**
89
90
== Changelog ==
91
92
+ #### [Version 2.2.7](https://github.com/Codeinwp/optimole-wp/compare/v2.2.6...v2.2.7) (2019-12-17)
93
+
94
+ * **Bug Fixes**
95
+ * blur remaining outside of an image after it gets lazyloaded ([0df2633](https://github.com/Codeinwp/optimole-wp/commit/0df2633))
96
+ * blur remaining outside of an image after it gets lazyloaded, references Codeinwp/optimole_js_lib[#55](https://github.com/Codeinwp/optimole-wp/issues/55) ([001bfe5](https://github.com/Codeinwp/optimole-wp/commit/001bfe5))
97
+ * edge case lazyload replacement when noscript images are present ([c788c3f](https://github.com/Codeinwp/optimole-wp/commit/c788c3f))
98
+ * improve compatibility with Divi builder ([7d1c469](https://github.com/Codeinwp/optimole-wp/commit/7d1c469))
99
+ * improve compatibility with W3TC minification system ([bf9f058](https://github.com/Codeinwp/optimole-wp/commit/bf9f058))
100
+ * improve compatibility with WP Migrate DB ([02df077](https://github.com/Codeinwp/optimole-wp/commit/02df077))
101
+ * improve lazyload and replacement on json strings ([b7f67fd](https://github.com/Codeinwp/optimole-wp/commit/b7f67fd))
102
+ * removed blur from lazyload placeholders ([2c7d66d](https://github.com/Codeinwp/optimole-wp/commit/2c7d66d))
103
+ * safari blur problem ([5e31ec3](https://github.com/Codeinwp/optimole-wp/commit/5e31ec3))
104
+ * safari blur problem ([2ea1d82](https://github.com/Codeinwp/optimole-wp/commit/2ea1d82))
105
+
106
+ * **Features**
107
+ * adds compatibility for schemaless and relative image URLs ([e3886eb](https://github.com/Codeinwp/optimole-wp/commit/e3886eb))
108
+ * hide Optimole menu via constant [#196](https://github.com/Codeinwp/optimole-wp/issues/196) ([e0268fa](https://github.com/Codeinwp/optimole-wp/commit/e0268fa))
109
+ * skip lazyload on images with skip-lazy flag ([4d9219f](https://github.com/Codeinwp/optimole-wp/commit/4d9219f))
110
+
111
+
112
+
113
#### [Version 2.2.6](https://github.com/Codeinwp/optimole-wp/compare/v2.2.5...v2.2.6) (2019-12-02)
114
115
* **Bug Fixes**
themeisle-hash.json CHANGED
@@ -1 +1 @@
1
- {"optimole-wp.php":"a264f55269244fed4143b86a263fc6c6"}
1
+ {"optimole-wp.php":"a7c4f6a9fad954a565b076fde60beab7"}
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
5
require_once __DIR__ . '/composer/autoload_real.php';
6
7
- return ComposerAutoloaderInit0b6580d19fdcfda40f4987503eb13ec5::getLoader();
4
5
require_once __DIR__ . '/composer/autoload_real.php';
6
7
+ return ComposerAutoloaderInita2a71cedc61637a6775122c3b580ba36::getLoader();
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
3
// autoload_real.php @generated by Composer
4
5
- class ComposerAutoloaderInit0b6580d19fdcfda40f4987503eb13ec5
6
{
7
private static $loader;
8
@@ -19,15 +19,15 @@ class ComposerAutoloaderInit0b6580d19fdcfda40f4987503eb13ec5
19
return self::$loader;
20
}
21
22
- spl_autoload_register(array('ComposerAutoloaderInit0b6580d19fdcfda40f4987503eb13ec5', 'loadClassLoader'), true, true);
23
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit0b6580d19fdcfda40f4987503eb13ec5', 'loadClassLoader'));
25
26
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
if ($useStaticLoader) {
28
require_once __DIR__ . '/autoload_static.php';
29
30
- call_user_func(\Composer\Autoload\ComposerStaticInit0b6580d19fdcfda40f4987503eb13ec5::getInitializer($loader));
31
} else {
32
$map = require __DIR__ . '/autoload_namespaces.php';
33
foreach ($map as $namespace => $path) {
@@ -48,19 +48,19 @@ class ComposerAutoloaderInit0b6580d19fdcfda40f4987503eb13ec5
48
$loader->register(true);
49
50
if ($useStaticLoader) {
51
- $includeFiles = Composer\Autoload\ComposerStaticInit0b6580d19fdcfda40f4987503eb13ec5::$files;
52
} else {
53
$includeFiles = require __DIR__ . '/autoload_files.php';
54
}
55
foreach ($includeFiles as $fileIdentifier => $file) {
56
- composerRequire0b6580d19fdcfda40f4987503eb13ec5($fileIdentifier, $file);
57
}
58
59
return $loader;
60
}
61
}
62
63
- function composerRequire0b6580d19fdcfda40f4987503eb13ec5($fileIdentifier, $file)
64
{
65
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
66
require $file;
2
3
// autoload_real.php @generated by Composer
4
5
+ class ComposerAutoloaderInita2a71cedc61637a6775122c3b580ba36
6
{
7
private static $loader;
8
19
return self::$loader;
20
}
21
22
+ spl_autoload_register(array('ComposerAutoloaderInita2a71cedc61637a6775122c3b580ba36', 'loadClassLoader'), true, true);
23
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInita2a71cedc61637a6775122c3b580ba36', 'loadClassLoader'));
25
26
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
if ($useStaticLoader) {
28
require_once __DIR__ . '/autoload_static.php';
29
30
+ call_user_func(\Composer\Autoload\ComposerStaticInita2a71cedc61637a6775122c3b580ba36::getInitializer($loader));
31
} else {
32
$map = require __DIR__ . '/autoload_namespaces.php';
33
foreach ($map as $namespace => $path) {
48
$loader->register(true);
49
50
if ($useStaticLoader) {
51
+ $includeFiles = Composer\Autoload\ComposerStaticInita2a71cedc61637a6775122c3b580ba36::$files;
52
} else {
53
$includeFiles = require __DIR__ . '/autoload_files.php';
54
}
55
foreach ($includeFiles as $fileIdentifier => $file) {
56
+ composerRequirea2a71cedc61637a6775122c3b580ba36($fileIdentifier, $file);
57
}
58
59
return $loader;
60
}
61
}
62
63
+ function composerRequirea2a71cedc61637a6775122c3b580ba36($fileIdentifier, $file)
64
{
65
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
66
require $file;
vendor/composer/autoload_static.php CHANGED
@@ -4,7 +4,7 @@
4
5
namespace Composer\Autoload;
6
7
- class ComposerStaticInit0b6580d19fdcfda40f4987503eb13ec5
8
{
9
public static $files = array (
10
'9fef4034ed73e26a337d9856ea126f7f' => __DIR__ . '/..' . '/codeinwp/themeisle-sdk/load.php',
4
5
namespace Composer\Autoload;
6
7
+ class ComposerStaticInita2a71cedc61637a6775122c3b580ba36
8
{
9
public static $files = array (
10
'9fef4034ed73e26a337d9856ea126f7f' => __DIR__ . '/..' . '/codeinwp/themeisle-sdk/load.php',