PluginProbe
Robin Image Optimizer – Unlimited Image Optimization, WebP & AVIF / 2.0.0
Robin Image Optimizer – Unlimited Image Optimization, WebP & AVIF v2.0.0
2.0.7 2.0.6 2.0.5 trunk 1.3.7 1.4.0 1.4.1 1.4.2 1.4.6 1.5.0 1.5.3 1.5.6 1.5.8 1.6.5 1.6.6 1.6.9 1.7.0 1.7.4 1.8.1 1.8.2 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 All 26 releases
robin-image-optimizer / includes / functions.php

functions.php in Robin Image Optimizer – Unlimited Image Optimization, WebP & AVIF 2.0.0, at includes/functions.php

592 lines 14.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // Exit if accessed directly
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit;
6 }
7
8 use WRIO\Paths\phpUri;
9
10 /**
11 * Checks if the current request is a WP REST API request.
12 *
13 * Case #1: After WP_REST_Request initialisation
14 * Case #2: Support "plain" permalink settings
15 * Case #3: URL Path begins with wp-json/ (your REST prefix)
16 * Also supports WP installations in subfolders
17 *
18 * @since 1.3.6
19 * @return boolean
20 */
21 function wrio_doing_rest_api() {
22 $prefix = rest_get_url_prefix();
23 $rest_route = WRIO_Plugin::app()->request->get( 'rest_route', null );
24 if ( ( defined( 'REST_REQUEST' ) && REST_REQUEST ) // (#1)
25 || ( ! is_null( $rest_route ) // (#2)
26 && strpos( trim( $rest_route, '\\/' ), $prefix, 0 ) === 0 ) ) {
27 return true;
28 }
29
30 // (#3)
31 $rest_url = wp_parse_url( site_url( $prefix ) );
32 $current_url = wp_parse_url( add_query_arg( [] ) );
33
34 return strpos( $current_url['path'] ?? '/', $rest_url['path'], 0 ) === 0;
35 }
36
37 /**
38 * @return bool
39 * @since 1.3.6
40 */
41 function wrio_doing_ajax() {
42 if ( function_exists( 'wp_doing_ajax' ) ) {
43 return wp_doing_ajax();
44 }
45
46 return defined( 'DOING_AJAX' ) && DOING_AJAX;
47 }
48
49 /**
50 * @return bool
51 * @since 1.3.6
52 */
53 function wrio_doing_cron() {
54 if ( function_exists( 'wp_doing_cron' ) ) {
55 return wp_doing_cron();
56 }
57
58 return defined( 'DOING_CRON' ) && DOING_CRON;
59 }
60
61 /**
62 * Convert full URL paths to absolute paths.
63 *
64 * @param string $url abs url https://site.com/wp-conent/uploads/10/05/image.jpeg
65 *
66 * @return string|null abs path var/site.com/www/wp-conent/uploads/10/05/image.jpeg, if failure null
67 * @since 1.4.0
68 */
69 function wrio_url_to_abs_path( $url ) {
70 if ( empty( $url ) ) {
71 return null;
72 }
73
74 if ( strpos( $url, '?' ) !== false ) {
75 $url_parts = explode( '?', $url );
76
77 if ( 2 == sizeof( $url_parts ) ) {
78 $url = $url_parts[0];
79 }
80 }
81
82 $url = rtrim( $url, '/' );
83
84 // todo: if the external site, then it will not work
85 return str_replace( get_site_url(), untrailingslashit( wp_normalize_path( ABSPATH ) ), $url );
86 }
87
88 /**
89 * Convert relative urls to absolute
90 *
91 * @param string $url relative url /wp-conent/uploads/10/05/image.jpeg
92 *
93 * @return string abs url https://site.com/wp-conent/uploads/10/05/image.jpeg
94 * @since 1.4.0
95 */
96 function wrio_rel_to_abs_url( $url ) {
97 require_once WRIO_PLUGIN_DIR . '/libs/class-rio-relative-to-abs-uri.php';
98
99 return WRIO\Paths\phpUri::parse( get_site_url() )->join( $url );
100 }
101
102 /**
103 * Converts relative urls to absolute paths
104 *
105 * @param string $url relative url /wp-conent/uploads/10/05/image.jpeg
106 *
107 * @return string abs path var/site.com/www/wp-conent/uploads/10/05/image.jpeg
108 * @since 1.4.0
109 */
110 function wrio_rel_url_to_abs_path( $url ) {
111 $abs_url = wrio_rel_to_abs_url( $url );
112
113 return wrio_url_to_abs_path( $abs_url );
114 }
115
116 /**
117 * @param $string
118 * @param bool $capitalize_first_character
119 *
120 * @return mixed|string
121 * @since 1.1
122 */
123 function wrio_dashes_to_camel_case( $string, $capitalize_first_character = false ) {
124
125 $str = str_replace( '-', '_', ucwords( $string, '-' ) );
126
127 if ( ! $capitalize_first_character ) {
128 $str = lcfirst( $str );
129 }
130
131 return $str;
132 }
133
134 /**
135 * Alternative php functions basename. Our function works with сyrillic file names.
136 *
137 * @param string $str file path
138 *
139 * @return string|string[]|null
140 * @since 1.3.0
141 */
142 /*
143 function wrio_basename( $str ) {
144 return preg_replace( '/^.+[\\\\\\/]/', '', $str );
145 }*/
146
147 /**
148 * @return bool
149 * @since 1.3.0
150 */
151 function wrio_is_active_nextgen_gallery() {
152 return is_plugin_active( 'nextgen-gallery/nggallery.php' );
153 }
154
155 /**
156 * @param string $dir
157 *
158 * @return bool
159 * @since 1.1
160 */
161 function wrio_rmdir( $dir ) {
162 if ( is_dir( $dir ) ) {
163 $scn = scandir( $dir );
164
165 foreach ( $scn as $files ) {
166 if ( $files !== '.' ) {
167 if ( $files !== '..' ) {
168 if ( ! is_dir( $dir . '/' . $files ) ) {
169 @unlink( $dir . '/' . $files );
170 } else {
171 wrio_rmdir( $dir . '/' . $files );
172 if ( is_dir( $dir . '/' . $files ) ) {
173 @rmdir( $dir . '/' . $files );
174 }
175 }
176 }
177 }
178 }
179 @rmdir( $dir );
180
181 return true;
182 }
183
184 return false;
185 }
186
187 /**
188 * Пересчёт размера файла в байта�
189 на человекопонятный вид
190 *
191 * Пример: вводим 67894 байт, получаем 67.8 KB
192 * Пример: вводим 6789477 байт, получаем 6.7 MB
193 *
194 * @param int $size размер файла в байта�
195
196 *
197 * @return string
198 */
199 function wrio_convert_bytes( $size ) {
200 if ( ! $size ) {
201 return 0;
202 }
203 $base = log( $size ) / log( 1024 );
204 $suffix = [ '', 'KB', 'MB', 'GB', 'TB' ];
205 $f_base = intval( floor( $base ) );
206
207 return round( pow( 1024, $base - floor( $base ) ), 2 ) . ' ' . $suffix[ $f_base ];
208 }
209
210 /**
211 * Генерирует �
212 еш строку
213 *
214 * @param int $length
215 *
216 * @return string
217 */
218 function wrio_generate_random_string( $length = 10 ) {
219 $characters = '0123456789abcdefghiklmnopqrstuvwxyz';
220 $charactersLength = strlen( $characters );
221 $randomString = '';
222 for ( $i = 0; $i < $length; $i++ ) {
223 $randomString .= $characters[ rand( 0, $charactersLength - 1 ) ];
224 }
225
226 return $randomString;
227 }
228
229 /**
230 * in priorities checks its license.
231 *
232 * @return bool
233 * @since 1.3.0
234 */
235 function wrio_is_license_activate() {
236 return wrio_is_clearfy_license_activate() || ( WRIO_Plugin::app()->premium->is_activate() && WRIO_Plugin::app()->premium->is_active() );
237 }
238
239 /**
240 *
241 * @return bool
242 * @since 1.3.0
243 */
244 function wrio_is_clearfy_license_activate() {
245 if ( class_exists( 'WCL_Plugin' ) ) {
246 if ( version_compare( WCL_PLUGIN_VERSION, '1.6.3', '>=' ) ) {
247 if ( WCL_Plugin::app()->premium->is_activate() ) {
248 $plan_id = WCL_Plugin::app()->premium->get_license()->get_plan_id();
249
250 // Now for new plans this doesn't work.
251 return '4710' === $plan_id || '3530' === $plan_id;
252 }
253 } else {
254 $current_license = WCL_Licensing::instance()->getStorage()->getLicense();
255
256 if ( ! empty( $current_license ) && ! empty( $current_license->id ) ) {
257 return true;
258 }
259 }
260 }
261
262 return false;
263 }
264
265 /**
266 * checks its license in priorities.
267 *
268 * @return bool
269 * @since 1.3.0
270 */
271 function wrio_is_license_active() {
272 if ( wrio_is_clearfy_license_activate() ) {
273 if ( version_compare( WCL_PLUGIN_VERSION, '1.6.3', '>=' ) ) {
274 return WCL_Plugin::app()->premium->is_active();
275 } else {
276 return WCL_Licensing::instance()->isLicenseValid();
277 }
278 }
279
280 return WRIO_Plugin::app()->premium->is_activate() && WRIO_Plugin::app()->premium->is_active();
281 }
282
283 /**
284 * return it key.
285 *
286 * @return string|null
287 * @since 1.3.0
288 */
289 function wrio_get_license_key() {
290 if ( ! wrio_is_license_activate() ) {
291 return null;
292 }
293
294 if ( wrio_is_clearfy_license_activate() ) {
295 if ( version_compare( WCL_PLUGIN_VERSION, '1.6.3', '>=' ) ) {
296 return WCL_Plugin::app()->premium->get_license()->get_key();
297 } else {
298 return WCL_Licensing::instance()->getStorage()->getLicense()->secret_key;
299 }
300 }
301
302 return WRIO_Plugin::app()->premium->get_license()->get_key();
303 /*
304 if ( WRIO_Plugin::app()->premium->is_activate() ) {
305 return WRIO_Plugin::app()->premium->get_license()->get_key();
306 } else {
307 if ( wrio_is_clearfy_license_activate() ) {
308 if ( version_compare( WCL_PLUGIN_VERSION, '1.6.3', '>=' ) ) {
309 return WCL_Plugin::app()->premium->get_license()->get_key();
310 } else {
311 return WCL_Licensing::instance()->getStorage()->getLicense()->secret_key;
312 }
313 } else {
314 return null;
315 }
316 }
317 */
318 }
319
320 /**
321 * Get the license source (freemius or sdk).
322 *
323 * @return string|null 'freemius', 'sdk', or null if no license.
324 * @since 1.6.0
325 */
326 function wrio_get_license_source() {
327 if ( ! wrio_is_license_activate() ) {
328 return null;
329 }
330
331 return WRIO_Plugin::app()->premium->get_license()->get_source();
332 }
333
334 /**
335 * @return number|null
336 * @since 1.3.0
337 */
338 function wrio_get_freemius_plugin_id() {
339 if ( wrio_is_clearfy_license_activate() ) {
340 return WCL_Plugin::app()->getPluginInfoAttr( 'freemius_plugin_id' );
341 }
342
343 return WRIO_Plugin::app()->premium->get_setting( 'plugin_id' );
344 }
345
346 /**
347 * Get size information for all currently-registered image sizes.
348 *
349 * @return array $sizes Data for all currently-registered image sizes.
350 * @uses get_intermediate_image_sizes()
351 * @global $_wp_additional_image_sizes
352 */
353 function wrio_get_image_sizes() {
354 global $_wp_additional_image_sizes;
355
356 $sizes = [];
357
358 foreach ( get_intermediate_image_sizes() as $_size ) {
359 if ( in_array( $_size, [ 'thumbnail', 'medium', 'medium_large', 'large' ] ) ) {
360 $sizes[ $_size ]['width'] = get_option( "{$_size}_size_w" );
361 $sizes[ $_size ]['height'] = get_option( "{$_size}_size_h" );
362 $sizes[ $_size ]['crop'] = (bool) get_option( "{$_size}_crop" );
363 } elseif ( isset( $_wp_additional_image_sizes[ $_size ] ) ) {
364 $sizes[ $_size ] = [
365 'width' => $_wp_additional_image_sizes[ $_size ]['width'],
366 'height' => $_wp_additional_image_sizes[ $_size ]['height'],
367 'crop' => $_wp_additional_image_sizes[ $_size ]['crop'],
368 ];
369 }
370 }
371
372 return $sizes;
373 }
374
375 /**
376 * Возвращает URL сервера оптимизации
377 *
378 * @param string $server_name имя сервера
379 *
380 * @return string
381 * @since 1.2.0
382 */
383 function wrio_get_server_url( $server_name ) {
384
385 $servers = [
386 'server_2' => 'https://dashboard.robinoptimizer.com/v1/free/image/optimize',
387 'server_5' => 'https://dashboard.robinoptimizer.com/v1/tariff/optimize',
388 ];
389
390 $servers = apply_filters( 'wbcr/rio/allow_servers', $servers );
391
392 if ( isset( $servers[ $server_name ] ) ) {
393 return $servers[ $server_name ];
394 }
395
396 return null;
397 }
398
399 /**
400 * Gets the User Agent of the current user, saves it to a WordPress option if not already saved,
401 * and retrieves it from the options table if it exists.
402 *
403 * @return string|null The stored User Agent or null if not available.
404 */
405 function wrio_get_user_agent() {
406 $saved_user_agent = WRIO_Plugin::app()->getPopulateOption( 'user_agent' );
407
408 if ( $saved_user_agent ) {
409 return $saved_user_agent;
410 }
411
412 $browsers = [
413 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36',
414 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36',
415 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:89.0) Gecko/20100101 Firefox/89.0',
416 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1',
417 'Mozilla/5.0 (Android 11; Mobile; rv:94.0) Gecko/94.0 Firefox/94.0',
418 'Mozilla/5.0 (iPad; CPU OS 15_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Mobile/15E148 Safari/604.1',
419 ];
420
421 $random_user_agent = $browsers[ array_rand( $browsers ) ];
422
423 $current_user_agent = isset( $_SERVER['HTTP_USER_AGENT'] )
424 ? sanitize_text_field( $_SERVER['HTTP_USER_AGENT'] )
425 : $random_user_agent;
426
427 if ( $current_user_agent ) {
428 WRIO_Plugin::app()->updatePopulateOption( 'user_agent', $current_user_agent );
429 }
430
431 return $current_user_agent;
432 }
433
434 /**
435 * Check whether there are some migrations left to be processed.
436 *
437 * @return bool
438 * @throws Exception
439 * @since 1.3.0
440 */
441 function wbcr_rio_has_meta_to_migrate() {
442
443 $db_version = RIO_Process_Queue::get_db_version();
444
445 if ( 2 === $db_version ) {
446 return false;
447 }
448
449 // Low number to limit resources consumption
450 $attachments = wbcr_rio_get_meta_to_migrate( 5 );
451
452 if ( isset( $attachments->posts ) && count( $attachments->posts ) > 0 ) {
453 return true;
454 }
455
456 if ( 1 === $db_version ) {
457 RIO_Process_Queue::update_db_version( 2 );
458 }
459
460 return false;
461 }
462
463 /**
464 * Get list of meta to migrate.
465 *
466 * @param int $limit Attachment limit per page.
467 *
468 * @return WP_Query
469 * @since 1.3.0
470 */
471 function wbcr_rio_get_meta_to_migrate( $limit = 0 ) {
472 $args = [
473 'post_type' => 'attachment',
474 'post_status' => 'inherit',
475 'post_mime_type' => [ 'image/jpeg', 'image/gif', 'image/png' ],
476 'posts_per_page' => - 1,
477 'meta_query' => [
478 [
479 'key' => 'wio_optimized',
480 'compare' => 'EXISTS',
481 ],
482 ],
483 ];
484
485 if ( $limit ) {
486 $args['posts_per_page'] = $limit;
487 }
488
489 return new WP_Query( $args );
490 }
491
492 /**
493 * @return string
494 * @since 1.3.0
495 */
496 function wrio_get_meta_migration_notice_text() {
497 $nonce = wp_create_nonce( 'wrio-meta-migrations' );
498
499 return sprintf(
500 // translators: %1$s is the opening anchor tag, %2$s is the closing anchor tag.
501 __( 'The database schema has changed. %1$sUpgrade now%2$s to the latest version.', 'robin-image-optimizer' ),
502 '<a href="#" id="wbcr-wio-meta-migration-action" class="button button-default" data-nonce="' . esc_attr( $nonce ) . '">',
503 '</a>'
504 );
505 }
506
507 /**
508 * @param string $scope
509 *
510 * @return WRIO_Folder_Processing|WRIO_Media_Processing|WRIO_Media_Processing_Webp|WRIO_Media_Processing_Avif|WRIO_Nextgen_Processing|null
511 */
512 function wrio_get_processing_class( $scope ) {
513 $object = null;
514 switch ( $scope ) {
515 case 'media-library':
516 if ( class_exists( 'WRIO_Media_Processing' ) ) {
517 $object = new WRIO_Media_Processing( $scope );
518 }
519 break;
520 case 'media-library_webp':
521 if ( class_exists( 'WRIO_Media_Processing_Webp' ) ) {
522 $object = new WRIO_Media_Processing_Webp( $scope );
523 }
524 break;
525 case 'media-library_avif':
526 if ( class_exists( 'WRIO_Media_Processing_Avif' ) ) {
527 $object = new WRIO_Media_Processing_Avif( $scope );
528 }
529 break;
530 case 'custom-folders':
531 if ( class_exists( 'WRIO_Folder_Processing' ) ) {
532 $object = new WRIO_Folder_Processing( $scope );
533 }
534 break;
535 case 'nextgen':
536 if ( class_exists( 'WRIO_Nextgen_Processing' ) ) {
537 $object = new WRIO_Nextgen_Processing( $scope );
538 }
539 break;
540 }
541
542 return $object;
543 }
544
545 /**
546 * @param bool $for_sql
547 *
548 * @return string|array<string>
549 */
550 function wrio_get_allowed_formats( $for_sql = false ) {
551 $allowed_formats = explode( ',', WRIO_Plugin::app()->getOption( 'allowed_formats', 'image/jpeg,image/png,image/gif' ) );
552 $allowed_formats_sql = [];
553 foreach ( $allowed_formats as $k => $format ) {
554 $format = esc_sql( $format );
555
556 $allowed_formats_sql[ $k ] = "'{$format}'";
557 }
558 $allowed_formats_sql = implode( ',', $allowed_formats_sql );
559
560 return $for_sql ? $allowed_formats_sql : $allowed_formats;
561 }
562
563 /**
564 * Get the currently enabled image conversion formats.
565 *
566 * @return string[] Array of enabled format names ('webp', 'avif'). Empty if none enabled.
567 * @since 1.9.0
568 */
569 function wrio_get_conversion_format() {
570 return WRIO_Format_Converter_Factory::get_enabled_formats();
571 }
572
573 /**
574 * Check if format conversion is currently enabled.
575 *
576 * @return bool True if WebP or AVIF conversion is enabled, false otherwise.
577 * @since 1.9.0
578 */
579 function wrio_is_format_conversion_enabled() {
580 return WRIO_Format_Converter_Factory::is_format_conversion_enabled();
581 }
582
583 /**
584 * Check if AVIF format is available (requires premium license).
585 *
586 * @return bool True if AVIF format is available, false otherwise.
587 * @since 1.9.0
588 */
589 function wrio_is_avif_available() {
590 return wrio_is_license_activate();
591 }
592