PluginProbe
Elementor Website Builder – more than just a page builder / 3.13.2
Elementor Website Builder – more than just a page builder v3.13.2
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 / core / editor / editor-loader.php

editor-loader.php in Elementor Website Builder – more than just a page builder 3.13.2, at core/editor/editor-loader.php

270 lines 7.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Elementor\Core\Editor;
3
4 use Elementor\Core\Editor\Config_Providers\Config_Provider_Interface;
5 use Elementor\Core\Utils\Collection;
6 use Elementor\Plugin;
7 use Elementor\Utils;
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit; // Exit if accessed directly.
11 }
12
13 class Editor_Loader {
14 /**
15 * @var Config_Provider_Interface
16 */
17 private $config_provider;
18
19 /**
20 * @param Config_Provider_Interface $config_provider
21 */
22 public function __construct( Config_Provider_Interface $config_provider ) {
23 $this->config_provider = $config_provider;
24 }
25
26 /**
27 * @return void
28 */
29 public function register_hooks() {
30 $script_configs = $this->get_script_configs();
31
32 // Pointing WordPress to use translations for external files ('assets/js/editor.strings.js') and not
33 // for the original file (assets/js/editor.js).
34 add_filter( 'load_script_textdomain_relative_path', function ( $relative_path, $src ) use ( $script_configs ) {
35 return $this->replace_requested_translation_file( $relative_path, $src, $script_configs );
36 }, 10, 2 );
37 }
38
39 /**
40 * @return void
41 */
42 public function register_scripts() {
43 $script_configs = $this->get_script_configs();
44
45 foreach ( $script_configs as $script_config ) {
46 wp_register_script(
47 $script_config['handle'],
48 $script_config['src'],
49 $script_config['deps'],
50 $script_config['version'],
51 $script_config['in_footer']
52 );
53 }
54 }
55
56 public function print_client_settings() {
57 $client_settings = $this->config_provider->get_client_settings();
58
59 $client_settings = Collection::make( $client_settings )
60 ->filter( function ( $config ) {
61 return (
62 ! empty( $config['handle'] ) &&
63 ! empty( $config['name'] ) &&
64 ! empty( $config['settings'] )
65 );
66 } );
67
68 foreach ( $client_settings as $client_setting ) {
69 Utils::print_js_config(
70 $client_setting['handle'],
71 $client_setting['name'],
72 $client_setting['settings']
73 );
74 }
75 }
76
77 /**
78 * @return void
79 */
80 public function enqueue_scripts() {
81 foreach ( $this->config_provider->get_script_handles_to_enqueue() as $script_handle ) {
82 wp_enqueue_script( $script_handle );
83 }
84 }
85
86 /**
87 * @return void
88 */
89 public function load_scripts_translations() {
90 $script_configs = $this->get_script_configs();
91
92 foreach ( $script_configs as $script_config ) {
93 if ( $script_config['i18n']['domain'] ) {
94 wp_set_script_translations(
95 $script_config['handle'],
96 $script_config['i18n']['domain']
97 );
98 }
99 }
100 }
101
102 /**
103 * @return void
104 */
105 public function register_styles() {
106 $styles_config = $this->get_style_configs();
107
108 foreach ( $styles_config as $style_config ) {
109 wp_register_style(
110 $style_config['handle'],
111 $style_config['src'],
112 $style_config['deps'],
113 $style_config['version'],
114 $style_config['media']
115 );
116 }
117 }
118
119 /**
120 * @return void
121 */
122 public function enqueue_styles() {
123 foreach ( $this->config_provider->get_style_handles_to_enqueue() as $style_handle ) {
124 wp_enqueue_style( $style_handle );
125 }
126 }
127
128 /**
129 * @return void
130 */
131 public function print_root_template() {
132 // Exposing the path for the view part to render the body of the editor template.
133 $body_file_path = $this->config_provider->get_template_body_file_path();
134
135 include ELEMENTOR_PATH . 'includes/editor-templates/editor-wrapper.php';
136 }
137
138 public function register_additional_templates() {
139 $templates = $this->config_provider->get_additional_template_paths();
140
141 foreach ( $templates as $template_path ) {
142 Plugin::$instance->common->add_template( $template_path );
143 }
144 }
145
146 /**
147 * @return Collection
148 */
149 private function get_script_configs() {
150 return $this->normalize_asset_configs(
151 $this->config_provider->get_script_configs(),
152 'script'
153 );
154 }
155
156 /**
157 * @return Collection
158 */
159 private function get_style_configs() {
160 return $this->normalize_asset_configs(
161 $this->config_provider->get_style_configs(),
162 'style'
163 );
164 }
165
166 /**
167 * Normalize script/style configs to enqueue and register methods.
168 *
169 * @param array $script_configs
170 * @param string $type can be ['script', 'style']
171 *
172 * @return Collection
173 */
174 private function normalize_asset_configs( array $script_configs, $type ) {
175 $additional_defaults = 'style' === $type ?
176 [ 'media' => 'all' ] :
177 [
178 'in_footer' => true,
179 'i18n' => [
180 'domain' => null,
181 'replace_requested_file' => false,
182 'replace_requested_file_callback' => function ( $relative_path ) {
183 // By default, we suffix the file with `.strings` e.g 'assets/js/editor.js' => 'assets/js/editor.strings.js'.
184
185 // Translations are always based on the non-minified filename.
186 $relative_path_without_ext = preg_replace( '/(\.min)?\.js$/i', '', $relative_path );
187
188 return implode( '.', [
189 $relative_path_without_ext,
190 'strings',
191 'js',
192 ] );
193 },
194 ],
195 ];
196
197 $default = array_replace_recursive( [
198 'handle' => '',
199 'src' => '',
200 'deps' => [],
201 'version' => ELEMENTOR_VERSION,
202 'in_footer' => true,
203 ], $additional_defaults );
204
205 $replacements = [
206 '{{ELEMENTOR_ASSETS_URL}}' => ELEMENTOR_ASSETS_URL,
207 '{{MIN_SUFFIX}}' => ( Utils::is_script_debug() || Utils::is_elementor_tests() ) ? '' : '.min',
208 '{{DIRECTION_SUFFIX}}' => is_rtl() ? '-rtl' : '',
209 ];
210
211 return Collection::make( $script_configs )
212 ->filter( function ( $config ) {
213 return ! empty( $config['handle'] ) && ! empty( $config['src'] );
214 } )
215 ->map( function ( $config ) use ( $default, $replacements ) {
216 // Assign default values.
217 $config = array_replace_recursive( $default, $config );
218
219 // Replace placeholders with actual values.
220 foreach ( $replacements as $replacement_key => $replacement_value ) {
221 $config['src'] = str_replace(
222 $replacement_key,
223 $replacement_value,
224 $config['src']
225 );
226 }
227
228 return $config;
229 } );
230 }
231
232 /**
233 * The purpose of this function is to replace the requested translation file
234 * with a file that contains all the translations for specific scripts.
235 *
236 * When writing a script and using Webpack's dynamic load feature,
237 * the script will be split into multiple chunks,
238 * therefore the translations that generated by WordPress will also split into multiple files,
239 * for that reason we replace the requested translation file with another file (generated in the build process)
240 * that contains all the translations for the specific script (including dynamically loaded chunks).
241 *
242 * Want to go deeper? Read the following article:
243 * @see https://developer.wordpress.com/2022/01/06/wordpress-plugin-i18n-webpack-and-composer/
244 *
245 * @param string $relative_path
246 * @param string $src
247 * @param Collection $script_configs Collection of all the script configs
248 *
249 * @return string
250 */
251 private function replace_requested_translation_file( $relative_path, $src, $script_configs ) {
252 $script_config = $script_configs->find( function ( $script_config ) use ( $src ) {
253 return $script_config['src'] === $src;
254 } );
255
256 $should_suffix_path = $script_config &&
257 $script_config['i18n']['domain'] &&
258 $script_config['i18n']['replace_requested_file'];
259
260 if ( ! $should_suffix_path ) {
261 return $relative_path;
262 }
263
264 return $script_config['i18n']['replace_requested_file_callback'](
265 $relative_path,
266 $script_config
267 );
268 }
269 }
270