PluginProbe
Elementor Website Builder – more than just a page builder / 3.30.2
Elementor Website Builder – more than just a page builder v3.30.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 / admin / admin-notices.php

admin-notices.php in Elementor Website Builder – more than just a page builder 3.30.2, at core/admin/admin-notices.php

823 lines 24.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Elementor\Core\Admin;
3
4 use Elementor\Api;
5 use Elementor\Core\Admin\UI\Components\Button;
6 use Elementor\Core\Base\Module;
7 use Elementor\Core\Utils\Promotions\Filtered_Promotions_Manager;
8 use Elementor\Plugin;
9 use Elementor\Settings;
10 use Elementor\Tracker;
11 use Elementor\User;
12 use Elementor\Utils;
13 use Elementor\Core\Admin\Notices\Base_Notice;
14
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit; // Exit if accessed directly.
17 }
18
19 class Admin_Notices extends Module {
20
21 const DEFAULT_EXCLUDED_PAGES = [ 'plugins.php', 'plugin-install.php', 'plugin-editor.php' ];
22
23 private $plain_notices = [
24 'api_notice',
25 'api_upgrade_plugin',
26 'tracker',
27 'tracker_last_update',
28 'rate_us_feedback',
29 'role_manager_promote',
30 'experiment_promotion',
31 'site_mailer_promotion',
32 'plugin_image_optimization',
33 'ally_pages_promotion',
34 ];
35
36 private $elementor_pages_count = null;
37
38 private $install_time = null;
39
40 private $current_screen_id = null;
41
42 private function get_notices() {
43 /**
44 * Admin notices.
45 *
46 * Filters Elementor admin notices.
47 *
48 * This hook can be used by external developers to manage existing
49 * admin notice or to add new notices for Elementor add-ons.
50 *
51 * @param array $notices A list of notice classes.
52 */
53 $notices = apply_filters( 'elementor/core/admin/notices', [] );
54
55 return $notices;
56 }
57
58 private function get_install_time() {
59 if ( null === $this->install_time ) {
60 $this->install_time = Plugin::$instance->get_install_time();
61 }
62
63 return $this->install_time;
64 }
65
66 private function get_elementor_pages_count() {
67 if ( null === $this->elementor_pages_count ) {
68 $elementor_pages = new \WP_Query( [
69 'no_found_rows' => true,
70 'post_type' => 'any',
71 'post_status' => 'publish',
72 'fields' => 'ids',
73 'update_post_meta_cache' => false,
74 'update_post_term_cache' => false,
75 'meta_key' => '_elementor_edit_mode',
76 'meta_value' => 'builder',
77 ] );
78
79 $this->elementor_pages_count = $elementor_pages->post_count;
80 }
81
82 return $this->elementor_pages_count;
83 }
84
85 private function notice_api_upgrade_plugin() {
86 $upgrade_notice = Api::get_upgrade_notice();
87 if ( empty( $upgrade_notice ) ) {
88 return false;
89 }
90
91 if ( ! current_user_can( 'update_plugins' ) ) {
92 return false;
93 }
94
95 if ( ! in_array( $this->current_screen_id, [ 'toplevel_page_elementor', 'edit-elementor_library', 'elementor_page_elementor-system-info', 'dashboard' ], true ) ) {
96 return false;
97 }
98
99 // Check for upgrades.
100 $update_plugins = get_site_transient( 'update_plugins' );
101
102 $has_remote_update_package = ! ( empty( $update_plugins ) || empty( $update_plugins->response[ ELEMENTOR_PLUGIN_BASE ] ) || empty( $update_plugins->response[ ELEMENTOR_PLUGIN_BASE ]->package ) );
103
104 if ( ! $has_remote_update_package && empty( $upgrade_notice['update_link'] ) ) {
105 return false;
106 }
107
108 if ( $has_remote_update_package ) {
109 $product = $update_plugins->response[ ELEMENTOR_PLUGIN_BASE ];
110
111 $details_url = self_admin_url( 'plugin-install.php?tab=plugin-information&plugin=' . $product->slug . '&section=changelog&TB_iframe=true&width=600&height=800' );
112 $upgrade_url = wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' . ELEMENTOR_PLUGIN_BASE ), 'upgrade-plugin_' . ELEMENTOR_PLUGIN_BASE );
113 $new_version = $product->new_version;
114 } else {
115 $upgrade_url = $upgrade_notice['update_link'];
116 $details_url = $upgrade_url;
117
118 $new_version = $upgrade_notice['version'];
119 }
120
121 // Check if upgrade messages should be shown.
122 if ( version_compare( ELEMENTOR_VERSION, $upgrade_notice['version'], '>=' ) ) {
123 return false;
124 }
125
126 $notice_id = 'upgrade_notice_' . $upgrade_notice['version'];
127 if ( User::is_user_notice_viewed( $notice_id ) ) {
128 return false;
129 }
130
131 $message = sprintf(
132 /* translators: 1: Details URL, 2: Accessibility text, 3: Version number, 4: Update URL, 5: Accessibility text. */
133 __( 'There is a new version of Elementor Page Builder available. <a href="%1$s" class="thickbox open-plugin-details-modal" aria-label="%2$s">View version %3$s details</a> or <a href="%4$s" class="update-link" aria-label="%5$s">update now</a>.', 'elementor' ),
134 esc_url( $details_url ),
135 esc_attr( sprintf(
136 /* translators: %s: Elementor version. */
137 __( 'View Elementor version %s details', 'elementor' ),
138 $new_version
139 ) ),
140 $new_version,
141 esc_url( $upgrade_url ),
142 esc_attr( esc_html__( 'Update Now', 'elementor' ) )
143 );
144
145 $options = [
146 'title' => esc_html__( 'Update Notification', 'elementor' ),
147 'description' => $message,
148 'button' => [
149 'icon_classes' => 'dashicons dashicons-update',
150 'text' => esc_html__( 'Update Now', 'elementor' ),
151 'url' => $upgrade_url,
152 ],
153 'id' => $notice_id,
154 ];
155
156 $this->print_admin_notice( $options );
157
158 return true;
159 }
160
161 private function notice_api_notice() {
162 $admin_notice = Api::get_admin_notice();
163 if ( empty( $admin_notice ) ) {
164 return false;
165 }
166
167 if ( ! current_user_can( 'manage_options' ) ) {
168 return false;
169 }
170
171 if ( ! in_array( $this->current_screen_id, [ 'toplevel_page_elementor', 'edit-elementor_library', 'elementor_page_elementor-system-info', 'dashboard' ], true ) ) {
172 return false;
173 }
174
175 $notice_id = 'admin_notice_api_' . $admin_notice['notice_id'];
176 if ( User::is_user_notice_viewed( $notice_id ) ) {
177 return false;
178 }
179
180 $options = [
181 'title' => esc_html__( 'Update Notification', 'elementor' ),
182 'description' => $admin_notice['notice_text'],
183 'id' => $notice_id,
184 ];
185
186 $this->print_admin_notice( $options );
187
188 return true;
189 }
190
191 private function notice_tracker() {
192 if ( ! current_user_can( 'manage_options' ) ) {
193 return false;
194 }
195
196 // Show tracker notice after 24 hours from installed time.
197 if ( strtotime( '+24 hours', $this->get_install_time() ) > time() ) {
198 return false;
199 }
200
201 if ( '1' === get_option( 'elementor_tracker_notice' ) ) {
202 return false;
203 }
204
205 if ( Tracker::is_allow_track() ) {
206 return false;
207 }
208
209 if ( 2 > $this->get_elementor_pages_count() ) {
210 return false;
211 }
212
213 // TODO: Skip for development env.
214 $optin_url = wp_nonce_url( add_query_arg( 'elementor_tracker', 'opt_into' ), 'opt_into' );
215 $optout_url = wp_nonce_url( add_query_arg( 'elementor_tracker', 'opt_out' ), 'opt_out' );
216
217 $tracker_description_text = esc_html__( 'Become a super contributor by helping us understand how you use our service to enhance your experience and improve our product.', 'elementor' );
218
219 /**
220 * Tracker admin description text.
221 *
222 * Filters the admin notice text for non-sensitive data collection.
223 *
224 * @since 1.0.0
225 *
226 * @param string $tracker_description_text Description text displayed in admin notice.
227 */
228 $tracker_description_text = apply_filters( 'elementor/tracker/admin_description_text', $tracker_description_text );
229
230 $message = esc_html( $tracker_description_text ) . ' <a href="https://go.elementor.com/usage-data-tracking/" target="_blank">' . esc_html__( 'Learn more.', 'elementor' ) . '</a>';
231
232 $options = [
233 'title' => esc_html__( 'Want to shape the future of web creation?', 'elementor' ),
234 'description' => $message,
235 'dismissible' => false,
236 'button' => [
237 'text' => esc_html__( 'Sure! I\'d love to help', 'elementor' ),
238 'url' => $optin_url,
239 'type' => 'cta',
240 ],
241 'button_secondary' => [
242 'text' => esc_html__( 'No thanks', 'elementor' ),
243 'url' => $optout_url,
244 'variant' => 'outline',
245 'type' => 'cta',
246 ],
247 ];
248
249 $this->print_admin_notice( $options );
250
251 return true;
252 }
253
254 private function notice_tracker_last_update() {
255 if ( ! current_user_can( 'manage_options' ) ) {
256 return false;
257 }
258
259 if ( ! Tracker::has_terms_changed() ) {
260 return false;
261 }
262
263 $notice_id = 'tracker_last_update_' . Tracker::LAST_TERMS_UPDATED;
264
265 if ( User::is_user_notice_viewed( $notice_id ) ) {
266 return false;
267 }
268
269 $optin_url = wp_nonce_url( add_query_arg( 'elementor_tracker', 'opt_into' ), 'opt_into' );
270
271 $message = esc_html__( 'We\'re updating our Terms and Conditions to include the collection of usage and behavioral data. This information helps us understand how you use Elementor so we can make informed improvements to the product.', 'elementor' );
272
273 $options = [
274 'id' => $notice_id,
275 'title' => esc_html__( 'Update regarding usage data collection', 'elementor' ),
276 'description' => $message,
277 'button' => [
278 'text' => esc_html__( 'Opt in', 'elementor' ),
279 'url' => $optin_url,
280 'type' => 'cta',
281 ],
282 'button_secondary' => [
283 'text' => esc_html__( 'Learn more', 'elementor' ),
284 'url' => 'https://go.elementor.com/wp-dash-update-usage-notice/',
285 'new_tab' => true,
286 'type' => 'cta',
287 ],
288 ];
289
290 $this->print_admin_notice( $options );
291
292 return true;
293 }
294
295 private function notice_rate_us_feedback() {
296 $notice_id = 'rate_us_feedback';
297
298 if ( ! current_user_can( 'manage_options' ) ) {
299 return false;
300 }
301
302 if ( 'dashboard' !== $this->current_screen_id || User::is_user_notice_viewed( $notice_id ) ) {
303 return false;
304 }
305
306 if ( 10 >= $this->get_elementor_pages_count() ) {
307 return false;
308 }
309
310 $dismiss_url = add_query_arg( [
311 'action' => 'elementor_set_admin_notice_viewed',
312 'notice_id' => esc_attr( $notice_id ),
313 '_wpnonce' => wp_create_nonce( 'elementor_set_admin_notice_viewed' ),
314 ], admin_url( 'admin-post.php' ) );
315
316 $options = [
317 'title' => esc_html__( 'Congrats!', 'elementor' ),
318 'description' => esc_html__( 'You created over 10 pages with Elementor. Great job! If you can spare a minute, please help us by leaving a five star review on WordPress.org.', 'elementor' ),
319 'id' => $notice_id,
320 'button' => [
321 'text' => esc_html__( 'Happy To Help', 'elementor' ),
322 'url' => 'https://go.elementor.com/admin-review/',
323 'new_tab' => true,
324 'type' => 'cta',
325 ],
326 'button_secondary' => [
327 'text' => esc_html__( 'Hide Notification', 'elementor' ),
328 'classes' => [ 'e-notice-dismiss' ],
329 'url' => esc_url_raw( $dismiss_url ),
330 'new_tab' => true,
331 'type' => 'cta',
332 ],
333 ];
334
335 $this->print_admin_notice( $options );
336
337 return true;
338 }
339
340 private function notice_role_manager_promote() {
341 $notice_id = 'role_manager_promote';
342
343 if ( Utils::has_pro() ) {
344 return false;
345 }
346
347 if ( ! current_user_can( 'manage_options' ) ) {
348 return false;
349 }
350
351 if ( 'elementor_page_elementor-role-manager' !== $this->current_screen_id || User::is_user_notice_viewed( $notice_id ) ) {
352 return false;
353 }
354
355 $users = new \WP_User_Query( [
356 'fields' => 'ID',
357 'number' => 10,
358 ] );
359
360 if ( 5 > $users->get_total() ) {
361 return false;
362 }
363
364 $options = [
365 'title' => esc_html__( 'Managing a multi-user site?', 'elementor' ),
366 'description' => esc_html__( 'With Elementor Pro, you can control user access and make sure no one messes up your design.', 'elementor' ),
367 'id' => $notice_id,
368
369 'button' => [
370 'text' => esc_html__( 'Learn More', 'elementor' ),
371 'url' => 'https://go.elementor.com/plugin-promotion-role-manager/',
372 'new_tab' => true,
373 'type' => 'cta',
374 ],
375 ];
376
377 $options = Filtered_Promotions_Manager::get_filtered_promotion_data( $options, 'core/admin/notice_role_manager_promote', 'button', 'url' );
378
379 $this->print_admin_notice( $options );
380
381 return true;
382 }
383
384 private function notice_experiment_promotion() {
385 $notice_id = 'experiment_promotion';
386
387 if ( ! current_user_can( 'manage_options' ) || User::is_user_notice_viewed( $notice_id ) ) {
388 return false;
389 }
390
391 $experiments = Plugin::$instance->experiments;
392 $is_all_performance_features_active = (
393 $experiments->is_feature_active( 'e_element_cache' ) &&
394 $experiments->is_feature_active( 'e_font_icon_svg' )
395 );
396
397 if ( $is_all_performance_features_active ) {
398 return false;
399 }
400
401 $options = [
402 'title' => esc_html__( 'Improve your site’s performance score.', 'elementor' ),
403 'description' => esc_html__( 'With our experimental speed boosting features you can go faster than ever before. Look for the Performance label on our Experiments page and activate those experiments to improve your site loading speed.', 'elementor' ),
404 'id' => $notice_id,
405 'button' => [
406 'text' => esc_html__( 'Try it out', 'elementor' ),
407 'url' => Settings::get_settings_tab_url( 'experiments' ),
408 'type' => 'cta',
409 ],
410 'button_secondary' => [
411 'text' => esc_html__( 'Learn more', 'elementor' ),
412 'url' => 'https://go.elementor.com/wp-dash-experiment-promotion/',
413 'new_tab' => true,
414 'type' => 'cta',
415 ],
416 ];
417
418 $this->print_admin_notice( $options );
419
420 return true;
421 }
422
423 private function site_has_forms_plugins() {
424 return defined( 'WPFORMS_VERSION' ) || defined( 'WPCF7_VERSION' ) || defined( 'FLUENTFORM_VERSION' ) || class_exists( '\GFCommon' ) || class_exists( '\Ninja_Forms' ) || function_exists( 'load_formidable_forms' ) || did_action( 'metform/after_load' ) || defined( 'FORMINATOR_PLUGIN_BASENAME' );
425 }
426
427 private function site_has_woocommerce() {
428 return class_exists( 'WooCommerce' );
429 }
430
431 private function notice_ally_pages_promotion() {
432 global $pagenow;
433 $notice_id = 'ally_pages_promotion';
434
435 if ( 'edit.php' !== $pagenow || empty( $_GET['post_type'] ) || 'page' !== $_GET['post_type'] ) {
436 return false;
437 }
438
439 if ( ! current_user_can( 'manage_options' ) || User::is_user_notice_viewed( $notice_id ) ) {
440 return false;
441 }
442
443 $plugin_file_path = 'pojo-accessibility/pojo-accessibility.php';
444 $plugin_slug = 'pojo-accessibility';
445
446 $cta_data = $this->get_plugin_cta_data( $plugin_slug, $plugin_file_path );
447 if ( empty( $cta_data ) ) {
448 return false;
449 }
450
451 $options = [
452 'title' => esc_html__( 'Make sure your site has an accessibility statement page', 'elementor' ),
453 'description' => esc_html__( 'Create a more inclusive site experience for all your visitors. With Ally, it\'s easy to add your statement page in just a few clicks.', 'elementor' ),
454 'id' => $notice_id,
455 'type' => 'cta',
456 'button' => [
457 'text' => $cta_data['text'],
458 'url' => self::add_plg_campaign_data( $cta_data['url'], [
459 'name' => 'elementor_ea11y_campaign',
460 'campaign' => 'acc-statement-plg-pages',
461 'source' => 'wp-pages',
462 'medium' => 'wp-dash',
463 ] ),
464 'type' => 'cta',
465 ],
466 'button_secondary' => [
467 'text' => esc_html__( 'Learn more', 'elementor' ),
468 'url' => 'https://go.elementor.com/acc-plg-learn-more',
469 'new_tab' => true,
470 'type' => 'cta',
471 ],
472 ];
473
474 $this->print_admin_notice( $options );
475
476 return true;
477 }
478
479 private function notice_site_mailer_promotion() {
480 $notice_id = 'site_mailer_promotion';
481 $has_forms = $this->site_has_forms_plugins();
482 $has_woocommerce = $this->site_has_woocommerce();
483
484 if ( ! $has_forms && ! $has_woocommerce ) {
485 return false;
486 }
487
488 if ( ! $this->is_elementor_page() && ! in_array( $this->current_screen_id, [ 'toplevel_page_elementor', 'edit-elementor_library', 'dashboard' ], true ) ) {
489 return false;
490 }
491
492 if ( ( Utils::has_pro() && ! $has_woocommerce ) || ! current_user_can( 'install_plugins' ) || User::is_user_notice_viewed( $notice_id ) ) {
493 return false;
494 }
495
496 $plugin_file_path = 'site-mailer/site-mailer.php';
497 $plugin_slug = 'site-mailer';
498
499 $cta_data = $this->get_plugin_cta_data( $plugin_slug, $plugin_file_path );
500 if ( empty( $cta_data ) ) {
501 return false;
502 }
503
504 $options = [
505 'title' => esc_html__( 'Ensure your form emails avoid the spam folder!', 'elementor' ),
506 'description' => esc_html__( 'Use Site Mailer for improved email deliverability, detailed email logs, and an easy setup.', 'elementor' ),
507 'id' => $notice_id,
508 'type' => 'cta',
509 'button' => [
510 'text' => $cta_data['text'],
511 'url' => $cta_data['url'],
512 'type' => 'cta',
513 ],
514 'button_secondary' => [
515 'text' => esc_html__( 'Learn more', 'elementor' ),
516 'url' => 'https://go.elementor.com/sm-core-form/',
517 'new_tab' => true,
518 'type' => 'cta',
519 ],
520 ];
521
522 if ( $this->should_render_woocommerce_hint( $has_forms, $has_woocommerce ) ) {
523 // We include WP's default notice class so it will be properly handled by WP's js handler
524 // And add a new one to distinguish between the two types of notices
525 $options['classes'] = [ 'notice', 'e-notice', 'sm-notice-wc' ];
526 $options['title'] = esc_html__( 'Improve Transactional Email Deliverability', 'elementor' );
527 $options['description'] = esc_html__( 'Use Elementor\'s Site Mailer to ensure your store emails like purchase confirmations, shipping updates and more are reliably delivered.', 'elementor' );
528 }
529
530 $this->print_admin_notice( $options );
531
532 return true;
533 }
534
535 private function should_render_woocommerce_hint( $has_forms, $has_woocommerce ): bool {
536 if ( ! $has_forms && ! $has_woocommerce ) {
537 return false;
538 }
539
540 if ( ! $has_forms && $has_woocommerce ) {
541 return true;
542 }
543
544 if ( $has_forms && $has_woocommerce && Utils::has_pro() ) {
545 return true;
546 }
547
548 if ( ! $has_woocommerce ) {
549 return false;
550 }
551
552 return (bool) wp_rand( 0, 1 );
553 }
554
555 private function is_elementor_page(): bool {
556 return 0 === strpos( $this->current_screen_id, 'elementor_page' );
557 }
558
559 private function get_plugin_cta_data( $plugin_slug, $plugin_file_path ) {
560 if ( is_plugin_active( $plugin_file_path ) ) {
561 return false;
562 }
563
564 if ( $this->is_plugin_installed( $plugin_file_path ) ) {
565 $url = wp_nonce_url( 'plugins.php?action=activate&amp;plugin=' . $plugin_file_path . '&amp;plugin_status=all&amp;paged=1&amp;s', 'activate-plugin_' . $plugin_file_path );
566 $cta_text = esc_html__( 'Activate Plugin', 'elementor' );
567 } else {
568 $url = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=' . $plugin_slug ), 'install-plugin_' . $plugin_slug );
569 $cta_text = esc_html__( 'Install Plugin', 'elementor' );
570 }
571
572 return [
573 'url' => $url,
574 'text' => $cta_text,
575 ];
576 }
577
578 /**
579 * For testing purposes
580 */
581 public function get_elementor_version() {
582 return ELEMENTOR_VERSION;
583 }
584
585 private function notice_plugin_image_optimization() {
586 $notice_id = 'plugin_image_optimization';
587
588 if ( 'upload' !== $this->current_screen_id ) {
589 return false;
590 }
591
592 if ( ! current_user_can( 'manage_options' ) || User::is_user_notice_viewed( $notice_id ) ) {
593 return false;
594 }
595
596 $attachments = new \WP_Query( [
597 'post_type' => 'attachment',
598 'post_status' => 'any',
599 'fields' => 'ids',
600 ] );
601
602 if ( 1 > $attachments->found_posts ) {
603 return false;
604 }
605
606 $plugin_file_path = 'image-optimization/image-optimization.php';
607 $plugin_slug = 'image-optimization';
608
609 $cta_data = $this->get_plugin_cta_data( $plugin_slug, $plugin_file_path );
610
611 if ( empty( $cta_data ) ) {
612 return false;
613 }
614
615 $options = [
616 'title' => esc_html__( 'Speed up your website with Image Optimizer by Elementor', 'elementor' ),
617 'description' => esc_html__( 'Automatically compress and optimize images, resize larger files, or convert to WebP. Optimize images individually, in bulk, or on upload.', 'elementor' ),
618 'id' => $notice_id,
619 'type' => 'cta',
620 'button_secondary' => [
621 'text' => $cta_data['text'],
622 'url' => $cta_data['url'],
623 'type' => 'cta',
624 ],
625 ];
626
627 $this->print_admin_notice( $options );
628
629 return true;
630 }
631
632 private function is_plugin_installed( $file_path ): bool {
633 $installed_plugins = get_plugins();
634
635 return isset( $installed_plugins[ $file_path ] );
636 }
637
638 public function print_admin_notice( array $options, $exclude_pages = self::DEFAULT_EXCLUDED_PAGES ) {
639 global $pagenow;
640
641 if ( in_array( $pagenow, $exclude_pages, true ) ) {
642 return;
643 }
644
645 $default_options = [
646 'id' => null,
647 'title' => '',
648 'description' => '',
649 'classes' => [ 'notice', 'e-notice' ], // We include WP's default notice class so it will be properly handled by WP's js handler
650 'type' => '',
651 'dismissible' => true,
652 'icon' => 'eicon-elementor',
653 'button' => [],
654 'button_secondary' => [],
655 ];
656
657 $options = array_replace_recursive( $default_options, $options );
658
659 $notice_classes = $options['classes'];
660 $dismiss_button = '';
661 $icon = '';
662
663 if ( $options['type'] ) {
664 $notice_classes[] = 'e-notice--' . $options['type'];
665 }
666
667 $wrapper_attributes = [];
668
669 if ( $options['dismissible'] ) {
670 $label = esc_html__( 'Dismiss this notice.', 'elementor' );
671 $notice_classes[] = 'e-notice--dismissible';
672 $dismiss_button = '<i class="e-notice__dismiss" role="button" aria-label="' . $label . '" tabindex="0"></i>';
673
674 $wrapper_attributes['data-nonce'] = wp_create_nonce( 'elementor_set_admin_notice_viewed' );
675 }
676
677 if ( $options['icon'] ) {
678 $notice_classes[] = 'e-notice--extended';
679 $icon = '<div class="e-notice__icon-wrapper"><i class="' . esc_attr( $options['icon'] ) . '" aria-hidden="true"></i></div>';
680 }
681
682 $wrapper_attributes['class'] = $notice_classes;
683
684 if ( $options['id'] ) {
685 $wrapper_attributes['data-notice_id'] = $options['id'];
686 }
687 ?>
688 <div <?php Utils::print_html_attributes( $wrapper_attributes ); ?>>
689 <?php echo $dismiss_button; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
690 <div class="e-notice__aside">
691 <?php echo $icon; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
692 </div>
693 <div class="e-notice__content">
694 <?php if ( $options['title'] ) { ?>
695 <h3><?php echo wp_kses_post( $options['title'] ); ?></h3>
696 <?php } ?>
697
698 <?php if ( $options['description'] ) { ?>
699 <p><?php echo wp_kses_post( $options['description'] ); ?></p>
700 <?php } ?>
701
702 <?php if ( ! empty( $options['button']['text'] ) || ! empty( $options['button_secondary']['text'] ) ) { ?>
703 <div class="e-notice__actions">
704 <?php
705 foreach ( [ $options['button'], $options['button_secondary'] ] as $index => $button_settings ) {
706 if ( empty( $button_settings['variant'] ) && $index ) {
707 $button_settings['variant'] = 'outline';
708 }
709
710 if ( empty( $button_settings['text'] ) ) {
711 continue;
712 }
713
714 $button = new Button( $button_settings );
715 $button->print_button();
716 } ?>
717 </div>
718 <?php } ?>
719 </div>
720 </div>
721 <?php }
722
723 public function admin_notices() {
724 $this->install_time = Plugin::$instance->get_install_time();
725 $this->current_screen_id = get_current_screen()->id;
726
727 foreach ( $this->plain_notices as $notice ) {
728 $method_callback = "notice_{$notice}";
729 if ( $this->$method_callback() ) {
730 return;
731 }
732 }
733
734 /** @var Base_Notice $notice_instance */
735 foreach ( $this->get_notices() as $notice_instance ) {
736 if ( ! $notice_instance->should_print() ) {
737 continue;
738 }
739
740 $this->print_admin_notice( $notice_instance->get_config() );
741
742 // It exits the method to make sure it prints only one notice.
743 return;
744 }
745 }
746
747 public function maybe_log_campaign() {
748 if ( empty( $_GET['plg_campaign'] ) || empty( $_GET['plg_campaign_name'] ) ) {
749 return;
750 }
751
752 $allowed_plgs = [
753 'elementor_image_optimization_campaign',
754 'elementor_ea11y_campaign',
755 'elementor_site_mailer_campaign',
756 ];
757
758 if ( ! in_array( $_GET['plg_campaign_name'], $allowed_plgs, true ) ) {
759 return;
760 }
761
762 if ( ! isset( $_GET['plg_campaign_nonce'] ) || ! wp_verify_nonce( sanitize_key( $_GET['plg_campaign_nonce'] ), sanitize_key( $_GET['plg_campaign_name'] ) ) ) {
763 return;
764 }
765
766 if ( ! current_user_can( 'manage_options' ) ) {
767 return;
768 }
769
770 if ( empty( $_GET['plg_source'] ) || empty( $_GET['plg_medium'] ) ) {
771 return;
772 }
773
774 $campaign_data = [
775 'source' => sanitize_key( $_GET['plg_source'] ),
776 'campaign' => sanitize_key( $_GET['plg_campaign'] ),
777 'medium' => sanitize_key( $_GET['plg_medium'] ),
778 ];
779
780 set_transient( sanitize_key( $_GET['plg_campaign_name'] ), $campaign_data, 30 * DAY_IN_SECONDS );
781 }
782
783 private static function add_plg_campaign_data( $url, $campaign_data ) {
784
785 foreach ( [ 'name', 'campaign' ] as $key ) {
786 if ( empty( $campaign_data[ $key ] ) ) {
787 return $url;
788 }
789 }
790
791 return add_query_arg( [
792 'plg_campaign_name' => $campaign_data['name'],
793 'plg_campaign' => $campaign_data['campaign'],
794 'plg_source' => empty( $campaign_data['source'] ) ? '' : $campaign_data['source'],
795 'plg_medium' => empty( $campaign_data['medium'] ) ? '' : $campaign_data['medium'],
796 'plg_campaign_nonce' => wp_create_nonce( $campaign_data['name'] ),
797 ], $url );
798 }
799
800 /**
801 * @since 2.9.0
802 * @access public
803 */
804 public function __construct() {
805 add_action( 'admin_notices', [ $this, 'admin_notices' ], 20 );
806 add_action( 'admin_action_install-plugin', [ $this, 'maybe_log_campaign' ] );
807 }
808
809 /**
810 * Get module name.
811 *
812 * Retrieve the module name.
813 *
814 * @since 2.9.0
815 * @access public
816 *
817 * @return string Module name.
818 */
819 public function get_name() {
820 return 'admin-notices';
821 }
822 }
823