PluginProbe
Elementor Website Builder – more than just a page builder / 4.2.0
Elementor Website Builder – more than just a page builder v4.2.0
4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 All 451 releases
elementor / modules / interactions / module.php

module.php in Elementor Website Builder – more than just a page builder 4.2.0, at modules/interactions/module.php

196 lines 5.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Elementor\Modules\Interactions;
4
5 use Elementor\Core\Base\Module as BaseModule;
6 use Elementor\Core\Base\Document;
7 use Elementor\Core\Experiments\Manager as Experiments_Manager;
8 use Elementor\Modules\AtomicWidgets\Module as AtomicWidgetsModule;
9 use Elementor\Modules\Interactions\Cache\Interactions_Postmeta;
10 use Elementor\Plugin;
11 use Elementor\Utils;
12
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit; // Exit if accessed directly.
15 }
16
17 class Module extends BaseModule {
18 const MODULE_NAME = 'e-interactions';
19 const EXPERIMENT_NAME = 'e_interactions';
20
21 const HANDLE_MOTION_JS = 'motion-js';
22 const HANDLE_SHARED_UTILS = 'elementor-interactions-shared-utils';
23 const HANDLE_FRONTEND = 'elementor-interactions';
24 const HANDLE_EDITOR = 'elementor-editor-interactions';
25 const JS_CONFIG_OBJECT = 'ElementorInteractionsConfig';
26 const SCRIPT_ID_INTERACTIONS_DATA = 'elementor-interactions-data';
27
28 public function get_name() {
29 return self::MODULE_NAME;
30 }
31
32 private $preset_animations;
33
34 private function get_presets() {
35 if ( ! $this->preset_animations ) {
36 $this->preset_animations = new Presets();
37 }
38
39 return $this->preset_animations;
40 }
41
42 private $frontend_handler;
43
44 private function get_frontend_handler() {
45 if ( ! $this->frontend_handler ) {
46 $this->frontend_handler = new Interactions_Frontend_Handler( fn () => $this->get_config() );
47 }
48
49 return $this->frontend_handler;
50 }
51
52 public static function get_experimental_data() {
53 return [
54 'name' => self::EXPERIMENT_NAME,
55 'title' => esc_html__( 'Interactions', 'elementor' ),
56 'description' => esc_html__( 'Enable element interactions.', 'elementor' ),
57 'hidden' => true,
58 'default' => Experiments_Manager::STATE_ACTIVE,
59 'release_status' => Experiments_Manager::RELEASE_STATUS_DEV,
60 ];
61 }
62
63 public function is_experiment_active() {
64 return Plugin::$instance->experiments->is_feature_active( self::EXPERIMENT_NAME )
65 && Plugin::$instance->experiments->is_feature_active( AtomicWidgetsModule::EXPERIMENT_NAME );
66 }
67
68 public function __construct() {
69 parent::__construct();
70
71 if ( ! $this->is_experiment_active() ) {
72 return;
73 }
74
75 $this->register_hooks();
76 }
77
78 private function register_hooks() {
79 add_action( 'elementor/frontend/after_register_scripts', fn () => $this->register_frontend_scripts() );
80 add_action( 'elementor/preview/enqueue_scripts', fn () => $this->enqueue_preview_scripts() );
81
82 add_action( 'elementor/editor/before_enqueue_scripts', fn () => $this->enqueue_editor_scripts() );
83 add_action( 'elementor/editor/after_enqueue_scripts', fn () => $this->enqueue_editor_scripts() );
84
85 add_filter( 'elementor/document/save/data', [ $this, 'handle_interactions' ], 10, 2 );
86 add_action( 'elementor/document/after_save', [ $this, 'handle_interactions_cache' ], 10, 2 );
87
88 // Collect interactions from documents before they render (header, footer, post content)
89 add_filter( 'elementor/frontend/builder_content_data', [
90 $this->get_frontend_handler(),
91 'collect_document_interactions',
92 ], 10, 2 );
93
94 // Output centralized interaction data in footer
95 add_action( 'wp_footer', [ $this->get_frontend_handler(), 'print_interactions_data' ], 1 );
96 }
97
98 /**
99 * Sanitize and validate data before saving the document.
100 *
101 * @throws \Exception When validation fails.
102 * @return array
103 */
104 public function handle_interactions( $data, $document ) {
105 $validation = new Validation();
106 $document_after_sanitization = $validation->sanitize( $data );
107
108 $validation->validate();
109
110 $parser = new Parser( $document->get_main_id() );
111 return $parser->assign_interaction_ids( $document_after_sanitization );
112 }
113
114 public function handle_interactions_cache( Document $document, $data ) {
115 $postmeta = new Interactions_Postmeta();
116 $postmeta->process_content( $document->get_main_id(), $data );
117 }
118
119 public function get_config() {
120 return [
121 'constants' => $this->get_presets()->defaults(),
122 'breakpoints' => $this->get_active_breakpoints(),
123 ];
124 }
125
126 private function get_active_breakpoints() {
127 $breakpoints_config = Plugin::$instance->breakpoints->get_breakpoints_config();
128 $active_breakpoints = Plugin::$instance->breakpoints->get_active_breakpoints();
129
130 $breakpoints = [];
131
132 foreach ( array_keys( $active_breakpoints ) as $breakpoint_label ) {
133 $breakpoints[ $breakpoint_label ] = $breakpoints_config[ $breakpoint_label ];
134 }
135
136 return $breakpoints;
137 }
138
139 private function register_frontend_scripts() {
140 $suffix = ( Utils::is_script_debug() || Utils::is_elementor_tests() ) ? '' : '.min';
141
142 wp_register_script(
143 self::HANDLE_MOTION_JS,
144 ELEMENTOR_ASSETS_URL . 'lib/motion/motion' . $suffix . '.js',
145 [],
146 '11.13.5',
147 true
148 );
149
150 wp_register_script(
151 self::HANDLE_SHARED_UTILS,
152 $this->get_js_assets_url( 'interactions-shared-utils' ),
153 [ self::HANDLE_MOTION_JS ],
154 '1.0.0',
155 true
156 );
157
158 wp_register_script(
159 self::HANDLE_FRONTEND,
160 $this->get_js_assets_url( 'interactions' ),
161 [ self::HANDLE_MOTION_JS, self::HANDLE_SHARED_UTILS ],
162 '1.0.0',
163 true
164 );
165
166 wp_register_script(
167 self::HANDLE_EDITOR,
168 $this->get_js_assets_url( 'editor-interactions' ),
169 [ self::HANDLE_MOTION_JS, self::HANDLE_SHARED_UTILS ],
170 '1.0.0',
171 true
172 );
173 }
174
175 public function enqueue_editor_scripts() {
176 wp_add_inline_script(
177 'elementor-common',
178 'window.' . self::JS_CONFIG_OBJECT . ' = ' . wp_json_encode( $this->get_config() ) . ';',
179 'before'
180 );
181 }
182
183 public function enqueue_preview_scripts() {
184 wp_enqueue_script( self::HANDLE_SHARED_UTILS );
185 // Ensure motion-js and editor-interactions handler are available in preview iframe
186 wp_enqueue_script( self::HANDLE_MOTION_JS );
187 wp_enqueue_script( self::HANDLE_EDITOR );
188
189 wp_localize_script(
190 self::HANDLE_EDITOR,
191 self::JS_CONFIG_OBJECT,
192 $this->get_config()
193 );
194 }
195 }
196