diff options
Diffstat (limited to 'plugins/jetpack/class.photon.php')
-rw-r--r-- | plugins/jetpack/class.photon.php | 392 |
1 files changed, 236 insertions, 156 deletions
diff --git a/plugins/jetpack/class.photon.php b/plugins/jetpack/class.photon.php index 9a7443c5..1d74c748 100644 --- a/plugins/jetpack/class.photon.php +++ b/plugins/jetpack/class.photon.php @@ -1,23 +1,43 @@ -<?php +<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName +/** + * Class for photon functionality. + * + * @package automattic/jetpack + */ use Automattic\Jetpack\Assets; +/** + * Class Jetpack_Photon + */ class Jetpack_Photon { /** - * Class variables + * Singleton. + * + * @var null */ - // Oh look, a singleton - private static $__instance = null; + private static $instance = null; - // Allowed extensions must match https://code.trac.wordpress.org/browser/photon/index.php#L31 + /** + * Allowed extensions. + * + * @var string[] Allowed extensions must match https://code.trac.wordpress.org/browser/photon/index.php#L41 + */ protected static $extensions = array( 'gif', 'jpg', 'jpeg', 'png', + 'webp', // Jetpack assumes Photon_OpenCV backend class is being used on the server. See link in docblock. ); - // Don't access this directly. Instead, use self::image_sizes() so it's actually populated with something. + /** + * Image sizes. + * + * Don't access this directly. Instead, use self::image_sizes() so it's actually populated with something. + * + * @var array Image sizes. + */ protected static $image_sizes = null; /** @@ -26,12 +46,12 @@ class Jetpack_Photon { * @return object */ public static function instance() { - if ( ! is_a( self::$__instance, 'Jetpack_Photon' ) ) { - self::$__instance = new Jetpack_Photon(); - self::$__instance->setup(); + if ( ! is_a( self::$instance, 'Jetpack_Photon' ) ) { + self::$instance = new Jetpack_Photon(); + self::$instance->setup(); } - return self::$__instance; + return self::$instance; } /** @@ -51,21 +71,22 @@ class Jetpack_Photon { return; } - // Images in post content and galleries + // Images in post content and galleries. add_filter( 'the_content', array( __CLASS__, 'filter_the_content' ), 999999 ); add_filter( 'get_post_galleries', array( __CLASS__, 'filter_the_galleries' ), 999999 ); add_filter( 'widget_media_image_instance', array( __CLASS__, 'filter_the_image_widget' ), 999999 ); - // Core image retrieval + // Core image retrieval. add_filter( 'image_downsize', array( $this, 'filter_image_downsize' ), 10, 3 ); add_filter( 'rest_request_before_callbacks', array( $this, 'should_rest_photon_image_downsize' ), 10, 3 ); + add_action( 'rest_after_insert_attachment', array( $this, 'should_rest_photon_image_downsize_insert_attachment' ), 10, 2 ); add_filter( 'rest_request_after_callbacks', array( $this, 'cleanup_rest_photon_image_downsize' ) ); - // Responsive image srcset substitution + // Responsive image srcset substitution. add_filter( 'wp_calculate_image_srcset', array( $this, 'filter_srcset_array' ), 10, 5 ); add_filter( 'wp_calculate_image_sizes', array( $this, 'filter_sizes' ), 1, 2 ); // Early so themes can still easily filter. - // Helpers for maniuplated images + // Helpers for maniuplated images. add_action( 'wp_enqueue_scripts', array( $this, 'action_wp_enqueue_scripts' ), 9 ); /** @@ -144,23 +165,29 @@ class Jetpack_Photon { * Short circuits the Photon filter to enable Photon processing for any URL. * * @param String $photon_url a proposed Photon URL for the media file. - * @param String $image_url the original media URL. + * * @return String an URL to be used for the media file. */ - public static function filter_photon_norezise_domain( $photon_url, $image_url ) { + public static function filter_photon_norezise_domain( $photon_url ) { return $photon_url; } /** * Disables intermediate sizes to disallow resizing. * - * @param Array $sizes an array containing image sizes. - * @return Boolean + * @return array Empty array. */ - public static function filter_photon_noresize_intermediate_sizes( $sizes ) { + public static function filter_photon_noresize_intermediate_sizes() { return array(); } + /** + * Filter thumbnail URLS to not generate. + * + * @param array $sizes Image sizes. + * + * @return mixed + */ public static function filter_photon_noresize_thumbnail_urls( $sizes ) { foreach ( $sizes as $size => $url ) { $parts = explode( '?', $url ); @@ -215,7 +242,7 @@ class Jetpack_Photon { /** * Inject image sizes to Jetpack REST API responses. This wraps the filter_photon_norezise_maybe_inject_sizes function. * - * @param array $data Attachment sizes data. + * @param array $sizes Attachment sizes data. * @param int $attachment_id Attachment's post ID. * * @return array Attachment sizes array. @@ -277,9 +304,11 @@ class Jetpack_Photon { /** * Identify images in post content, and if images are local (uploaded to the current site), pass through Photon. * - * @param string $content + * @param string $content The content. + * * @uses self::validate_image_url, apply_filters, jetpack_photon_url, esc_url * @filter the_content + * * @return string */ public static function filter_the_content( $content ) { @@ -293,17 +322,18 @@ class Jetpack_Photon { $upload_dir = wp_get_upload_dir(); foreach ( $images[0] as $index => $tag ) { - // Default to resize, though fit may be used in certain cases where a dimension cannot be ascertained + // Default to resize, though fit may be used in certain cases where a dimension cannot be ascertained. $transform = 'resize'; - // Start with a clean attachment ID each time + // Start with a clean attachment ID each time. $attachment_id = false; - // Flag if we need to munge a fullsize URL + // Flag if we need to munge a fullsize URL. $fullsize_url = false; - // Identify image source - $src = $src_orig = $images['img_url'][ $index ]; + // Identify image source. + $src_orig = $images['img_url'][ $index ]; + $src = $src_orig; /** * Allow specific images to be skipped by Photon. @@ -320,40 +350,41 @@ class Jetpack_Photon { continue; } - // Support Automattic's Lazy Load plugin - // Can't modify $tag yet as we need unadulterated version later + // Support Automattic's Lazy Load plugin. + // Can't modify $tag yet as we need unadulterated version later. if ( preg_match( '#data-lazy-src=["|\'](.+?)["|\']#i', $images['img_tag'][ $index ], $lazy_load_src ) ) { - $placeholder_src = $placeholder_src_orig = $src; - $src = $src_orig = $lazy_load_src[1]; + $placeholder_src_orig = $src; + $placeholder_src = $placeholder_src_orig; + $src_orig = $lazy_load_src[1]; + $src = $src_orig; } elseif ( preg_match( '#data-lazy-original=["|\'](.+?)["|\']#i', $images['img_tag'][ $index ], $lazy_load_src ) ) { - $placeholder_src = $placeholder_src_orig = $src; - $src = $src_orig = $lazy_load_src[1]; + $placeholder_src_orig = $src; + $placeholder_src = $placeholder_src_orig; + $src_orig = $lazy_load_src[1]; + $src = $src_orig; } - // Check if image URL should be used with Photon + // Check if image URL should be used with Photon. if ( self::validate_image_url( $src ) ) { - // Find the width and height attributes - $width = $height = false; + // Find the width and height attributes. + $width = false; + $height = false; - // First, check the image tag + // First, check the image tag. Note we only check for pixel sizes now; HTML4 percentages have never been correctly + // supported, so we stopped pretending to support them in JP 9.1.0. if ( preg_match( '#[\s|"|\']width=["|\']?([\d%]+)["|\']?#i', $images['img_tag'][ $index ], $width_string ) ) { - $width = $width_string[1]; + $width = false === strpos( $width_string[1], '%' ) ? $width_string[1] : false; } if ( preg_match( '#[\s|"|\']height=["|\']?([\d%]+)["|\']?#i', $images['img_tag'][ $index ], $height_string ) ) { - $height = $height_string[1]; + $height = false === strpos( $height_string[1], '%' ) ? $height_string[1] : false; } - // Can't pass both a relative width and height, so unset the height in favor of not breaking the horizontal layout. - if ( false !== strpos( $width, '%' ) && false !== strpos( $height, '%' ) ) { - $width = $height = false; - } - - // Detect WP registered image size from HTML class + // Detect WP registered image size from HTML class. if ( preg_match( '#class=["|\']?[^"\']*size-([^"\'\s]+)[^"\']*["|\']?#i', $images['img_tag'][ $index ], $size ) ) { $size = array_pop( $size ); - if ( false === $width && false === $height && 'full' != $size && array_key_exists( $size, $image_sizes ) ) { + if ( false === $width && false === $height && 'full' !== $size && array_key_exists( $size, $image_sizes ) ) { $width = (int) $image_sizes[ $size ]['width']; $height = (int) $image_sizes[ $size ]['height']; $transform = $image_sizes[ $size ]['crop'] ? 'resize' : 'fit'; @@ -362,7 +393,7 @@ class Jetpack_Photon { unset( $size ); } - // WP Attachment ID, if uploaded to this site + // WP Attachment ID, if uploaded to this site. if ( preg_match( '#class=["|\']?[^"\']*wp-image-([\d]+)[^"\']*["|\']?#i', $images['img_tag'][ $index ], $attachment_id ) && 0 === strpos( $src, $upload_dir['baseurl'] ) && @@ -385,27 +416,27 @@ class Jetpack_Photon { */ apply_filters( 'jetpack_photon_image_is_local', false, compact( 'src', 'tag', 'images', 'index' ) ) ) { - $attachment_id = intval( array_pop( $attachment_id ) ); + $attachment_id = (int) array_pop( $attachment_id ); if ( $attachment_id ) { $attachment = get_post( $attachment_id ); - // Basic check on returned post object - if ( is_object( $attachment ) && ! is_wp_error( $attachment ) && 'attachment' == $attachment->post_type ) { + // Basic check on returned post object. + if ( is_object( $attachment ) && ! is_wp_error( $attachment ) && 'attachment' === $attachment->post_type ) { $src_per_wp = wp_get_attachment_image_src( $attachment_id, isset( $size ) ? $size : 'full' ); if ( self::validate_image_url( $src_per_wp[0] ) ) { $src = $src_per_wp[0]; $fullsize_url = true; - // Prevent image distortion if a detected dimension exceeds the image's natural dimensions + // Prevent image distortion if a detected dimension exceeds the image's natural dimensions. if ( ( false !== $width && $width > $src_per_wp[1] ) || ( false !== $height && $height > $src_per_wp[2] ) ) { $width = false === $width ? false : min( $width, $src_per_wp[1] ); $height = false === $height ? false : min( $height, $src_per_wp[2] ); } - // If no width and height are found, max out at source image's natural dimensions - // Otherwise, respect registered image sizes' cropping setting + // If no width and height are found, max out at source image's natural dimensions. + // Otherwise, respect registered image sizes' cropping setting. if ( false === $width && false === $height ) { $width = $src_per_wp[1]; $height = $src_per_wp[2]; @@ -430,18 +461,16 @@ class Jetpack_Photon { $height_orig = $height; $transform_orig = $transform; - // If width is available, constrain to $content_width - if ( false !== $width && false === strpos( $width, '%' ) && is_numeric( $content_width ) ) { - if ( $width > $content_width && false !== $height && false === strpos( $height, '%' ) ) { + // If width is available, constrain to $content_width. + if ( false !== $width && is_numeric( $content_width ) && $width > $content_width ) { + if ( false !== $height ) { $height = round( ( $content_width * $height ) / $width ); - $width = $content_width; - } elseif ( $width > $content_width ) { - $width = $content_width; } + $width = $content_width; } - // Set a width if none is found and $content_width is available - // If width is set in this manner and height is available, use `fit` instead of `resize` to prevent skewing + // Set a width if none is found and $content_width is available. + // If width is set in this manner and height is available, use `fit` instead of `resize` to prevent skewing. if ( false === $width && is_numeric( $content_width ) ) { $width = (int) $content_width; @@ -455,15 +484,15 @@ class Jetpack_Photon { $fullsize_url = true; } - // Build URL, first maybe removing WP's resized string so we pass the original image to Photon + // Build URL, first maybe removing WP's resized string so we pass the original image to Photon. if ( ! $fullsize_url && 0 === strpos( $src, $upload_dir['baseurl'] ) ) { $src = self::strip_image_dimensions_maybe( $src ); } - // Build array of Photon args and expose to filter before passing to Photon URL function + // Build array of Photon args and expose to filter before passing to Photon URL function. $args = array(); - if ( false !== $width && false !== $height && false === strpos( $width, '%' ) && false === strpos( $height, '%' ) ) { + if ( false !== $width && false !== $height ) { $args[ $transform ] = $width . ',' . $height; } elseif ( false !== $width ) { $args['w'] = $width; @@ -502,23 +531,23 @@ class Jetpack_Photon { // Modify image tag if Photon function provides a URL // Ensure changes are only applied to the current image by copying and modifying the matched tag, then replacing the entire tag with our modified version. - if ( $src != $photon_url ) { + if ( $src !== $photon_url ) { $new_tag = $tag; // If present, replace the link href with a Photoned URL for the full-size image. if ( ! empty( $images['link_url'][ $index ] ) && self::validate_image_url( $images['link_url'][ $index ] ) ) { - $new_tag = preg_replace( '#(href=["|\'])' . $images['link_url'][ $index ] . '(["|\'])#i', '\1' . jetpack_photon_url( $images['link_url'][ $index ] ) . '\2', $new_tag, 1 ); + $new_tag = preg_replace( '#(href=["|\'])' . preg_quote( $images['link_url'][ $index ], '#' ) . '(["|\'])#i', '\1' . jetpack_photon_url( $images['link_url'][ $index ] ) . '\2', $new_tag, 1 ); } - // Supplant the original source value with our Photon URL + // Supplant the original source value with our Photon URL. $photon_url = esc_url( $photon_url ); $new_tag = str_replace( $src_orig, $photon_url, $new_tag ); - // If Lazy Load is in use, pass placeholder image through Photon + // If Lazy Load is in use, pass placeholder image through Photon. if ( isset( $placeholder_src ) && self::validate_image_url( $placeholder_src ) ) { $placeholder_src = jetpack_photon_url( $placeholder_src ); - if ( $placeholder_src != $placeholder_src_orig ) { + if ( $placeholder_src !== $placeholder_src_orig ) { $new_tag = str_replace( $placeholder_src_orig, esc_url( $placeholder_src ), $new_tag ); } @@ -526,20 +555,21 @@ class Jetpack_Photon { } // If we are not transforming the image with resize, fit, or letterbox (lb), then we should remove - // the width and height arguments from the image to prevent distortion. Even if $args['w'] and $args['h'] - // are present, Photon does not crop to those dimensions. Instead, it appears to favor height. + // the width and height arguments (including HTML4 percentages) from the image to prevent distortion. + // Even if $args['w'] and $args['h'] are present, Photon does not crop to those dimensions. Instead, + // it appears to favor height. // // If we are transforming the image via one of those methods, let's update the width and height attributes. if ( empty( $args['resize'] ) && empty( $args['fit'] ) && empty( $args['lb'] ) ) { $new_tag = preg_replace( '#(?<=\s)(width|height)=["|\']?[\d%]+["|\']?\s?#i', '', $new_tag ); } else { $resize_args = isset( $args['resize'] ) ? $args['resize'] : false; - if ( false == $resize_args ) { + if ( false === $resize_args ) { $resize_args = ( ! $resize_args && isset( $args['fit'] ) ) ? $args['fit'] : false; } - if ( false == $resize_args ) { + if ( false === $resize_args ) { $resize_args = ( ! $resize_args && isset( $args['lb'] ) ) ? $args['lb'] : false; @@ -549,23 +579,23 @@ class Jetpack_Photon { // (?<=\s) - Ensure width or height attribute is preceded by a space // (width=["|\']?) - Matches, and captures, width=, width=", or width=' - // [\d%]+ - Matches 1 or more digits + // [\d%]+ - Matches 1 or more digits or percent signs // (["|\']?) - Matches, and captures, ", ', or empty string // \s - Ensures there's a space after the attribute $new_tag = preg_replace( '#(?<=\s)(width=["|\']?)[\d%]+(["|\']?)\s?#i', sprintf( '${1}%d${2} ', $resize_args[0] ), $new_tag ); $new_tag = preg_replace( '#(?<=\s)(height=["|\']?)[\d%]+(["|\']?)\s?#i', sprintf( '${1}%d${2} ', $resize_args[1] ), $new_tag ); } - // Tag an image for dimension checking + // Tag an image for dimension checking. if ( ! self::is_amp_endpoint() ) { $new_tag = preg_replace( '#(\s?/)?>(\s*</a>)?$#i', ' data-recalc-dims="1"\1>\2', $new_tag ); } - // Replace original tag with modified version + // Replace original tag with modified version. $content = str_replace( $tag, $new_tag, $content ); } } elseif ( preg_match( '#^http(s)?://i[\d]{1}.wp.com#', $src ) && ! empty( $images['link_url'][ $index ] ) && self::validate_image_url( $images['link_url'][ $index ] ) ) { - $new_tag = preg_replace( '#(href=["|\'])' . $images['link_url'][ $index ] . '(["|\'])#i', '\1' . jetpack_photon_url( $images['link_url'][ $index ] ) . '\2', $tag, 1 ); + $new_tag = preg_replace( '#(href=["|\'])' . preg_quote( $images['link_url'][ $index ], '#' ) . '(["|\'])#i', '\1' . jetpack_photon_url( $images['link_url'][ $index ] ) . '\2', $tag, 1 ); $content = str_replace( $tag, $new_tag, $content ); } @@ -575,6 +605,13 @@ class Jetpack_Photon { return $content; } + /** + * Filter Core galleries + * + * @param array $galleries Gallery array. + * + * @return array + */ public static function filter_the_galleries( $galleries ) { if ( empty( $galleries ) || ! is_array( $galleries ) ) { return $galleries; @@ -584,13 +621,6 @@ class Jetpack_Photon { foreach ( $galleries as &$this_gallery ) { if ( is_string( $this_gallery ) ) { $this_gallery = self::filter_the_content( $this_gallery ); - // LEAVING COMMENTED OUT as for the moment it doesn't seem - // necessary and I'm not sure how it would propagate through. - // } elseif ( is_array( $this_gallery ) - // && ! empty( $this_gallery['src'] ) - // && ! empty( $this_gallery['type'] ) - // && in_array( $this_gallery['type'], array( 'rectangle', 'square', 'circle' ) ) ) { - // $this_gallery['src'] = array_map( 'jetpack_photon_url', $this_gallery['src'] ); } } unset( $this_gallery ); // break the reference. @@ -598,7 +628,6 @@ class Jetpack_Photon { return $galleries; } - /** * Runs the image widget through photon. * @@ -626,9 +655,9 @@ class Jetpack_Photon { /** * Filter post thumbnail image retrieval, passing images through Photon * - * @param string|bool $image - * @param int $attachment_id - * @param string|array $size + * @param string|bool $image Image URL. + * @param int $attachment_id Attachment ID. + * @param string|array $size Declared size or a size array. * @uses is_admin, apply_filters, wp_get_attachment_url, self::validate_image_url, this::image_sizes, jetpack_photon_url * @filter image_downsize * @return string|bool @@ -679,14 +708,14 @@ class Jetpack_Photon { return $image; } - // Get the image URL and proceed with Photon-ification if successful + // Get the image URL and proceed with Photon-ification if successful. $image_url = wp_get_attachment_url( $attachment_id ); // Set this to true later when we know we have size meta. $has_size_meta = false; if ( $image_url ) { - // Check if image URL should be used with Photon + // Check if image URL should be used with Photon. if ( ! self::validate_image_url( $image_url ) ) { return $image; } @@ -705,7 +734,7 @@ class Jetpack_Photon { $image_meta = image_get_intermediate_size( $attachment_id, $size ); // 'full' is a special case: We need consistent data regardless of the requested size. - if ( 'full' == $size ) { + if ( 'full' === $size ) { $image_meta = wp_get_attachment_metadata( $attachment_id ); $intermediate = false; } elseif ( ! $image_meta ) { @@ -723,27 +752,28 @@ class Jetpack_Photon { } if ( isset( $image_meta['width'], $image_meta['height'] ) ) { - $image_args['width'] = $image_meta['width']; - $image_args['height'] = $image_meta['height']; + $image_args['width'] = (int) $image_meta['width']; + $image_args['height'] = (int) $image_meta['height']; list( $image_args['width'], $image_args['height'] ) = image_constrain_size_for_editor( $image_args['width'], $image_args['height'], $size, 'display' ); $has_size_meta = true; } - // Expose determined arguments to a filter before passing to Photon + // Expose determined arguments to a filter before passing to Photon. $transform = $image_args['crop'] ? 'resize' : 'fit'; // Check specified image dimensions and account for possible zero values; photon fails to resize if a dimension is zero. - if ( 0 == $image_args['width'] || 0 == $image_args['height'] ) { - if ( 0 == $image_args['width'] && 0 < $image_args['height'] ) { + if ( 0 === $image_args['width'] || 0 === $image_args['height'] ) { + if ( 0 === $image_args['width'] && 0 < $image_args['height'] ) { $photon_args['h'] = $image_args['height']; - } elseif ( 0 == $image_args['height'] && 0 < $image_args['width'] ) { + } elseif ( 0 === $image_args['height'] && 0 < $image_args['width'] ) { $photon_args['w'] = $image_args['width']; } } else { - if ( ( 'resize' === $transform ) && $image_meta = wp_get_attachment_metadata( $attachment_id ) ) { + $image_meta = wp_get_attachment_metadata( $attachment_id ); + if ( ( 'resize' === $transform ) && $image_meta ) { if ( isset( $image_meta['width'], $image_meta['height'] ) ) { - // Lets make sure that we don't upscale images since wp never upscales them as well + // Lets make sure that we don't upscale images since wp never upscales them as well. $smaller_width = ( ( $image_meta['width'] < $image_args['width'] ) ? $image_meta['width'] : $image_args['width'] ); $smaller_height = ( ( $image_meta['height'] < $image_args['height'] ) ? $image_meta['height'] : $image_args['height'] ); @@ -766,17 +796,17 @@ class Jetpack_Photon { * @param array $args { * Array of image details. * - * @type $image_args Array of Image arguments (width, height, crop). - * @type $image_url Image URL. - * @type $attachment_id Attachment ID of the image. - * @type $size Image size. Can be a string (name of the image size, e.g. full) or an integer. - * @type $transform Value can be resize or fit. + * @type array $image_args Array of Image arguments (width, height, crop). + * @type string $image_url Image URL. + * @type int $attachment_id Attachment ID of the image. + * @type string|int $size Image size. Can be a string (name of the image size, e.g. full) or an integer. + * @type string $transform Value can be resize or fit. * @see https://developer.wordpress.com/docs/photon/api * } */ $photon_args = apply_filters( 'jetpack_photon_image_downsize_string', $photon_args, compact( 'image_args', 'image_url', 'attachment_id', 'size', 'transform' ) ); - // Generate Photon URL + // Generate Photon URL. $image = array( jetpack_photon_url( $image_url, $photon_args ), $has_size_meta ? $image_args['width'] : false, @@ -784,7 +814,7 @@ class Jetpack_Photon { $intermediate, ); } elseif ( is_array( $size ) ) { - // Pull width and height values from the provided array, if possible + // Pull width and height values from the provided array, if possible. $width = isset( $size[0] ) ? (int) $size[0] : false; $height = isset( $size[1] ) ? (int) $size[1] : false; @@ -810,7 +840,7 @@ class Jetpack_Photon { list( $width, $height ) = image_constrain_size_for_editor( $width, $height, $size ); - // Expose arguments to a filter before passing to Photon + // Expose arguments to a filter before passing to Photon. $photon_args = array( 'fit' => $width . ',' . $height, ); @@ -835,7 +865,7 @@ class Jetpack_Photon { */ $photon_args = apply_filters( 'jetpack_photon_image_downsize_array', $photon_args, compact( 'width', 'height', 'image_url', 'attachment_id' ) ); - // Generate Photon URL + // Generate Photon URL. $image = array( jetpack_photon_url( $image_url, $photon_args ), $has_size_meta ? $width : false, @@ -853,9 +883,16 @@ class Jetpack_Photon { * * @since 3.8.0 * @since 4.0.4 Added automatically additional sizes beyond declared image sizes. + * * @param array $sources An array of image urls and widths. + * @param array $size_array The size array for srcset. + * @param array $image_src The image srcs. + * @param array $image_meta The image meta. + * @param int $attachment_id Attachment ID. + * * @uses self::validate_image_url, jetpack_photon_url, Jetpack_Photon::parse_from_filename * @uses Jetpack_Photon::strip_image_dimensions_maybe, Jetpack::get_content_width + * * @return array An array of Photon image urls and widths. */ public function filter_srcset_array( $sources = array(), $size_array = array(), $image_src = array(), $image_meta = array(), $attachment_id = 0 ) { @@ -877,7 +914,7 @@ class Jetpack_Photon { $url = $source['url']; list( $width, $height ) = self::parse_dimensions_from_filename( $url ); - // It's quicker to get the full size with the data we have already, if available + // It's quicker to get the full size with the data we have already, if available. if ( ! empty( $attachment_id ) ) { $url = wp_get_attachment_url( $attachment_id ); } else { @@ -886,7 +923,7 @@ class Jetpack_Photon { $args = array(); if ( 'w' === $source['descriptor'] ) { - if ( $height && ( $source['value'] == $width ) ) { + if ( $height && ( (int) $source['value'] === $width ) ) { $args['resize'] = $width . ',' . $height; } else { $args['w'] = $source['value']; @@ -951,15 +988,15 @@ class Jetpack_Photon { foreach ( $currentwidths as $currentwidth ) { // If a new width would be within 100 pixes of an existing one or larger than the full size image, skip. if ( abs( $currentwidth - $newwidth ) < 50 || ( $newwidth > $fullwidth ) ) { - continue 2; // Back to the foreach ( $multipliers as $multiplier ) + continue 2; // Bump out back to the $multipliers as $multiplier. } - } // foreach ( $currentwidths as $currentwidth ){ + } //end foreach ( $currentwidths as $currentwidth ){ - if ( 'soft' == $crop ) { + if ( 'soft' === $crop ) { $args = array( 'w' => $newwidth, ); - } else { // hard crop, e.g. add_image_size( 'example', 200, 200, true ); + } else { // hard crop, e.g. add_image_size( 'example', 200, 200, true ). $args = array( 'zoom' => $multiplier, 'resize' => $reqwidth . ',' . $reqheight, @@ -971,11 +1008,11 @@ class Jetpack_Photon { 'descriptor' => 'w', 'value' => $newwidth, ); - } // foreach ( $multipliers as $multiplier ) + } //end foreach ( $multipliers as $multiplier ) if ( is_array( $newsources ) ) { $sources = array_replace( $sources, $newsources ); } - } // if ( isset( $image_meta['width'] ) && isset( $image_meta['file'] ) ) + } //end if isset( $image_meta['width'] ) && isset( $image_meta['file'] ) ) return $sources; } @@ -986,7 +1023,7 @@ class Jetpack_Photon { * @since 4.0.4 * @since 4.1.0 Returns early for images not within the_content. * @param array $sizes An array of media query breakpoints. - * @param array $size Width and height of the image + * @param array $size Width and height of the image. * @uses Jetpack::get_content_width * @return array An array of media query breakpoints. */ @@ -1014,7 +1051,7 @@ class Jetpack_Photon { * Ensure image URL is valid for Photon. * Though Photon functions address some of the URL issues, we should avoid unnecessary processing if we know early on that the image isn't supported. * - * @param string $url + * @param string $url Image URL. * @uses wp_parse_args * @return bool */ @@ -1036,9 +1073,9 @@ class Jetpack_Photon { ) ); - // Bail if scheme isn't http or port is set that isn't port 80 + // Bail if scheme isn't http or port is set that isn't port 80. if ( - ( 'http' != $url_info['scheme'] || ! in_array( $url_info['port'], array( 80, null ) ) ) && + ( 'http' !== $url_info['scheme'] || ! in_array( $url_info['port'], array( 80, null ), true ) ) && /** * Allow Photon to fetch images that are served via HTTPS. * @@ -1054,23 +1091,23 @@ class Jetpack_Photon { return false; } - // Bail if no host is found + // Bail if no host is found. if ( is_null( $url_info['host'] ) ) { return false; } - // Bail if the image alredy went through Photon + // Bail if the image already went through Photon. if ( preg_match( '#^i[\d]{1}.wp.com$#i', $url_info['host'] ) ) { return false; } - // Bail if no path is found + // Bail if no path is found. if ( is_null( $url_info['path'] ) ) { return false; } - // Ensure image extension is acceptable - if ( ! in_array( strtolower( pathinfo( $url_info['path'], PATHINFO_EXTENSION ) ), self::$extensions ) ) { + // Ensure image extension is acceptable. + if ( ! in_array( strtolower( pathinfo( $url_info['path'], PATHINFO_EXTENSION ) ), self::$extensions, true ) ) { return false; } @@ -1091,20 +1128,20 @@ class Jetpack_Photon { } /** - * Checks if the file exists before it passes the file to photon + * Checks if the file exists before it passes the file to photon. * - * @param string $src The image URL + * @param string $src The image URL. * @return string **/ public static function strip_image_dimensions_maybe( $src ) { $stripped_src = $src; - // Build URL, first removing WP's resized string so we pass the original image to Photon + // Build URL, first removing WP's resized string so we pass the original image to Photon. if ( preg_match( '#(-\d+x\d+)\.(' . implode( '|', self::$extensions ) . '){1}$#i', $src, $src_parts ) ) { $stripped_src = str_replace( $src_parts[1], '', $src ); $upload_dir = wp_get_upload_dir(); - // Extracts the file path to the image minus the base url + // Extracts the file path to the image minus the base url. $file_path = substr( $stripped_src, strlen( $upload_dir['baseurl'] ) ); if ( file_exists( $upload_dir['basedir'] . $file_path ) ) { @@ -1124,29 +1161,29 @@ class Jetpack_Photon { * @return array */ protected static function image_sizes() { - if ( null == self::$image_sizes ) { + if ( null === self::$image_sizes ) { global $_wp_additional_image_sizes; - // Populate an array matching the data structure of $_wp_additional_image_sizes so we have a consistent structure for image sizes + // Populate an array matching the data structure of $_wp_additional_image_sizes so we have a consistent structure for image sizes. $images = array( 'thumb' => array( - 'width' => intval( get_option( 'thumbnail_size_w' ) ), - 'height' => intval( get_option( 'thumbnail_size_h' ) ), + 'width' => (int) get_option( 'thumbnail_size_w' ), + 'height' => (int) get_option( 'thumbnail_size_h' ), 'crop' => (bool) get_option( 'thumbnail_crop' ), ), 'medium' => array( - 'width' => intval( get_option( 'medium_size_w' ) ), - 'height' => intval( get_option( 'medium_size_h' ) ), + 'width' => (int) get_option( 'medium_size_w' ), + 'height' => (int) get_option( 'medium_size_h' ), 'crop' => false, ), 'medium_large' => array( - 'width' => intval( get_option( 'medium_large_size_w' ) ), - 'height' => intval( get_option( 'medium_large_size_h' ) ), + 'width' => (int) get_option( 'medium_large_size_w' ), + 'height' => (int) get_option( 'medium_large_size_h' ), 'crop' => false, ), 'large' => array( - 'width' => intval( get_option( 'large_size_w' ) ), - 'height' => intval( get_option( 'large_size_h' ) ), + 'width' => (int) get_option( 'large_size_w' ), + 'height' => (int) get_option( 'large_size_h' ), 'crop' => false, ), 'full' => array( @@ -1156,10 +1193,10 @@ class Jetpack_Photon { ), ); - // Compatibility mapping as found in wp-includes/media.php + // Compatibility mapping as found in wp-includes/media.php. $images['thumbnail'] = $images['thumb']; - // Update class variable, merging in $_wp_additional_image_sizes if any are set + // Update class variable, merging in $_wp_additional_image_sizes if any are set. if ( is_array( $_wp_additional_image_sizes ) && ! empty( $_wp_additional_image_sizes ) ) { self::$image_sizes = array_merge( $images, $_wp_additional_image_sizes ); } else { @@ -1173,12 +1210,12 @@ class Jetpack_Photon { /** * Pass og:image URLs through Photon * - * @param array $tags - * @param array $parameters + * @param array $tags Open graph tags. + * @param array $parameters Image parameters. * @uses jetpack_photon_url - * @return array + * @return array Open graph tags. */ - function filter_open_graph_tags( $tags, $parameters ) { + public function filter_open_graph_tags( $tags, $parameters ) { if ( empty( $tags['og:image'] ) ) { return $tags; } @@ -1200,10 +1237,6 @@ class Jetpack_Photon { return $tags; } - public function noresize_intermediate_sizes( $sizes ) { - return __return_empty_array(); - } - /** * Enqueue Photon helper script * @@ -1240,8 +1273,8 @@ class Jetpack_Photon { * * @see Jetpack_Photon::filter_image_downsize() * - * @param null|WP_Error $response - * @param array $endpoint_data + * @param null|WP_Error $response REST API response. + * @param array $endpoint_data Endpoint data. Not used, but part of the filter. * @param WP_REST_Request $request Request used to generate the response. * * @return null|WP_Error The original response object without modification. @@ -1256,15 +1289,55 @@ class Jetpack_Photon { return $response; } + $this->should_rest_photon_image_downsize_override( $request ); + + return $response; + + } + + /** + * Helper function to check if a WP_REST_Request is the media endpoint in the edit context. + * + * @param WP_REST_Request $request The current REST request. + */ + private function should_rest_photon_image_downsize_override( WP_REST_Request $request ) { $route = $request->get_route(); - if ( false !== strpos( $route, 'wp/v2/media' ) && 'edit' === $request['context'] ) { + if ( + ( + false !== strpos( $route, 'wp/v2/media' ) + && 'edit' === $request->get_param( 'context' ) + ) + || false !== strpos( $route, 'wpcom/v2/external-media/copy' ) + ) { // Don't use `__return_true()`: Use something unique. See ::_override_image_downsize_in_rest_edit_context() // Late execution to avoid conflict with other plugins as we really don't want to run in this situation. - add_filter( 'jetpack_photon_override_image_downsize', array( $this, '_override_image_downsize_in_rest_edit_context' ), 999999 ); + add_filter( + 'jetpack_photon_override_image_downsize', + array( + $this, + 'override_image_downsize_in_rest_edit_context', + ), + 999999 + ); } + } - return $response; + /** + * Brings in should_rest_photon_image_downsize for the rest_after_insert_attachment hook. + * + * @since 8.7.0 + * + * @param WP_Post $attachment Inserted or updated attachment object. + * @param WP_REST_Request $request Request object. + */ + public function should_rest_photon_image_downsize_insert_attachment( WP_Post $attachment, WP_REST_Request $request ) { + if ( ! is_a( $request, 'WP_REST_Request' ) ) { + // Something odd is happening. + return; + } + + $this->should_rest_photon_image_downsize_override( $request ); } @@ -1274,11 +1347,18 @@ class Jetpack_Photon { * every used here, we can always remove it without ever worrying * about breaking any other configuration. * - * @param mixed $response + * @param mixed $response REST API Response. * @return mixed Unchanged $response */ public function cleanup_rest_photon_image_downsize( $response ) { - remove_filter( 'jetpack_photon_override_image_downsize', array( $this, '_override_image_downsize_in_rest_edit_context' ), 999999 ); + remove_filter( + 'jetpack_photon_override_image_downsize', + array( + $this, + 'override_image_downsize_in_rest_edit_context', + ), + 999999 + ); return $response; } @@ -1292,7 +1372,7 @@ class Jetpack_Photon { * @internal * @return true */ - public function _override_image_downsize_in_rest_edit_context() { + public function override_image_downsize_in_rest_edit_context() { return true; } |