Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 51
0.00% covered (danger)
0.00%
0 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
ImageCommandHandler
0.00% covered (danger)
0.00%
0 / 51
0.00% covered (danger)
0.00%
0 / 11
756
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
 bulk_optimization
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 lazy_loading
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 auto_optimize
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 auto_delete
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 webp_preference
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 all
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
 toggle_setting
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
20
 set_nested_value
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
20
 set_all_values
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 validate_status
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3namespace NewfoldLabs\WP\Module\Performance\Images\WPCLI;
4
5use NewfoldLabs\WP\Module\Performance\NFD_WPCLI;
6use NewfoldLabs\WP\Module\Performance\Images\ImageSettings;
7use function NewfoldLabs\WP\ModuleLoader\container;
8
9/**
10 * Handles WP-CLI commands for Image Optimization settings.
11 */
12class ImageCommandHandler {
13
14    /**
15     * Allowed status values.
16     *
17     * @var array
18     */
19    private const VALID_STATUSES = array( 'on', 'off' );
20
21    /**
22     * Container.
23     *
24     * @var object Container
25     */
26    private $container;
27
28
29    /**
30     * Class constructor.
31     */
32    public function __construct() {
33        $this->container = container();
34    }
35
36    /**
37     * Toggles the bulk optimization setting.
38     *
39     * ## OPTIONS
40     *
41     * <status>
42     * : Enable or disable bulk optimization. Accepts 'on' or 'off'.
43     *
44     * ## EXAMPLES
45     *
46     *     wp nfd performance images bulk_optimization on
47     *     wp nfd performance images bulk_optimization off
48     *
49     * @param array $args Positional arguments.
50     *
51     * @return void
52     */
53    public function bulk_optimization( $args ) {
54        $status = $this->validate_status( isset( $args[0] ) ? $args[0] : null );
55        $this->toggle_setting( 'bulk_optimization', $status );
56    }
57
58    /**
59     * Toggles lazy loading.
60     *
61     * ## OPTIONS
62     *
63     * <status>
64     * : Enable or disable lazy loading. Accepts 'on' or 'off'.
65     *
66     * ## EXAMPLES
67     *
68     *     wp nfd performance images lazy_loading on
69     *     wp nfd performance images lazy_loading off
70     *
71     * @param array $args Positional arguments.
72     *
73     * @return void
74     */
75    public function lazy_loading( $args ) {
76        $status = $this->validate_status( isset( $args[0] ) ? $args[0] : null );
77        $this->toggle_setting( 'lazy_loading.enabled', $status );
78    }
79
80    /**
81     * Toggles automatic optimization of uploaded images.
82     *
83     * ## OPTIONS
84     *
85     * <status>
86     * : Enable or disable auto-optimization. Accepts 'on' or 'off'.
87     *
88     * ## EXAMPLES
89     *
90     *     wp nfd performance images auto_optimize on
91     *     wp nfd performance images auto_optimize off
92     *
93     * @param array $args Positional arguments.
94     *
95     * @return void
96     */
97    public function auto_optimize( $args ) {
98        $status = $this->validate_status( isset( $args[0] ) ? $args[0] : null );
99        $this->toggle_setting( 'auto_optimized_uploaded_images.enabled', $status );
100    }
101
102    /**
103     * Toggles automatic deletion of the original image.
104     *
105     * ## OPTIONS
106     *
107     * <status>
108     * : Enable or disable auto-delete of original images. Accepts 'on' or 'off'.
109     *
110     * ## EXAMPLES
111     *
112     *     wp nfd performance images auto_delete on
113     *     wp nfd performance images auto_delete off
114     *
115     * @param array $args Positional arguments.
116     *
117     * @return void
118     */
119    public function auto_delete( $args ) {
120        $status = $this->validate_status( isset( $args[0] ) ? $args[0] : null );
121        $this->toggle_setting( 'auto_optimized_uploaded_images.auto_delete_original_image', $status );
122    }
123
124    /**
125     * Toggles WebP preference when optimized images exist.
126     *
127     * ## OPTIONS
128     *
129     * <status>
130     * : Enable or disable WebP preference. Accepts 'on' or 'off'.
131     *
132     * ## EXAMPLES
133     *
134     *     wp nfd performance images webp_preference on
135     *     wp nfd performance images webp_preference off
136     *
137     * @param array $args Positional arguments.
138     *
139     * @return void
140     */
141    public function webp_preference( $args ) {
142        $status = $this->validate_status( isset( $args[0] ) ? $args[0] : null );
143        $this->toggle_setting( 'prefer_optimized_image_when_exists', $status );
144    }
145
146    /**
147     * Toggles all image optimization settings at once.
148     *
149     * ## OPTIONS
150     *
151     * <status>
152     * : Enable or disable all image optimization settings. Accepts 'on' or 'off'.
153     *
154     * ## EXAMPLES
155     *
156     *     wp nfd performance images all on
157     *     wp nfd performance images all off
158     *
159     * @alias all
160     *
161     * @param array $args Positional arguments.
162     *
163     * @return void
164     */
165    public function all( $args ) {
166        $status   = $this->validate_status( isset( $args[0] ) ? $args[0] : null );
167        $enabled  = ( 'on' === $status );
168        $settings = ImageSettings::get( $this->container );
169        $this->set_all_values( $settings, $enabled );
170        ImageSettings::update( $settings, $this->container );
171        /* translators: %s is the on/off status. */
172        NFD_WPCLI::success( sprintf( __( 'All image optimization settings have been turned %s.', 'wp-module-performance' ), $status ) );
173    }
174
175    /**
176     * Toggles a specific image optimization setting.
177     *
178     * @param string $setting The setting key (use dot notation for nested values).
179     * @param string $status  The status ('on' or 'off').
180     *
181     * @return void
182     */
183    private function toggle_setting( $setting, $status ) {
184        $enabled  = ( 'on' === $status );
185        $settings = ImageSettings::get( $this->container );
186
187        // If a feature is turned on (except for the "all" command), enable overall image optimization.
188        if ( $enabled ) {
189            $settings['enabled'] = true;
190        }
191
192        // Update the specified setting.
193        $this->set_nested_value( $settings, $setting, $enabled );
194
195        // If both auto_optimize and bulk_optimization are turned off,
196        // then force auto_delete (auto_delete_original_image) to be off.
197        $auto_optimize     = ! empty( $settings['auto_optimized_uploaded_images']['enabled'] );
198        $bulk_optimization = ! empty( $settings['bulk_optimization'] );
199        if ( ! $auto_optimize && ! $bulk_optimization ) {
200            $settings['auto_optimized_uploaded_images']['auto_delete_original_image'] = false;
201        }
202
203        ImageSettings::update( $settings, $this->container );
204
205        NFD_WPCLI::success(
206            sprintf(
207                /* translators: 1: the setting key, 2: the on/off status */
208                __( "Setting '%1\$s' has been turned %2\$s.", 'wp-module-performance' ),
209                $setting,
210                $status
211            )
212        );
213    }
214
215
216    /**
217     * Updates a nested setting value using dot notation.
218     *
219     * @param array  $settings The settings array.
220     * @param string $key      The nested key in dot notation.
221     * @param mixed  $value    The new value to set.
222     *
223     * @return void
224     */
225    private function set_nested_value( &$settings, $key, $value ) {
226        $keys = explode( '.', $key );
227        $temp = &$settings;
228        foreach ( $keys as $part ) {
229            if ( ! isset( $temp[ $part ] ) || ! is_array( $temp[ $part ] ) ) {
230                $temp[ $part ] = array();
231            }
232            $temp = &$temp[ $part ];
233        }
234        $temp = $value;
235    }
236
237    /**
238     * Recursively updates all boolean settings within an array.
239     *
240     * @param array $settings The settings array to update.
241     * @param bool  $enabled  The boolean value to set.
242     *
243     * @return void
244     */
245    private function set_all_values( &$settings, $enabled ) {
246        foreach ( $settings as $key => &$value ) {
247            if ( is_array( $value ) ) {
248                $this->set_all_values( $value, $enabled );
249            } else {
250                $value = $enabled;
251            }
252        }
253    }
254
255    /**
256     * Validates and normalizes the status input.
257     *
258     * @param string|null $status The input status.
259     * @return string The normalized status.
260     */
261    private function validate_status( $status ) {
262        if ( empty( $status ) ) {
263            NFD_WPCLI::error( __( "A status ('on' or 'off') is required.", 'wp-module-performance' ) );
264        }
265        $status = strtolower( $status );
266        if ( ! in_array( $status, self::VALID_STATUSES, true ) ) {
267            NFD_WPCLI::error( __( "Invalid status: Use 'on' or 'off'.", 'wp-module-performance' ) );
268        }
269        return $status;
270    }
271}