'ShortPixel Image Optimizer',
'slug' => 'shortpixel',
'handles_compression' => true,
'handles_format_conversion' => true,
'supports_avif' => true,
'supports_webp' => true,
'cdn_based' => false,
'cloud_service' => true,
);
}
// Imagify.
if ( defined( 'IMAGIFY_VERSION' ) || class_exists( 'Imagify' ) ) {
$optimization_plugins[] = array(
'name' => 'Imagify',
'slug' => 'imagify',
'handles_compression' => true,
'handles_format_conversion' => true,
'supports_avif' => false,
'supports_webp' => true,
'cdn_based' => false,
'cloud_service' => true,
);
}
// Smush.
if ( defined( 'WP_SMUSH_VERSION' ) || class_exists( 'WP_Smush' ) || class_exists( 'Smush\Core\Core' ) ) {
$optimization_plugins[] = array(
'name' => 'Smush',
'slug' => 'smush',
'handles_compression' => true,
'handles_format_conversion' => true,
'supports_avif' => false,
'supports_webp' => true,
'cdn_based' => false,
'cloud_service' => false,
);
}
// EWWW Image Optimizer.
if ( defined( 'EWWW_IMAGE_OPTIMIZER_VERSION' ) || class_exists( 'EWWW_Image_Optimizer' ) ) {
$optimization_plugins[] = array(
'name' => 'EWWW Image Optimizer',
'slug' => 'ewww',
'handles_compression' => true,
'handles_format_conversion' => true,
'supports_avif' => true,
'supports_webp' => true,
'cdn_based' => false,
'cloud_service' => true,
);
}
// Optimole.
if ( defined( 'OPTIMOLE_VERSION' ) || class_exists( 'Optml_Main' ) ) {
$optimization_plugins[] = array(
'name' => 'Optimole',
'slug' => 'optimole',
'handles_compression' => false,
'handles_format_conversion' => false,
'supports_avif' => true,
'supports_webp' => true,
'cdn_based' => true,
'cloud_service' => true,
);
}
// TinyPNG / Compress JPEG & PNG images.
if ( defined( 'TINYPNG_VERSION' ) || class_exists( 'Tiny_Settings' ) || class_exists( 'Tiny_Plugin' ) ) {
$optimization_plugins[] = array(
'name' => 'TinyPNG',
'slug' => 'tinypng',
'handles_compression' => true,
'handles_format_conversion' => false,
'supports_avif' => false,
'supports_webp' => true,
'cdn_based' => false,
'cloud_service' => true,
);
}
// Jetpack (Photon / Site Accelerator).
if ( class_exists( 'Jetpack' ) && method_exists( 'Jetpack', 'is_module_active' ) ) {
if ( \Jetpack::is_module_active( 'photon' ) || \Jetpack::is_module_active( 'photon-cdn' ) ) {
$optimization_plugins[] = array(
'name' => 'Jetpack (Site Accelerator)',
'slug' => 'jetpack',
'handles_compression' => false,
'handles_format_conversion' => false,
'supports_avif' => false,
'supports_webp' => true,
'cdn_based' => true,
'cloud_service' => true,
);
}
}
// Cache the results.
self::$detected_plugins = $optimization_plugins;
return $optimization_plugins;
}
/**
* Check if any optimization plugin is active.
*
* @return bool True if at least one optimization plugin is detected.
* @since 1.3.0
*/
public static function has_optimization_plugin() {
return ! empty( self::get_active_optimization_plugins() );
}
/**
* Check if an active plugin can handle format conversion.
*
* @param string $format Target format (webp, avif).
* @return bool True if an external plugin can handle this format.
* @since 1.3.0
*/
public static function external_plugin_handles_format( $format ) {
$plugins = self::get_active_optimization_plugins();
foreach ( $plugins as $plugin ) {
if ( $format === 'webp' && ! empty( $plugin['supports_webp'] ) && $plugin['handles_format_conversion'] ) {
return true;
}
if ( $format === 'avif' && ! empty( $plugin['supports_avif'] ) && $plugin['handles_format_conversion'] ) {
return true;
}
}
return false;
}
/**
* Get recommended cooperation mode based on detected plugins and server capabilities.
*
* @return string Recommended mode ('gatewell_primary', 'external_primary', 'both', or 'auto').
* @since 1.3.0
*/
public static function get_recommended_mode() {
$plugins = self::get_active_optimization_plugins();
if ( empty( $plugins ) ) {
return 'gatewell_primary'; // No competition, Gatewell is in charge.
}
foreach ( $plugins as $plugin ) {
// CDN-based plugins don't conflict - Gatewell can be primary.
if ( ! empty( $plugin['cdn_based'] ) ) {
continue;
}
// If external plugin supports AVIF and server doesn't, recommend external.
if ( $plugin['supports_avif'] && ! Format_Capabilities::supports_avif() && $plugin['handles_format_conversion'] ) {
return 'external_primary';
}
// If external plugin supports WebP and server doesn't, recommend external.
if ( $plugin['supports_webp'] && ! Format_Capabilities::supports_webp() && $plugin['handles_format_conversion'] ) {
return 'external_primary';
}
// If external plugin has cloud service and server has limited capabilities.
if ( ! empty( $plugin['cloud_service'] ) && $plugin['handles_compression'] ) {
// Server has both compression plugins - let user decide.
return 'auto';
}
}
// Default: Gatewell primary.
return 'gatewell_primary';
}
/**
* Get recommendations and warnings based on active plugins.
*
* @return array Array of recommendation/warning messages.
* @since 1.3.0
*/
public static function get_recommendations() {
$plugins = self::get_active_optimization_plugins();
$recommendations = array();
if ( empty( $plugins ) ) {
return $recommendations;
}
$recommended_mode = self::get_recommended_mode();
foreach ( $plugins as $plugin ) {
// CDN-based plugins play nicely.
if ( ! empty( $plugin['cdn_based'] ) ) {
$recommendations[] = array(
'type' => 'info',
'message' => sprintf(
/* translators: %s: plugin name */
__( '%s detected: This CDN-based plugin works alongside Gatewell without conflicts. Both can remain active.', 'gatewell' ),
'' . $plugin['name'] . ''
),
'action' => 'none',
);
continue;
}
// External plugin has better format support.
if ( $recommended_mode === 'external_primary' ) {
if ( $plugin['supports_avif'] && ! Format_Capabilities::supports_avif() ) {
$recommendations[] = array(
'type' => 'warning',
'message' => sprintf(
/* translators: %s: plugin name */
__( '%s can create AVIF images (your server cannot). We recommend setting cooperation mode to "External Plugin Primary" to use this capability.', 'gatewell' ),
'' . $plugin['name'] . ''
),
'action' => 'set_external_primary',
);
continue;
}
}
// Compression conflict warning.
if ( $plugin['handles_compression'] && ! $plugin['cdn_based'] ) {
$recommendations[] = array(
'type' => 'warning',
'message' => sprintf(
/* translators: %s: plugin name */
__( '%s detected: This plugin compresses images. To avoid double processing, choose a cooperation mode below.', 'gatewell' ),
'' . $plugin['name'] . ''
),
'action' => 'choose_mode',
);
}
}
return $recommendations;
}
/**
* Get a user-friendly explanation of what each cooperation mode does.
*
* @return array Array of mode explanations.
* @since 1.3.0
*/
public static function get_mode_explanations() {
$plugins = self::get_active_optimization_plugins();
$plugin_name = ! empty( $plugins[0]['name'] ) ? $plugins[0]['name'] : __( 'external plugin', 'gatewell' );
return array(
'auto' => array(
'label' => __( 'Auto (Recommended)', 'gatewell' ),
'description' => __( 'Automatically choose the best mode based on your server capabilities and installed plugins. Gatewell will coordinate intelligently.', 'gatewell' ),
),
'gatewell_primary' => array(
'label' => __( 'Gatewell Primary', 'gatewell' ),
'description' => sprintf(
/* translators: %s: plugin name */
__( 'Gatewell handles compression and format conversion. %s will skip processing or only optimize thumbnails.', 'gatewell' ),
$plugin_name
),
),
'external_primary' => array(
'label' => __( 'External Plugin Primary', 'gatewell' ),
'description' => sprintf(
/* translators: %s: plugin name */
__( 'Gatewell collects metadata (alt text, captions) only. %s handles all compression and format conversion.', 'gatewell' ),
$plugin_name
),
),
'both' => array(
'label' => __( 'Both (Advanced)', 'gatewell' ),
'description' => sprintf(
/* translators: %s: plugin name */
__( 'Both Gatewell and %s process images. May result in better compression but risks quality loss from double processing. Use with caution.', 'gatewell' ),
$plugin_name
),
),
);
}
/**
* Get the effective cooperation mode (resolves 'auto' to actual mode).
*
* @return string Effective mode ('gatewell_primary', 'external_primary', or 'both').
* @since 1.3.0
*/
public static function get_effective_mode() {
$mode = get_option( 'gatewell_plugin_cooperation', 'auto' );
if ( $mode === 'auto' ) {
// Auto mode: use recommendation logic.
$recommended = self::get_recommended_mode();
return $recommended === 'auto' ? 'gatewell_primary' : $recommended;
}
return $mode;
}
/**
* Check if Gatewell should process compression.
*
* @return bool True if Gatewell should compress images.
* @since 1.3.0
*/
public static function should_gatewell_compress() {
$mode = self::get_effective_mode();
// External primary: skip compression.
if ( $mode === 'external_primary' ) {
return false;
}
// Gatewell primary or Both: compress.
return true;
}
/**
* Check if Gatewell should process format conversion.
*
* @return bool True if Gatewell should convert formats.
* @since 1.3.0
*/
public static function should_gatewell_convert() {
$mode = self::get_effective_mode();
// External primary: skip conversion.
if ( $mode === 'external_primary' ) {
return false;
}
// Gatewell primary or Both: convert.
return true;
}
}