PluginProbe
Elementor Website Builder – more than just a page builder / 3.23.0-dev3
Elementor Website Builder – more than just a page builder v3.23.0-dev3
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
← All changes | modules/floating-buttons/module.php +128 -168 4.2.43.23.0-dev3 View file →
@@ -2,143 +2,117 @@
2 2
3 3 namespace Elementor\Modules\FloatingButtons;
4 4
5 5 use Elementor\Controls_Manager;
6 +use Elementor\Core\Admin\Menu\Admin_Menu_Manager;
6 7 use Elementor\Core\Base\Document;
7 8 use Elementor\Core\Base\Module as BaseModule;
8 9 use Elementor\Core\Documents_Manager;
9 -use Elementor\Modules\FloatingButtons\Base\Widget_Floating_Bars_Base;
10 +use Elementor\Core\Experiments\Manager;
11 +use Elementor\Modules\FloatingButtons\AdminMenuItems\Floating_Buttons_Empty_View_Menu_Item;
12 +use Elementor\Modules\FloatingButtons\AdminMenuItems\Floating_Buttons_Menu_Item;
10 13 use Elementor\Modules\FloatingButtons\Base\Widget_Contact_Button_Base;
11 -use Elementor\Modules\FloatingButtons\Classes\Action\Action_Handler;
12 14 use Elementor\Modules\FloatingButtons\Control\Hover_Animation_Floating_Buttons;
13 15 use Elementor\Modules\FloatingButtons\Documents\Floating_Buttons;
14 16 use Elementor\Plugin;
15 17 use Elementor\TemplateLibrary\Source_Local;
16 18 use Elementor\Utils as ElementorUtils;
17 -use Elementor\Modules\EditorOne\Classes\Menu_Data_Provider;
18 -use Elementor\Modules\FloatingButtons\AdminMenuItems\Editor_One_Floating_Elements_Menu;
19 19
20 20 if ( ! defined( 'ABSPATH' ) ) {
21 - exit; // Exit if accessed directly.
21 + exit; // Exit if accessed directly
22 22 }
23 23
24 24 class Module extends BaseModule {
25 25
26 - const FLOATING_ELEMENTS_TYPE_META_KEY = '_elementor_floating_elements_type';
26 + const EXPERIMENT_NAME = 'floating-buttons';
27 +
28 + const ROUTER_VERSION = '1.0.0';
27 29 const ROUTER_OPTION_KEY = 'elementor_floating_buttons_router_version';
30 +
28 31 const META_CLICK_TRACKING = '_elementor_click_tracking';
32 +
29 33 const CLICK_TRACKING_NONCE = 'elementor-conversion-center-click';
34 +
30 35 const FLOATING_BUTTONS_DOCUMENT_TYPE = 'floating-buttons';
31 36 const CPT_FLOATING_BUTTONS = 'e-floating-buttons';
32 37 const ADMIN_PAGE_SLUG_CONTACT = 'edit.php?post_type=e-floating-buttons';
33 - const WIDGET_HAS_CUSTOM_BREAKPOINTS = true;
34 38
35 39 private $has_contact_pages = null;
36 40 private $trashed_contact_pages;
41 + private $new_contact_pages_url;
37 42
38 43 public static function is_active(): bool {
39 - return Plugin::$instance->experiments->is_feature_active( 'container' );
44 + return Plugin::$instance->experiments->is_feature_active( static::EXPERIMENT_NAME );
40 45 }
41 46
42 - public static function get_floating_elements_types() {
43 - return [
44 - 'floating-buttons' => esc_html__( 'Floating Buttons', 'elementor' ),
45 - 'floating-bars' => esc_html__( 'Floating Bars', 'elementor' ),
46 - ];
47 - }
48 -
49 47 public function get_name(): string {
50 - return 'floating-buttons';
48 + return static::EXPERIMENT_NAME;
51 49 }
52 50
53 51 public function get_widgets(): array {
52 + return [
53 + 'Contact_Buttons',
54 + ];
55 + }
54 56
57 + public static function get_experimental_data(): array {
55 58 return [
56 - 'Contact_Buttons',
57 - 'Floating_Bars_Var_1',
59 + 'name' => static::EXPERIMENT_NAME,
60 + 'title' => esc_html__( 'Floating Buttons', 'elementor' ),
61 + 'description' => esc_html__( 'Boost visitor engagement with Floating Buttons. The Floating Button template library offers a variety of interactive one-click contact options, highlighted links, and calls to action to increase your website conversions.', 'elementor' ),
62 + 'default' => Manager::STATE_INACTIVE,
63 + 'release_status' => Manager::RELEASE_STATUS_BETA,
64 + 'dependencies' => [
65 + 'container',
66 + ],
67 + 'new_site' => [
68 + 'default_active' => true,
69 + 'minimum_installation_version' => '3.23.0',
70 + ],
58 71 ];
59 72 }
60 73
61 - private function register_editor_one_menu( Menu_Data_Provider $menu_data_provider ) {
62 - $menu_data_provider->register_menu( new Editor_One_Floating_Elements_Menu() );
74 + private function register_admin_menu_legacy( Admin_Menu_Manager $admin_menu ) {
75 + $menu_args = $this->get_contact_menu_args();
76 + $function = $menu_args['function'];
77 + if ( is_callable( $function ) ) {
78 + $admin_menu->register( $menu_args['menu_slug'], new Floating_Buttons_Empty_View_Menu_Item( $function ) );
79 + } else {
80 + $admin_menu->register( $menu_args['menu_slug'], new Floating_Buttons_Menu_Item() );
81 + };
82 +
63 83 }
64 84
65 85 public function __construct() {
66 86 parent::__construct();
67 87
68 - if ( Floating_Buttons::is_creating_floating_buttons_page() || Floating_Buttons::is_editing_existing_floating_buttons_page() ) {
88 + if ( $this->is_editing_existing_floating_buttons_page() || $this->is_creating_floating_buttons_page() ) {
69 89 Controls_Manager::add_tab(
70 90 Widget_Contact_Button_Base::TAB_ADVANCED,
71 91 esc_html__( 'Advanced', 'elementor' )
72 92 );
73 -
74 - Controls_Manager::add_tab(
75 - Widget_Floating_Bars_Base::TAB_ADVANCED,
76 - esc_html__( 'Advanced', 'elementor' )
77 - );
78 93 }
79 94
80 95 $this->register_contact_pages_cpt();
81 96
82 - add_action( 'elementor/documents/register', function ( Documents_Manager $documents_manager ) {
83 - $documents_manager->register_document_type(
84 - static::FLOATING_BUTTONS_DOCUMENT_TYPE,
85 - Floating_Buttons::get_class_full_name()
86 - );
87 - } );
97 + if ( ! ElementorUtils::has_pro() ) {
98 + add_action( 'elementor/documents/register', function ( Documents_Manager $documents_manager ) {
99 + $documents_manager->register_document_type(
100 + static::FLOATING_BUTTONS_DOCUMENT_TYPE,
101 + Floating_Buttons::get_class_full_name()
102 + );
103 + } );
104 + }
88 105
89 - add_action( 'current_screen', function() {
90 - $screen = get_current_screen();
91 - if ( $screen && 'edit-e-floating-buttons' === $screen->id ) {
92 - $this->flush_permalinks_on_elementor_version_change();
93 - }
94 - });
106 + add_action( 'save_post_' . static::CPT_FLOATING_BUTTONS, [ $this, 'flush_permalinks_on_save' ] );
95 107
96 - add_filter( 'elementor/editor-one/menu/elementor_post_types', function ( array $elementor_post_types ): array {
97 - $elementor_post_types[ static::CPT_FLOATING_BUTTONS ] = [
98 - 'menu_slug' => 'elementor-editor-templates',
99 - 'child_slug' => 'edit.php?post_type=e-floating-buttons',
100 - ];
101 - return $elementor_post_types;
102 - } );
103 -
104 108 add_action( 'wp_ajax_elementor_send_clicks', [ $this, 'handle_click_tracking' ] );
105 109 add_action( 'wp_ajax_nopriv_elementor_send_clicks', [ $this, 'handle_click_tracking' ] );
106 110
107 - add_action( 'elementor/frontend/after_register_styles', [ $this, 'register_styles' ] );
108 -
109 111 add_action( 'elementor/controls/register', function ( Controls_Manager $controls_manager ) {
110 112 $controls_manager->register( new Hover_Animation_Floating_Buttons() );
111 113 });
112 114
113 - add_filter( 'elementor/widget/common/register_css_attributes_control', function ( $common_controls ) {
114 - if ( Floating_Buttons::is_creating_floating_buttons_page() || Floating_Buttons::is_editing_existing_floating_buttons_page() ) {
115 - return false;
116 - }
117 -
118 - return $common_controls;
119 - } );
120 -
121 - add_filter( 'elementor/settings/controls/checkbox_list_cpt/post_type_objects', function ( $post_types ) {
122 - unset( $post_types[ static::CPT_FLOATING_BUTTONS ] );
123 -
124 - return $post_types;
125 - } );
126 -
127 - add_filter(
128 - 'elementor/template_library/sources/local/is_valid_template_type',
129 - function ( $is_valid_template_type, $cpt ) {
130 -
131 - if ( in_array( static::CPT_FLOATING_BUTTONS, $cpt, true ) ) {
132 - return true;
133 - }
134 -
135 - return $is_valid_template_type;
136 - },
137 - 10,
138 - 2
139 - );
140 -
141 115 if ( ! ElementorUtils::has_pro() ) {
142 116 add_action( 'wp_footer', function () {
143 117 $this->render_floating_buttons();
144 118 } );
@@ -143,8 +117,17 @@
143 117 $this->render_floating_buttons();
144 118 } );
145 119 }
146 120
121 + add_action( 'elementor/common/localize_settings', function ( $settings ) {
122 + $settings['floatingButtons'] = [
123 + 'nonce' => wp_create_nonce( static::CLICK_TRACKING_NONCE ),
124 + 'ajaxurl' => admin_url( 'admin-ajax.php' ),
125 + ];
126 +
127 + return $settings;
128 + } );
129 +
147 130 add_action( 'elementor/admin-top-bar/is-active', function ( $is_top_bar_active, $current_screen ) {
148 131
149 132 if ( strpos( $current_screen->id ?? '', static::CPT_FLOATING_BUTTONS ) !== false ) {
150 133 return true;
@@ -152,11 +135,11 @@
152 135
153 136 return $is_top_bar_active;
154 137 }, 10, 2 );
155 138
156 - add_action( 'elementor/editor-one/menu/register', function ( Menu_Data_Provider $menu_data_provider ) {
157 - $this->register_editor_one_menu( $menu_data_provider );
158 - } );
139 + add_action( 'elementor/admin/menu/register', function( Admin_Menu_Manager $admin_menu ) {
140 + $this->register_admin_menu_legacy( $admin_menu );
141 + }, Source_Local::ADMIN_MENU_PRIORITY + 20 );
159 142
160 143 add_action( 'elementor/admin/localize_settings', function ( array $settings ) {
161 144 return $this->admin_localize_settings( $settings );
162 145 } );
@@ -171,14 +154,41 @@
171 154 return $cpts;
172 155 } );
173 156
174 157 add_action( 'admin_init', function () {
175 - $action = sanitize_text_field( filter_input( INPUT_GET, 'action' ) );
158 + $action = filter_input( INPUT_GET, 'action' );
159 + $menu_args = $this->get_contact_menu_args();
176 160
177 - if ( $action ) {
178 - $menu_args = $this->get_contact_menu_args();
179 - $action_handler = new Action_Handler( $action, $menu_args );
180 - $action_handler->process_action();
161 + switch ( $action ) {
162 + case 'remove_from_entire_site':
163 + $post = filter_input( INPUT_GET, 'post', FILTER_VALIDATE_INT );
164 + check_admin_referer( 'remove_from_entire_site_' . $post );
165 + delete_post_meta( $post, '_elementor_conditions' );
166 + wp_redirect( $menu_args['menu_slug'] );
167 + exit;
168 + case 'set_as_entire_site':
169 + $post = filter_input( INPUT_GET, 'post', FILTER_VALIDATE_INT );
170 + check_admin_referer( 'set_as_entire_site_' . $post );
171 +
172 + $posts = get_posts( [
173 + 'post_type' => static::CPT_FLOATING_BUTTONS,
174 + 'posts_per_page' => -1,
175 + 'post_status' => 'publish',
176 + 'fields' => 'ids',
177 + 'meta_key' => '_elementor_conditions',
178 + 'meta_compare' => 'EXISTS',
179 + ] );
180 +
181 + foreach ( $posts as $post_id ) {
182 + delete_post_meta( $post_id, '_elementor_conditions' );
183 + }
184 +
185 + update_post_meta( $post, '_elementor_conditions', [ 'include/general' ] );
186 +
187 + wp_redirect( $menu_args['menu_slug'] );
188 + exit;
189 + default:
190 + break;
181 191 }
182 192 } );
183 193
184 194 add_action( 'manage_' . static::CPT_FLOATING_BUTTONS . '_posts_columns', function( $posts_columns ) {
@@ -206,15 +216,8 @@
206 216 $this->override_admin_bar_add_contact( $admin_bar );
207 217 }, 100 );
208 218 }
209 219
210 - public function is_preview_for_document( $post_id ) {
211 - $preview_id = ElementorUtils::get_super_global_value( $_GET, 'preview_id' );
212 - $preview = ElementorUtils::get_super_global_value( $_GET, 'preview' );
213 -
214 - return 'true' === $preview && (int) $post_id === (int) $preview_id;
215 - }
216 -
217 220 public function handle_click_tracking() {
218 221 $data = filter_input_array( INPUT_POST, [
219 222 'clicks' => [
220 223 'filter' => FILTER_VALIDATE_INT,
@@ -237,20 +240,12 @@
237 240 if ( ! isset( $posts_to_update[ $post_id ] ) ) {
238 241 $starting_clicks = (int) get_post_meta( $post_id, static::META_CLICK_TRACKING, true );
239 242 $posts_to_update[ $post_id ] = $starting_clicks ? $starting_clicks : 0;
240 243 }
241 - ++$posts_to_update[ $post_id ];
244 + $posts_to_update[ $post_id ] ++;
242 245 }
243 246
244 247 foreach ( $posts_to_update as $post_id => $clicks ) {
245 - if ( self::CPT_FLOATING_BUTTONS !== get_post_type( $post_id ) ) {
246 - continue;
247 - }
248 -
249 - if ( 'publish' !== get_post_status( $post_id ) ) {
250 - continue;
251 - }
252 -
253 248 update_post_meta( $post_id, static::META_CLICK_TRACKING, $clicks );
254 249 }
255 250
256 251 wp_send_json_success();
@@ -281,12 +276,16 @@
281 276 break;
282 277 }
283 278 }
284 279
285 - public function flush_permalinks_on_elementor_version_change() {
286 - if ( get_option( static::ROUTER_OPTION_KEY ) !== ELEMENTOR_VERSION ) {
280 + public function flush_permalinks_on_save() {
281 + if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
282 + return;
283 + }
284 +
285 + if ( get_option( static::ROUTER_OPTION_KEY ) !== static::ROUTER_VERSION ) {
287 286 flush_rewrite_rules();
288 - update_option( static::ROUTER_OPTION_KEY, ELEMENTOR_VERSION );
287 + update_option( static::ROUTER_OPTION_KEY, static::ROUTER_VERSION );
289 288 }
290 289 }
291 290
292 291 private function get_trashed_contact_posts(): array {
@@ -338,11 +337,11 @@
338 337 <div class="e-landing-pages-empty">
339 338 <?php
340 339 /** @var Source_Local $source_local */
341 340 $source_local->print_blank_state_template(
342 - esc_html__( 'Floating Element', 'elementor' ),
341 + esc_html__( 'Floating Button', 'elementor' ),
343 342 $this->get_add_new_contact_page_url(),
344 - nl2br( esc_html__( 'Add a Floating element so your users can easily get in touch!', 'elementor' ) )
343 + nl2br( esc_html__( 'Add a Floating button so your users can easily get in touch!', 'elementor' ) )
345 344 );
346 345
347 346 if ( ! empty( $trashed_posts ) ) : ?>
348 347 <div class="e-trashed-items">
@@ -347,10 +346,10 @@
347 346 if ( ! empty( $trashed_posts ) ) : ?>
348 347 <div class="e-trashed-items">
349 348 <?php
350 349 printf(
351 - /* translators: %1$s Link open tag, %2$s: Link close tag. */
352 - esc_html__( 'Or view %1$sTrashed Items%2$s', 'elementor' ),
350 + /* translators: %1$s Link open tag, %2$s: Link close tag. */
351 + esc_html__( 'Or view %1$sTrashed Items%1$s', 'elementor' ),
353 352 '<a href="' . esc_url( admin_url( 'edit.php?post_status=trash&post_type=' . self::CPT_FLOATING_BUTTONS ) ) . '">',
354 353 '</a>'
355 354 );
356 355 ?>
@@ -386,26 +385,33 @@
386 385 static::CPT_FLOATING_BUTTONS
387 386 );
388 387 }
389 388
389 + private function is_editing_existing_floating_buttons_page() {
390 + $action = ElementorUtils::get_super_global_value( $_GET, 'action' );
391 + $post_id = ElementorUtils::get_super_global_value( $_GET, 'post' );
392 +
393 + return 'elementor' === $action && $this->is_floating_buttons_type_meta_key( $post_id );
394 + }
395 +
396 + private function is_creating_floating_buttons_page() {
397 + $action = ElementorUtils::get_super_global_value( $_POST, 'action' ); //phpcs:ignore WordPress.Security.NonceVerification.Missing
398 + $post_id = ElementorUtils::get_super_global_value( $_POST, 'editor_post_id' ); //phpcs:ignore WordPress.Security.NonceVerification.Missing
399 +
400 + return 'elementor_ajax' === $action && $this->is_floating_buttons_type_meta_key( $post_id );
401 + }
402 +
403 + private function is_floating_buttons_type_meta_key( $post_id ) {
404 + return static::FLOATING_BUTTONS_DOCUMENT_TYPE === get_post_meta( $post_id, Document::TYPE_META_KEY, true );
405 + }
406 +
390 407 private function register_post_type( array $labels, string $cpt ) {
391 408 $args = [
392 409 'labels' => $labels,
393 410 'public' => true,
394 411 'show_in_menu' => 'edit.php?post_type=elementor_library&tabs_group=library',
395 - 'show_in_nav_menus' => false,
396 - 'capabilities' => [
397 - 'edit_post' => 'manage_options',
398 - 'read_post' => 'manage_options',
399 - 'delete_post' => 'manage_options',
400 - 'edit_posts' => 'manage_options',
401 - 'edit_others_posts' => 'manage_options',
402 - 'publish_posts' => 'manage_options',
403 - 'read_private_posts' => 'manage_options',
404 - 'create_posts' => 'manage_options',
405 - ],
412 + 'capability_type' => 'page',
406 413 'taxonomies' => [ Source_Local::TAXONOMY_TYPE_SLUG ],
407 - 'show_in_rest' => true,
408 414 'supports' => [
409 415 'title',
410 416 'editor',
411 417 'comments',
@@ -447,8 +453,9 @@
447 453 'meta_value' => $document_type,
448 454 ] );
449 455
450 456 return $posts_query->post_count > 0;
457 +
451 458 }
452 459
453 460 private function get_contact_menu_args(): array {
454 461 if ( $this->has_contact_pages() ) {
@@ -507,63 +514,16 @@
507 514 }
508 515
509 516 foreach ( $query->posts as $post_id ) {
510 517 $conditions = get_post_meta( $post_id, '_elementor_conditions', true );
511 -
512 518 if ( ! $conditions ) {
513 519 continue;
514 520 }
515 -
516 - if (
517 - in_array( 'include/general', $conditions ) &&
518 - ! $this->is_preview_for_document( $post_id ) &&
519 - get_the_ID() !== $post_id
520 - ) {
521 + if ( in_array( 'include/general', $conditions ) ) {
521 522 $document = Plugin::$instance->documents->get( $post_id );
522 523 $document->print_content();
524 + break;
523 525 }
524 526 }
525 527 }
526 528
527 - /**
528 - * Register styles.
529 - *
530 - * At build time, Elementor compiles `/modules/floating-buttons/assets/scss/widgets/*.scss`
531 - * to `/assets/css/widget-*.min.css`.
532 - *
533 - * @return void
534 - */
535 - public function register_styles() {
536 - $direction_suffix = is_rtl() ? '-rtl' : '';
537 - $widget_styles = $this->get_widgets_style_list();
538 - $has_custom_breakpoints = Plugin::$instance->breakpoints->has_custom_breakpoints();
539 -
540 - foreach ( $widget_styles as $widget_style_name => $widget_has_responsive_style ) {
541 - $should_load_responsive_css = $widget_has_responsive_style ? $has_custom_breakpoints : false;
542 -
543 - wp_register_style(
544 - $widget_style_name,
545 - $this->get_frontend_file_url( "{$widget_style_name}{$direction_suffix}.min.css", $should_load_responsive_css ),
546 - [ 'elementor-frontend', 'elementor-icons' ],
547 - $should_load_responsive_css ? null : ELEMENTOR_VERSION
548 - );
549 - }
550 - }
551 -
552 - private function get_widgets_style_list(): array {
553 - return [
554 - 'widget-floating-buttons' => self::WIDGET_HAS_CUSTOM_BREAKPOINTS, // TODO: Remove in v3.27.0 [ED-15717]
555 - 'widget-floating-bars-base' => self::WIDGET_HAS_CUSTOM_BREAKPOINTS,
556 - 'widget-floating-bars-var-2' => ! self::WIDGET_HAS_CUSTOM_BREAKPOINTS,
557 - 'widget-floating-bars-var-3' => self::WIDGET_HAS_CUSTOM_BREAKPOINTS,
558 - 'widget-contact-buttons-base' => self::WIDGET_HAS_CUSTOM_BREAKPOINTS,
559 - 'widget-contact-buttons-var-1' => ! self::WIDGET_HAS_CUSTOM_BREAKPOINTS,
560 - 'widget-contact-buttons-var-3' => ! self::WIDGET_HAS_CUSTOM_BREAKPOINTS,
561 - 'widget-contact-buttons-var-4' => ! self::WIDGET_HAS_CUSTOM_BREAKPOINTS,
562 - 'widget-contact-buttons-var-6' => ! self::WIDGET_HAS_CUSTOM_BREAKPOINTS,
563 - 'widget-contact-buttons-var-7' => self::WIDGET_HAS_CUSTOM_BREAKPOINTS,
564 - 'widget-contact-buttons-var-8' => ! self::WIDGET_HAS_CUSTOM_BREAKPOINTS,
565 - 'widget-contact-buttons-var-9' => self::WIDGET_HAS_CUSTOM_BREAKPOINTS,
566 - 'widget-contact-buttons-var-10' => self::WIDGET_HAS_CUSTOM_BREAKPOINTS,
567 - ];
568 - }
569 529 }