File: //home/crowdandsafety/www/wp-content/plugins/shortpixel-image-optimiser/class/Helper/UtilHelper.php
<?php
namespace ShortPixel\Helper;
use ShortPixel\ShortPixelLogger\ShortPixelLogger as Log;
if (! defined('ABSPATH')) {
exit; // Exit if accessed directly.
}
// Our newest Tools class
class UtilHelper
{
public static function getPostMetaTable()
{
global $wpdb;
return $wpdb->prefix . 'shortpixel_postmeta';
}
public static function shortPixelIsPluginActive($plugin)
{
$activePlugins = apply_filters('active_plugins', get_option('active_plugins', array()));
if (is_multisite()) {
$activePlugins = array_merge($activePlugins, get_site_option('active_sitewide_plugins'));
}
return in_array($plugin, $activePlugins);
}
public static function timestampToDB($timestamp)
{
return date("Y-m-d H:i:s", $timestamp);
}
public static function DBtoTimestamp($date)
{
return strtotime($date);
}
public static function getWordPressImageSizes()
{
global $_wp_additional_image_sizes;
$sizes_names = get_intermediate_image_sizes();
$sizes = array();
foreach ($sizes_names as $size) {
$sizes[$size]['width'] = intval(get_option("{$size}_size_w"));
$sizes[$size]['height'] = intval(get_option("{$size}_size_h"));
$sizes[$size]['crop'] = get_option("{$size}_crop") ? get_option("{$size}_crop") : false;
$sizes[$size]['nice-name'] = ucfirst($size);
}
if (function_exists('wp_get_additional_image_sizes')) {
$sizes = array_merge($sizes, wp_get_additional_image_sizes());
} elseif (is_array($_wp_additional_image_sizes)) {
$sizes = array_merge($sizes, $_wp_additional_image_sizes);
}
$sizes = apply_filters('shortpixel/settings/image_sizes', $sizes);
return $sizes;
}
// wp_normalize_path doesn't work for windows installs in some situations, so we can use it, but we still want some of the functions.
public static function spNormalizePath($path)
{
$path = preg_replace('|(?<=.)/+|', '/', $path);
return $path;
}
public static function getExifParameter()
{
return (\wpSPIO()->settings()->exif + \wpSPIO()->settings()->exif_ai);
}
// Copy of private https://developer.wordpress.org/reference/functions/_wp_relative_upload_path/
public static function getRelativeUploadPath($path)
{
$new_path = $path;
$uploads = wp_get_upload_dir();
if (0 === strpos($new_path, $uploads['basedir'])) {
$new_path = str_replace($uploads['basedir'], '', $new_path);
$new_path = ltrim($new_path, '/');
}
return $new_path;
}
/** Usage: Plug this into array_filter method.
*
* @return bool
*/
public static function arrayFilterNullValues($val)
{
return $val !== null;
}
public static function validateJSON($json)
{
if (!is_string($json)) {
return false;
}
// Try to simpler bail out without checking for the decode.
if (strpos($json, '{' ) === false && strpos($json, ':') === false)
{
return false;
}
if (function_exists('json_validate')) {
return \json_validate($json);
}
json_decode($json);
return json_last_error() === JSON_ERROR_NONE;
}
public static function getExclusions($args = array())
{
$defaults = array(
'filter' => false,
'thumbname' => null,
'is_thumbnail' => false,
'is_custom' => false,
);
$args = wp_parse_args($args, $defaults);
$patterns = \wpSPIO()->settings()->excludePatterns;
$matches = array();
if (false === is_array($patterns)) {
return array();
}
foreach ($patterns as $index => $pattern) {
if (! isset($pattern['apply'])) {
$patterns[$index]['apply'] = 'all';
}
if (true === $args['filter']) {
if (true === self::matchExclusion($patterns[$index], $args)) {
$matches[] = $pattern;
}
}
}
if (true === $args['filter']) {
return $matches;
} else
return $patterns;
}
protected static function matchExclusion($pattern, $options)
{
$apply = $pattern['apply'];
$thumblist = isset($pattern['thumblist']) ? $pattern['thumblist'] : array();
$bool = false;
if ($apply === 'all') {
$bool = true;
} elseif ($apply == 'only-thumbs' && true === $options['is_thumbnail']) {
$bool = true;
} elseif ($apply == 'only-custom' && true === $options['is_custom']) {
$bool = true;
} elseif (count($thumblist) > 0 && ! is_null($options['thumbname'])) {
$thumbname = $options['thumbname'];
if (in_array($thumbname, $thumblist)) {
$bool = true;
}
}
return $bool;
}
public static function getAiSettings($params = [])
{
$settings = \wpSPIO()->settings();
$defaults = [
'ai_general_context' => $settings->ai_general_context,
'ai_use_post' => $settings->ai_use_post,
'ai_gen_alt' => $settings->ai_gen_alt,
'ai_gen_caption' => $settings->ai_gen_caption,
'ai_gen_description' => $settings->ai_gen_description,
'ai_gen_post_title' => $settings->ai_gen_post_title,
'ai_filename_prefercurrent' => $settings->ai_filename_prefercurrent,
'ai_limit_alt_chars' => $settings->ai_limit_alt_chars,
'ai_alt_context' => $settings->ai_alt_context,
'ai_limit_description_chars' => $settings->ai_limit_description_chars,
'ai_description_context' => $settings->ai_description_context,
'ai_limit_caption_chars' => $settings->ai_limit_caption_chars,
'ai_caption_context' => $settings->ai_caption_context,
'ai_limit_post_title_chars' => $settings->ai_limit_post_title_chars,
'ai_post_title_context' => $settings->ai_post_title_context,
'ai_gen_filename' => $settings->ai_gen_filename,
'ai_limit_filename_chars' => $settings->ai_limit_filename_chars,
'ai_filename_context' => $settings->ai_filename_context,
'ai_use_exif' => $settings->ai_use_exif,
'ai_language' => $settings->ai_language,
'aiPreserve' => $settings->aiPreserve,
];
$params = wp_parse_args($params, $defaults);
return $params;
}
public static function convertExclusionFileSizeToBytes($value)
{
return preg_replace_callback('/^\s*(\d+)\s*(?:([kmgt]?)b?)?\s*$/i', function ($m) {
switch (strtolower($m[2])) {
case 't': $m[1] *= 1024;
case 'g': $m[1] *= 1024;
case 'm': $m[1] *= 1024;
case 'k': $m[1] *= 1024;
}
return $m[1];
}, $value);
}
public static function alterHtaccess($webp = false, $avif = false)
{
// [BS] Backward compat. 11/03/2019 - remove possible settings from root .htaccess
/* Plugin init is before loading these admin scripts. So it can happen misc.php is not yet loaded */
if (! function_exists('insert_with_markers')) {
Log::addWarn('AlterHtaccess Called before WP init');
return;
//require_once( ABSPATH . 'wp-admin/includes/misc.php' );
}
$upload_dir = wp_upload_dir();
$upload_base = trailingslashit($upload_dir['basedir']);
if (false === $webp && false === $avif) {
insert_with_markers(get_home_path() . '.htaccess', 'ShortPixelWebp', '');
// Only empty these tags if the file actually exist, they are created by SPIO.
if (file_exists($upload_base . '.htaccess')) {
insert_with_markers($upload_base . '.htaccess', 'ShortPixelWebp', '');
}
if (file_exists(trailingslashit(WP_CONTENT_DIR) . '.htaccess')) {
insert_with_markers(trailingslashit(WP_CONTENT_DIR) . '.htaccess', 'ShortPixelWebp', '');
}
} else {
$avif_rules = '
<IfModule mod_rewrite.c>
RewriteEngine On
##### Directives for delivering AVIF files, if they exist #####
# Does the browser support avif?
RewriteCond %{HTTP_ACCEPT} image/avif
# AND is the request a JPG, PNG, or WebP? (no GIFs because the animation is sometimes lost in AVIF);
# (also grab the basepath %1 to match in the next rule)
RewriteCond %{REQUEST_URI} ^(.+)\.(?:jpe?g|png|webp)$
# AND does a .avif image exist?
RewriteCond %{DOCUMENT_ROOT}/%1.avif -f
# THEN send the avif image and set the env var avif
RewriteRule (.+)\.(?:jpe?g|png|webp)$ $1.avif [NC,T=image/avif,E=avif,L]
# Does the browser support avif?
RewriteCond %{HTTP_ACCEPT} image/avif
# AND is the request a JPG, PNG, or WebP? (no GIFs because the animation is sometimes lost in AVIF);
# (also grab the basepath %1 to match in the next rule)
RewriteCond %{REQUEST_URI} ^(.+)\.(?:jpe?g|png|webp)$
# AND does a .jpg.avif image exist?
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.avif -f
# THEN send the avif image and set the env var avif
RewriteRule ^(.+)$ $1.avif [NC,T=image/avif,E=avif,L]
</IfModule>
<IfModule mod_headers.c>
# If REDIRECT_avif env var exists, append Accept to the Vary header
Header append Vary Accept env=REDIRECT_avif
<FilesMatch ".(webp)$">
Header set Cache-Control "max-age=31536000, public"
</FilesMatch>
</IfModule>
<IfModule mod_mime.c>
AddType image/avif .avif
</IfModule>
';
$webp_rules = '
<IfModule mod_rewrite.c>
RewriteEngine On
##### TRY FIRST the file appended with .webp (ex. test.jpg.webp) #####
# Is the browser Chrome?
RewriteCond %{HTTP_USER_AGENT} Chrome [OR]
# OR Is this request from Page Speed
RewriteCond %{HTTP_USER_AGENT} "Google Page Speed Insights" [OR]
# OR does this browser explicitly support webp
RewriteCond %{HTTP_ACCEPT} image/webp
# AND NOT MS EDGE 42/17 - doesnt work.
RewriteCond %{HTTP_USER_AGENT} !Edge/17
# AND is the request a jpg, png, or gif?
RewriteCond %{REQUEST_URI} ^(.+)\.(?:jpe?g|png|gif)$
# AND does a .ext.webp image exist?
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.webp -f
# THEN send the webp image and set the env var webp
RewriteRule ^(.+)$ $1.webp [NC,T=image/webp,E=webp,L]
##### IF NOT, try the file with replaced extension (test.webp) #####
RewriteCond %{HTTP_USER_AGENT} Chrome [OR]
RewriteCond %{HTTP_USER_AGENT} "Google Page Speed Insights" [OR]
RewriteCond %{HTTP_ACCEPT} image/webp
RewriteCond %{HTTP_USER_AGENT} !Edge/17
# AND is the request a jpg, png, or gif? (also grab the basepath %1 to match in the next rule)
RewriteCond %{REQUEST_URI} ^(.+)\.(?:jpe?g|png|gif)$
# AND does a .webp image exist?
RewriteCond %{DOCUMENT_ROOT}/%1.webp -f
# THEN send the webp image and set the env var webp
RewriteRule (.+)\.(?:jpe?g|png|gif)$ $1.webp [NC,T=image/webp,E=webp,L]
</IfModule>
<IfModule mod_headers.c>
# If REDIRECT_webp env var exists, append Accept to the Vary header
Header append Vary Accept env=REDIRECT_webp
<FilesMatch ".(avif)$">
Header set Cache-Control "max-age=31536000, public"
</FilesMatch>
</IfModule>
<IfModule mod_mime.c>
AddType image/webp .webp
</IfModule>
';
$rules = '';
// if ($avif)
$rules .= $avif_rules;
// if ($webp)
$rules .= $webp_rules;
insert_with_markers(get_home_path() . '.htaccess', 'ShortPixelWebp', $rules);
/** In uploads and on, it needs Inherit. Otherwise things such as the 404 error page will not be loaded properly
* since the WP rewrite will not be active at that point (overruled) **/
$deepOptions = array(
'uploads' => array('useInherit' => true),
'wp_content' => array('useInherit' => true)
);
$deepOptionsFiltered = apply_filters('shortpixel/install/write_deep_htaccess', $deepOptions);
// Previous filter used a boolean. This is backward compat.
if (true === $deepOptionsFiltered) {
$deepOptionsFiltered = $deepOptions;
} elseif (false === $deepOptionsFiltered) {
return;
}
if (is_array($deepOptionsFiltered)) {
foreach ($deepOptionsFiltered as $name => $options) {
$inherit = isset($options['useInherit']) ? $options['useInherit'] : true; // default to true.
if (true === $inherit) {
$deepRules = str_replace('RewriteEngine On', 'RewriteEngine On' . PHP_EOL . 'RewriteOptions Inherit', $rules);
} else {
$deepRules = $rules;
}
if ('uploads' === $name) {
insert_with_markers($upload_base . '.htaccess', 'ShortPixelWebp', $deepRules);
} elseif ('wp_content' === $name) {
insert_with_markers(trailingslashit(WP_CONTENT_DIR) . '.htaccess', 'ShortPixelWebp', $deepRules);
}
}
}
}
} // alter htaccess
} // class