Skip to content

Commit 20a45a3

Browse files
Merge pull request #1689 from b1ink0/add/option-to-generate-all-image-sizes
Enable end user opt-in to generate all sizes in fallback format
2 parents 3c5dd7f + 10e0c39 commit 20a45a3

File tree

5 files changed

+185
-0
lines changed

5 files changed

+185
-0
lines changed

plugins/webp-uploads/helper.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,17 @@ function webp_uploads_is_fallback_enabled(): bool {
411411
return (bool) get_option( 'perflab_generate_webp_and_jpeg' );
412412
}
413413

414+
/**
415+
* Checks if the `perflab_generate_all_fallback_sizes` option is enabled.
416+
*
417+
* @since n.e.x.t
418+
*
419+
* @return bool Whether the option is enabled. Default is false.
420+
*/
421+
function webp_uploads_should_generate_all_fallback_sizes(): bool {
422+
return (bool) get_option( 'perflab_generate_all_fallback_sizes', 0 );
423+
}
424+
414425
/**
415426
* Retrieves the image URL for a specified MIME type from the attachment metadata.
416427
*

plugins/webp-uploads/hooks.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,3 +806,24 @@ function webp_uploads_opt_in_extra_image_sizes(): void {
806806
}
807807
}
808808
add_action( 'plugins_loaded', 'webp_uploads_opt_in_extra_image_sizes' );
809+
810+
/**
811+
* Enables additional MIME type support for all image sizes based on the generate all fallback sizes settings.
812+
*
813+
* @since n.e.x.t
814+
*
815+
* @param array<string, bool> $allowed_sizes A map of image size names and whether they are allowed to have additional MIME types.
816+
* @return array<string, bool> Modified map of image sizes with additional MIME type support.
817+
*/
818+
function webp_uploads_enable_additional_mime_type_support_for_all_sizes( array $allowed_sizes ): array {
819+
if ( ! webp_uploads_should_generate_all_fallback_sizes() ) {
820+
return $allowed_sizes;
821+
}
822+
823+
foreach ( array_keys( $allowed_sizes ) as $size ) {
824+
$allowed_sizes[ $size ] = true;
825+
}
826+
827+
return $allowed_sizes;
828+
}
829+
add_filter( 'webp_uploads_image_sizes_with_additional_mime_type_support', 'webp_uploads_enable_additional_mime_type_support_for_all_sizes' );

plugins/webp-uploads/settings.php

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,18 @@ function webp_uploads_register_media_settings_field(): void {
4040
'show_in_rest' => false,
4141
)
4242
);
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+
4355
// Add a setting to use the picture element.
4456
register_setting(
4557
'media',
@@ -96,6 +108,16 @@ function webp_uploads_add_media_settings_fields(): void {
96108
array( 'class' => 'perflab-generate-webp-and-jpeg' )
97109
);
98110

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+
99121
// Add picture element support settings field.
100122
add_settings_field(
101123
'webp_uploads_use_picture_element',
@@ -178,6 +200,94 @@ function webp_uploads_generate_webp_jpeg_setting_callback(): void {
178200
<?php
179201
}
180202

203+
204+
/**
205+
* Renders the settings field for generating all fallback image sizes.
206+
*
207+
* @since n.e.x.t
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+
181291
/**
182292
* Renders the settings field for the 'webp_uploads_use_picture_element' setting.
183293
*

plugins/webp-uploads/tests/test-load.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,4 +1045,46 @@ public function temp_filename(): string {
10451045

10461046
return $filename;
10471047
}
1048+
1049+
/**
1050+
* Test that fallback images are generated for all sizes when the `perflab_generate_all_fallback_sizes` option is enabled.
1051+
*
1052+
* @dataProvider data_provider_supported_image_types
1053+
*
1054+
* @param string $image_type The image type.
1055+
*/
1056+
public function test_it_should_generate_fallback_images_for_all_sizes_when_generate_all_fallback_sizes_option_is_enabled( string $image_type ): void {
1057+
$mime_type = 'image/' . $image_type;
1058+
1059+
// Ensure the MIME type is supported; skip the test if not.
1060+
if ( ! webp_uploads_mime_type_supported( $mime_type ) ) {
1061+
$this->markTestSkipped( 'Mime type ' . $mime_type . ' is not supported.' );
1062+
}
1063+
1064+
// Register custom image sizes.
1065+
add_image_size( 'custom_size_1', 200, 200, true );
1066+
add_image_size( 'custom_size_2', 400, 400, true );
1067+
1068+
// Generate image output type and fallback image.
1069+
update_option( 'perflab_generate_webp_and_jpeg', true );
1070+
1071+
// Generate fallback images for all sizes.
1072+
update_option( 'perflab_generate_all_fallback_sizes', true );
1073+
1074+
$this->set_image_output_type( $image_type );
1075+
1076+
$attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/data/images/leaves.jpg' );
1077+
1078+
// Clean up custom sizes.
1079+
remove_image_size( 'custom_size_1' );
1080+
remove_image_size( 'custom_size_2' );
1081+
1082+
// Verify that fallback images are generated for custom sizes.
1083+
foreach ( array( 'custom_size_1', 'custom_size_2' ) as $size_name ) {
1084+
$this->assertImageHasSizeSource( $attachment_id, $size_name, 'image/jpeg' );
1085+
$this->assertImageHasSizeSource( $attachment_id, $size_name, $mime_type );
1086+
}
1087+
1088+
wp_delete_attachment( $attachment_id );
1089+
}
10481090
}

plugins/webp-uploads/uninstall.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,5 @@
3838
*/
3939
function webp_uploads_delete_plugin_option(): void {
4040
delete_option( 'perflab_generate_webp_and_jpeg' );
41+
delete_option( 'perflab_generate_all_fallback_sizes' );
4142
}

0 commit comments

Comments
 (0)