| Server IP : 104.21.74.147 / 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/Frontend/ |
Upload File : |
<?php
/**
* Envira Gallery Rest Class.
*
* @since 1.8.5
*
* @package Envira Gallery
* @author Envira Gallery Team <[email protected]>
*/
namespace Envira\Frontend;
use Envira\Utils\Shortcode_Utils;
use Envira\Utils\Sanitize_Utils;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Rest Class for envira.
*/
class Rest {
/**
* Class Constructor
*
* @since 1.8.5
*/
public function __construct() {
$this->init();
}
/**
* Helper Init Method
*
* @since 1.8.8
*
* @return void
*/
public function init() {
add_action( 'rest_api_init', [ $this, 'register_post_meta' ] );
}
/**
* Helper Method to register Envira gallery Meta
*
* @since 1.8.5
*
* @return void
*/
public function register_post_meta() {
// Probably to be used with gutenberg part later.
// ( new Overlay_Rest() )->register_routes();.
register_rest_field(
'envira',
'gallery_data',
[
'get_callback' => [ $this, 'get_gallery_data' ],
'update_callback' => [ $this, 'update_gallery_data' ],
]
);
}
/**
* Rest API callback to get gallery data.
*
* @param [type] $post_object Post Object.
* @param [type] $field_name Rest Field Name.
* @param [type] $request Rest Request.
* @return array
*/
public function get_gallery_data( $post_object, $field_name, $request ) {
$data = get_post_meta( $post_object['id'], '_eg_gallery_data', true );
if ( ! is_array( $data ) ) {
$data = [];
}
$data = ( ! isset( $data['config']['layout'] ) ) ? envira_convert_columns_to_layouts( $data, $data['id'] ?? $post_object['id'] ) : envira_override_layout_settings( $data );
$i = 0;
$images = [];
$data = apply_filters( 'envira_gallery_pre_data', $data, $post_object['id'] );
if ( isset( $data['gallery'] ) && is_array( $data['gallery'] ) ) {
foreach ( $data['gallery'] as $id => $item ) {
// Skip over images that are pending (ignore if in Preview mode).
if ( isset( $item['status'] ) && 'pending' === $item['status'] && ! is_preview() ) {
continue;
}
$width = null;
$height = null;
$imagesrc = envira_get_image_src( $id, $item, $data, false, false );
// Get the image file path.
$urlinfo = wp_parse_url( $imagesrc );
$wp_upload_dir = wp_upload_dir();
// Interpret the file path of the image.
if ( preg_match( '/\/[0-9]{4}\/[0-9]{2}\/.+$/', $urlinfo['path'], $matches ) ) {
$file_path = $wp_upload_dir['basedir'] . $matches[0];
} else {
$content_dir = defined( 'WP_CONTENT_DIR' ) ? WP_CONTENT_DIR : '/wp-content/';
$uploads_dir = is_multisite() ? '/files/' : $content_dir;
$file_path = trailingslashit( $wp_upload_dir['basedir'] ) . basename( $urlinfo['path'] );
$file_path = preg_replace( '/(\/\/)/', '/', $file_path );
}
if ( file_exists( $file_path ) && is_file( $file_path ) ) { // file_exists checks for file/directory, is_file can be an extra check.
list( $width, $height ) = getimagesize( $file_path );
}
$item['src'] = $imagesrc;
$item['id'] = $id;
$item['height'] = intval( $height );
$item['width'] = intval( $width );
$images[ $i ] = $item;
++$i;
}
$data['gallery'] = $images;
}
if ( ! isset( $data['config'] ) || ! is_array( $data['config'] ) ) {
$data['config'] = [];
}
$data['config']['title'] = wp_strip_all_tags( get_the_title( $post_object['id'] ) );
$data['config']['description'] = Shortcode_Utils::get_description( $data );
return $data;
}
/**
* Rest API updater callback.
*
* @since 1.8.5
*
* @param array $value Value to update.
* @param object $post Post Object.
* @param string $field_name Meta field name.
*
* @return array
*/
public function update_gallery_data( $value, $post, $field_name ) {
$gallery_data = get_post_meta( $post->ID, '_eg_gallery_data', true );
// If Gallery Data is emptyy prepare it.
if ( ! is_array( $gallery_data ) ) {
$gallery_data = [];
}
if ( ! isset( $gallery_data['config'] ) ) {
$gallery_data['config'] = [];
}
if ( ! is_array( $gallery_data['config'] ) || empty( $gallery_data['config'] ) ) {
// Loop through the defaults and prepare them to be stored.
$defaults = envira_get_config_defaults( $post->ID );
foreach ( $defaults as $key => $default ) {
$gallery_data['config'][ $key ] = $default;
}
}
// Update Fields.
$gallery_data['id'] = $post->ID;
$gallery_data['config']['title'] = $post->title;
if ( isset( $value['config'] ) ) {
// Sanitize config values before saving to prevent XSS
$value['config'] = $this->sanitize_config_values( $value['config'] );
$gallery_data['config'] = wp_parse_args( $value['config'], $gallery_data['config'] );
}
if ( isset( $value['remove_image'] ) ) {
$in_gallery = get_post_meta( $post->ID, '_eg_in_gallery', true );
$has_gallery = get_post_meta( $value['attach_id'], '_eg_has_gallery', true );
// Unset the image from the gallery, in_gallery and has_gallery checkers.
unset( $gallery_data['gallery'][ $value['attach_id'] ] );
$key = array_search( $value['attach_id'], (array) $in_gallery, true );
if ( false !== $key ) {
unset( $in_gallery[ $key ] );
}
$has_key = array_search( $post->ID, (array) $has_gallery, true );
if ( false !== $has_key ) {
unset( $has_gallery[ $has_key ] );
}
}
if ( isset( $value['update_image'] ) ) {
$attach_id = $value['attach_id'];
$update_image = $value['updated_image'];
if ( isset( $update_image['title'] ) ) {
$gallery_data['gallery'][ $attach_id ]['title'] = trim( $update_image['title'] );
}
if ( isset( $update_image['caption'] ) ) {
$gallery_data['gallery'][ $attach_id ]['caption'] = trim( $update_image['caption'] );
}
}
if ( isset( $value['gallery'] ) ) {
foreach ( (array) $value['gallery'] as $i => $image ) {
$gallery_data = envira_prepare_gallery_data( $gallery_data, $image['id'] );
}
}
// Flush gallery cache.
envira_flush_gallery_caches( $post->ID );
return update_post_meta( $post->ID, '_eg_gallery_data', $gallery_data );
}
/**
* Sanitizes config values to prevent XSS attacks.
*
* Uses shared Sanitize_Utils helper to eliminate code duplication and maintain
* consistent validation logic across REST API and frontend rendering.
*
* @since 1.13.2
*
* @param array $config The config array to sanitize.
* @return array Sanitized config array.
*/
private function sanitize_config_values( $config ) {
// Sanitize description to prevent stored XSS via the REST API.
// REST payloads can supply any JSON type, so guard against non-scalar values before
// passing to wp_kses_post() which expects a string (fatal on PHP 8.1+ otherwise).
if ( isset( $config['description'] ) ) {
$description = is_scalar( $config['description'] ) ? (string) $config['description'] : '';
$config['description'] = wp_kses_post( $description );
}
// Sanitize justified_gallery_theme - ensure it's a valid theme
if ( isset( $config['justified_gallery_theme'] ) ) {
$valid_themes = envira_get_justified_gallery_themes();
$valid_theme_values = Sanitize_Utils::extract_values( $valid_themes );
$config['justified_gallery_theme'] = Sanitize_Utils::sanitize_against_allowlist(
$config['justified_gallery_theme'],
$valid_theme_values,
envira_get_config_default( 'justified_gallery_theme' )
);
}
// Sanitize justified_gallery_theme_detail - ensure it's a valid theme detail
if ( isset( $config['justified_gallery_theme_detail'] ) ) {
$valid_details = envira_get_justified_gallery_themes_details();
$valid_detail_values = Sanitize_Utils::extract_values( $valid_details );
$config['justified_gallery_theme_detail'] = Sanitize_Utils::sanitize_against_allowlist(
$config['justified_gallery_theme_detail'],
$valid_detail_values,
envira_get_config_default( 'justified_gallery_theme_detail' )
);
}
// Sanitize justified_row_height - ensure it's a positive integer
if ( isset( $config['justified_row_height'] ) ) {
$row_height = absint( $config['justified_row_height'] );
if ( $row_height <= 0 ) {
$row_height = envira_get_config_default( 'justified_row_height' );
}
$config['justified_row_height'] = $row_height;
}
return $config;
}
}