PluginProbe ʕ •ᴥ•ʔ
Modern Image Formats / 2.5.1
Modern Image Formats v2.5.1
2.7.0 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.1.0 1.1.1 2.0.0 2.0.1 2.0.2 2.1.0 2.2.0 2.3.0 2.4.0 2.5.0 2.5.1 2.6.0 2.6.1
webp-uploads / settings.php
webp-uploads Last commit date
deprecated.php 1 year ago helper.php 1 year ago hooks.php 1 year ago image-edit.php 1 year ago load.php 1 year ago picture-element.php 1 year ago readme.txt 1 year ago rest-api.php 1 year ago settings.php 1 year ago uninstall.php 1 year ago
settings.php
411 lines
1 <?php
2 /**
3 * Settings for the Modern Image Formats plugin.
4 *
5 * @package webp-uploads
6 *
7 * @since 1.0.0
8 */
9
10 // @codeCoverageIgnoreStart
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit; // Exit if accessed directly.
13 }
14 // @codeCoverageIgnoreEnd
15
16 /**
17 * Registers setting for generating JPEG in addition to the selected modern format for image uploads.
18 *
19 * @since 1.0.0
20 * @since 2.0.0 The setting was made more general to cover outputting JPEG as a secondary type. The "webp" option naming
21 * was left unchanged for backward compatibility. Also, the `perflab_modern_image_format` was added to
22 * enable selecting an output format. Currently includes AVIF and WebP.
23 */
24 function webp_uploads_register_media_settings_field(): void {
25 register_setting(
26 'media',
27 'perflab_modern_image_format',
28 array(
29 'sanitize_callback' => 'webp_uploads_sanitize_image_format',
30 'type' => 'string',
31 'default' => 'avif', // AVIF is the default if the editor supports it.
32 'show_in_rest' => false,
33 )
34 );
35
36 register_setting(
37 'media',
38 'perflab_generate_webp_and_jpeg',
39 array(
40 'type' => 'boolean',
41 'default' => current_theme_supports( 'html5', 'picture' ), // If picture element is supported by the theme, default to enabling the JPEG fallback.
42 'show_in_rest' => false,
43 )
44 );
45
46 // Add a setting to generate fallback images in all sizes including custom sizes.
47 register_setting(
48 'media',
49 'perflab_generate_all_fallback_sizes',
50 array(
51 'type' => 'boolean',
52 'default' => false,
53 'show_in_rest' => false,
54 )
55 );
56
57 // Add a setting to use the picture element.
58 register_setting(
59 'media',
60 'webp_uploads_use_picture_element',
61 array(
62 'type' => 'boolean',
63 // Use picture element by default if the theme declares support for it.
64 'default' => current_theme_supports( 'html5', 'picture' ), // Use picture element by default if the theme declares support for it.
65 'show_in_rest' => false,
66 )
67 );
68 }
69 add_action( 'init', 'webp_uploads_register_media_settings_field' );
70
71 /**
72 * Adds media settings field for the 'perflab_generate_webp_and_jpeg' setting.
73 *
74 * @since 1.0.0
75 */
76 function webp_uploads_add_media_settings_fields(): void {
77 add_settings_section(
78 'perflab_modern_image_format_settings',
79 _x( 'Modern Image Formats', 'settings page section name', 'webp-uploads' ),
80 '__return_empty_string',
81 'media',
82 array(
83 'before_section' => '<div id="modern-image-formats">',
84 'after_section' => '</div>',
85 )
86 );
87
88 // Add a dropdown to select the output format between AVIF and WebP output.
89 add_settings_field(
90 'perflab_modern_image_format',
91 __( 'Image output format', 'webp-uploads' ),
92 'webp_uploads_generate_avif_webp_setting_callback',
93 'media',
94 'perflab_modern_image_format_settings',
95 array( 'class' => 'perflab-generate-avif-and-webp' )
96 );
97
98 // Only add the remaining settings fields if at least one modern image format is supported.
99 if ( ! webp_uploads_mime_type_supported( 'image/avif' ) && ! webp_uploads_mime_type_supported( 'image/webp' ) ) {
100 return;
101 }
102
103 // Add fallback image output settings field.
104 add_settings_field(
105 'perflab_generate_webp_and_jpeg',
106 __( 'Output fallback images', 'webp-uploads' ),
107 'webp_uploads_generate_webp_jpeg_setting_callback',
108 'media',
109 'perflab_modern_image_format_settings',
110 array( 'class' => 'perflab-generate-webp-and-jpeg' )
111 );
112
113 // Add setting field for generating fallback images in all sizes including custom sizes.
114 add_settings_field(
115 'perflab_generate_all_fallback_sizes',
116 __( 'Generate all fallback image sizes', 'webp-uploads' ),
117 'webp_uploads_generate_all_fallback_sizes_callback',
118 'media',
119 'perflab_modern_image_format_settings',
120 array( 'class' => 'perflab-generate-fallback-all-sizes' )
121 );
122
123 // Add picture element support settings field.
124 add_settings_field(
125 'webp_uploads_use_picture_element',
126 __( 'Picture element', 'webp-uploads' ),
127 'webp_uploads_use_picture_element_callback',
128 'media',
129 'perflab_modern_image_format_settings',
130 array( 'class' => 'webp-uploads-use-picture-element' )
131 );
132 }
133 add_action( 'admin_init', 'webp_uploads_add_media_settings_fields' );
134
135 /**
136 * Renders the settings field for the 'perflab_modern_image_format' setting.
137 *
138 * @since 2.0.0
139 */
140 function webp_uploads_generate_avif_webp_setting_callback(): void {
141
142 $selected = webp_uploads_get_image_output_format();
143 $avif_supported = webp_uploads_mime_type_supported( 'image/avif' );
144 $webp_supported = webp_uploads_mime_type_supported( 'image/webp' );
145
146 // If neither format is support, the entire field is not shown.
147 if ( ! $avif_supported && ! $webp_supported ) {
148 ?>
149 <br />
150 <div class="notice notice-warning inline">
151 <p><b><?php esc_html_e( 'Modern image support is not available.', 'webp-uploads' ); ?></b></p>
152 <p><?php esc_html_e( 'WebP or AVIF support can only be enabled by your hosting provider, so contact them for more information.', 'webp-uploads' ); ?></p>
153 </div>
154 <?php
155 return;
156 }
157
158 // If only one of the two formats is supported, the dropdown defaults to that type and the other type is disabled.
159 if ( ! $avif_supported && 'avif' === $selected ) {
160 $selected = 'webp';
161 } elseif ( ! $webp_supported && 'webp' === $selected ) {
162 $selected = 'avif';
163 }
164 ?>
165 <select name="perflab_modern_image_format" id="perflab_modern_image_format" aria-describedby="perflab_modern_image_format_description">
166 <option value="webp"<?php selected( 'webp', $selected ); ?><?php disabled( ! $webp_supported ); ?>><?php esc_html_e( 'WebP', 'webp-uploads' ); ?></option>
167 <option value="avif"<?php selected( 'avif', $selected ); ?><?php disabled( ! $avif_supported ); ?>><?php esc_html_e( 'AVIF', 'webp-uploads' ); ?></option>
168 </select>
169 <label for="perflab_modern_image_format">
170 <?php esc_html_e( 'Generate images in this format', 'webp-uploads' ); ?>
171 </label>
172 <p class="description" id="perflab_modern_image_format_description"><?php esc_html_e( 'Select the format to use when generating new images from uploaded images.', 'webp-uploads' ); ?></p>
173 <?php if ( ! $avif_supported ) : ?>
174 <br />
175 <div class="notice notice-warning inline">
176 <p><b><?php esc_html_e( 'AVIF support is not available.', 'webp-uploads' ); ?></b></p>
177 <p><?php esc_html_e( 'AVIF support can only be enabled by your hosting provider, so contact them for more information.', 'webp-uploads' ); ?></p>
178 </div>
179 <?php endif; ?>
180 <?php if ( ! $webp_supported ) : ?>
181 <br />
182 <div class="notice notice-warning inline">
183 <p><b><?php esc_html_e( 'WebP support is not available.', 'webp-uploads' ); ?></b></p>
184 <p><?php esc_html_e( 'WebP support can only be enabled by your hosting provider, so contact them for more information.', 'webp-uploads' ); ?></p>
185 </div>
186 <?php endif; ?>
187 <?php
188 }
189
190 /**
191 * Renders the settings field for the 'perflab_generate_webp_and_jpeg' setting.
192 *
193 * @since 1.0.0
194 */
195 function webp_uploads_generate_webp_jpeg_setting_callback(): void {
196 ?>
197 <label for="perflab_generate_webp_and_jpeg">
198 <input name="perflab_generate_webp_and_jpeg" type="checkbox" id="perflab_generate_webp_and_jpeg" aria-describedby="perflab_generate_webp_and_jpeg_description" value="1"<?php checked( '1', get_option( 'perflab_generate_webp_and_jpeg' ) ); ?> />
199 <?php esc_html_e( 'Also generate fallback images in the original upload format', 'webp-uploads' ); ?>
200 </label>
201 <p class="description" id="perflab_generate_webp_and_jpeg_description"><?php esc_html_e( 'Enabling fallback image output can improve compatibility, but will increase the filesystem storage use of your images.', 'webp-uploads' ); ?></p>
202 <?php
203 }
204
205
206 /**
207 * Renders the settings field for generating all fallback image sizes.
208 *
209 * @since 2.4.0
210 */
211 function webp_uploads_generate_all_fallback_sizes_callback(): void {
212 $all_fallback_sizes_enabled = webp_uploads_should_generate_all_fallback_sizes();
213 $fallback_enabled = webp_uploads_is_fallback_enabled();
214 $all_fallback_sizes_hidden_id = 'perflab_generate_all_fallback_sizes_hidden';
215
216 ?>
217 <style>
218 #perflab_generate_all_fallback_sizes_fieldset.disabled label,
219 #perflab_generate_all_fallback_sizes_fieldset.disabled p {
220 opacity: 0.7;
221 }
222 </style>
223 <div id="perflab_generate_all_fallback_sizes_notice" class="notice notice-info inline" <?php echo $fallback_enabled ? 'hidden' : ''; ?>>
224 <p><?php esc_html_e( 'This setting requires fallback image output to be enabled.', 'webp-uploads' ); ?></p>
225 </div>
226 <div id="perflab_generate_all_fallback_sizes_fieldset" class="<?php echo ! $fallback_enabled ? 'disabled' : ''; ?>">
227 <label for="perflab_generate_all_fallback_sizes" id="perflab_generate_all_fallback_sizes_label">
228 <input
229 type="checkbox"
230 id="perflab_generate_all_fallback_sizes"
231 name="perflab_generate_all_fallback_sizes"
232 aria-describedby="perflab_generate_all_fallback_sizes_description"
233 value="1"
234 <?php checked( $all_fallback_sizes_enabled ); ?>
235 <?php disabled( ! $fallback_enabled ); ?>
236 >
237 <?php
238 /*
239 * If the checkbox is disabled, but the option is enabled, include a hidden input to continue sending the
240 * same value upon form submission.
241 */
242 if ( ! $fallback_enabled && $all_fallback_sizes_enabled ) {
243 ?>
244 <input
245 type="hidden"
246 id="<?php echo esc_attr( $all_fallback_sizes_hidden_id ); ?>"
247 name="perflab_generate_all_fallback_sizes"
248 value="1"
249 >
250 <?php
251 }
252 esc_html_e( 'Generate all fallback image sizes including custom sizes', 'webp-uploads' );
253 ?>
254 </label>
255 <p class="description" id="perflab_generate_all_fallback_sizes_description"><?php esc_html_e( 'Enabling this option will generate all fallback image sizes including custom sizes. Note: uses even more storage space.', 'webp-uploads' ); ?></p>
256 </div>
257 <script>
258 ( function ( allFallbackSizesHiddenId ) {
259 const fallbackCheckbox = document.getElementById( 'perflab_generate_webp_and_jpeg' );
260 const allFallbackSizesCheckbox = document.getElementById( 'perflab_generate_all_fallback_sizes' );
261 const allFallbackSizesFieldset = document.getElementById( 'perflab_generate_all_fallback_sizes_fieldset' );
262 const allFallbackSizesNotice = document.getElementById( 'perflab_generate_all_fallback_sizes_notice' );
263
264 function toggleAllFallbackSizes() {
265 const fallbackEnabled = fallbackCheckbox.checked;
266 allFallbackSizesFieldset.classList.toggle( 'disabled', ! fallbackEnabled );
267 allFallbackSizesCheckbox.disabled = ! fallbackEnabled;
268 allFallbackSizesNotice.hidden = fallbackEnabled;
269
270 // Remove or inject hidden input to preserve original setting value as needed.
271 if ( fallbackEnabled ) {
272 const hiddenInput = document.getElementById( allFallbackSizesHiddenId );
273 if ( hiddenInput ) {
274 hiddenInput.parentElement.removeChild( hiddenInput );
275 }
276 } else if ( allFallbackSizesCheckbox.checked && ! document.getElementById( allFallbackSizesHiddenId ) ) {
277 // The hidden input is only needed if the value was originally set (i.e., the checkbox enabled).
278 const hiddenInput = document.createElement( 'input' );
279 hiddenInput.type = 'hidden';
280 hiddenInput.id = allFallbackSizesHiddenId;
281 hiddenInput.name = allFallbackSizesCheckbox.name;
282 hiddenInput.value = allFallbackSizesCheckbox.value;
283 allFallbackSizesCheckbox.parentElement.insertBefore( hiddenInput, allFallbackSizesCheckbox.nextSibling );
284 }
285 }
286
287 fallbackCheckbox.addEventListener( 'change', toggleAllFallbackSizes );
288 } )( <?php echo wp_json_encode( $all_fallback_sizes_hidden_id ); ?> );
289 </script>
290 <?php
291 }
292
293 /**
294 * Renders the settings field for the 'webp_uploads_use_picture_element' setting.
295 *
296 * @since 2.0.0
297 */
298 function webp_uploads_use_picture_element_callback(): void {
299 // Picture element support requires the JPEG output to be enabled.
300 $picture_element_option = 1 === (int) get_option( 'webp_uploads_use_picture_element', 0 );
301 $jpeg_fallback_enabled = webp_uploads_is_fallback_enabled();
302 $picture_element_hidden_id = 'webp_uploads_use_picture_element_hidden';
303 ?>
304 <style>
305 #webp_uploads_picture_element_fieldset.disabled label,
306 #webp_uploads_picture_element_fieldset.disabled p {
307 opacity: 0.7;
308 }
309 </style>
310 <div id="webp_uploads_picture_element_notice" class="notice notice-info inline" <?php echo $jpeg_fallback_enabled ? 'hidden' : ''; ?>>
311 <p><?php esc_html_e( 'This setting requires fallback image output to be enabled.', 'webp-uploads' ); ?></p>
312 </div>
313 <div id="webp_uploads_picture_element_fieldset" class="<?php echo ! $jpeg_fallback_enabled ? 'disabled' : ''; ?>">
314 <label for="webp_uploads_use_picture_element" id="webp_uploads_use_picture_element_label">
315 <input
316 type="checkbox"
317 id="webp_uploads_use_picture_element"
318 name="webp_uploads_use_picture_element"
319 aria-describedby="webp_uploads_use_picture_element_description"
320 value="1"
321 <?php checked( $picture_element_option ); // Option intentionally used instead of webp_uploads_is_picture_element_enabled() to persist when perflab_generate_webp_and_jpeg is updated. ?>
322 <?php disabled( ! $jpeg_fallback_enabled ); ?>
323 >
324 <?php
325 /*
326 * If the checkbox is disabled, but the option is enabled, include a hidden input to continue sending the
327 * same value upon form submission.
328 */
329 if ( ! $jpeg_fallback_enabled && $picture_element_option ) {
330 ?>
331 <input
332 type="hidden"
333 id="<?php echo esc_attr( $picture_element_hidden_id ); ?>"
334 name="webp_uploads_use_picture_element"
335 value="1"
336 >
337 <?php
338 }
339 esc_html_e( 'Use <picture> Element', 'webp-uploads' );
340 ?>
341 <em><?php esc_html_e( '(experimental)', 'webp-uploads' ); ?></em>
342 </label>
343 <p class="description" id="webp_uploads_use_picture_element_description"><?php esc_html_e( 'The picture element serves a modern image format with a fallback to the original upload format. Warning: Make sure you test your theme and plugins for compatibility. In particular, CSS selectors will not match images when using the child combinator (e.g. figure > img).', 'webp-uploads' ); ?></p>
344 <div id="webp_uploads_jpeg_fallback_notice" class="notice notice-info inline" <?php echo $picture_element_option ? '' : 'hidden'; ?>>
345 <p><?php esc_html_e( 'Picture elements will only be used when fallback images are available. So this will only apply to images you have uploaded while the "Also generate fallback images" setting was enabled.', 'webp-uploads' ); ?></p>
346 </div>
347 </div>
348 <script>
349 ( function ( pictureElementHiddenId ) {
350 document.getElementById( 'webp_uploads_use_picture_element' ).addEventListener( 'change', function () {
351 document.getElementById( 'webp_uploads_jpeg_fallback_notice' ).hidden = ! this.checked;
352 } );
353
354 // Listen for clicks on the fallback output checkbox, enabling/disabling the
355 // picture element checkbox accordingly.
356 document.getElementById( 'perflab_generate_webp_and_jpeg' ).addEventListener( 'change', function () {
357 document.querySelector( '.webp-uploads-use-picture-element' ).classList.toggle( 'webp-uploads-disabled', ! this.checked );
358 document.getElementById( 'webp_uploads_picture_element_notice' ).hidden = this.checked;
359 document.getElementById( 'webp_uploads_picture_element_fieldset' ).classList.toggle( 'disabled', ! this.checked );
360
361 const checkbox = document.getElementById( 'webp_uploads_use_picture_element' );
362 checkbox.disabled = ! this.checked;
363
364 // Remove or inject hidden input to preserve original setting value as needed.
365 if ( this.checked ) {
366 const hiddenInput = document.getElementById( pictureElementHiddenId );
367 if ( hiddenInput ) {
368 hiddenInput.parentElement.removeChild( hiddenInput );
369 }
370 } else if ( checkbox.checked && ! document.getElementById( pictureElementHiddenId ) ) {
371 // The hidden input is only needed if the value was originally set (i.e. the checkbox enabled).
372 const hiddenInput = document.createElement( 'input' );
373 hiddenInput.type = 'hidden';
374 hiddenInput.id = pictureElementHiddenId;
375 hiddenInput.name = checkbox.name;
376 hiddenInput.value = checkbox.value;
377 checkbox.parentElement.insertBefore( hiddenInput, checkbox.nextSibling );
378 }
379 } );
380 } )( <?php echo wp_json_encode( $picture_element_hidden_id ); ?> );
381 </script>
382 <?php
383 }
384
385 /**
386 * Adds a settings link to the plugin's action links.
387 *
388 * @since 1.1.0
389 * @since 1.1.1 Renamed from webp_uploads_settings_link() to webp_uploads_add_settings_action_link()
390 *
391 * @param string[]|mixed $links An array of plugin action links.
392 * @return string[]|mixed The modified list of actions.
393 */
394 function webp_uploads_add_settings_action_link( $links ) {
395 if ( ! is_array( $links ) ) {
396 return $links;
397 }
398
399 $settings_link = sprintf(
400 '<a href="%1$s">%2$s</a>',
401 esc_url( admin_url( 'options-media.php#modern-image-formats' ) ),
402 esc_html__( 'Settings', 'webp-uploads' )
403 );
404
405 return array_merge(
406 array( 'settings' => $settings_link ),
407 $links
408 );
409 }
410 add_filter( 'plugin_action_links_' . WEBP_UPLOADS_MAIN_FILE, 'webp_uploads_add_settings_action_link' );
411