PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / trunk
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF vtrunk
2.3.4 2.3.3 2.3.2 2.3.1 2.3.0 2.2.9 2.2.8 trunk 1.10 1.3.3 1.3.4 1.3.5 1.3.5.1 1.3.5.2 1.3.6 1.3.6.1 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.5 All 103 releases
← All changes | inc/classes/class-imagify-filesystem.php +76 -66 1.10 → trunk View file →
@@ -1,7 +1,8 @@
1 1 <?php
2 -defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
3 2
3 +use Imagify\Traits\InstanceGetterTrait;
4 +
4 5 require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php';
5 6 require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php';
6 7
7 8 /**
@@ -10,8 +11,9 @@
10 11 * @since 1.7.1
11 12 * @author Grégory Viguier
12 13 */
13 14 class Imagify_Filesystem extends WP_Filesystem_Direct {
15 + use InstanceGetterTrait;
14 16
15 17 /**
16 18 * Class version.
17 19 *
@@ -28,16 +30,16 @@
28 30 */
29 31 const PATTERN_DELIMITER = '@';
30 32
31 33 /**
32 - * The single instance of the class.
34 + * Cached site root URLs, keyed by blog ID.
33 35 *
34 - * @var object
35 - * @access protected
36 + * @since 2.3.1
37 + *
38 + * @var array<int,string>
36 39 */
37 - protected static $_instance;
40 + private $site_root_urls = [];
38 41
39 -
40 42 /** ----------------------------------------------------------------------------------------- */
41 43 /** INSTANCIATION =========================================================================== */
42 44 /** ----------------------------------------------------------------------------------------- */
43 45
@@ -59,26 +61,9 @@
59 61
60 62 parent::__construct( '' );
61 63 }
62 64
63 - /**
64 - * Get the main Instance.
65 - *
66 - * @since 1.7.1
67 - * @access public
68 - * @author Grégory Viguier
69 - *
70 - * @return object Main instance.
71 - */
72 - public static function get_instance() {
73 - if ( ! isset( self::$_instance ) ) {
74 - self::$_instance = new self();
75 - }
76 65
77 - return self::$_instance;
78 - }
79 -
80 -
81 66 /** ----------------------------------------------------------------------------------------- */
82 67 /** CUSTOM TOOLS ============================================================================ */
83 68 /** ----------------------------------------------------------------------------------------- */
84 69
@@ -140,23 +125,23 @@
140 125 if ( isset( $option ) ) {
141 126 return '';
142 127 }
143 128
144 - return array(
129 + return [
145 130 'dir_path' => '',
146 131 'file_name' => '',
147 132 'extension' => null,
148 133 'file_base' => '',
149 - );
134 + ];
150 135 }
151 136
152 137 if ( isset( $option ) ) {
153 - $options = array(
138 + $options = [
154 139 'dir_path' => PATHINFO_DIRNAME,
155 140 'file_name' => PATHINFO_BASENAME,
156 141 'extension' => PATHINFO_EXTENSION,
157 142 'file_base' => PATHINFO_FILENAME,
158 - );
143 + ];
159 144
160 145 if ( ! isset( $options[ $option ] ) ) {
161 146 return '';
162 147 }
@@ -171,18 +156,18 @@
171 156 }
172 157
173 158 $output = pathinfo( $file_path );
174 159
175 - $output['dirname'] = $this->is_root( $output['dirname'] ) ? $this->get_root() : trailingslashit( $output['dirname'] );
176 - $output['extension'] = isset( $output['extension'] ) ? $output['extension'] : null;
160 + $output['dirname'] = $this->is_root( $output['dirname'] ) ? $this->get_root() : trailingslashit( $output['dirname'] );
161 + $output['extension'] = isset( $output['extension'] ) ? $output['extension'] : null;
177 162
178 163 // '/www/htdocs/inc/lib.inc.php'
179 - return array(
164 + return [
180 165 'dir_path' => $output['dirname'], // '/www/htdocs/inc/'
181 166 'file_name' => $output['basename'], // 'lib.inc.php'
182 167 'extension' => $output['extension'], // 'php'
183 168 'file_base' => $output['filename'], // 'lib.inc'
184 - );
169 + ];
185 170 }
186 171
187 172 /**
188 173 * Recursive directory creation based on full path. Will attempt to set permissions on folders.
@@ -348,9 +333,9 @@
348 333 * @return bool
349 334 */
350 335 public function is_symlinked( $file_path ) {
351 336 static $site_root;
352 - static $plugin_paths = array();
337 + static $plugin_paths = [];
353 338 global $wp_plugin_paths;
354 339
355 340 if ( ! $file_path ) {
356 341 return false;
@@ -374,9 +359,9 @@
374 359
375 360 if ( $wp_plugin_paths && is_array( $wp_plugin_paths ) ) {
376 361 if ( ! $plugin_paths ) {
377 362 foreach ( $wp_plugin_paths as $dir => $real_dir ) {
378 - $dir = $this->normalize_path_for_comparison( $dir );
363 + $dir = $this->normalize_path_for_comparison( $dir );
379 364 $plugin_paths[ $dir ] = $this->normalize_path_for_comparison( $real_dir );
380 365 }
381 366 }
382 367
@@ -530,18 +515,18 @@
530 515 * @return array The image data. An empty array on failure.
531 516 */
532 517 public function get_image_size( $file_path ) {
533 518 if ( ! $file_path ) {
534 - return array();
519 + return [];
535 520 }
536 521
537 - $size = @getimagesize( $file_path );
522 + $size = @getimagesize( $file_path ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
538 523
539 524 if ( ! $size || ! isset( $size[0], $size[1] ) ) {
540 - return array();
525 + return [];
541 526 }
542 527
543 - return array(
528 + return [
544 529 0 => (int) $size[0],
545 530 1 => (int) $size[1],
546 531 'width' => (int) $size[0],
547 532 'height' => (int) $size[1],
@@ -547,11 +532,11 @@
547 532 'height' => (int) $size[1],
548 533 'type' => (int) $size[2],
549 534 'attr' => $size[3],
550 535 'channels' => isset( $size['channels'] ) ? (int) $size['channels'] : null,
551 - 'bits' => isset( $size['bits'] ) ? (int) $size['bits'] : null,
536 + 'bits' => isset( $size['bits'] ) ? (int) $size['bits'] : null,
552 537 'mime' => $size['mime'],
553 - );
538 + ];
554 539 }
555 540
556 541 /**
557 542 * Tell if exif_read_data() is available.
@@ -588,14 +573,14 @@
588 573 * @return array The EXIF headers. An empty array on failure.
589 574 */
590 575 public function get_image_exif( $file_path, $sections = null, $arrays = false, $thumbnail = false ) {
591 576 if ( ! $file_path || ! $this->can_get_exif() ) {
592 - return array();
577 + return [];
593 578 }
594 579
595 - $exif = @exif_read_data( $file_path, $sections, $arrays, $thumbnail );
580 + $exif = @exif_read_data( $file_path, $sections, $arrays, $thumbnail ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
596 581
597 - return is_array( $exif ) ? $exif : array();
582 + return is_array( $exif ) ? $exif : [];
598 583 }
599 584
600 585 /**
601 586 * Tell if a file is an animated gif.
@@ -613,9 +598,9 @@
613 598 // Not a gif file.
614 599 return false;
615 600 }
616 601
617 - $fh = @fopen( $file_path, 'rb' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fopen
602 + $fh = @fopen( $file_path, 'rb' ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_operations_fopen
618 603
619 604 if ( ! $fh ) {
620 605 // Could not open the file.
621 606 return null;
@@ -631,13 +616,13 @@
631 616
632 617 // We read through the file til we reach the end of the file, or we've found at least 2 frame headers.
633 618 while ( ! feof( $fh ) && $count < 2 ) {
634 619 // Read 100kb at a time.
635 - $chunk = fread( $fh, 1024 * 100 ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fread
620 + $chunk = fread( $fh, 1024 * 100 ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fread
636 621 $count += preg_match_all( '#\x00\x21\xF9\x04.{4}\x00(\x2C|\x21)#s', $chunk, $matches );
637 622 }
638 623
639 - fclose( $fh ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fclose
624 + fclose( $fh ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
640 625
641 626 return $count > 1;
642 627 }
643 628
@@ -826,8 +811,12 @@
826 811 $root_path = $this->get_abspath();
827 812 return $root_path;
828 813 }
829 814
815 + if ( empty( $_SERVER['DOCUMENT_ROOT'] ) ) {
816 + return $root_path;
817 + }
818 +
830 819 /**
831 820 * For a multisite in its own directory, get_home_path() returns the expected path only for the main site.
832 821 *
833 822 * Friend, each time an attempt is made to improve this method, and especially this part, please increment the following counter.
@@ -832,9 +821,10 @@
832 821 *
833 822 * Friend, each time an attempt is made to improve this method, and especially this part, please increment the following counter.
834 823 * Improvement attempts: 3.
835 824 */
836 - $document_root = realpath( wp_unslash( $_SERVER['DOCUMENT_ROOT'] ) ); // `realpath()` is needed for those cases where $_SERVER['DOCUMENT_ROOT'] is totally different from ABSPATH.
825 + $document_root = realpath( wp_unslash( $_SERVER['DOCUMENT_ROOT'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
826 + // `realpath()` is needed for those cases where $_SERVER['DOCUMENT_ROOT'] is totally different from ABSPATH.
837 827 $document_root = trailingslashit( str_replace( '\\', '/', $document_root ) );
838 828 $path_current_site = trim( str_replace( '\\', '/', PATH_CURRENT_SITE ), '/' );
839 829 $root_path = trailingslashit( wp_normalize_path( $document_root . $path_current_site ) );
840 830
@@ -844,8 +834,9 @@
844 834 /**
845 835 * Get the URL of the site's root. It corresponds to the main site's home page URL.
846 836 *
847 837 * @since 1.8.1
838 + * @since 2.3.1 Added the imagify_site_root_url filter.
848 839 * @access public
849 840 * @author Grégory Viguier
850 841 *
851 842 * @return string
@@ -850,37 +841,56 @@
850 841 *
851 842 * @return string
852 843 */
853 844 public function get_site_root_url() {
854 - static $root_url;
845 + $blog_id = get_current_blog_id();
855 846
856 - if ( isset( $root_url ) ) {
857 - return $root_url;
847 + if ( isset( $this->site_root_urls[ $blog_id ] ) ) {
848 + return $this->site_root_urls[ $blog_id ];
858 849 }
859 850
860 - if ( ! is_multisite() || is_main_site() ) {
861 - $root_url = home_url( '/' );
862 - return $root_url;
863 - }
851 + $root_url = home_url( '/' );
864 852
865 - $current_network = false;
853 + if ( is_multisite() && ! is_main_site() ) {
854 + $current_network = false;
866 855
867 - if ( function_exists( 'get_network' ) ) {
868 - $current_network = get_network();
869 - } elseif ( function_exists( 'get_current_site' ) ) {
870 - $current_network = get_current_site();
856 + if ( function_exists( 'get_network' ) ) {
857 + $current_network = get_network();
858 + } elseif ( function_exists( 'get_current_site' ) ) {
859 + $current_network = get_current_site();
860 + }
861 +
862 + if ( $current_network ) {
863 + $scheme = is_ssl() ? 'https' : 'http';
864 + $root_url = set_url_scheme( 'http://' . $current_network->domain . $current_network->path, $scheme );
865 + $root_url = trailingslashit( $root_url );
866 + }
871 867 }
872 868
873 - if ( ! $current_network ) {
874 - $root_url = home_url( '/' );
875 - return $root_url;
876 - }
869 + /**
870 + * Filters the URL of the site's root.
871 + *
872 + * On a multisite, this URL is built from the current network's domain and path. Sites using
873 + * domain mapping are served from a domain that does not match it, which prevents Imagify from
874 + * recognizing their image URLs as internal. Use this filter to return the URL actually used to
875 + * serve the current site.
876 + *
877 + * The returned value is cached per blog for the rest of the request: callbacks must be
878 + * deterministic for a given blog ID.
879 + *
880 + * @since 2.3.1
881 + *
882 + * @param string $root_url URL of the site's root, with a trailing slash.
883 + * @param int $blog_id ID of the blog the URL was built for.
884 + */
885 + $filtered_url = apply_filters( 'imagify_site_root_url', $root_url, $blog_id );
877 886
878 - $root_url = is_ssl() ? 'https' : 'http';
879 - $root_url = set_url_scheme( 'http://' . $current_network->domain . $current_network->path, $root_url );
880 - $root_url = trailingslashit( $root_url );
887 + // Ignore anything a callback returns that is not a usable URL, rather than casting it blindly.
888 + $this->site_root_urls[ $blog_id ] = is_string( $filtered_url ) && '' !== trim( $filtered_url )
889 + ? trailingslashit( trim( $filtered_url ) )
890 + : home_url( '/' );
881 891
882 - return $root_url;
892 + return $this->site_root_urls[ $blog_id ];
883 893 }
884 894
885 895 /**
886 896 * Tell if a path is the site's root.