[ SYSTEM ]: Linux wordpress 6.1.0-44-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.164-1 (2026-03-09) x86_64
[ SERVER ]: Apache/2.4.66 (Debian) | PHP: 8.2.30
[ USER ]: www-data | IP: 172.19.30.54
GEFORCE FILE MANAGER
/
var
/
www
/
html
/
wordpress
/
wp-content
/
plugins
/
elementor
/
modules
/
interactions
/
UPLOAD:
NAME
SIZE
QUICK PERMS
ACTIONS
📁 props
SET
[ DEL ]
📁 schema
SET
[ DEL ]
📁 validators
SET
[ DEL ]
📄 interactions-collector.php
1,666 B
SET
[ EDIT ]
|
[ DEL ]
📄 interactions-frontend-handler.php
6,780 B
SET
[ EDIT ]
|
[ DEL ]
📄 module.php
5,325 B
SET
[ EDIT ]
|
[ DEL ]
📄 parser.php
2,779 B
SET
[ EDIT ]
|
[ DEL ]
📄 presets.php
1,705 B
SET
[ EDIT ]
|
[ DEL ]
📄 validation.php
11,277 B
SET
[ EDIT ]
|
[ DEL ]
DELETE SELECTED
[ CLOSE ]
EDIT: interactions-frontend-handler.php
<?php namespace Elementor\Modules\Interactions; use Elementor\Plugin; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Handles frontend-specific interaction logic including: * - Collecting interactions from document elements during render * - Outputting interaction data as JSON in the page footer * * This class is responsible for the frontend rendering pipeline of interactions, * working with the Interactions_Collector for data storage and Adapter for data transformation. */ class Interactions_Frontend_Handler { /** * @var callable|null */ private $config_provider; public function __construct( $config_provider = null ) { $this->config_provider = is_callable( $config_provider ) ? $config_provider : null; } /** * Collect interactions from document elements during frontend render. * * This method is hooked to 'elementor/frontend/builder_content_data' filter * to capture interactions from all documents (header, footer, post content) * as they are rendered. * * @param array $elements_data The document's elements data. * @param int $post_id The document's post ID. * @return array The unmodified elements data (pass-through filter). */ public function collect_document_interactions( $elements_data, $post_id ) { // Only collect on frontend, not in editor if ( Plugin::$instance->editor->is_edit_mode() ) { return $elements_data; } if ( empty( $elements_data ) || ! is_array( $elements_data ) ) { return $elements_data; } $collector = Interactions_Collector::instance(); // Recursively collect interactions from all elements $this->collect_interactions_recursive( $elements_data, $collector ); return $elements_data; } /** * Recursively iterate through all elements and collect interactions. * * @param array $elements Array of element data. * @param Interactions_Collector $collector The collector instance. */ private function collect_interactions_recursive( $elements, $collector ) { if ( ! is_array( $elements ) ) { return; } foreach ( $elements as $element ) { if ( ! is_array( $element ) ) { continue; } // Check if this element has interactions if ( ! empty( $element['id'] ) && isset( $element['interactions'] ) ) { $element_id = $element['id']; $interactions = $element['interactions']; // Decode if it's a JSON string if ( is_string( $interactions ) ) { $decoded = json_decode( $interactions, true ); if ( json_last_error() === JSON_ERROR_NONE && is_array( $decoded ) ) { $interactions = $decoded; } else { $interactions = null; } } // Normalize the interactions format - ensure we have items array if ( is_array( $interactions ) ) { // If interactions has 'items' key, it's already in the right format // If not, check if it's a direct array of items or has other structure if ( ! isset( $interactions['items'] ) ) { // Check if this looks like a direct array of interaction items // (first element has 'trigger' or 'animation' or '$$type') $first_item = reset( $interactions ); if ( is_array( $first_item ) && ( isset( $first_item['trigger'] ) || isset( $first_item['animation'] ) || isset( $first_item['$$type'] ) ) ) { // It's a direct array of items, wrap it $interactions = [ 'items' => $interactions ]; } } // Register with collector if we have valid items $items = $interactions['items'] ?? []; if ( ! empty( $items ) || ! empty( $interactions ) ) { $collector->register( $element_id, $interactions ); } } } // Recursively process child elements if ( ! empty( $element['elements'] ) && is_array( $element['elements'] ) ) { $this->collect_interactions_recursive( $element['elements'], $collector ); } } } /** * Output collected interaction data as a JSON script tag in the footer. * * This method is hooked to 'wp_footer' to output all collected interactions * as a centralized JSON data block that the frontend JavaScript can consume. */ public function print_interactions_data() { // Only output on frontend, not in editor if ( Plugin::$instance->editor->is_edit_mode() ) { return; } $collector = Interactions_Collector::instance(); $all_interactions = $collector->get_all(); if ( empty( $all_interactions ) ) { return; } // Format: array of elements, each with elementId, dataId, and cleaned interactions $elements_with_interactions = []; foreach ( $all_interactions as $element_id => $interactions ) { $items = $this->extract_interaction_items( $interactions ); if ( empty( $items ) ) { continue; } // Build element entry with elementId, dataId, and cleaned interactions array $elements_with_interactions[] = [ 'elementId' => $element_id, 'dataId' => $element_id, 'interactions' => $items, ]; } if ( empty( $elements_with_interactions ) ) { return; } $this->enqueue_interactions_assets(); // Output as JSON script tag $json_data = wp_json_encode( $elements_with_interactions, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- JSON data is already encoded echo '<script type="application/json" id="' . Module::SCRIPT_ID_INTERACTIONS_DATA . '">' . $json_data . '</script>'; } /** * Extract interaction items from various data formats. * * Handles multiple formats: * - v1 format: { items: [...] } * - v2 format with $$type: { items: { $$type: '...', value: [...] } } * - Direct arrays: [{ trigger: ..., animation: ... }, ...] * * @param array $interactions The interactions data. * @return array The extracted items array. */ private function extract_interaction_items( $interactions ) { if ( ! is_array( $interactions ) ) { return []; } // Check if it has 'items' key (standard format) if ( isset( $interactions['items'] ) ) { $items = $interactions['items']; return is_array( $items ) ? $items : []; } // Check if interactions itself is a direct array of items // (first element has interaction-related keys) $first_item = reset( $interactions ); if ( is_array( $first_item ) && ( isset( $first_item['trigger'] ) || isset( $first_item['animation'] ) || isset( $first_item['$$type'] ) ) ) { return $interactions; } return []; } private function enqueue_interactions_assets() { wp_enqueue_script( Module::HANDLE_MOTION_JS ); wp_enqueue_script( Module::HANDLE_FRONTEND ); $config = $this->config_provider ? call_user_func( $this->config_provider ) : []; wp_localize_script( Module::HANDLE_FRONTEND, Module::JS_CONFIG_OBJECT, $config ); } }