????

Your IP : 216.73.216.188


Current Path : /home/degesdxb/public_html/wp-content/themes/extendable/inc/
Upload File :
Current File : /home/degesdxb/public_html/wp-content/themes/extendable/inc/animations.php

<?php
/**
 * Animation functionality for Extendable theme
 *
 * @package Extendable
 * @since Extendable 2.0.33
 */

// Prevent direct access
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Register animation settings with WordPress Settings API
 * Registers REST API endpoint for managing animation preferences
 * 
 * @since Extendable 2.0.33
 * @return void
 */
function extendable_register_animation_settings() {
	register_setting( 'extendable_animations', 'extendify_animation_settings', array(
		'type' => 'object',
		'default' => array(
			'type' => 'none',
			'speed' => 'medium'
		),
		'show_in_rest' => array(
			'schema' => array(
				'type' => 'object',
				'properties' => array(
					'type' => array(
						'type' => 'string',
						'enum' => array( 'none', 'fade', 'fade-up', 'zoom-in' ),
					),
					'speed' => array(
						'type' => 'string',
						'enum' => array( 'slow', 'medium', 'fast' ),
					),
				),
			),
		),
		'sanitize_callback' => 'extendable_sanitize_animation_settings',
	));
}
add_action( 'rest_api_init', 'extendable_register_animation_settings' );

/**
 * Sanitize animation settings
 * Validates and sanitizes user input for animation configuration
 * 
 * @since Extendable 2.0.33
 * @param mixed $settings Animation settings to sanitize
 * @return array Sanitized settings with type and speed keys
 */
function extendable_sanitize_animation_settings( $settings ) {
	$valid_types = array( 'none', 'fade', 'fade-up', 'zoom-in' );
	$valid_speeds = array( 'slow', 'medium', 'fast' );
	
	if ( ! is_array( $settings ) ) {
		$settings = array();
	}
	
	$sanitized = array(
		'type' => 'none',
		'speed' => 'medium'
	);
	
	if ( isset( $settings['type'] ) && in_array( $settings['type'], $valid_types, true ) ) {
		$sanitized['type'] = $settings['type'];
	}
	
	if ( isset( $settings['speed'] ) && in_array( $settings['speed'], $valid_speeds, true ) ) {
		$sanitized['speed'] = $settings['speed'];
	}
	
	return $sanitized;
}

/**
 * Enqueue animations on frontend
 * Loads animation CSS/JS and configures based on user settings
 *
 * @since Extendable 2.0.33
 * @return void
 */
function extendable_enqueue_animations() {

	$animation_settings = get_option( 'extendify_animation_settings', array(
		'type' => 'none',
		'speed' => 'medium'
	));
	
	$animation_type = $animation_settings['type'] ?? 'none';
	$animation_speed = $animation_settings['speed'] ?? 'medium';
	
	if ( ! apply_filters( 'extendable_enable_animations', true ) ) {
	    return;
	}
	
    // Skip loading for visitors when animations disabled
    // Logged-in users need JS for real-time switching in agent UI
	if ( 'none' === $animation_type && ! is_user_logged_in() ) {
        return;
    }

	$config_file = get_template_directory() . '/assets/config/animations.json';
	
	if ( ! file_exists( $config_file ) || ! is_readable( $config_file ) ) {
		return;
	}
	
	$config = json_decode( file_get_contents( $config_file ), true );
	
	if ( ! is_array( $config ) ) {
		return;
	}
	
	$type = sanitize_key( $animation_type );
	
	if ( ! isset( $config['types'][ $type ] ) ) {
		$type = 'fade';
	}
	
	$mappings = $config['types'][ $type ]['mappings'] ?? array();
	$defaults = $config['defaults'] ?? array();
	$css_config = $config['css'] ?? array();

	$all_types = array();
	foreach ( $config['types'] as $type_key => $type_config ) {
		$type_mappings = array();
		if ( isset( $type_config['mappings'] ) && is_array( $type_config['mappings'] ) ) {
			foreach ( $type_config['mappings'] as $selector => $animation ) {
				$clean_selector = sanitize_text_field( trim( $selector ) );
				$clean_animation = sanitize_key( trim( $animation ) );
				if ( ! empty( $clean_selector ) && ! empty( $clean_animation ) ) {
					$type_mappings[ $clean_selector ] = $clean_animation;
				}
			}
		}
		if ( ! empty( $type_mappings ) ) {
			$all_types[ sanitize_key( $type_key ) ] = $type_mappings;
		}
	}

	$sanitized = array();
	foreach ( $mappings as $selector => $animation ) {
		$clean_selector = sanitize_text_field( trim( $selector ) );
		$clean_animation = sanitize_key( trim( $animation ) );
		
		if ( ! empty( $clean_selector ) && ! empty( $clean_animation ) ) {
			$sanitized[ $clean_selector ] = $clean_animation;
		}
	}
	
	if ( empty( $sanitized ) ) {
		return;
	}

	wp_enqueue_style(
		'extendable-animations',
		get_template_directory_uri() . '/assets/css/animations.css',
		array( 'extendable-style' ),
		EXTENDABLE_THEME_VERSION
	);

	wp_enqueue_script( 
		'extendable-animations', 
		get_template_directory_uri() . '/assets/js/animations-interactivity.js', 
		array(), 
		EXTENDABLE_THEME_VERSION, 
		true 
	);

	wp_localize_script( 'extendable-animations', 'ExtendableAnimations', array(
		'map' => $sanitized,
		'allTypes' => $all_types,
		'defaults' => array_map( 'sanitize_text_field', $defaults ),
		'speed' => sanitize_key( $animation_speed ),
		'type' => sanitize_key( $animation_type ),
	));

	// Generate FOUC prevention CSS (respects override classes and reduced motion preference)
	
	if ( 'none' === $animation_type ) {
        return;
    }

	$animation_css = '';
	foreach ( $sanitized as $selector => $animation ) {
		$css_rule = isset( $css_config[ $animation ] ) && ! empty( $css_config[ $animation ] )
			?  $css_config[ $animation ] 
			: 'opacity: 0;';
		
		// Only hide elements if reduced motion is not preferred
		$animation_css .= '@media (prefers-reduced-motion: no-preference) { ' . $selector . ':not(.ext-animate--off) { ' . $css_rule . ' } } ';
	}
	
	if ( ! empty( $animation_css ) ) {
		wp_add_inline_style( 'extendable-style', $animation_css );
	}
}
add_action( 'wp_enqueue_scripts', 'extendable_enqueue_animations' );

/**
 * Enqueue animation control for block editor
 *
 * @since Extendable 2.0.33
 * @return void
 */
function extendable_enqueue_animation_editor_control() {
	
	$animation_settings = get_option( 'extendify_animation_settings', array(
		'type' => 'none',
		'speed' => 'medium'
	));
	
	$animation_type = $animation_settings['type'] ?? 'none';
	$is_enabled = apply_filters( 'extendable_enable_animations', true ) && 
	              ! empty( $animation_type ) && 
	              'none' !== $animation_type;

	wp_enqueue_script(
		'extendable-animate-control',
		get_template_directory_uri() . '/assets/editor/block-animate-control.js',
		array( 'wp-blocks', 'wp-element', 'wp-components', 'wp-block-editor', 'wp-compose', 'wp-hooks', 'wp-i18n' ),
		EXTENDABLE_THEME_VERSION,
		true
	);

	wp_localize_script( 'extendable-animate-control', 'ExtendableAnimateControl', array(
		'enabled' => $is_enabled ? '1' : '0',
	) );
}
add_action( 'enqueue_block_editor_assets', 'extendable_enqueue_animation_editor_control' );

/**
 * Enqueue animation settings sidebar for site editor
 *
 * @since Extendable 2.0.33
 * @return void
 */
function extendable_enqueue_animation_sidebar() {
	
	wp_enqueue_script(
		'extendable-animation-sidebar',
		get_template_directory_uri() . '/assets/editor/animation-settings-modal.js',
		array( 'wp-plugins', 'wp-element', 'wp-components', 'wp-data', 'wp-api-fetch', 'wp-i18n' ),
		EXTENDABLE_THEME_VERSION,
		true
	);

	$animation_settings = get_option( 'extendify_animation_settings', array(
		'type' => 'none',
		'speed' => 'medium'
	));

	wp_localize_script( 'extendable-animation-sidebar', 'ExtendableAnimationSettings', array(
		'current' => $animation_settings,
	) );
}
add_action( 'enqueue_block_editor_assets', 'extendable_enqueue_animation_sidebar' );