File: //home/shrsglobal/www/wp-content/plugins/w3-total-cache/Extension_ImageService_Environment.php
<?php
/**
* File: Extension_ImageService_Environment.php
*
* @since 2.2.0
*
* @package W3TC
*/
namespace W3TC;
/**
* Class: Extension_ImageService_Environment
*
* phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter
*/
class Extension_ImageService_Environment {
/**
* Fixes environment in each wp-admin request.
*
* @since 2.2.0
*
* @param Config $config Configuration.
* @param bool $force_all_checks Force all checks.
* @throws Util_Environment_Exceptions Exceptions.
*/
public function fix_on_wpadmin_request( $config, $force_all_checks ) {
$exs = new Util_Environment_Exceptions();
if ( $config->get_boolean( 'config.check' ) || $force_all_checks ) {
$extensions_active = $config->get_array( 'extensions.active' );
if ( array_key_exists( 'imageservice', $extensions_active ) ) {
$this->rules_add( $config, $exs );
} else {
$this->rules_remove( $exs );
}
}
if ( count( $exs->exceptions() ) > 0 ) {
throw $exs;
}
}
/**
* Fixes environment once event occurs.
*
* @since 2.2.0
*
* @param Config $config Config object.
* @param mixed $event Event.
* @param Config $old_config Old config object.
*/
public function fix_on_event( $config, $event, $old_config = null ) {
}
/**
* Fixes environment after plugin deactivation
*
* @since 2.2.0
*
* @throws Util_Environment_Exceptions Exceptions.
*/
public function fix_after_deactivation() {
$exs = new Util_Environment_Exceptions();
$this->rules_remove( $exs );
if ( count( $exs->exceptions() ) > 0 ) {
throw $exs;
}
}
/**
* Returns required rules for module.
*
* @since 2.2.0
*
* @param Config $config Configuration object.
* @return array
*/
public function get_required_rules( $config ) {
return array(
array(
'filename' => Util_Rule::get_browsercache_rules_cache_path(),
'content' => $this->rules_generate_avif() . $this->rules_generate_webp(),
),
);
}
/**
* Write rewrite rules.
*
* @since 2.2.0
*
* @param Config $config Configuration.
* @param Util_Environment_Exceptions $exs Exceptions.
*
* @throws Util_WpFile_FilesystemOperationException S/FTP form if it can't get the required filesystem credentials.
*/
private function rules_add( $config, $exs ) {
// Remove existing rules first to ensure correct positioning on re-add.
// This is necessary because add_rules replaces in place when rules exist.
Util_Rule::remove_rules(
$exs,
Util_Rule::get_browsercache_rules_cache_path(),
W3TC_MARKER_BEGIN_AVIF,
W3TC_MARKER_END_AVIF
);
Util_Rule::remove_rules(
$exs,
Util_Rule::get_browsercache_rules_cache_path(),
W3TC_MARKER_BEGIN_WEBP,
W3TC_MARKER_END_WEBP
);
// Add AVIF rules first (higher priority).
// Position before Page Cache so image requests are handled before Page Cache location blocks.
Util_Rule::add_rules(
$exs,
Util_Rule::get_browsercache_rules_cache_path(),
$this->rules_generate_avif(),
W3TC_MARKER_BEGIN_AVIF,
W3TC_MARKER_END_AVIF,
array(
W3TC_MARKER_BEGIN_PGCACHE_CACHE => 0,
W3TC_MARKER_BEGIN_PGCACHE_CORE => 0,
W3TC_MARKER_BEGIN_BROWSERCACHE_CACHE => 0,
W3TC_MARKER_BEGIN_WORDPRESS => 0,
)
);
// Add WebP rules (lower priority than AVIF).
// Position before Page Cache so image requests are handled before Page Cache location blocks.
Util_Rule::add_rules(
$exs,
Util_Rule::get_browsercache_rules_cache_path(),
$this->rules_generate_webp(),
W3TC_MARKER_BEGIN_WEBP,
W3TC_MARKER_END_WEBP,
array(
W3TC_MARKER_BEGIN_PGCACHE_CACHE => 0,
W3TC_MARKER_BEGIN_PGCACHE_CORE => 0,
W3TC_MARKER_BEGIN_BROWSERCACHE_CACHE => 0,
W3TC_MARKER_BEGIN_WORDPRESS => 0,
)
);
}
/**
* Generate AVIF rewrite rules (higher priority).
*
* @since 2.9.1
*
* @see Dispatcher::nginx_rules_for_browsercache_section()
*
* @return string
*/
private function rules_generate_avif() {
switch ( true ) {
case Util_Environment::is_apache():
case Util_Environment::is_litespeed():
return '
# BEGIN W3TC AVIF
<IfModule mod_mime.c>
AddType image/avif .avif
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_ACCEPT} image/avif
RewriteCond %{REQUEST_FILENAME} (.+)\.(jpe?g|png|gif)$
RewriteCond %1\.avif -f
RewriteCond %{QUERY_STRING} !type=original
RewriteRule (.+)\.(jpe?g|png|gif)$ $1.avif [NC,T=image/avif,E=avif,L]
</IfModule>
<IfModule mod_headers.c>
<FilesMatch "\.(jpe?g|png|gif|avif)$">
Header append Vary Accept
</FilesMatch>
</IfModule>
# END W3TC AVIF
';
case Util_Environment::is_nginx():
$config = Dispatcher::config();
/*
* Add Nginx rules only if Browser Cache is disabled.
* Otherwise, the rules are added in "BrowserCache_Environment_Nginx.php".
* @see BrowserCache_Environment_Nginx::generate_section()
*/
if ( ! $config->get_boolean( 'browsercache.enabled' ) ) {
if ( $config->get_boolean( 'browsercache.no404wp' ) ) {
$fallback = '=404';
} else {
$fallback = '/index.php$is_args$args';
}
return '
# BEGIN W3TC AVIF
location ~* ^(?<path>.+)\.(jpe?g|png|gif)$ {
' . implode( "\n ", Dispatcher::nginx_rules_for_browsercache_section( $config, 'other' ) ) . '
add_header Vary Accept;
# Initialize variables.
set $avif_ok 0;
set $webp_ok 0;
set $want_avif 0;
set $want_webp 0;
set $serve_avif 0;
set $serve_webp 0;
# Check file existence.
if ( -f $document_root${path}.avif ) {
set $avif_ok 1;
}
if ( -f $document_root${path}.webp ) {
set $webp_ok 1;
}
# Check Accept header.
if ( $http_accept ~* "image/avif" ) {
set $want_avif 1;
}
if ( $http_accept ~* "image/webp" ) {
set $want_webp 1;
}
# Combine conditions: serve AVIF if both accepted and file exists.
if ( $want_avif = 1 ) {
set $serve_avif $avif_ok;
}
if ( $serve_avif = 1 ) {
rewrite ^ ${path}.avif last;
}
# Serve WEBP if accepted and file exists (only if AVIF wasn\'t served).
if ( $want_webp = 1 ) {
set $serve_webp $webp_ok;
}
if ( $serve_webp = 1 ) {
rewrite ^ ${path}.webp last;
}
# Default: serve original file.
try_files $uri ' . $fallback . ';
}
location ~* \.(avif|avifs)$ {
default_type image/avif;
}
# END W3TC AVIF
';
} else {
return '';
}
default:
return '';
}
}
/**
* Generate WebP rewrite rules (lower priority than AVIF).
*
* @since 2.9.1
*
* @see Dispatcher::nginx_rules_for_browsercache_section()
*
* @return string
*/
private function rules_generate_webp() {
switch ( true ) {
case Util_Environment::is_apache():
case Util_Environment::is_litespeed():
return '
# BEGIN W3TC WEBP
<IfModule mod_mime.c>
AddType image/webp .webp
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{REQUEST_FILENAME} (.+)\.(jpe?g|png|gif)$
RewriteCond %1\.webp -f
RewriteCond %{QUERY_STRING} !type=original
RewriteRule (.+)\.(jpe?g|png|gif)$ $1.webp [NC,T=image/webp,E=webp,L]
</IfModule>
<IfModule mod_headers.c>
<FilesMatch "\.(jpe?g|png|gif|webp)$">
Header append Vary Accept
</FilesMatch>
</IfModule>
# END W3TC WEBP
';
case Util_Environment::is_nginx():
$config = Dispatcher::config();
/*
* Add Nginx rules only if Browser Cache is disabled.
* Otherwise, the rules are added in "BrowserCache_Environment_Nginx.php".
* @see BrowserCache_Environment_Nginx::generate_section()
*/
if ( ! $config->get_boolean( 'browsercache.enabled' ) ) {
if ( $config->get_boolean( 'browsercache.no404wp' ) ) {
$fallback = '=404';
} else {
$fallback = '/index.php?$args';
}
return '
# BEGIN W3TC WEBP
location ~* \.webp$ {
default_type image/webp;
}
# END W3TC WEBP
';
} else {
return '';
}
default:
return '';
}
}
/**
* Removes cache directives
*
* @since 2.2.0
*
* @param Util_Environment_Exceptions $exs Exceptions.
*
* @throws Util_WpFile_FilesystemOperationException S/FTP form if it can't get the required filesystem credentials.
*/
private function rules_remove( $exs ) {
// Remove AVIF rules.
Util_Rule::remove_rules(
$exs,
Util_Rule::get_pgcache_rules_core_path(),
W3TC_MARKER_BEGIN_AVIF,
W3TC_MARKER_END_AVIF
);
// Remove WebP rules.
Util_Rule::remove_rules(
$exs,
Util_Rule::get_pgcache_rules_core_path(),
W3TC_MARKER_BEGIN_WEBP,
W3TC_MARKER_END_WEBP
);
}
}