Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
ImageRewriteHandler
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 7
110
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 add_missing_image_rule
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
2
 add_existing_image_rule
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
 remove_rules
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 on_activation
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 on_deactivation
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 on_image_setting_change
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3namespace NewfoldLabs\WP\Module\Performance\Images;
4
5use WP_Forge\WP_Htaccess_Manager\htaccess;
6use function WP_Forge\WP_Htaccess_Manager\removeMarkers;
7
8/**
9 * Handles the management of .htaccess rules for optimized image redirects.
10 */
11class ImageRewriteHandler {
12
13    /**
14     * Marker for missing image redirect rules.
15     */
16    const MISSING_IMAGE_MARKER = 'Newfold WebP Missing Image Redirect';
17
18    /**
19     * Marker for existing image redirect rules.
20     */
21    const EXISTING_IMAGE_MARKER = 'Newfold WebP Existing Image Redirect';
22
23    /**
24     * Constructor to set up listeners.
25     */
26    public function __construct() {
27        add_action( 'update_option_nfd_image_optimization', array( $this, 'on_image_setting_change' ), 10, 2 );
28    }
29
30    /**
31     * Add the missing image redirect rule to .htaccess.
32     */
33    public function add_missing_image_rule() {
34        $rules = array(
35            '<IfModule mod_rewrite.c>',
36            "\tRewriteEngine On",
37            "\tRewriteCond %{REQUEST_FILENAME} !-f",
38            "\tRewriteCond %{REQUEST_FILENAME} !-d",
39            "\tRewriteCond %{REQUEST_URI} (.+)\\.(gif|bmp|jpg|jpeg|png|tiff|svg|webp)$ [NC]",
40            "\tRewriteCond %{DOCUMENT_ROOT}%1.webp -f",
41            "\tRewriteRule ^(.+)\\.(gif|bmp|jpg|jpeg|png|tiff|svg|webp)$ $1.webp [T=image/webp,E=WEBP_REDIRECT:1,L]",
42            '</IfModule>',
43        );
44
45        $htaccess = new htaccess( self::MISSING_IMAGE_MARKER );
46        return $htaccess->addContent( $rules );
47    }
48
49    /**
50     * Add the existing image redirect rule to .htaccess.
51     */
52    public function add_existing_image_rule() {
53        $rules = array(
54            '<IfModule mod_rewrite.c>',
55            "\tRewriteEngine On",
56            "\tRewriteCond %{REQUEST_FILENAME} -f",
57            "\tRewriteCond %{REQUEST_URI} (.+)\\.(gif|bmp|jpg|jpeg|png|tiff|svg|webp)$ [NC]",
58            "\tRewriteCond %{DOCUMENT_ROOT}%1.webp -f",
59            "\tRewriteRule ^(.+)\\.(gif|bmp|jpg|jpeg|png|tiff|svg|webp)$ $1.webp [T=image/webp,E=WEBP_REDIRECT:1,L]",
60            '</IfModule>',
61        );
62
63        $htaccess = new htaccess( self::EXISTING_IMAGE_MARKER );
64        return $htaccess->addContent( $rules );
65    }
66
67    /**
68     * Remove both rules from the .htaccess file.
69     */
70    public function remove_rules() {
71        removeMarkers( self::MISSING_IMAGE_MARKER );
72        removeMarkers( self::EXISTING_IMAGE_MARKER );
73    }
74
75    /**
76     * Activate the rules when needed.
77     */
78    public function on_activation() {
79        $this->add_missing_image_rule();
80        $this->add_existing_image_rule();
81    }
82
83    /**
84     * Deactivate the rules when needed.
85     */
86    public function on_deactivation() {
87        $this->remove_rules();
88    }
89
90    /**
91     * Handle changes to image optimization settings.
92     *
93     * @param array $old_value The previous settings (not used).
94     * @param array $new_value The updated settings.
95     */
96    public function on_image_setting_change( $old_value, $new_value ) {
97        // If the image optimization is disabled, remove all rules and return.
98        if ( empty( $new_value['enabled'] ) ) {
99            $this->remove_rules();
100            return;
101        }
102
103        // Handle 'auto_delete_original_image' setting.
104        if ( ! empty( $new_value['auto_optimized_uploaded_images']['auto_delete_original_image'] ) ) {
105            $this->add_missing_image_rule();
106        } else {
107            removeMarkers( self::MISSING_IMAGE_MARKER );
108        }
109
110        // Handle 'prefer_optimized_image_when_exists' setting.
111        if ( ! empty( $new_value['prefer_optimized_image_when_exists'] ) ) {
112            $this->add_existing_image_rule();
113        } else {
114            removeMarkers( self::EXISTING_IMAGE_MARKER );
115        }
116    }
117}