Changeset 3268572
- Timestamp:
- 04/08/2025 09:45:55 AM (9 months ago)
- Location:
- edge-images
- Files:
-
- 69 added
- 11 edited
-
tags/5.5.1 (added)
-
tags/5.5.1/assets (added)
-
tags/5.5.1/assets/css (added)
-
tags/5.5.1/assets/css/admin-front.css (added)
-
tags/5.5.1/assets/css/admin-front.less (added)
-
tags/5.5.1/assets/css/admin.less (added)
-
tags/5.5.1/assets/css/admin.min.css (added)
-
tags/5.5.1/assets/css/images.less (added)
-
tags/5.5.1/assets/css/images.min.css (added)
-
tags/5.5.1/assets/js (added)
-
tags/5.5.1/assets/js/admin.js (added)
-
tags/5.5.1/assets/js/admin.min.js (added)
-
tags/5.5.1/assets/js/main.js (added)
-
tags/5.5.1/assets/js/main.min.js (added)
-
tags/5.5.1/autoload.php (added)
-
tags/5.5.1/classes (added)
-
tags/5.5.1/classes/blocks (added)
-
tags/5.5.1/classes/blocks/class-gallery.php (added)
-
tags/5.5.1/classes/blocks/class-image.php (added)
-
tags/5.5.1/classes/class-activation.php (added)
-
tags/5.5.1/classes/class-admin-page.php (added)
-
tags/5.5.1/classes/class-block.php (added)
-
tags/5.5.1/classes/class-blocks.php (added)
-
tags/5.5.1/classes/class-content-transformer.php (added)
-
tags/5.5.1/classes/class-edge-provider.php (added)
-
tags/5.5.1/classes/class-features.php (added)
-
tags/5.5.1/classes/class-handler.php (added)
-
tags/5.5.1/classes/class-helpers.php (added)
-
tags/5.5.1/classes/class-image-dimensions.php (added)
-
tags/5.5.1/classes/class-images.php (added)
-
tags/5.5.1/classes/class-integration.php (added)
-
tags/5.5.1/classes/class-integrations.php (added)
-
tags/5.5.1/classes/class-providers.php (added)
-
tags/5.5.1/classes/class-rewrites.php (added)
-
tags/5.5.1/classes/class-settings.php (added)
-
tags/5.5.1/classes/class-srcset-transformer.php (added)
-
tags/5.5.1/classes/edge-providers (added)
-
tags/5.5.1/classes/edge-providers/class-accelerated-domains.php (added)
-
tags/5.5.1/classes/edge-providers/class-bunny.php (added)
-
tags/5.5.1/classes/edge-providers/class-cloudflare.php (added)
-
tags/5.5.1/classes/edge-providers/class-imgix.php (added)
-
tags/5.5.1/classes/edge-providers/class-imgproxy.php (added)
-
tags/5.5.1/classes/edge-providers/class-native.php (added)
-
tags/5.5.1/classes/edge-providers/class-none.php (added)
-
tags/5.5.1/classes/features (added)
-
tags/5.5.1/classes/features/class-avatars.php (added)
-
tags/5.5.1/classes/features/class-cache.php (added)
-
tags/5.5.1/classes/features/class-htaccess-cache.php (added)
-
tags/5.5.1/classes/features/class-picture.php (added)
-
tags/5.5.1/classes/integrations (added)
-
tags/5.5.1/classes/integrations/bricks (added)
-
tags/5.5.1/classes/integrations/bricks/class-bricks.php (added)
-
tags/5.5.1/classes/integrations/enable-media-replace (added)
-
tags/5.5.1/classes/integrations/enable-media-replace/class-enable-media-replace.php (added)
-
tags/5.5.1/classes/integrations/rank-math (added)
-
tags/5.5.1/classes/integrations/rank-math/class-schema-images.php (added)
-
tags/5.5.1/classes/integrations/rank-math/class-social-images.php (added)
-
tags/5.5.1/classes/integrations/rank-math/class-xml-sitemaps.php (added)
-
tags/5.5.1/classes/integrations/relevanssi (added)
-
tags/5.5.1/classes/integrations/relevanssi/class-live-ajax-search.php (added)
-
tags/5.5.1/classes/integrations/yoast-seo (added)
-
tags/5.5.1/classes/integrations/yoast-seo/class-schema-images.php (added)
-
tags/5.5.1/classes/integrations/yoast-seo/class-social-images.php (added)
-
tags/5.5.1/classes/integrations/yoast-seo/class-xml-sitemaps.php (added)
-
tags/5.5.1/edge-images.php (added)
-
tags/5.5.1/languages (added)
-
tags/5.5.1/readme.md (added)
-
tags/5.5.1/readme.txt (added)
-
tags/5.5.1/uninstall.php (added)
-
trunk/classes/blocks/class-image.php (modified) (4 diffs)
-
trunk/classes/class-helpers.php (modified) (2 diffs)
-
trunk/classes/class-settings.php (modified) (11 diffs)
-
trunk/classes/edge-providers/class-accelerated-domains.php (modified) (2 diffs)
-
trunk/classes/edge-providers/class-bunny.php (modified) (1 diff)
-
trunk/classes/edge-providers/class-cloudflare.php (modified) (1 diff)
-
trunk/classes/edge-providers/class-imgix.php (modified) (4 diffs)
-
trunk/classes/edge-providers/class-native.php (modified) (1 diff)
-
trunk/classes/integrations/yoast-seo/class-schema-images.php (modified) (3 diffs)
-
trunk/edge-images.php (modified) (3 diffs)
-
trunk/readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
edge-images/trunk/classes/blocks/class-image.php
r3253580 r3268572 35 35 */ 36 36 public function transform(string $block_content, array $block): string { 37 // Check if we have a div.wp-block-image wrapper38 $processor = new \WP_HTML_Tag_Processor($block_content);39 $has_div_wrapper = false;40 41 // Look for div with wp-block-image class42 while ($processor->next_tag('div')) {43 $class = $processor->get_attribute('class');44 if ($class && strpos($class, 'wp-block-image') !== false) {45 $has_div_wrapper = true;46 break;47 }48 }49 50 37 // Extract the image tag 51 38 $img_html = $this->extract_image($block_content); … … 72 59 if ($dimensions) { 73 60 $classes = $this->extract_classes($block_content, $block); 74 $picture = $this->create_picture_element($transformed, $dimensions, $classes, $has_link, $link_data); 75 76 // If we have a div wrapper, preserve the structure 77 if ($has_div_wrapper) { 78 return $this->preserve_div_wrapper($block_content, $picture); 61 $picture = $this->create_picture($transformed, $dimensions, $classes); 62 63 // If we have a link, move it inside the picture element 64 if ($has_link) { 65 // Extract the anchor opening tag 66 preg_match('/<a[^>]*>/', $link_data['link'], $link_open); 67 $link_open = $link_open[0]; 68 69 $picture = str_replace( 70 '<img', 71 $link_open . '<img', 72 $picture 73 ); 74 $picture = str_replace('</picture>', '</a></picture>', $picture); 79 75 } 80 76 81 // Return just the picture element if we couldn't preserve the wrapper77 // Return just the picture element 82 78 return $picture; 83 79 } … … 89 85 } 90 86 91 // Create a figure with the transformed content 92 $figure = $this->create_figure_element($block_content, $transformed); 93 94 // If we have a div wrapper, preserve it 95 if ($has_div_wrapper && $figure) { 96 return $this->preserve_div_wrapper($block_content, $figure); 97 } 98 99 return $figure ?: $transformed; 100 } 101 102 /** 103 * Create a picture element with proper link handling. 104 * 105 * @since 5.4.0 106 * 107 * @param string $transformed The transformed image HTML. 108 * @param array $dimensions The image dimensions. 109 * @param array $classes The classes to add to the picture. 110 * @param bool $has_link Whether the image has a link. 111 * @param array $link_data The link data if present. 112 * @return string The picture element HTML. 113 */ 114 private function create_picture_element(string $transformed, array $dimensions, array $classes, bool $has_link, array $link_data = []): string { 115 $picture = $this->create_picture($transformed, $dimensions, $classes); 116 117 // If we have a link, move it inside the picture element 118 if ($has_link && !empty($link_data['link'])) { 119 // We need to extract the opening <a> tag using a simple regex 120 // since WP_HTML_Tag_Processor doesn't provide a way to get the full tag 121 preg_match('/<a[^>]*>/', $link_data['link'], $link_open); 122 if (!empty($link_open[0])) { 123 $picture = str_replace( 124 '<img', 125 $link_open[0] . '<img', 126 $picture 127 ); 128 $picture = str_replace('</picture>', '</a></picture>', $picture); 129 } 130 } 131 132 return $picture; 133 } 134 135 /** 136 * Create a figure element with the transformed content. 137 * 138 * @since 5.4.0 139 * 140 * @param string $block_content The original block content. 141 * @param string $transformed The transformed image HTML. 142 * @return string|null The figure element HTML or null if figure not found. 143 */ 144 private function create_figure_element(string $block_content, string $transformed): ?string { 87 // Extract the figure classes 145 88 $processor = new \WP_HTML_Tag_Processor($block_content); 146 89 if ($processor->next_tag('figure')) { … … 154 97 ); 155 98 } 156 157 return null; 158 } 159 160 /** 161 * Preserve the div wrapper structure when replacing content. 162 * 163 * @since 5.4.0 164 * 165 * @param string $block_content The original block content. 166 * @param string $new_element The new element to insert. 167 * @return string The block content with preserved div wrapper. 168 */ 169 private function preserve_div_wrapper(string $block_content, string $new_element): string { 170 // Since WP_HTML_Tag_Processor doesn't provide a way to get the full tag with content, 171 // we'll use a simple string replacement approach 172 173 // Find the figure tag in the content 174 if (preg_match('/<figure[^>]*>.*?<\/figure>/s', $block_content, $figure_match)) { 175 // Replace the figure with our new element 176 return str_replace($figure_match[0], $new_element, $block_content); 177 } 178 179 // If we couldn't find a figure to replace, return the new element 180 return $new_element; 99 100 return $transformed; 181 101 } 182 102 } -
edge-images/trunk/classes/class-helpers.php
r3245305 r3268572 53 53 'alt', 54 54 'class', 55 'container-class',56 55 'decoding', 57 56 'height', … … 62 61 'srcset', 63 62 'style', 64 'title',65 63 'width', 66 64 'data-attachment-id', 67 'data-original-width',68 'data-original-height',69 65 'data-wrap-in-picture', 70 66 'fetchpriority' -
edge-images/trunk/classes/class-settings.php
r3253580 r3268572 72 72 73 73 /** 74 * Imgproxy URL option name.75 *76 * The option name used to store the URL for the imgproxy provider.77 * This setting allows configuring the URL for a self-hosted imgproxy setup.78 *79 * @since 5.4.080 * @var string81 */82 public const IMGPROXY_URL_OPTION = 'edge_images_imgproxy_url';83 84 /**85 74 * Cache for settings values. 86 75 * … … 120 109 * @param int $max_width The maximum width in pixels. 121 110 */ 122 return (int) apply_filters('edge_images_max_width', $max_width);111 return (int) \apply_filters('edge_images_max_width', $max_width); 123 112 } 124 113 … … 209 198 */ 210 199 public static function register_settings(): void { 200 211 201 // Register provider setting 212 register_setting(202 \register_setting( 213 203 self::OPTION_GROUP, 214 204 self::PROVIDER_OPTION, … … 222 212 223 213 // Register domain setting 224 register_setting(214 \register_setting( 225 215 self::OPTION_GROUP, 226 216 self::DOMAIN_OPTION, … … 235 225 236 226 // Register max width setting 237 register_setting(227 \register_setting( 238 228 self::OPTION_GROUP, 239 229 self::MAX_WIDTH_OPTION, … … 247 237 ); 248 238 249 // Register imgproxy URL setting250 register_setting(251 self::OPTION_GROUP,252 self::IMGPROXY_URL_OPTION,253 [254 'type' => 'string',255 'description' => __('The URL for the imgproxy provider', 'edge-images'),256 'sanitize_callback' => [self::class, 'sanitize_url'],257 'default' => '',258 ]259 );260 239 } 261 240 … … 277 256 */ 278 257 public static function get_domain(): string { 279 $domain = self::get_option(self::DOMAIN_OPTION );258 $domain = self::get_option(self::DOMAIN_OPTION, ''); 280 259 if (empty($domain)) { 281 260 return ''; 282 261 } 283 284 return untrailingslashit($domain); 262 return rtrim($domain, '/'); 285 263 } 286 264 … … 294 272 */ 295 273 public static function sanitize_domain(string $value): string { 274 296 275 $value = trim($value); 297 276 if (empty($value)) { … … 304 283 } 305 284 306 return untrailingslashit(esc_url_raw($value));285 return \untrailingslashit(esc_url_raw($value)); 307 286 } 308 287 … … 316 295 */ 317 296 public static function sanitize_url(string $value): string { 297 318 298 $value = trim($value); 319 299 if (empty($value)) { … … 326 306 } 327 307 328 return untrailingslashit(esc_url_raw($value));308 return \untrailingslashit(esc_url_raw($value)); 329 309 } 330 310 } -
edge-images/trunk/classes/edge-providers/class-accelerated-domains.php
r3217818 r3268572 53 53 */ 54 54 public function get_edge_url(): string { 55 55 56 // Bail early if no path 56 57 if (empty($this->path)) { … … 101 102 self::EDGE_ROOT, 102 103 $image_path, 103 http_build_query($transform_args)104 \http_build_query($transform_args) 104 105 ); 105 106 -
edge-images/trunk/classes/edge-providers/class-bunny.php
r3223857 r3268572 154 154 */ 155 155 private function get_bunny_transform_args(): array { 156 157 // Get the parent args 156 158 $args = $this->get_transform_args(); 157 159 $bunny_args = []; -
edge-images/trunk/classes/edge-providers/class-cloudflare.php
r3217818 r3268572 61 61 62 62 // Build the URL with comma-separated parameters. 63 $edge_url = $edge_prefix . http_build_query(63 $edge_url = $edge_prefix . \http_build_query( 64 64 $transform_args, 65 65 '', -
edge-images/trunk/classes/edge-providers/class-imgix.php
r3223857 r3268572 69 69 */ 70 70 public static function register_settings(): void { 71 register_setting(71 \register_setting( 72 72 Settings::OPTION_GROUP, 73 73 self::SUBDOMAIN_OPTION, … … 111 111 */ 112 112 public function get_edge_url(): string { 113 113 114 // Get the Imgix subdomain from settings 114 115 $subdomain = self::get_subdomain(); … … 168 169 */ 169 170 private function get_imgix_transform_args(): array { 171 172 // Get the standard transform args 170 173 $args = $this->get_transform_args(); 174 175 // Initialize the imgix args array 171 176 $imgix_args = []; 172 177 … … 273 278 */ 274 279 public static function get_transform_pattern(): string { 280 275 281 // Get the configured subdomain 276 282 $subdomain = self::get_subdomain(); 283 284 // Bail if no subdomain is configured 277 285 if (empty($subdomain)) { 278 286 return ''; -
edge-images/trunk/classes/edge-providers/class-native.php
r3253580 r3268572 59 59 60 60 // Add our filters 61 add_action('parse_request', [$this, 'maybe_transform_image']); 62 add_filter('redirect_canonical', [$this, 'alter_canonical_redirect'], 10, 2); 63 add_filter('edge_images_srcset_widths', [$this, 'filter_srcset_widths'], 10, 2); 64 61 \add_action('parse_request', [$this, 'maybe_transform_image']); 62 \add_filter('redirect_canonical', [$this, 'alter_canonical_redirect'], 10, 2); 63 \add_filter('edge_images_srcset_widths', [$this, 'filter_srcset_widths'], 10, 2); 65 64 } 66 65 -
edge-images/trunk/classes/integrations/yoast-seo/class-schema-images.php
r3240045 r3268572 65 65 66 66 add_filter('wpseo_schema_imageobject', [$this, 'transform_schema_image'], 10, 3); 67 add_filter('wpseo_schema_organization', [$this, 'edge_organization_logo']); 68 add_filter('wpseo_schema_webpage', [$this, 'edge_thumbnail']); 69 add_filter('wpseo_schema_article', [$this, 'edge_thumbnail']); 67 add_filter('wpseo_schema_organization', [$this, 'edge_organization_logo'], PHP_INT_MAX - 10); 68 add_filter('wpseo_schema_webpage', [$this, 'edge_thumbnail'], PHP_INT_MAX - 10); 69 add_filter('wpseo_schema_article', [$this, 'edge_thumbnail'], PHP_INT_MAX - 10); 70 add_filter('wpseo_schema_webpage', [$this, 'edge_images'], PHP_INT_MAX - 10); 71 add_filter('wpseo_schema_article', [$this, 'edge_images'], PHP_INT_MAX - 10); 72 } 73 74 /** 75 * Process and transform image properties in schema data. 76 * 77 * Handles multiple image formats in schema: 78 * - Single image URL as string 79 * - Array of image URLs 80 * - Array of reference objects with @id properties 81 * 82 * @since 4.5.0 83 * 84 * @param array $data The schema data containing image properties. 85 * @return array The modified schema data with transformed image URLs. 86 */ 87 public function edge_images( array $data ): array { 88 // Process 'image' property if it exists. 89 if ( isset( $data['image'] ) ) { 90 // Case 1: Single image URL as string. 91 if ( is_string( $data['image'] ) ) { 92 $processed = $this->process_schema_image( $data['image'] ); 93 if ( $processed ) { 94 $data['image'] = $processed['url']; 95 } 96 } 97 // Case 2: Array of values (either URLs or reference objects). 98 elseif ( is_array( $data['image'] ) ) { 99 foreach ( $data['image'] as $key => $image ) { 100 // Case 2a: Direct URL string in array. 101 if ( is_string( $image ) ) { 102 $processed = $this->process_schema_image( $image ); 103 if ( $processed ) { 104 $data['image'][ $key ] = $processed['url']; 105 } 106 } 107 // Case 2b: Reference object with @id. 108 elseif ( is_array( $image ) && isset( $image['@id'] ) ) { 109 // Only process if @id looks like a URL (not just a reference ID). 110 if ( filter_var( $image['@id'], FILTER_VALIDATE_URL ) ) { 111 $processed = $this->process_schema_image( $image['@id'] ); 112 if ( $processed ) { 113 $data['image'][ $key ]['@id'] = $processed['url']; 114 } 115 } 116 } 117 } 118 } 119 } 120 121 // Process 'primaryImageOfPage' property if it exists. 122 if ( isset( $data['primaryImageOfPage'] ) ) { 123 // Case 1: Direct URL string. 124 if ( is_string( $data['primaryImageOfPage'] ) ) { 125 $processed = $this->process_schema_image( $data['primaryImageOfPage'] ); 126 if ( $processed ) { 127 $data['primaryImageOfPage'] = $processed['url']; 128 } 129 } 130 // Case 2: Reference object with @id. 131 elseif ( is_array( $data['primaryImageOfPage'] ) && isset( $data['primaryImageOfPage']['@id'] ) ) { 132 // Only process if @id looks like a URL (not just a reference ID). 133 if ( filter_var( $data['primaryImageOfPage']['@id'], FILTER_VALIDATE_URL ) ) { 134 $processed = $this->process_schema_image( $data['primaryImageOfPage']['@id'] ); 135 if ( $processed ) { 136 $data['primaryImageOfPage']['@id'] = $processed['url']; 137 } 138 } 139 } 140 } 141 142 return $data; 70 143 } 71 144 … … 104 177 */ 105 178 private function process_schema_image( string $image_url, array $custom_args = [] ) { 106 179 107 180 // Check cache first 108 181 $cache_key = 'schema_' . md5($image_url . serialize($custom_args)); … … 131 204 'height' => self::SCHEMA_HEIGHT, 132 205 'fit' => 'cover', 133 'sharpen' => (int) $dimensions['width'] < self::SCHEMA_WIDTH ? 3 : 2,134 206 ]; 135 207 136 208 // Merge with custom args 137 209 $args = array_merge( $args, $custom_args ); 138 139 // Tweak the behaviour for small images140 if ( (int) $dimensions['width'] < self::SCHEMA_WIDTH || (int) $dimensions['height'] < self::SCHEMA_HEIGHT ) {141 $args['fit'] = 'pad';142 $args['sharpen'] = 2;143 }144 210 145 211 // Get the edge URL -
edge-images/trunk/edge-images.php
r3253580 r3268572 8 8 * @link https://github.com/jonoalderson/edge-images/ 9 9 * @since 1.0.0 10 * @version 5.5 10 * @version 5.5.1 11 11 * 12 12 * @wordpress-plugin … … 14 14 * Plugin URI: https://github.com/jonoalderson/edge-images/ 15 15 * Description: Routes images through edge providers (like Cloudflare or Accelerated Domains) for automatic optimization and transformation. Improves page speed and image loading performance. 16 * Version: 5.5 16 * Version: 5.5.1 17 17 * Requires PHP: 7.4 18 18 * Requires at least: 5.6 19 * Tested up to: 6. 719 * Tested up to: 6.8 20 20 * Author: Jono Alderson 21 21 * Author URI: https://www.jonoalderson.com/ … … 34 34 35 35 // Define plugin constants. 36 define( 'EDGE_IMAGES_VERSION', '5.5 ' );36 define( 'EDGE_IMAGES_VERSION', '5.5.1' ); 37 37 define( 'EDGE_IMAGES_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); 38 38 define( 'EDGE_IMAGES_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); -
edge-images/trunk/readme.txt
r3253580 r3268572 2 2 Contributors: jonoaldersonwp 3 3 Tags: images, optimization, cdn, cloudflare, performance 4 Tested up to: 6. 74 Tested up to: 6.8 5 5 Requires PHP: 7.4 6 Stable tag: 5.5 6 Stable tag: 5.5.1 7 7 License: GPLv2 or later 8 8 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 254 254 == Changelog == 255 255 256 = 5.5.1 ( 08/04/2025 ) = 257 * FEATURE: Tested up to WP 6.8. 258 * MISC: Tidied up some code. 259 256 260 = 5.5 ( 10/03/2025) = 257 261 * BUGFIX: Prevented a layout-breaking bug for images in content, wrapped in picture els.
Note: See TracChangeset
for help on using the changeset viewer.