PluginProbe ʕ •ᴥ•ʔ
Modern Image Formats / 2.1.0
Modern Image Formats v2.1.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 2 years ago
settings.php
299 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 // Add a setting to use the picture element.
44 register_setting(
45 'media',
46 'webp_uploads_use_picture_element',
47 array(
48 'type' => 'boolean',
49 // Use picture element by default if the theme declares support for it.
50 'default' => current_theme_supports( 'html5', 'picture' ), // Use picture element by default if the theme declares support for it.
51 'show_in_rest' => false,
52 )
53 );
54 }
55 add_action( 'init', 'webp_uploads_register_media_settings_field' );
56
57 /**
58 * Adds media settings field for the 'perflab_generate_webp_and_jpeg' setting.
59 *
60 * @since 1.0.0
61 */
62 function webp_uploads_add_media_settings_fields(): void {
63 add_settings_section(
64 'perflab_modern_image_format_settings',
65 _x( 'Modern Image Formats', 'settings page section name', 'webp-uploads' ),
66 '__return_empty_string',
67 'media',
68 array(
69 'before_section' => '<div id="modern-image-formats">',
70 'after_section' => '</div>',
71 )
72 );
73
74 // Add a dropdown to select the output format between AVIF and WebP output.
75 add_settings_field(
76 'perflab_modern_image_format',
77 __( 'Image output format', 'webp-uploads' ),
78 'webp_uploads_generate_avif_webp_setting_callback',
79 'media',
80 'perflab_modern_image_format_settings',
81 array( 'class' => 'perflab-generate-avif-and-webp' )
82 );
83
84 // Only add the remaining settings fields if at least one modern image format is supported.
85 if ( ! webp_uploads_mime_type_supported( 'image/avif' ) && ! webp_uploads_mime_type_supported( 'image/webp' ) ) {
86 return;
87 }
88
89 // Add JPEG Output settings field.
90 add_settings_field(
91 'perflab_generate_webp_and_jpeg',
92 __( 'Also output JPEG', 'webp-uploads' ),
93 'webp_uploads_generate_webp_jpeg_setting_callback',
94 'media',
95 'perflab_modern_image_format_settings',
96 array( 'class' => 'perflab-generate-webp-and-jpeg' )
97 );
98
99 // Add picture element support settings field.
100 add_settings_field(
101 'webp_uploads_use_picture_element',
102 __( 'Picture element', 'webp-uploads' ),
103 'webp_uploads_use_picture_element_callback',
104 'media',
105 'perflab_modern_image_format_settings',
106 array( 'class' => 'webp-uploads-use-picture-element' )
107 );
108 }
109 add_action( 'admin_init', 'webp_uploads_add_media_settings_fields' );
110
111 /**
112 * Renders the settings field for the 'perflab_modern_image_format' setting.
113 *
114 * @since 2.0.0
115 */
116 function webp_uploads_generate_avif_webp_setting_callback(): void {
117
118 $selected = webp_uploads_get_image_output_format();
119 $avif_supported = webp_uploads_mime_type_supported( 'image/avif' );
120 $webp_supported = webp_uploads_mime_type_supported( 'image/webp' );
121
122 // If neither format is support, the entire field is not shown.
123 if ( ! $avif_supported && ! $webp_supported ) {
124 ?>
125 <br />
126 <div class="notice notice-warning inline">
127 <p><b><?php esc_html_e( 'Modern image support is not available.', 'webp-uploads' ); ?></b></p>
128 <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>
129 </div>
130 <?php
131 return;
132 }
133
134 // If only one of the two formats is supported, the dropdown defaults to that type and the other type is disabled.
135 if ( ! $avif_supported && 'avif' === $selected ) {
136 $selected = 'webp';
137 } elseif ( ! $webp_supported && 'webp' === $selected ) {
138 $selected = 'avif';
139 }
140 ?>
141 <select name="perflab_modern_image_format" id="perflab_modern_image_format" aria-describedby="perflab_modern_image_format_description">
142 <option value="webp"<?php selected( 'webp', $selected ); ?><?php disabled( ! $webp_supported ); ?>><?php esc_html_e( 'WebP', 'webp-uploads' ); ?></option>
143 <option value="avif"<?php selected( 'avif', $selected ); ?><?php disabled( ! $avif_supported ); ?>><?php esc_html_e( 'AVIF', 'webp-uploads' ); ?></option>
144 </select>
145 <label for="perflab_modern_image_format">
146 <?php esc_html_e( 'Generate images in this format', 'webp-uploads' ); ?>
147 </label>
148 <p class="description" id="perflab_modern_image_format_description"><?php esc_html_e( 'Select the format to use when generating new images from uploaded JPEGs.', 'webp-uploads' ); ?></p>
149 <?php if ( ! $avif_supported ) : ?>
150 <br />
151 <div class="notice notice-warning inline">
152 <p><b><?php esc_html_e( 'AVIF support is not available.', 'webp-uploads' ); ?></b></p>
153 <p><?php esc_html_e( 'AVIF support can only be enabled by your hosting provider, so contact them for more information.', 'webp-uploads' ); ?></p>
154 </div>
155 <?php endif; ?>
156 <?php if ( ! $webp_supported ) : ?>
157 <br />
158 <div class="notice notice-warning inline">
159 <p><b><?php esc_html_e( 'WebP support is not available.', 'webp-uploads' ); ?></b></p>
160 <p><?php esc_html_e( 'WebP support can only be enabled by your hosting provider, so contact them for more information.', 'webp-uploads' ); ?></p>
161 </div>
162 <?php endif; ?>
163 <?php
164 }
165
166 /**
167 * Renders the settings field for the 'perflab_generate_webp_and_jpeg' setting.
168 *
169 * @since 1.0.0
170 */
171 function webp_uploads_generate_webp_jpeg_setting_callback(): void {
172 ?>
173 <label for="perflab_generate_webp_and_jpeg">
174 <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' ) ); ?> />
175 <?php esc_html_e( 'Output JPEG images in addition to the modern format', 'webp-uploads' ); ?>
176 </label>
177 <p class="description" id="perflab_generate_webp_and_jpeg_description"><?php esc_html_e( 'Enabling JPEG output can improve compatibility, but will increase the filesystem storage use of your images.', 'webp-uploads' ); ?></p>
178 <?php
179 }
180
181 /**
182 * Renders the settings field for the 'webp_uploads_use_picture_element' setting.
183 *
184 * @since 2.0.0
185 */
186 function webp_uploads_use_picture_element_callback(): void {
187 // Picture element support requires the JPEG output to be enabled.
188 $picture_element_option = 1 === (int) get_option( 'webp_uploads_use_picture_element', 0 );
189 $jpeg_fallback_enabled = webp_uploads_is_jpeg_fallback_enabled();
190 $picture_element_hidden_id = 'webp_uploads_use_picture_element_hidden';
191 ?>
192 <style>
193 #webp_uploads_picture_element_fieldset.disabled label,
194 #webp_uploads_picture_element_fieldset.disabled p {
195 opacity: 0.7;
196 }
197 </style>
198 <div id="webp_uploads_picture_element_notice" class="notice notice-info inline" <?php echo $jpeg_fallback_enabled ? 'hidden' : ''; ?>>
199 <p><?php esc_html_e( 'This setting requires JPEG also be output as a fallback option.', 'webp-uploads' ); ?></p>
200 </div>
201 <div id="webp_uploads_picture_element_fieldset" class="<?php echo ! $jpeg_fallback_enabled ? 'disabled' : ''; ?>">
202 <label for="webp_uploads_use_picture_element" id="webp_uploads_use_picture_element_label">
203 <input
204 type="checkbox"
205 id="webp_uploads_use_picture_element"
206 name="webp_uploads_use_picture_element"
207 aria-describedby="webp_uploads_use_picture_element_description"
208 value="1"
209 <?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. ?>
210 <?php disabled( ! $jpeg_fallback_enabled ); ?>
211 >
212 <?php
213 /*
214 * If the checkbox is disabled, but the option is enabled, include a hidden input to continue sending the
215 * same value upon form submission.
216 */
217 if ( ! $jpeg_fallback_enabled && $picture_element_option ) {
218 ?>
219 <input
220 type="hidden"
221 id="<?php echo esc_attr( $picture_element_hidden_id ); ?>"
222 name="webp_uploads_use_picture_element"
223 value="1"
224 >
225 <?php
226 }
227 esc_html_e( 'Use <picture> Element', 'webp-uploads' );
228 ?>
229 <em><?php esc_html_e( '(experimental)', 'webp-uploads' ); ?></em>
230 </label>
231 <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 JPEG. 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>
232 <div id="webp_uploads_jpeg_fallback_notice" class="notice notice-info inline" <?php echo $picture_element_option ? '' : 'hidden'; ?>>
233 <p><?php esc_html_e( 'Picture elements will only be used when JPEG fallback images are available. So this will not apply to any images you may have uploaded while the "Also generate JPEG" setting was disabled.', 'webp-uploads' ); ?></p>
234 </div>
235 </div>
236 <script>
237 ( function ( pictureElementHiddenId ) {
238 document.getElementById( 'webp_uploads_use_picture_element' ).addEventListener( 'change', function () {
239 document.getElementById( 'webp_uploads_jpeg_fallback_notice' ).hidden = ! this.checked;
240 } );
241
242 // Listen for clicks on the JPEG output checkbox, enabling/disabling the
243 // picture element checkbox accordingly.
244 document.getElementById( 'perflab_generate_webp_and_jpeg' ).addEventListener( 'change', function () {
245 document.querySelector( '.webp-uploads-use-picture-element' ).classList.toggle( 'webp-uploads-disabled', ! this.checked );
246 document.getElementById( 'webp_uploads_picture_element_notice' ).hidden = this.checked;
247 document.getElementById( 'webp_uploads_picture_element_fieldset' ).classList.toggle( 'disabled', ! this.checked );
248
249 const checkbox = document.getElementById( 'webp_uploads_use_picture_element' );
250 checkbox.disabled = ! this.checked;
251
252 // Remove or inject hidden input to preserve original setting value as needed.
253 if ( this.checked ) {
254 const hiddenInput = document.getElementById( pictureElementHiddenId );
255 if ( hiddenInput ) {
256 hiddenInput.parentElement.removeChild( hiddenInput );
257 }
258 } else if ( checkbox.checked && ! document.getElementById( pictureElementHiddenId ) ) {
259 // The hidden input is only needed if the value was originally set (i.e. the checkbox enabled).
260 const hiddenInput = document.createElement( 'input' );
261 hiddenInput.type = 'hidden';
262 hiddenInput.id = pictureElementHiddenId;
263 hiddenInput.name = checkbox.name;
264 hiddenInput.value = checkbox.value;
265 checkbox.parentElement.insertBefore( hiddenInput, checkbox.nextSibling );
266 }
267 } );
268 } )( <?php echo wp_json_encode( $picture_element_hidden_id ); ?> );
269 </script>
270 <?php
271 }
272
273 /**
274 * Adds a settings link to the plugin's action links.
275 *
276 * @since 1.1.0
277 * @since 1.1.1 Renamed from webp_uploads_settings_link() to webp_uploads_add_settings_action_link()
278 *
279 * @param string[]|mixed $links An array of plugin action links.
280 * @return string[]|mixed The modified list of actions.
281 */
282 function webp_uploads_add_settings_action_link( $links ) {
283 if ( ! is_array( $links ) ) {
284 return $links;
285 }
286
287 $settings_link = sprintf(
288 '<a href="%1$s">%2$s</a>',
289 esc_url( admin_url( 'options-media.php#modern-image-formats' ) ),
290 esc_html__( 'Settings', 'webp-uploads' )
291 );
292
293 return array_merge(
294 array( 'settings' => $settings_link ),
295 $links
296 );
297 }
298 add_filter( 'plugin_action_links_' . WEBP_UPLOADS_MAIN_FILE, 'webp_uploads_add_settings_action_link' );
299