HEX
Server: nginx
System: Linux pool195-106-36.bur.atomicsites.net 6.12.57+deb12-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.57-1~bpo12+1 (2025-11-17) x86_64
User: (0)
PHP: 8.3.32
Disabled: pcntl_fork
Upload Files
File: /wordpress/mu-plugins/photon-subsizes/photon-subsizes.php
<?php
/**
 * Plugin Name: Photon Image Subsizes
 * Description: Eliminate the storage cost of intermediate image sizes by delegating requests to Photon.
 * Version: 1.0.0
 */

require_once __DIR__ . '/photon-subsizes-cli.php';

define( 'PHOTON_SUBSIZES_FILE_EXTENSIONS', array( '.gif', '.jpg', '.jpeg', '.png', '.webp' ) );

// Use a large priority to increase the chance we can override a custom image editor
add_filter( 'wp_image_editors', 'photon_subsizes_override_image_editors', 99999 );

// TODO: Look into disabling scaled images (apparently for things like retina displays)
// TODO: Only add crop settings query params for standard uploads locations

// Use a large priority to allow the Jetpack photon module to replace URLs first.
// Otherwise, we augment URLs that Jetpack would have remapped to photon,
// and it undermines Jetpack's application of subsize crop settings. 
add_filter( 'wp_calculate_image_srcset', 'photon_subsizes_calculate_image_srcset', 99999 );

// Use a large priority to allow other plugins to add their own image_downsize filter
// response before we augment it with photon-subsizes query params
add_filter( 'image_downsize', 'photon_subsizes_image_downsize', 99999, 3 );

add_filter( 'image_get_intermediate_size', 'photon_subsizes_image_get_intermediate_size', 99999, 2 );

add_action( 'plugins_loaded', function () {
	if ( false === has_filter( 'the_content', array( 'Jetpack_Photon', 'filter_the_content' ) ) ) {
		add_filter( 'the_content', 'photon_subsizes_filter_the_content' );
	}
} );

/**
 * Override list of image editors with compatible editors that do not generate image subsizes
 * 
 * @param string[] $image_editors Image editor class names
 * @return string[] Image editor classes that extend the original classes and disable image subsize generation
 */
function photon_subsizes_override_image_editors( $image_editors ) {
	// Server features required by photon-subsizes won't work for non-standard uploads locations
	if ( photon_subsizes_site_has_standard_uploads_location() ) {
		return array_map( 'photon_subsizes_declare_image_editor', $image_editors );
	}
	return $image_editors;
}

function photon_subsizes_site_has_standard_uploads_location() {
	// Based on
	// https://github.com/WordPress/wordpress-develop/blob/c7f5af72dcc4f36365656fdbfccfa0fb51fefd1f/src/wp-includes/default-constants.php#L156
	$default_uploads_baseurl = network_site_url( '/wp-content/uploads/' );
	$default_uploads_basedir = '/srv/htdocs/wp-content/uploads/';

	$uploads = wp_get_upload_dir();

	return (
		// Using trailingslashit() to make sure we avoid false positives like
		// `/wp-content/uploads-enhanced` being seen as a descendant of `/wp-content/uploads`
		0 === strpos( trailingslashit( $uploads['basedir'] ), trailingslashit( $default_uploads_basedir ) ) &&
		0 === strpos( trailingslashit( $uploads['baseurl'] ), trailingslashit( $default_uploads_baseurl ) )
	);
}

/**
 * Answers whether a path is for a photon-supported file type
 * 
 * @param string $path Path to an image file
 * @return boolean Whether the file extension represents a photon-supported file type
 */
function photon_subsizes_has_supported_image_extension( $path ) {
	foreach ( PHOTON_SUBSIZES_FILE_EXTENSIONS as $extension ) {
		// TODO: FIX: This should be case-insensitive.
		if ( photon_subsizes_string_ends_with( $path, $extension ) ) {
			return true;
		}
	}
	return false;
}

/**
 * Answers whether the specified MIME type is supported by Photon
 *
 * @param string $mime_type The MIME type
 *
 * @return boolean Whether the MIME type is supported by Photon
 */
function photon_subsizes_is_photon_mime_type( $mime_type ) {
	return false !== $mime_type && (
		"image/gif" === $mime_type ||
		"image/png" === $mime_type ||
		"image/jpeg" === $mime_type ||
		"image/webp" === $mime_type
	);
}

/**
 * Declare an image editor class to extend the specified image editor to stop saving image subsizes
 * 
 * @param string $editor_parent_class Image editor class name
 * @return string Name of the derived, overriding image editor class
 */
function photon_subsizes_declare_image_editor( $editor_parent_class ) {
	if ( ! class_exists( $editor_parent_class ) ) {
		return false;
	}

	$editor_subclass = "Photon_Subsizes_$editor_parent_class";
	if ( class_exists( $editor_subclass ) ) {
		return $editor_subclass;
	}

	if ( 'Photon_Subsizes_WP_Image_Editor_Imagick' === $editor_subclass ) {
		require_once __DIR__ . '/class.photon-subsizes-wp-image-editor-imagick.php';
		return $editor_subclass;
	} else if ( 'Photon_Subsizes_WP_Image_Editor_GD' === $editor_subclass ) {
		require_once __DIR__ . '/class.photon-subsizes-wp-image-editor-gd.php';
		return $editor_subclass;
	} else if ( method_exists( $editor_parent_class, 'make_subsize' ) ) {
		require_once __DIR__ . '/trait.photon-subsizes-image-editor-with-make-subsize.php';
		$editor_trait = 'Photon_Subsizes_Image_Editor_With_Make_Subsize';
	} else {
		require_once __DIR__ . '/trait.photon-subsizes-image-editor.php';
		$editor_trait = 'Photon_Subsizes_Image_Editor';
	}

	// Validate everything necessary for eval() even if we've checked it before.
	// That way, earlier code may change without compromising the security of the eval.
	if (
		! class_exists( $editor_subclass ) &&
		class_exists( $editor_parent_class ) &&
		is_subclass_of( $editor_parent_class, 'WP_Image_Editor' ) &&
		trait_exists( $editor_trait )
	) {
		// ATTENTION: eval() is incredibly dangerous but appears to be necessary here
		// because we are extending an image editor class which is determined at runtime.
		eval(
			'class ' . $editor_subclass . ' extends ' . $editor_parent_class . '{
				use ' . $editor_trait . ';
			}'
		);
		return $editor_subclass;
	}

	return false;
}

/**
 * Filter `calculate_image_srcset` to add photon subsizes query params to image URLs where needed
 *
 * @param array $source Array of srcset items which have 'url', 'descriptor', and 'value' entries
 *
 * @return array Array of augmented srcset info
 */
function photon_subsizes_calculate_image_srcset( $sources ) {
	if ( is_array( $sources ) ) {
		foreach ( $sources as &$source ) {
			$source['url'] = photon_subsizes_map_url( $source['url'] );
		}
	}

	return $sources;
}

/**
 * Filter `image_downsize` to add crop settings to image URLs
 *
 * @param bool|array   $downsize      Whether to short-circuit the image_downsize
 * @param int          $attachment_id The attachment ID
 * @param array|string $size          Image size name or array of width and height values
 *
 * @return array An array of image downsize info with the image URL augmented with
 *               photon subsize query params (if needed)
 */
function photon_subsizes_image_downsize( $downsize, $attachment_id, $size ) {
	if ( false === $downsize ) {
		$filter_priority = has_filter( 'image_downsize', __FUNCTION__ );
		if ( is_int( $filter_priority ) ) {
			remove_filter( 'image_downsize', __FUNCTION__, $filter_priority );
		}

		$downsize = image_downsize( $attachment_id, $size );

		if ( is_int( $filter_priority ) ) {
			add_filter( 'image_downsize', __FUNCTION__, $filter_priority, 3 );
		}
	}

	if ( is_array( $downsize ) && isset( $downsize[0] ) && 'string' === gettype( $downsize[0] ) ) {
		$downsize[0] = photon_subsizes_map_url( $downsize[0] );
	}

	return $downsize;
}

/**
 * Filter `image_get_intermediate_size` to add crop settings to image URLs
 *
 * @param array $data    Associative array of image data
 * @param int   $post_id Attachment ID
 *
 * @return array An array of image data that includes an image subsize URL
 */
function photon_subsizes_image_get_intermediate_size( $data, $post_id ) {
	if ( ! isset( $data['mime-type'] ) || ! photon_subsizes_is_photon_mime_type( $data['mime-type'] ) ) {
		return $data;
	}

	$url = false;
	if ( isset( $data['url'] ) ) {
		$url = photon_subsizes_map_url( $data['url'] );
	} else if (
		isset( $data['file'], $data['width'], $data['height'] ) && (
			( isset( $data['virtual'] ) && $data['virtual'] ) ||
			( isset( $data['path'] ) && 0 === strncmp( $data['path'], '/srv/htdocs/', strlen( '/srv/htdocs/' ) ) )
		)
	) {
		$url = photon_subsizes_get_subsize_url( $post_id, $data['file'], $data['width'], $data['height'] );
	}

	if ( false !== $url ) {
		$data['url'] = $url;
	}

	return $data;
}

/**
 * Filter `the_content` to add crop settings to photon subsize URLs
 *
 * @param string $content The content to be filtered
 * @return string The resulting content with updated image URLs
 */
function photon_subsizes_filter_the_content( $content ) {
	$img_tag_pattern =
		'#' .
		'(?P<head><(?:img|amp-img|amp-anim)[^>]*?\s+?src=["|\'])' .
		'(?P<url>[^\s]+?)' .
		'(?P<tail>["|\'].*?>)' .
		'#is';

	$match = array();
	$match_offset = 0;
	while (
		1 === preg_match( $img_tag_pattern, $content, $match, PREG_OFFSET_CAPTURE, $match_offset )
	) {
		$original_offset = $match[0][1];
		$original_length = strlen( $match[0][0] );

		$head = $match['head'][0];
		$url = $match['url'][0];
		$tail = $match['tail'][0];

		$new_img_tag = $head . photon_subsizes_map_url( $url ) . $tail;
		$new_length = strlen( $new_img_tag );

		$content = substr_replace( $content, $new_img_tag, $original_offset, $original_length );
		$match_offset = $original_offset + $new_length;
	}

	return $content;
}

/**
 * Map an image URL to a URL with crop settings query param (if needed)
 *
 * @param string $url The image URL
 * @return string The image URL with a crop settings query param added
 *                if it refers to a cropped subsize
 */
function photon_subsizes_map_url( $url ) {
	static $upload_dir = null;
	if ( null === $upload_dir ) {
		$upload_dir = wp_get_upload_dir();
		$upload_dir['basedir'] = untrailingslashit( $upload_dir['basedir'] );
		$upload_dir['baseurl'] = untrailingslashit( $upload_dir['baseurl'] );
	}

	if ( ! empty( $upload_dir['error'] ) ) {
		return $url;
	}

	if ( ! photon_subsizes_string_starts_with( $url, $upload_dir['baseurl'] ) ) {
		return $url;
	}

	if ( 1 === preg_match( '#[\?&]crop=#', $url ) ) {
		return $url;
	}

	$upload_relative_url = substr( $url, strlen( $upload_dir['baseurl'] ) );
	$url_path = parse_url( $upload_relative_url, PHP_URL_PATH );
	if ( empty( $url_path ) ) {
		return $url;
	}

	if ( file_exists( "{$upload_dir['basedir']}{$url_path}" ) ) {
		return $url;
	}

	if ( ! photon_subsizes_has_supported_image_extension( $url_path ) ) {
		return $url;
	}

	$pattern = '#^(?<base>.+)-(?<width>\d+)x(?<height>\d+)(?<ext>' . implode( '|', PHOTON_SUBSIZES_FILE_EXTENSIONS ) . ')$#i';
	$match = array();
	if ( 0 === preg_match( $pattern, $url_path, $match ) ) {
		return $url;
	}

	if ( ! file_exists( "{$upload_dir['basedir']}{$match['base']}{$match['ext']}" ) ) {
		return $url;
	}

	if ( ! photon_subsizes_is_cropped_subsize( $match['width'], $match['height'] ) ) {
		return $url;	
	}

	return add_query_arg( 'crop', '1', $url );
}

/**
 * Get a subsize URL from an attachment post ID and a subsize filename
 *
 * @param int    $attachment_post_id An attachment post ID
 * @param string $subsize_filename   The subsize filename
 * @param int    $width              Subsize width
 * @param int    $height             Subsize height
 *
 * @return string The subsize URL
 */
function photon_subsizes_get_subsize_url( $attachment_post_id, $subsize_filename, $width, $height ) {
	$attachment_url = wp_get_attachment_url( $attachment_post_id );
	if ( false === $attachment_url ) {
		return false;
	}

	$base_url = dirname( $attachment_url );
	$subsize_url = "{$base_url}/{$subsize_filename}";

	$crop_settings = photon_subsizes_get_crop_settings();
	$dimensions = "{$width}x{$height}";

	if ( isset( $crop_settings[ $dimensions ] ) && $crop_settings[ $dimensions ] ) {
		$subsize_url = add_query_arg( 'crop', '1', $subsize_url );
	}

	return $subsize_url;	
}

/**
 * Compile a map of subsize crop settings by <width>x<height> key
 *
 * @return array A map of subsize crop settings by <width>x<height> key
 */
function photon_subsizes_get_crop_settings() {
	static $settings = null;
	if ( null !== $settings ) {
		return $settings;
	}

	$settings = array();
	foreach ( wp_get_registered_image_subsizes() as $subsize ) {
		if ( ! isset( $subsize['crop'] ) ) {
			$crop_setting = false;
		} else if ( is_array( $subsize['crop'] ) ) {
			if (
				2 === count( $subsize['crop'] ) &&
				in_array( $subsize['crop'][0], array( 'left', 'center', 'right' ) ) &&
				in_array( $subsize['crop'][1], array( 'top', 'center', 'bottom' ) )
			) {
				$crop_setting = $subsize['crop'];
			} else {
				// Default to cropped because it looks like there are crop settings
				// even if they don't appear valid
				$crop_setting = true;
			}
		} else {
			$crop_setting = !! $subsize['crop'];
		}

		$settings[ "{$subsize['width']}x{$subsize['height']}" ] = $crop_setting;
	}
	return $settings;
}

/**
 * Answers whether the given dimensions correspond to a cropped subsize
 *
 * @param int $width  Subsize width
 * @param int $height Subsize height
 *
 * @return boolean Whether the subsize should be cropped
 */
function photon_subsizes_is_cropped_subsize( $width, $height ) {
	$settings = photon_subsizes_get_crop_settings();
	$key = "{$width}x{$height}";
	return isset( $settings[ $key ] ) && $settings[ $key ];
}

/**
 * Answers whether a string starts with another string
 *
 * @param string $haystack String to examine
 * @param string $needle   String to search for
 * @return boolean Whether the string starts with the specified string
 */
function photon_subsizes_string_starts_with( $haystack, $needle ) {
	return strncmp( $haystack, $needle, strlen( $needle ) ) === 0; 
}

/**
 * Answers whether a string ends with another string
 * 
 * @param string $haystack String to examine
 * @param string $needle   String to search for
 * @return boolean Whether the string ends with the specified string
 */
function photon_subsizes_string_ends_with( $haystack, $needle ) {
	return substr( $haystack, -strlen( $needle ) ) === $needle; 
}