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