PluginProbe
Elementor Website Builder – more than just a page builder / 3.3.0
Elementor Website Builder – more than just a page builder v3.3.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 / core / kits / manager.php

manager.php in Elementor Website Builder – more than just a page builder 3.3.0, at core/kits/manager.php

411 lines 11.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Elementor\Core\Kits;
3
4 use Elementor\Core\Base\Document;
5 use Elementor\Core\Kits\Controls\Repeater;
6 use Elementor\Core\Kits\Documents\Tabs\Global_Colors;
7 use Elementor\Core\Kits\Documents\Tabs\Global_Typography;
8 use Elementor\Plugin;
9 use Elementor\Core\Files\CSS\Post as Post_CSS;
10 use Elementor\Core\Files\CSS\Post_Preview as Post_Preview;
11 use Elementor\Core\Documents_Manager;
12 use Elementor\Core\Kits\Documents\Kit;
13 use Elementor\TemplateLibrary\Source_Local;
14 use Elementor\Utils;
15
16 if ( ! defined( 'ABSPATH' ) ) {
17 exit; // Exit if accessed directly.
18 }
19
20 class Manager {
21
22 const OPTION_ACTIVE = 'elementor_active_kit';
23
24 const E_HASH_COMMAND_OPEN_SITE_SETTINGS = 'e:run:panel/global/open';
25
26 public function get_active_id() {
27 return get_option( self::OPTION_ACTIVE );
28 }
29
30 public function get_active_kit() {
31 $kit = Plugin::$instance->documents->get( $this->get_active_id() );
32
33 if ( ! $this->is_valid_kit( $kit ) ) {
34 return $this->get_empty_kit_instance();
35 }
36
37 return $kit;
38 }
39
40 public function get_active_kit_for_frontend() {
41 $kit = Plugin::$instance->documents->get_doc_for_frontend( $this->get_active_id() );
42
43 if ( ! $this->is_valid_kit( $kit ) ) {
44 return $this->get_empty_kit_instance();
45 }
46
47 return $kit;
48 }
49
50 /**
51 * @param $kit
52 *
53 * @return bool
54 */
55 private function is_valid_kit( $kit ) {
56 return $kit && $kit instanceof Kit && 'trash' !== $kit->get_main_post()->post_status;
57 }
58
59 /**
60 * Returns an empty kit for situation when there is no kit in the site.
61 *
62 * @return Kit
63 * @throws \Exception
64 */
65 private function get_empty_kit_instance() {
66 return new Kit( [
67 'settings' => [],
68 'post_id' => 0,
69 ] );
70 }
71
72 /**
73 * Checks if specific post is a kit.
74 *
75 * @param $post_id
76 *
77 * @return bool
78 */
79 public function is_kit( $post_id ) {
80 $document = Plugin::$instance->documents->get( $post_id );
81
82 return $document && $document instanceof Kit && ! $document->is_revision();
83 }
84
85
86 /**
87 * Init kit controls.
88 *
89 * A temp solution in order to avoid init kit group control from within another group control.
90 *
91 * After moving the `default_font` to the kit, the Typography group control cause initialize the kit controls at: https://github.com/elementor/elementor/blob/e6e1db9eddef7e3c1a5b2ba0c2338e2af2a3bfe3/includes/controls/groups/typography.php#L91
92 * and because the group control is a singleton, its args are changed to the last kit group control.
93 */
94 public function init_kit_controls() {
95 $this->get_active_kit_for_frontend()->get_settings();
96 }
97
98 public function get_current_settings( $setting = null ) {
99 $kit = $this->get_active_kit_for_frontend();
100
101 if ( ! $kit ) {
102 return '';
103 }
104
105 return $kit->get_settings( $setting );
106 }
107
108 public function create( array $kit_data = [], array $kit_meta_data = [] ) {
109 $default_kit_data = [
110 'post_status' => 'publish',
111 ];
112
113 $kit_data = array_merge( $default_kit_data, $kit_data );
114
115 $kit_data['post_type'] = Source_Local::CPT;
116
117 $kit = Plugin::$instance->documents->create( 'kit', $kit_data, $kit_meta_data );
118
119 return $kit->get_id();
120 }
121
122 public function create_default() {
123 return $this->create( [
124 'post_title' => __( 'Default Kit', 'elementor' ),
125 ] );
126 }
127
128 /**
129 * Create a default kit if needed.
130 *
131 * This action runs on activation hook, all the Plugin components do not exists and
132 * the Document manager and Kits manager instances cannot be used.
133 *
134 * @return int|void|\WP_Error
135 */
136 public static function create_default_kit() {
137 if ( get_option( self::OPTION_ACTIVE ) ) {
138 return;
139 }
140
141 $id = wp_insert_post( [
142 'post_title' => __( 'Default Kit', 'elementor' ),
143 'post_type' => Source_Local::CPT,
144 'post_status' => 'publish',
145 'meta_input' => [
146 '_elementor_edit_mode' => 'builder',
147 Document::TYPE_META_KEY => 'kit',
148 ],
149 ] );
150
151 update_option( self::OPTION_ACTIVE, $id );
152
153 return $id;
154 }
155
156 /**
157 * @param Documents_Manager $documents_manager
158 */
159 public function register_document( $documents_manager ) {
160 $documents_manager->register_document_type( 'kit', Kit::get_class_full_name() );
161 }
162
163 public function localize_settings( $settings ) {
164 $kit = $this->get_active_kit();
165 $kit_controls = $kit->get_controls();
166 $design_system_controls = [
167 'colors' => $kit_controls['system_colors']['fields'],
168 'typography' => $kit_controls['system_typography']['fields'],
169 ];
170
171 $settings = array_replace_recursive( $settings, [
172 'kit_id' => $kit->get_main_id(),
173 'kit_config' => [
174 'typography_prefix' => Global_Typography::TYPOGRAPHY_GROUP_PREFIX,
175 'design_system_controls' => $design_system_controls,
176 ],
177 'user' => [
178 'can_edit_kit' => $kit->is_editable_by_current_user(),
179 ],
180 ] );
181
182 return $settings;
183 }
184
185 public function preview_enqueue_styles() {
186 $kit = $this->get_kit_for_frontend();
187
188 if ( $kit ) {
189 // On preview, the global style is not enqueued.
190 $this->frontend_before_enqueue_styles();
191
192 Plugin::$instance->frontend->print_fonts_links();
193 }
194 }
195
196 public function frontend_before_enqueue_styles() {
197 $kit = $this->get_kit_for_frontend();
198
199 if ( $kit ) {
200 if ( $kit->is_autosave() ) {
201 $css_file = Post_Preview::create( $kit->get_id() );
202 } else {
203 $css_file = Post_CSS::create( $kit->get_id() );
204 }
205
206 $css_file->enqueue();
207 }
208 }
209
210 public function render_panel_html() {
211 require __DIR__ . '/views/panel.php';
212 }
213
214 public function get_kit_for_frontend() {
215 $kit = false;
216 $active_kit = $this->get_active_kit();
217 $is_kit_preview = is_preview() && isset( $_GET['preview_id'] ) && $active_kit->get_main_id() === (int) $_GET['preview_id'];
218
219 if ( $is_kit_preview ) {
220 $kit = Plugin::$instance->documents->get_doc_or_auto_save( $active_kit->get_main_id(), get_current_user_id() );
221 } elseif ( 'publish' === $active_kit->get_main_post()->post_status ) {
222 $kit = $active_kit;
223 }
224
225 return $kit;
226 }
227
228 public function update_kit_settings_based_on_option( $key, $value ) {
229 /** @var Kit $active_kit */
230 $active_kit = $this->get_active_kit();
231
232 if ( $active_kit->is_saving() ) {
233 return;
234 }
235
236 $active_kit->update_settings( [ $key => $value ] );
237 }
238
239 /**
240 * Map Scheme To Global
241 *
242 * Convert a given scheme value to its corresponding default global value
243 *
244 * @param string $type 'color'/'typography'
245 * @param $value
246 * @return mixed
247 */
248 private function map_scheme_to_global( $type, $value ) {
249 $schemes_to_globals_map = [
250 'color' => [
251 '1' => Global_Colors::COLOR_PRIMARY,
252 '2' => Global_Colors::COLOR_SECONDARY,
253 '3' => Global_Colors::COLOR_TEXT,
254 '4' => Global_Colors::COLOR_ACCENT,
255 ],
256 'typography' => [
257 '1' => Global_Typography::TYPOGRAPHY_PRIMARY,
258 '2' => Global_Typography::TYPOGRAPHY_SECONDARY,
259 '3' => Global_Typography::TYPOGRAPHY_TEXT,
260 '4' => Global_Typography::TYPOGRAPHY_ACCENT,
261 ],
262 ];
263
264 return $schemes_to_globals_map[ $type ][ $value ];
265 }
266
267 /**
268 * Convert Scheme to Default Global
269 *
270 * If a control has a scheme property, convert it to a default Global.
271 *
272 * @param $scheme - Control scheme property
273 * @return array - Control/group control args
274 * @since 3.0.0
275 * @access public
276 */
277 public function convert_scheme_to_global( $scheme ) {
278 if ( isset( $scheme['type'] ) && isset( $scheme['value'] ) ) {
279 //_deprecated_argument( $args['scheme'], '3.0.0', 'Schemes are now deprecated - use $args[\'global\'] instead.' );
280 return $this->map_scheme_to_global( $scheme['type'], $scheme['value'] );
281 }
282
283 // Typography control 'scheme' properties usually only include the string with the typography value ('1'-'4').
284 return $this->map_scheme_to_global( 'typography', $scheme );
285 }
286
287 public function register_controls() {
288 $controls_manager = Plugin::$instance->controls_manager;
289
290 $controls_manager->register_control( Repeater::CONTROL_TYPE, new Repeater() );
291 }
292
293 public function is_custom_colors_enabled() {
294 return ! get_option( 'elementor_disable_color_schemes' );
295 }
296
297 public function is_custom_typography_enabled() {
298 return ! get_option( 'elementor_disable_typography_schemes' );
299 }
300
301 /**
302 * Add kit wrapper body class.
303 *
304 * It should be added even for non Elementor pages,
305 * in order to support embedded templates.
306 */
307 private function add_body_class() {
308 $kit = $this->get_kit_for_frontend();
309
310 if ( $kit ) {
311 Plugin::$instance->frontend->add_body_class( 'elementor-kit-' . $kit->get_main_id() );
312 }
313 }
314
315 /**
316 * Send a confirm message before move a kit to trash, or if delete permanently not for trash.
317 *
318 * @param $post_id
319 * @param false $is_permanently_delete
320 */
321 private function before_delete_kit( $post_id, $is_permanently_delete = false ) {
322 $document = Plugin::$instance->documents->get( $post_id );
323
324 if (
325 ! $document ||
326 ! $this->is_kit( $post_id ) ||
327 isset( $_GET['force_delete_kit'] ) || // phpcs:ignore -- nonce validation is not require here.
328 ( $is_permanently_delete && $document->is_trash() )
329 ) {
330 return;
331 }
332
333 ob_start();
334 require __DIR__ . '/views/trash-kit-confirmation.php';
335
336 $confirmation_content = ob_get_clean();
337
338 wp_die(
339 new \WP_Error( 'cant_delete_kit', $confirmation_content )
340 );
341 }
342
343 /**
344 * Add 'Edit with elementor -> Site Settings' in admin bar.
345 *
346 * @param [] $admin_bar_config
347 *
348 * @return array $admin_bar_config
349 */
350 private function add_menu_in_admin_bar( $admin_bar_config ) {
351 $document = Plugin::$instance->documents->get( get_the_ID() );
352
353 if ( ! $document || ! $document->is_built_with_elementor() ) {
354 $recent_edited_post = Utils::get_recently_edited_posts_query( [
355 'posts_per_page' => 1,
356 ] );
357
358 if ( $recent_edited_post->post_count ) {
359 $posts = $recent_edited_post->get_posts();
360 $document = Plugin::$instance->documents->get( reset( $posts )->ID );
361 }
362 }
363
364 if ( $document ) {
365 $admin_bar_config['elementor_edit_page']['children'][] = [
366 'id' => 'elementor_site_settings',
367 'title' => __( 'Site Settings', 'elementor' ),
368 'sub_title' => __( 'Site', 'elementor' ),
369 'href' => $document->get_edit_url() . '#' . self::E_HASH_COMMAND_OPEN_SITE_SETTINGS,
370 'class' => 'elementor-site-settings',
371 'parent_class' => 'elementor-second-section',
372 ];
373 }
374
375 return $admin_bar_config;
376 }
377
378 public function __construct() {
379 add_action( 'elementor/documents/register', [ $this, 'register_document' ] );
380 add_filter( 'elementor/editor/localize_settings', [ $this, 'localize_settings' ] );
381 add_filter( 'elementor/editor/footer', [ $this, 'render_panel_html' ] );
382 add_action( 'elementor/frontend/after_enqueue_styles', [ $this, 'frontend_before_enqueue_styles' ], 0 );
383 add_action( 'elementor/preview/enqueue_styles', [ $this, 'preview_enqueue_styles' ], 0 );
384 add_action( 'elementor/controls/controls_registered', [ $this, 'register_controls' ] );
385
386 add_action( 'wp_trash_post', function ( $post_id ) {
387 $this->before_delete_kit( $post_id );
388 } );
389
390 add_action( 'before_delete_post', function ( $post_id ) {
391 $this->before_delete_kit( $post_id, true );
392 } );
393
394 add_action( 'update_option_blogname', function ( $old_value, $value ) {
395 $this->update_kit_settings_based_on_option( 'site_name', $value );
396 }, 10, 2 );
397
398 add_action( 'update_option_blogdescription', function ( $old_value, $value ) {
399 $this->update_kit_settings_based_on_option( 'site_description', $value );
400 }, 10, 2 );
401
402 add_action( 'wp_head', function() {
403 $this->add_body_class();
404 } );
405
406 add_filter( 'elementor/frontend/admin_bar/settings', function ( $admin_bar_config ) {
407 return $this->add_menu_in_admin_bar( $admin_bar_config );
408 }, 9 /* Before site-editor (theme-builder) */ );
409 }
410 }
411