Skip to content
Merged

Release #1015

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
a832451
chore(deps): bump codeinwp/themeisle-sdk from 3.3.49 to 3.3.50
dependabot[bot] Dec 1, 2025
f4bf311
fix: compatibility with otter blocks background images defined in CSS…
abaicus Dec 4, 2025
26aa59f
enh: adds Hummingbird compatibility [ref Codeinwp/optimole-service#1595]
abaicus Dec 9, 2025
d3b896d
enh: adds Aruba Hispeed Cache compatibility [ref Codeinwp/optimole-se…
abaicus Dec 9, 2025
28f1b00
enh: adds Cache Enabler compatibility [ref Codeinwp/optimole-service#…
abaicus Dec 9, 2025
ae1492e
enh: adds Super Page Cache compatibility [ref Codeinwp/optimole-servi…
abaicus Dec 9, 2025
c3bb78e
enh: ensure single url cache is bust when a single path is invalidated
abaicus Dec 9, 2025
a1adc3e
chore: fix phpstan
abaicus Dec 10, 2025
9b26d49
enh: adds kadence blocks compatibility with bg lazyload [ref Codeinwp…
abaicus Dec 10, 2025
58898c6
enh: enhance elementor compatibility with bg lazyload [ref Codeinwp/o…
abaicus Dec 10, 2025
feabd69
enh: enhance Beaver Builder compatibility with bg lazyload [ref Codei…
abaicus Dec 10, 2025
e65ab25
enh: enhance Spectra compatibility with bg lazyload [ref Codeinwp/opt…
abaicus Dec 10, 2025
1b58ed9
enh: Essential Blocks plugin compatibility with bg lazyload [ref Code…
abaicus Dec 10, 2025
85d56e1
chore: fixes phpstan issues
abaicus Dec 11, 2025
e4c582d
chore: update visit limit notice text [closes Codeinwp/optimole-servi…
abaicus Dec 11, 2025
58789dc
chore: update view all stats link [closes Codeinwp/optimole-service#1…
abaicus Dec 11, 2025
b127fe8
fix: strings consistency & issues [closes Codeinwp/optimole-service#1…
abaicus Dec 11, 2025
1079168
chore: adds diff translations workflow
abaicus Dec 12, 2025
b6ac77b
Sync branch [skip ci]
pirate-bot Dec 12, 2025
716690c
Sync branch [skip ci]
pirate-bot Dec 12, 2025
ac927fb
chore: fix formatting issues
abaicus Dec 12, 2025
61bfd7b
fix: translation diff action docker commands
abaicus Dec 12, 2025
9b519fc
chore: remove spaces and redundant placeholders [ref Codeinwp/optimol…
abaicus Dec 12, 2025
188c9b8
chore: do not include make-pot task on build
abaicus Dec 12, 2025
fdf5b00
Merge pull request #1004 from Codeinwp/dependabot/composer/developmen…
abaicus Jan 8, 2026
26dfce9
Merge pull request #1009 from Codeinwp/fix/otter-css-bg-compat
abaicus Jan 8, 2026
fbba0ab
Merge pull request #1011 from Codeinwp/enh/cache-clear
abaicus Jan 8, 2026
5a02a7a
Merge pull request #1012 from Codeinwp/enh/bg-lazy-coverage
abaicus Jan 8, 2026
a0fef77
Merge pull request #1013 from Codeinwp/enh/translations-generic
abaicus Jan 8, 2026
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
53 changes: 53 additions & 0 deletions .github/workflows/diff-translations.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Translations Diff

on:
pull_request_review:
pull_request:
types: [opened, edited, synchronize, ready_for_review]
branches:
- development
- master

jobs:
translation:
runs-on: ubuntu-latest
steps:
- name: Checkout Base Branch
uses: actions/checkout@v4
with:
ref: ${{ github.base_ref }}
path: optimole-base
- name: Setup node 16
uses: actions/setup-node@v4
with:
node-version: 16.x
- name: Build POT for Base Branch
run: |
cd optimole-base
composer install --no-dev --prefer-dist --no-progress --no-suggest
npm ci
npm run build
# TODO: when is merged to master, switch to npm run make-pot
docker run --user root --rm --volume $(pwd):/var/www/html/optimole-wp wordpress:cli bash -c 'php -d memory_limit=512M $(which wp) --version --allow-root && wp i18n make-pot optimole-wp ./optimole-wp/languages/optimole-wp.pot --include=inc,assets/src --allow-root --domain=optimole-wp'
ls languages/
- name: Checkout PR Branch (Head)
uses: actions/checkout@v4
with:
path: optimole-head
- name: Build POT for PR Branch
run: |
cd optimole-head
composer install --no-dev --prefer-dist --no-progress --no-suggest
npm ci
npm run build
npm run make-pot
ls languages/
- name: Compare POT files
uses: Codeinwp/action-i18n-string-reviewer@main
with:
fail-on-changes: 'true'
openrouter-key: ${{ secrets.OPEN_ROUTER_API_KEY }}
openrouter-model: 'google/gemini-2.5-flash'
base-pot-file: 'optimole-base/languages/optimole-wp.pot'
target-pot-file: 'optimole-head/languages/optimole-wp.pot'
github-token: ${{ secrets.BOT_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ assets/build
test-results
tests/assets/filestash
coverage
languages
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -998,7 +998,7 @@ Fix edge cases for auto allowing domain on site migration.

**Documentation**

* improve readme description of the OptiMole service ([e020300](https://github.com/Codeinwp/optimole-wp/commit/e020300))
* improve readme description of the Optimole service ([e020300](https://github.com/Codeinwp/optimole-wp/commit/e020300))



Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -262,12 +262,12 @@ Discover how to make the most of Optimole with our detailed and user-friendly [d


## Installation ##
The following are the steps to install the OptiMole plugin
The following are the steps to install the Optimole plugin

1. In your WordPress Administration Panels, click on Add New option under Plugins from the menu.
Click on upload at the top.
2. Browse the location and select the OptiMole Plugin and click install now.
3. Go to Media -> OptiMole and follow in the instructions on how to enable the service.
2. Browse the location and select the Optimole Plugin and click install now.
3. Go to Media -> Optimole and follow in the instructions on how to enable the service.

## Frequently Asked Questions ##

Expand Down
4 changes: 2 additions & 2 deletions assets/src/dashboard/parts/connected/dashboard/LastImages.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const Image = ({
} }
ref={ squareRef }
/>
<p className="optml__bullet w-full h-4">{ getSize() }% { optimoleDashboardApp.strings.latest_images.saved } </p>
<p className="optml__bullet w-full h-4">{ optimoleDashboardApp.strings.latest_images.percentage_saved.replace( '{ratio}', getSize() ) } </p>
</div>
);
};
Expand Down Expand Up @@ -136,7 +136,7 @@ const LastImages = () => {

return (
<div>
<h3 className="text-gray-800 text-xl font-semibold mb-5 m-0">{ optimoleDashboardApp.strings.latest_images.last } { optimoleDashboardApp.strings.latest_images.optimized_images }</h3>
<h3 className="text-gray-800 text-xl font-semibold mb-5 m-0">{ optimoleDashboardApp.strings.latest_images.last_optimized_images }</h3>

{ ( isInitialLoading && ! isLoaded ) && (
<div className="flex items-center flex-col py-2">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ const Compression = ({
{ ( sampleImages.id && 0 < sampleImages.original_size ) && (
<div>
{ 0 < getCompressionRatio() ? (
<p className="text-base">{ 100 - getCompressionRatio() }% { optimoleDashboardApp.strings.latest_images.smaller }</p>
<p className="text-base">{ optimoleDashboardApp.strings.latest_images.percentage_smaller.replace( '{ratio}', 100 - getCompressionRatio() ) }</p>
) : (
<p className="text-base">{ optimoleDashboardApp.strings.latest_images.same_size }</p>
) }
Expand Down
8 changes: 4 additions & 4 deletions assets/src/dashboard/utils/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ export const connectAccount = ( data, callback = () => {}) => {
sendOnboardingImages();
toggleDashboardSidebarSubmenu( true );

console.log( '%c OptiMole API connection successful.', 'color: #59B278' );
console.log( '%c Optimole API connection successful.', 'color: #59B278' );

} else {
setHasValidKey( false );
Expand Down Expand Up @@ -195,7 +195,7 @@ export const disconnectAccount = () => {
sethasDashboardLoaded( false );
setShowDisconnect( false );
toggleDashboardSidebarSubmenu( false );
console.log( '%c Disconnected from OptiMole API.', 'color: #59B278' );
console.log( '%c Disconnected from Optimole API.', 'color: #59B278' );
} else {
console.error( response );
}
Expand All @@ -221,7 +221,7 @@ export const selectDomain = ( data, callback = () => {}) => {
setAPIKey( response.data.api_key );
setUserData( response.data );
setAvailableApps( response.data );
console.log( '%c OptiMole API connection successful.', 'color: #59B278' );
console.log( '%c Optimole API connection successful.', 'color: #59B278' );
} else {
setHasValidKey( false );
console.log( '%c Invalid API Key.', 'color: #E7602A' );
Expand Down Expand Up @@ -271,7 +271,7 @@ export const requestStatsUpdate = () => {
if ( 'disconnected' === response.code ) {
setIsConnected( false );
sethasDashboardLoaded( false );
console.log( '%c Disconnected from OptiMole API.', 'color: #59B278' );
console.log( '%c Disconnected from Optimole API.', 'color: #59B278' );
}
});
};
Expand Down
7 changes: 3 additions & 4 deletions assets/src/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -481,10 +481,9 @@ export interface LatestImages {
no_images_found: string
compression: string
loading_latest_images: string
last: string
saved: string
smaller: string
optimized_images: string
last_optimized_images: string
percentage_saved: string
percentage_smaller: string
same_size: string
small_optimization: string
medium_optimization: string
Expand Down
5 changes: 3 additions & 2 deletions assets/src/widget/components/WidgetFooter.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Icon, external } from '@wordpress/icons';

export default function WidgetFooter() {
const { i18n, dashboardURL, adminPageURL } = optimoleDashboardWidget;
const { i18n, dashboardURL, dashboardMetricsURL } = optimoleDashboardWidget;

return (
<div className="flex justify-between gap-4 items-center px-4 py-2 bg-gray-50">
Expand All @@ -10,8 +10,9 @@ export default function WidgetFooter() {
<span className="text-base font-bold text-gray-800 group-hover:text-dark-blue transition-colors duration-300">Optimole</span>
</a>

<a href={ adminPageURL } className="text-sm text-info font-medium cursor-pointer hover:text-dark-blue no-underline transition-colors duration-300">
<a href={ dashboardMetricsURL } className="text-sm text-info font-medium cursor-pointer hover:text-dark-blue no-underline transition-colors duration-300 flex items-center gap-1">
{ i18n.viewAllStats }
<Icon icon={ external } className="w-5 h-5 fill-current transition-colors duration-300"/>
</a>
</div>
);
Expand Down
12 changes: 6 additions & 6 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 12 additions & 16 deletions inc/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -635,22 +635,17 @@ public function add_notice_upgrade() {
}
?>
<div class="notice optml-notice-optin"
style="background-color: #577BF9; color:white; border: none !important; display: flex;">
style="background-color: #577BF9; color:white; border: none !important; display: flex; align-items: center;">
<div style="margin: 1% 2%;">
<img src='<?php echo OPTML_URL . 'assets/img/upgrade_icon.png'; ?>'>
<img style="max-width: 100px;" src='<?php echo OPTML_URL . 'assets/img/upgrade_icon.png'; ?>'>
</div>
<div style="margin-top: 0.7%;">
<div style="display: grid; gap: 10px;">
<p style="font-size: 16px !important;">
<?php
printf(
/* translators: 1 - opening strong tag, 2 - visits limit, 3 - closing strong tag, 4 - opening strong tag, 5 - closing strong tag, 6 - br tag */
__( '%1$sIt seems you are close to the %2$s visits limit with %3$sOptimole%4$s for this month.%5$s %6$s For a larger quota you may want to check the upgrade plans. If you exceed the quota we will need to deliver back your original, un-optimized images, which might decrease your site speed performance.', 'optimole-wp' ),
'<strong>',
number_format_i18n( 2000 ),
'</strong>',
'<strong>',
'</strong>',
'<br/><br/>'
/* translators: 1 - visits limit */
__( 'You\'re nearing your %1$s-visit monthly cap on Optimole. If you exceed it, we\'ll serve original (unoptimized) images - expect slower pages.', 'optimole-wp' ),
'<strong>' . number_format_i18n( 2000 ) . '</strong>'
);
?>
</p>
Expand Down Expand Up @@ -864,7 +859,7 @@ public function add_notice() {
</p>
<div class="actions">
<a href="<?php echo esc_url( admin_url( 'admin.php?page=optimole' ) ); ?>"
class="button button-primary button-hero"><?php _e( 'Connect to OptiMole', 'optimole-wp' ); ?>
class="button button-primary button-hero"><?php _e( 'Connect to Optimole', 'optimole-wp' ); ?>
</a>
<a class="button button-secondary button-hero"
href="<?php echo wp_nonce_url( add_query_arg( [ 'optml_hide_optin' => 'yes' ] ), 'hide_nonce', 'optml_nonce' ); ?>"><?php _e( 'I will do it later', 'optimole-wp' ); ?>
Expand Down Expand Up @@ -2286,10 +2281,11 @@ private function get_dashboard_strings() {
'no_images_found' => sprintf( /* translators: 1 is the starting anchor tag, 2 is the ending anchor tag */ __( 'We are currently optimizing your images. Meanwhile you can visit your %1$shomepage%2$s and check how our plugin performs.', 'optimole-wp' ), '<a href="' . esc_url( home_url() ) . '" target="_blank" >', '</a>' ),
'compression' => __( 'Optimization', 'optimole-wp' ),
'loading_latest_images' => __( 'Loading your optimized images...', 'optimole-wp' ),
'last' => __( 'Last', 'optimole-wp' ),
'saved' => __( 'Saved', 'optimole-wp' ),
'smaller' => __( 'smaller', 'optimole-wp' ),
'optimized_images' => __( 'optimized images', 'optimole-wp' ),
'last_optimized_images' => __( 'Last optimized images', 'optimole-wp' ),
// translators: %s is the percentage (e.g. 10%).
'percentage_saved' => sprintf( __( '%s Saved', 'optimole-wp' ), '{ratio}%' ),
// translators: %s is the percentage (e.g. 10%).
'percentage_smaller' => sprintf( __( '%s smaller', 'optimole-wp' ), '{ratio}%' ),
'same_size' => __( '🙉 We couldn\'t do better, this image is already optimized at maximum.', 'optimole-wp' ),
'small_optimization' => __( '😬 Not that much, just <strong>{ratio}</strong> smaller.', 'optimole-wp' ),
'medium_optimization' => __( '🤓 We are on the right track, <strong>{ratio}</strong> squeezed.', 'optimole-wp' ),
Expand Down
11 changes: 5 additions & 6 deletions inc/cli/cli_setting.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,11 @@ public function connect( $args ) {
if ( $data === false || is_wp_error( $data ) ) {
$extra = '';
if ( is_wp_error( $data ) ) {
/**
* Error from api.
*
* @var WP_Error $data Error object.
*/
$extra = sprintf( /* translators: errors details */ __( '. ERROR details: %s', 'optimole-wp' ), $data->get_error_message() );
$extra = sprintf(
/* translators: Error details */
__( '. ERROR details: %s', 'optimole-wp' ),
$data->get_error_message()
);
}

return \WP_CLI::error( __( 'Can not connect to Optimole service', 'optimole-wp' ) . $extra );
Expand Down
68 changes: 68 additions & 0 deletions inc/compatibilities/aruba_hsc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

/**
* Class Optml_aruba_hsc.
*
* @reason Clear cache on Aruba Hispeed Cache.
*/
class Optml_aruba_hsc extends Optml_compatibility {

/**
* Should we load the integration logic.
*
* @return bool Should we load.
*/
public function should_load() {
include_once ABSPATH . 'wp-admin/includes/plugin.php';

return is_plugin_active( 'aruba-hispeed-cache/aruba-hispeed-cache.php' );
}

/**
* Register integration details.
*
* @return void
*/
public function register() {
add_action( 'optml_clear_cache', [ $this, 'add_clear_cache_action' ] );
}


/**
* Should we early load the compatibility?
*
* @return bool Whether to load the compatibility or not.
*/
public function should_load_early() {
return true;
}

/**
* Clear cache for Aruba Hispeed Cache.
*
* @param string|bool $location The location to clear the cache for. If true, clear the cache globally. If a string, clear the cache for a particular url.
* @return void
*/
public function add_clear_cache_action( $location ) {
if ( ! class_exists( '\ArubaSPA\HiSpeedCache\Purger\WpPurger' ) || ! defined( 'AHSC_PURGER' ) ) {
return;
}

// Initialize the purger.
$purge = new \ArubaSPA\HiSpeedCache\Purger\WpPurger();
$purge->setPurger( AHSC_PURGER );

// Purge all cache when no location is provided.
if ( $location === true && method_exists( $purge, 'purgeAll' ) ) {
$purge->purgeAll();
return;
}

// Purge single URL based on the location parameter.
if ( ! method_exists( $purge, 'purgeUrl' ) ) {
return;
}

$purge->purgeUrl( $location );
}
}
1 change: 1 addition & 0 deletions inc/compatibilities/beaver_builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public function register() {
function ( $all_watchers ) {
$all_watchers[] = '.fl-col-content';
$all_watchers[] = '.fl-row-bg-photo > .fl-row-content-wrap';
$all_watchers[] = '.fl-module-box';

return $all_watchers;
}
Expand Down
17 changes: 17 additions & 0 deletions inc/compatibilities/cache_enabler.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,23 @@ function () {
do_action( 'cache_enabler_clear_site_cache' );
}
);

add_action( 'optml_clear_cache', [ $this, 'add_clear_cache_action' ] );
}

/**
* Clear cache for Super Page Cache for Cloudflare.
*
* @param string|bool $location The location to clear the cache for. If true, clear the cache globally. If a string, clear the cache for a particular url.
* @return void
*/
public function add_clear_cache_action( $location ) {
if ( $location === true ) {
do_action( 'cache_enabler_clear_site_cache' );
return;
}

do_action( 'cache_enabler_clear_page_cache_by_url', $location );
}

/**
Expand Down
Loading
Loading