Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Image Optimization: Configure .htaccess to Serve WebP Images When Available #42

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 55 additions & 52 deletions components/imageOptimizationSettings/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import { useState, useEffect } from '@wordpress/element';
import {
Alert,
Container,
ToggleField,
Button,
} from '@newfold/ui-component-library';
import { Alert, Container, ToggleField } from '@newfold/ui-component-library';

import defaultText from '../performance/defaultText';

Expand Down Expand Up @@ -69,6 +64,7 @@ const ImageOptimizationSettings = ( { methods } ) => {
updatedSettings.auto_optimized_uploaded_images.enabled = value;
updatedSettings.bulk_optimization = value;
updatedSettings.lazy_loading.enabled = value;
updatedSettings.prefer_optimized_image_when_exists = value;
break;

case 'autoOptimizeEnabled':
Expand All @@ -88,6 +84,10 @@ const ImageOptimizationSettings = ( { methods } ) => {
value;
break;

case 'preferOptimizedImageWhenExists':
updatedSettings.prefer_optimized_image_when_exists = value;
break;

default:
break;
}
Expand Down Expand Up @@ -135,6 +135,8 @@ const ImageOptimizationSettings = ( { methods } ) => {

const {
enabled,
prefer_optimized_image_when_exists:
preferOptimizedImageWhenExists = true,
auto_optimized_uploaded_images: autoOptimizedUploadedImages,
lazy_loading: lazyLoading = { enabled: true },
bulk_optimization: bulkOptimization = false,
Expand All @@ -145,6 +147,11 @@ const ImageOptimizationSettings = ( { methods } ) => {
auto_delete_original_image: autoDeleteOriginalImage,
} = autoOptimizedUploadedImages || {};

const mediaLibraryLink = () => {
const basePath = window.location.pathname.split( '/wp-admin' )[ 0 ];
return `${ window.location.origin }${ basePath }/wp-admin/upload.php`;
};

return (
<Container.SettingsField
title={ defaultText.imageOptimizationSettingsTitle }
Expand Down Expand Up @@ -180,25 +187,55 @@ const ImageOptimizationSettings = ( { methods } ) => {
/>

<ToggleField
id="auto-delete-original"
label={ defaultText.imageOptimizationAutoDeleteLabel }
id="bulk-optimize-images"
label={ defaultText.imageOptimizationBulkOptimizeLabel }
description={
<>
{
defaultText.imageOptimizationAutoDeleteDescription
}
<p
style={ {
color: 'red',
marginTop: '8px',
} }
>
<p>
{
defaultText.imageOptimizationAutoDeleteCaution
defaultText.imageOptimizationBulkOptimizeDescription
}
</p>
<a
href={ mediaLibraryLink() }
target="_blank"
rel="noopener noreferrer"
>
{
defaultText.imageOptimizationBulkOptimizeButtonLabel
}
</a>
</>
}
checked={ bulkOptimization }
onChange={ () =>
handleToggleChange( 'bulkOptimize', ! bulkOptimization )
}
disabled={ ! enabled }
/>

<ToggleField
id="prefer-webp-when-exists"
label={ defaultText.imageOptimizationPreferWebPLabel }
description={
defaultText.imageOptimizationPreferWebPDescription
}
checked={ preferOptimizedImageWhenExists }
onChange={ () =>
handleToggleChange(
'preferOptimizedImageWhenExists',
! preferOptimizedImageWhenExists
)
}
disabled={ ! enabled }
/>

<ToggleField
id="auto-delete-original"
label={ defaultText.imageOptimizationAutoDeleteLabel }
description={
defaultText.imageOptimizationAutoDeleteDescription
}
checked={ autoDeleteOriginalImage }
onChange={ () =>
handleToggleChange(
Expand Down Expand Up @@ -227,40 +264,6 @@ const ImageOptimizationSettings = ( { methods } ) => {
}
disabled={ ! enabled }
/>

<ToggleField
id="bulk-optimize-images"
label={ defaultText.imageOptimizationBulkOptimizeLabel }
description={
defaultText.imageOptimizationBulkOptimizeDescription
}
checked={ bulkOptimization }
onChange={ () =>
handleToggleChange( 'bulkOptimize', ! bulkOptimization )
}
disabled={ ! enabled }
/>

{ bulkOptimization && (
<div className="nfd-flex nfd-justify-end">
<Button
variant="primary"
size="small"
onClick={ () => {
const basePath =
window.location.pathname.split(
'/wp-admin'
)[ 0 ];
const adminUrl = `${ window.location.origin }${ basePath }/wp-admin/upload.php`;
window.open( adminUrl, '_blank' );
} }
>
{
defaultText.imageOptimizationBulkOptimizeButtonLabel
}
</Button>
</div>
) }
</div>
</Container.SettingsField>
);
Expand Down
12 changes: 8 additions & 4 deletions components/performance/defaultText.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,6 @@ const defaultText = {
'When enabled, the original uploaded image is deleted and replaced with the optimized version, helping to save storage space. If disabled, the optimized image is saved as a separate file, retaining the original.',
'wp-module-performance'
),
imageOptimizationAutoDeleteCaution: __(
'Caution: If the original image is being referenced elsewhere (e.g., in posts, pages, or custom templates), those references will break. You will need to manually update those references to use the optimized image.',
'wp-module-performance'
),
imageOptimizationNoSettings: __(
'No settings available.',
'wp-module-performance'
Expand Down Expand Up @@ -156,6 +152,14 @@ const defaultText = {
'Error Updating Settings',
'wp-module-performance'
),
imageOptimizationPreferWebPLabel: __(
'Prefer Optimized Image When Exists',
'wp-module-performance'
),
imageOptimizationPreferWebPDescription: __(
'When enabled, optimized images will be served in place of original images when they exist, improving performance.',
'wp-module-performance'
),
imageOptimizationGenericErrorMessage: __(
'Something went wrong while updating the settings. Please try again.',
'wp-module-performance'
Expand Down
56 changes: 42 additions & 14 deletions includes/Images/ImageManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,26 @@

namespace NewfoldLabs\WP\Module\Performance\Images;

use NewfoldLabs\WP\ModuleLoader\Container;
use NewfoldLabs\WP\Module\Performance\Permissions;
use NewfoldLabs\WP\Module\Performance\Images\RestApi\RestApi;
use NewfoldLabs\WP\Module\Performance\Images\ImageRewriteHandler;

/**
* Manages the initialization of image optimization settings and listeners.
*/
class ImageManager {

/**
* Constructor to initialize the ImageManager.
* It registers settings and conditionally initializes services.
*
* Registers settings and conditionally initializes related services.
*
* @param Container $container Dependency injection container.
*/
public function __construct() {
public function __construct( Container $container ) {
$this->initialize_settings();
$this->maybe_initialize_upload_listener();
$this->maybe_initialize_lazy_loader();
$this->maybe_initialize_bulk_optimizer();
$this->maybe_initialize_rest_api();
$this->maybe_initialize_marker();
$this->initialize_services( $container );
}

/**
Expand All @@ -30,17 +32,30 @@ private function initialize_settings() {
}

/**
* Conditionally initializes the ImageUploadListener based on the settings.
* Initializes conditional services based on settings and environment.
*
* @param Container $container Dependency injection container.
*/
private function initialize_services( Container $container ) {
$this->maybe_initialize_upload_listener();
$this->maybe_initialize_lazy_loader();
$this->maybe_initialize_bulk_optimizer();
$this->maybe_initialize_rest_api();
$this->maybe_initialize_marker();
$this->maybe_initialize_image_rewrite_handler( $container );
}

/**
* Initializes the ImageUploadListener if auto-optimization is enabled.
*/
private function maybe_initialize_upload_listener() {
if ( ImageSettings::is_optimization_enabled() && ImageSettings::is_auto_optimization_enabled() ) {
$auto_delete_original_image = ImageSettings::is_auto_delete_enabled();
new ImageUploadListener( $auto_delete_original_image );
new ImageUploadListener( ImageSettings::is_auto_delete_enabled() );
}
}

/**
* Conditionally initializes the LazyLoader based on settings.
* Initializes the LazyLoader if lazy loading is enabled.
*/
private function maybe_initialize_lazy_loader() {
if ( ImageSettings::is_optimization_enabled() && ImageSettings::is_lazy_loading_enabled() ) {
Expand All @@ -49,7 +64,7 @@ private function maybe_initialize_lazy_loader() {
}

/**
* Conditionally initializes the ImageBulkOptimizer only within `wp-admin`.
* Initializes the ImageBulkOptimizer if bulk optimization is enabled and user is an admin.
*/
private function maybe_initialize_bulk_optimizer() {
if ( Permissions::is_authorized_admin() && ImageSettings::is_bulk_optimization_enabled() ) {
Expand All @@ -58,7 +73,7 @@ private function maybe_initialize_bulk_optimizer() {
}

/**
* Conditionally initializes the REST API routes only when called via REST.
* Initializes the REST API routes if accessed via REST and user is an admin.
*/
private function maybe_initialize_rest_api() {
if ( Permissions::rest_is_authorized_admin() ) {
Expand All @@ -67,11 +82,24 @@ private function maybe_initialize_rest_api() {
}

/**
* Conditionally initializes the ImageOptimizedMarker if image optimization is enabled.
* Initializes the ImageOptimizedMarker if image optimization is enabled.
*/
private function maybe_initialize_marker() {
if ( ImageSettings::is_optimization_enabled() ) {
new ImageOptimizedMarker();
}
}

/**
* Initializes the ImageRewriteHandler for managing WebP redirects if the server is Apache.
*
* @param Container $container Dependency injection container.
*/
private function maybe_initialize_image_rewrite_handler( Container $container ) {
if ( Permissions::rest_is_authorized_admin()
&& $container->has( 'isApache' )
&& $container->get( 'isApache' ) ) {
new ImageRewriteHandler();
}
}
}
Loading
Loading