| Server IP : 172.67.159.97 / Your IP : 216.73.217.154 Web Server : nginx/1.24.0 System : Linux wordpress-sites 6.8.0-134-generic #134-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun 26 18:43:11 UTC 2026 x86_64 User : www-data ( 33) PHP Version : 8.1.34 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /var/www/rebeccaone.com/wp-content/plugins/envira-gallery/src/Utils/ |
Upload File : |
<?php
/**
* Frontend utilities.
*
* @since ??
*
* @package Envira_Gallery
*/
namespace Envira\Utils;
use Envira\Frontend\Gallery_Markup\Layouts\Automatic;
use Envira\Frontend\Gallery_Markup\Layouts\Blogroll;
use Envira\Frontend\Gallery_Markup\Layouts\BnB;
use Envira\Frontend\Gallery_Markup\Layouts\BnB_Overlay;
use Envira\Frontend\Gallery_Markup\Layouts\Grid;
use Envira\Frontend\Gallery_Markup\Layouts\Mason;
use Envira\Frontend\Gallery_Markup\Layouts\Square;
use Envira\Frontend\Gallery_Markup\Layouts\Polaroid;
use Envira\Frontend\Gallery_Markup\Layouts\Creative;
use Envira\Frontend\Gallery_Markup\Layouts\Vertical_Focus;
use Envira\Frontend\Gallery_Markup\Layouts\Grid_Fixed_Title;
use Envira\Frontend\Gallery_Markup\Layouts\Spread_Harmony;
use Envira\Frontend\Gallery_Markup\Layouts\Highlight_Grid;
use Envira\Frontend\Gallery_Markup\Layouts\Vertical_Line_Grid;
/**
* Utilities shared among shortcode classes.
*/
class Shortcode_Utils {
/**
* Shortcode default attributes. Used on gallery and link shortcode.
*/
const DEFAULT_ATTRS = [
'id' => null,
'limit' => null,
'settings' => null,
'type' => null,
'slug' => null,
'images' => null,
'dynamic' => null,
'cache' => true,
'gallery_images_raw' => null,
'bnb_overlay' => null,
];
/**
* Main script loaded.
*
* @var bool
*/
private static $main_script_loaded = false;
/**
* Enqueue Main Script.
*
* @param array $data Gallery data.
*
* @return void
*/
public static function enqueue_main_script( $data ) {
if ( self::$main_script_loaded ) {
return;
}
// TODO pass lazy loading delay to general config because it will only read the config on one gallery if there are multiple on the same page.
$lazy_loading_delay = isset( $data['config']['lazy_loading_delay'] ) ? intval( $data['config']['lazy_loading_delay'] ) : '500';
wp_enqueue_script( ENVIRA_SLUG . '-script' );
wp_localize_script(
ENVIRA_SLUG . '-script',
'envira_gallery',
[
'debug' => is_envira_debug_on(),
'll_delay' => $lazy_loading_delay,
'll_initial' => 'false',
'll' => self::is_lazy_loading( $data ),
'mobile' => envira_mobile_detect()->isMobile(),
]
);
self::$main_script_loaded = true;
}
/**
* Is lazy loading option on.
*
* @param array $data Gallery data.
*
* @return bool
*/
public static function is_lazy_loading( $data ) {
// If this is being viewed by AMP, javascript is being disabled and lazy loading shouldn't be on.
$is_ll = function_exists( 'ampforwp_is_amp_endpoint' ) && ampforwp_is_amp_endpoint()
? false
: filter_var( envira_get_config( 'lazy_loading', $data ), FILTER_VALIDATE_BOOLEAN );
return apply_filters( 'envira_is_lazy_loading', $is_ll, $data );
}
/**
* Obtain gallery data and ids from shortcode attrs.
*
* @param array $attrs Shortcode attributes.
*
* @return array|null
*/
public static function get_data_and_id( $attrs ) {
global $post;
$parsed_attrs = self::get_parsed_attrs( $attrs );
// Initialize ids.
$gallery_id = null;
$options_id = null;
$use_cached_data = ! ( is_preview() || is_envira_debug_on() );
if ( self::DEFAULT_ATTRS === $parsed_attrs ) {
// Pull gallery id from current post. For envira post_type.
$gallery_id = $post->ID;
$data = $use_cached_data ? envira_get_gallery( $gallery_id ) : _envira_get_gallery( $gallery_id );
} elseif ( $parsed_attrs['id'] ) {
$gallery_id = (int) $parsed_attrs['id'];
// Determine data by type. Probably is deprecated.
if ( ! $parsed_attrs['type'] ) {
$data = $use_cached_data ? _envira_get_gallery( $gallery_id ) : envira_get_gallery( $gallery_id );
} elseif ( 'widget' === $parsed_attrs['type'] && $parsed_attrs['settings'] ) {
// Only used on random gallery widget.
$settings = json_decode( urldecode( $parsed_attrs['settings'] ), ARRAY_A );
$base_gallery_id = (int) $settings['base_gallery_id'];
$data = $use_cached_data ? envira_get_gallery( $base_gallery_id ) : _envira_get_gallery( $base_gallery_id );
// Validate gallery data exists before accessing to prevent PHP 8.x errors
if ( ! $data || ! is_array( $data ) || ! isset( $data['config'] ) ) {
return null;
}
// Null coalescing operator safely handles missing 'lightbox_enabled' key with default value of 1
$lightbox_enabled = isset( $settings['lightbox'] ) ? (int) $settings['lightbox'] : ( $data['config']['lightbox_enabled'] ?? 1 );
$data['config']['lightbox_enabled'] = $lightbox_enabled;
$data['config']['sort_order'] = '1';
} else {
// New filter for being able to maniupulate data for custom scenarios (widgets, Gutenberg, alien attacks, etc).
$data = apply_filters(
'envira_gallery_custom_gallery_data_by_' . $parsed_attrs['type'],
$use_cached_data ? envira_get_gallery( $gallery_id ) : _envira_get_gallery( $gallery_id ),
$attrs,
$post,
$gallery_id
);
}
} elseif ( $parsed_attrs['slug'] ) {
$gallery_id = $parsed_attrs['slug'];
$data = $use_cached_data ? envira_get_gallery_by_slug( $gallery_id ) : _envira_get_gallery_by_slug( $gallery_id );
// We have the gallery data, now just translate slug into the ID.
if ( $data['id'] ) {
$gallery_id = (int) $data['id'];
}
} else {
// TODO seems to be only used when 'dynamic' and 'images' attrs are passed.
// A custom attribute must have been passed. Allow it to be filtered to grab data from a custom source.
$data = apply_filters( 'envira_gallery_custom_gallery_data', false, $attrs, $post );
$gallery_id = isset( $data['config']['id'] ) ? $data['config']['id'] : $gallery_id;
$options_id = isset( $data['dynamic_id'] ) ? $data['dynamic_id'] : $options_id;
}
if ( ! $options_id ) {
$options_id = $gallery_id;
}
if ( ! $gallery_id || ! $data ) {
if ( is_envira_debug_on() ) {
( 'Empty gallery or data. id: ' . print_r( $gallery_id, true ) . PHP_EOL . print_r( $data, true ) );
}
return null;
}
if ( ! isset( $data['config'] ) ) {
// Legacy lite versions do not store defaults if no settings are modified.
$data['config'] = envira_get_config_defaults( $gallery_id );
}
// Force shortcode to return bnb_overlay layout.
if ( ! empty( $parsed_attrs['bnb_overlay'] ) ) {
$data['config']['layout'] = 'bnb-overlay';
}
return [
'id' => "$gallery_id",
'options_id' => absint( $options_id ),
'data' => $data,
'parsed_attrs' => $parsed_attrs,
];
}
/**
* Parse shortcode attributes.
*
* @param array $attrs Shortcode attributes.
*
* @return array|null
*/
private static function get_parsed_attrs( $attrs ) {
// Set all values to string.
$parsed_attrs = array_map( 'strval', wp_parse_args( $attrs, self::DEFAULT_ATTRS ) );
// Sanitize specific attrs.
$parsed_attrs['cache'] = $parsed_attrs['cache'] ? filter_var( $parsed_attrs['cache'], FILTER_VALIDATE_BOOLEAN ) : true;
$parsed_attrs['limit'] = absint( $parsed_attrs['limit'] );
return $parsed_attrs;
}
/**
* Sanitizes gallery/album description.
*
* @param array $data Gallery/Album data.
*
* @return string Gallery description
*/
public static function get_description( $data ) {
// Check if description exists to prevent PHP 8.x warnings. Sanitize to prevent stored XSS.
// Guard against non-scalar values (e.g. arrays stored by a pre-fix version) before
// passing to wp_kses_post() and the subsequent content-formatting functions.
$raw_description = isset( $data['config']['description'] ) ? $data['config']['description'] : '';
$raw_description = is_scalar( $raw_description ) ? (string) $raw_description : '';
$description = wp_kses_post( $raw_description );
// If the WP_Embed class is available, use that to parse the content using registered oEmbed providers.
if ( isset( $GLOBALS['wp_embed'] ) ) {
$description = $GLOBALS['wp_embed']->autoembed( $description );
}
// Get the description and apply most of the filters that apply_filters( 'the_content' ) would use
// We don't use apply_filters( 'the_content' ) as this would result in a nested loop and a failure.
$description = wptexturize( $description );
$description = convert_smilies( $description );
$description = wpautop( $description );
$description = prepend_attachment( $description );
return ( function_exists( 'wp_filter_content_tags' ) ) ? wp_filter_content_tags( $description ) : $description;
}
/**
* Generates html class string from array of classes.
*
* @param string[] $classes Array of classes.
*
* @return string
*/
public static function classnames( $classes ) {
$sanitized = array_map( 'sanitize_html_class', $classes );
// Avoid extra spaces in string by removing empty classes.
$filtered = array_filter(
$sanitized,
function ( $class_name ) {
return ! empty( $class_name );
}
);
return implode( ' ', array_unique( $filtered ) );
}
/**
* Get the layout class.
*
* @param string $layout Layout name.
* @param array $config Config array.
*
* @return object|null Layout class object.
*/
public static function get_layout_object( $layout, $config ) {
$object = null;
switch ( $layout ) {
case 'automatic':
$object = new Automatic( $config );
break;
case 'blogroll':
$object = new Blogroll( $config );
break;
case 'grid':
$object = new Grid( $config );
break;
case 'mason':
$object = new Mason( $config );
break;
case 'square':
$object = new Square( $config );
break;
case 'bnb':
$object = ( new BnB( $config ) );
break;
case 'bnb-overlay':
$object = ( new BnB_Overlay( $config ) );
break;
case 'polaroid':
$object = ( new Polaroid( $config ) );
break;
case 'creative':
$object = ( new Creative( $config ) );
break;
case 'vertical':
$object = ( new Vertical_Focus( $config ) );
break;
case 'grid-fixed-title':
$object = ( new Grid_Fixed_Title( $config ) );
break;
case 'spread-harmony':
$object = ( new Spread_Harmony( $config ) );
break;
case 'highlight-grid':
$object = ( new Highlight_Grid( $config ) );
break;
case 'vertical-line-grid':
$object = ( new Vertical_Line_Grid( $config ) );
break;
default:
// no default.
}
return $object;
}
/**
* Outputs an individual gallery item in the grid
*
* @param string $gallery Gallery HTML.
* @param array $data Gallery Config.
* @param array $item Gallery Item (Image).
* @param int $item_id Gallery Image ID.
* @param int $count Index.
*
* @return string Gallery HTML
*/
public static function get_single_item_markup( $gallery, $data, $item, $item_id, $count ) {
$layout = envira_get_config( 'layout', $data );
// This config is not accurate as the real one can only be obtained from the Shortcode class.
// It is compatible enough for single item render.
$config = $data['config'];
$layout_object = self::get_layout_object( $layout, $config );
if ( 'bnb' === $layout ) {
$layout_object = new BnB_Overlay( $config );
}
if ( null === $layout_object ) {
return "ERROR: Layout not found: $layout";
}
return $layout_object->generate_gallery_item_markup( $gallery, $data, $item, $item_id, $count );
}
}