Skip to content

Commit

Permalink
Merge pull request #1689 from b1ink0/add/option-to-generate-all-image…
Browse files Browse the repository at this point in the history
…-sizes

Enable end user opt-in to generate all sizes in fallback format
  • Loading branch information
mukeshpanchal27 authored Dec 6, 2024
2 parents 3c5dd7f + 10e0c39 commit 20a45a3
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 0 deletions.
11 changes: 11 additions & 0 deletions plugins/webp-uploads/helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,17 @@ function webp_uploads_is_fallback_enabled(): bool {
return (bool) get_option( 'perflab_generate_webp_and_jpeg' );
}

/**
* Checks if the `perflab_generate_all_fallback_sizes` option is enabled.
*
* @since n.e.x.t
*
* @return bool Whether the option is enabled. Default is false.
*/
function webp_uploads_should_generate_all_fallback_sizes(): bool {
return (bool) get_option( 'perflab_generate_all_fallback_sizes', 0 );
}

/**
* Retrieves the image URL for a specified MIME type from the attachment metadata.
*
Expand Down
21 changes: 21 additions & 0 deletions plugins/webp-uploads/hooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -806,3 +806,24 @@ function webp_uploads_opt_in_extra_image_sizes(): void {
}
}
add_action( 'plugins_loaded', 'webp_uploads_opt_in_extra_image_sizes' );

/**
* Enables additional MIME type support for all image sizes based on the generate all fallback sizes settings.
*
* @since n.e.x.t
*
* @param array<string, bool> $allowed_sizes A map of image size names and whether they are allowed to have additional MIME types.
* @return array<string, bool> Modified map of image sizes with additional MIME type support.
*/
function webp_uploads_enable_additional_mime_type_support_for_all_sizes( array $allowed_sizes ): array {
if ( ! webp_uploads_should_generate_all_fallback_sizes() ) {
return $allowed_sizes;
}

foreach ( array_keys( $allowed_sizes ) as $size ) {
$allowed_sizes[ $size ] = true;
}

return $allowed_sizes;
}
add_filter( 'webp_uploads_image_sizes_with_additional_mime_type_support', 'webp_uploads_enable_additional_mime_type_support_for_all_sizes' );
110 changes: 110 additions & 0 deletions plugins/webp-uploads/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@ function webp_uploads_register_media_settings_field(): void {
'show_in_rest' => false,
)
);

// Add a setting to generate fallback images in all sizes including custom sizes.
register_setting(
'media',
'perflab_generate_all_fallback_sizes',
array(
'type' => 'boolean',
'default' => false,
'show_in_rest' => false,
)
);

// Add a setting to use the picture element.
register_setting(
'media',
Expand Down Expand Up @@ -96,6 +108,16 @@ function webp_uploads_add_media_settings_fields(): void {
array( 'class' => 'perflab-generate-webp-and-jpeg' )
);

// Add setting field for generating fallback images in all sizes including custom sizes.
add_settings_field(
'perflab_generate_all_fallback_sizes',
__( 'Generate all fallback image sizes', 'webp-uploads' ),
'webp_uploads_generate_all_fallback_sizes_callback',
'media',
'perflab_modern_image_format_settings',
array( 'class' => 'perflab-generate-fallback-all-sizes' )
);

// Add picture element support settings field.
add_settings_field(
'webp_uploads_use_picture_element',
Expand Down Expand Up @@ -178,6 +200,94 @@ function webp_uploads_generate_webp_jpeg_setting_callback(): void {
<?php
}


/**
* Renders the settings field for generating all fallback image sizes.
*
* @since n.e.x.t
*/
function webp_uploads_generate_all_fallback_sizes_callback(): void {
$all_fallback_sizes_enabled = webp_uploads_should_generate_all_fallback_sizes();
$fallback_enabled = webp_uploads_is_fallback_enabled();
$all_fallback_sizes_hidden_id = 'perflab_generate_all_fallback_sizes_hidden';

?>
<style>
#perflab_generate_all_fallback_sizes_fieldset.disabled label,
#perflab_generate_all_fallback_sizes_fieldset.disabled p {
opacity: 0.7;
}
</style>
<div id="perflab_generate_all_fallback_sizes_notice" class="notice notice-info inline" <?php echo $fallback_enabled ? 'hidden' : ''; ?>>
<p><?php esc_html_e( 'This setting requires fallback image output to be enabled.', 'webp-uploads' ); ?></p>
</div>
<div id="perflab_generate_all_fallback_sizes_fieldset" class="<?php echo ! $fallback_enabled ? 'disabled' : ''; ?>">
<label for="perflab_generate_all_fallback_sizes" id="perflab_generate_all_fallback_sizes_label">
<input
type="checkbox"
id="perflab_generate_all_fallback_sizes"
name="perflab_generate_all_fallback_sizes"
aria-describedby="perflab_generate_all_fallback_sizes_description"
value="1"
<?php checked( $all_fallback_sizes_enabled ); ?>
<?php disabled( ! $fallback_enabled ); ?>
>
<?php
/*
* If the checkbox is disabled, but the option is enabled, include a hidden input to continue sending the
* same value upon form submission.
*/
if ( ! $fallback_enabled && $all_fallback_sizes_enabled ) {
?>
<input
type="hidden"
id="<?php echo esc_attr( $all_fallback_sizes_hidden_id ); ?>"
name="perflab_generate_all_fallback_sizes"
value="1"
>
<?php
}
esc_html_e( 'Generate all fallback image sizes including custom sizes', 'webp-uploads' );
?>
</label>
<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>
</div>
<script>
( function ( allFallbackSizesHiddenId ) {
const fallbackCheckbox = document.getElementById( 'perflab_generate_webp_and_jpeg' );
const allFallbackSizesCheckbox = document.getElementById( 'perflab_generate_all_fallback_sizes' );
const allFallbackSizesFieldset = document.getElementById( 'perflab_generate_all_fallback_sizes_fieldset' );
const allFallbackSizesNotice = document.getElementById( 'perflab_generate_all_fallback_sizes_notice' );

function toggleAllFallbackSizes() {
const fallbackEnabled = fallbackCheckbox.checked;
allFallbackSizesFieldset.classList.toggle( 'disabled', ! fallbackEnabled );
allFallbackSizesCheckbox.disabled = ! fallbackEnabled;
allFallbackSizesNotice.hidden = fallbackEnabled;

// Remove or inject hidden input to preserve original setting value as needed.
if ( fallbackEnabled ) {
const hiddenInput = document.getElementById( allFallbackSizesHiddenId );
if ( hiddenInput ) {
hiddenInput.parentElement.removeChild( hiddenInput );
}
} else if ( allFallbackSizesCheckbox.checked && ! document.getElementById( allFallbackSizesHiddenId ) ) {
// The hidden input is only needed if the value was originally set (i.e., the checkbox enabled).
const hiddenInput = document.createElement( 'input' );
hiddenInput.type = 'hidden';
hiddenInput.id = allFallbackSizesHiddenId;
hiddenInput.name = allFallbackSizesCheckbox.name;
hiddenInput.value = allFallbackSizesCheckbox.value;
allFallbackSizesCheckbox.parentElement.insertBefore( hiddenInput, allFallbackSizesCheckbox.nextSibling );
}
}

fallbackCheckbox.addEventListener( 'change', toggleAllFallbackSizes );
} )( <?php echo wp_json_encode( $all_fallback_sizes_hidden_id ); ?> );
</script>
<?php
}

/**
* Renders the settings field for the 'webp_uploads_use_picture_element' setting.
*
Expand Down
42 changes: 42 additions & 0 deletions plugins/webp-uploads/tests/test-load.php
Original file line number Diff line number Diff line change
Expand Up @@ -1045,4 +1045,46 @@ public function temp_filename(): string {

return $filename;
}

/**
* Test that fallback images are generated for all sizes when the `perflab_generate_all_fallback_sizes` option is enabled.
*
* @dataProvider data_provider_supported_image_types
*
* @param string $image_type The image type.
*/
public function test_it_should_generate_fallback_images_for_all_sizes_when_generate_all_fallback_sizes_option_is_enabled( string $image_type ): void {
$mime_type = 'image/' . $image_type;

// Ensure the MIME type is supported; skip the test if not.
if ( ! webp_uploads_mime_type_supported( $mime_type ) ) {
$this->markTestSkipped( 'Mime type ' . $mime_type . ' is not supported.' );
}

// Register custom image sizes.
add_image_size( 'custom_size_1', 200, 200, true );
add_image_size( 'custom_size_2', 400, 400, true );

// Generate image output type and fallback image.
update_option( 'perflab_generate_webp_and_jpeg', true );

// Generate fallback images for all sizes.
update_option( 'perflab_generate_all_fallback_sizes', true );

$this->set_image_output_type( $image_type );

$attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/data/images/leaves.jpg' );

// Clean up custom sizes.
remove_image_size( 'custom_size_1' );
remove_image_size( 'custom_size_2' );

// Verify that fallback images are generated for custom sizes.
foreach ( array( 'custom_size_1', 'custom_size_2' ) as $size_name ) {
$this->assertImageHasSizeSource( $attachment_id, $size_name, 'image/jpeg' );
$this->assertImageHasSizeSource( $attachment_id, $size_name, $mime_type );
}

wp_delete_attachment( $attachment_id );
}
}
1 change: 1 addition & 0 deletions plugins/webp-uploads/uninstall.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,5 @@
*/
function webp_uploads_delete_plugin_option(): void {
delete_option( 'perflab_generate_webp_and_jpeg' );
delete_option( 'perflab_generate_all_fallback_sizes' );
}

0 comments on commit 20a45a3

Please sign in to comment.