PluginProbe
Elementor Website Builder – more than just a page builder / 3.16.2
Elementor Website Builder – more than just a page builder v3.16.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.16.2, at core/admin/admin-notices.php

509 lines 14.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\Admin;
3
4 use Elementor\Api;
5 use Elementor\Core\Admin\UI\Components\Button;
6 use Elementor\Core\Base\Module;
7 use Elementor\Plugin;
8 use Elementor\Tracker;
9 use Elementor\User;
10 use Elementor\Utils;
11 use Elementor\Core\Admin\Notices\Base_Notice;
12 use Elementor\Core\Admin\Notices\Elementor_Dev_Notice;
13
14 if ( ! defined( 'ABSPATH' ) ) {
15 exit; // Exit if accessed directly.
16 }
17
18 class Admin_Notices extends Module {
19
20 const EXCLUDE_PAGES = [ 'plugins.php', 'plugin-install.php', 'plugin-editor.php' ];
21
22 private $plain_notices = [
23 'api_notice',
24 'api_upgrade_plugin',
25 'tracker',
26 'rate_us_feedback',
27 'role_manager_promote',
28 'experiment_promotion',
29 ];
30
31 private $elementor_pages_count = null;
32
33 private $install_time = null;
34
35 private $current_screen_id = null;
36
37 private function get_notices() {
38 $notices = [
39 new Elementor_Dev_Notice(),
40 ];
41
42 /**
43 * Admin notices.
44 *
45 * Filters Elementor admin notices.
46 *
47 * This hook can be used by external developers to manage existing
48 * admin notice or to add new notices for Elementor addons.
49 *
50 * @param array $notices A list of notice classes.
51 */
52 $notices = apply_filters( 'elementor/core/admin/notices', $notices );
53
54 return $notices;
55 }
56
57 private function get_install_time() {
58 if ( null === $this->install_time ) {
59 $this->install_time = Plugin::$instance->get_install_time();
60 }
61
62 return $this->install_time;
63 }
64
65 private function get_elementor_pages_count() {
66 if ( null === $this->elementor_pages_count ) {
67 $elementor_pages = new \WP_Query( [
68 'no_found_rows' => true,
69 'post_type' => 'any',
70 'post_status' => 'publish',
71 'fields' => 'ids',
72 'update_post_meta_cache' => false,
73 'update_post_term_cache' => false,
74 'meta_key' => '_elementor_edit_mode',
75 'meta_value' => 'builder',
76 ] );
77
78 $this->elementor_pages_count = $elementor_pages->post_count;
79 }
80
81 return $this->elementor_pages_count;
82 }
83
84 private function notice_api_upgrade_plugin() {
85 $upgrade_notice = Api::get_upgrade_notice();
86 if ( empty( $upgrade_notice ) ) {
87 return false;
88 }
89
90 if ( ! current_user_can( 'update_plugins' ) ) {
91 return false;
92 }
93
94 if ( ! in_array( $this->current_screen_id, [ 'toplevel_page_elementor', 'edit-elementor_library', 'elementor_page_elementor-system-info', 'dashboard' ], true ) ) {
95 return false;
96 }
97
98 // Check for upgrades.
99 $update_plugins = get_site_transient( 'update_plugins' );
100
101 $has_remote_update_package = ! ( empty( $update_plugins ) || empty( $update_plugins->response[ ELEMENTOR_PLUGIN_BASE ] ) || empty( $update_plugins->response[ ELEMENTOR_PLUGIN_BASE ]->package ) );
102
103 if ( ! $has_remote_update_package && empty( $upgrade_notice['update_link'] ) ) {
104 return false;
105 }
106
107 if ( $has_remote_update_package ) {
108 $product = $update_plugins->response[ ELEMENTOR_PLUGIN_BASE ];
109
110 $details_url = self_admin_url( 'plugin-install.php?tab=plugin-information&plugin=' . $product->slug . '&section=changelog&TB_iframe=true&width=600&height=800' );
111 $upgrade_url = wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' . ELEMENTOR_PLUGIN_BASE ), 'upgrade-plugin_' . ELEMENTOR_PLUGIN_BASE );
112 $new_version = $product->new_version;
113 } else {
114 $upgrade_url = $upgrade_notice['update_link'];
115 $details_url = $upgrade_url;
116
117 $new_version = $upgrade_notice['version'];
118 }
119
120 // Check if upgrade messages should be shown.
121 if ( version_compare( ELEMENTOR_VERSION, $upgrade_notice['version'], '>=' ) ) {
122 return false;
123 }
124
125 $notice_id = 'upgrade_notice_' . $upgrade_notice['version'];
126 if ( User::is_user_notice_viewed( $notice_id ) ) {
127 return false;
128 }
129
130 $message = sprintf(
131 /* translators: 1: Details URL, 2: Accessibility text, 3: Version number, 4: Update URL, 5: Accessibility text. */
132 __( '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' ),
133 esc_url( $details_url ),
134 esc_attr( sprintf(
135 /* translators: %s: Elementor version. */
136 __( 'View Elementor version %s details', 'elementor' ),
137 $new_version
138 ) ),
139 $new_version,
140 esc_url( $upgrade_url ),
141 esc_attr( esc_html__( 'Update Now', 'elementor' ) )
142 );
143
144 $options = [
145 'title' => esc_html__( 'Update Notification', 'elementor' ),
146 'description' => $message,
147 'button' => [
148 'icon_classes' => 'dashicons dashicons-update',
149 'text' => esc_html__( 'Update Now', 'elementor' ),
150 'url' => $upgrade_url,
151 ],
152 'id' => $notice_id,
153 ];
154
155 $this->print_admin_notice( $options );
156
157 return true;
158 }
159
160 private function notice_api_notice() {
161 $admin_notice = Api::get_admin_notice();
162 if ( empty( $admin_notice ) ) {
163 return false;
164 }
165
166 if ( ! current_user_can( 'manage_options' ) ) {
167 return false;
168 }
169
170 if ( ! in_array( $this->current_screen_id, [ 'toplevel_page_elementor', 'edit-elementor_library', 'elementor_page_elementor-system-info', 'dashboard' ], true ) ) {
171 return false;
172 }
173
174 $notice_id = 'admin_notice_api_' . $admin_notice['notice_id'];
175 if ( User::is_user_notice_viewed( $notice_id ) ) {
176 return false;
177 }
178
179 $options = [
180 'title' => esc_html__( 'Update Notification', 'elementor' ),
181 'description' => $admin_notice['notice_text'],
182 'id' => $notice_id,
183 ];
184
185 $this->print_admin_notice( $options );
186
187 return true;
188 }
189
190 private function notice_tracker() {
191 if ( ! current_user_can( 'manage_options' ) ) {
192 return false;
193 }
194
195 // Show tracker notice after 24 hours from installed time.
196 if ( strtotime( '+24 hours', $this->get_install_time() ) > time() ) {
197 return false;
198 }
199
200 if ( '1' === get_option( 'elementor_tracker_notice' ) ) {
201 return false;
202 }
203
204 if ( Tracker::is_allow_track() ) {
205 return false;
206 }
207
208 if ( 2 > $this->get_elementor_pages_count() ) {
209 return false;
210 }
211
212 // TODO: Skip for development env.
213 $optin_url = wp_nonce_url( add_query_arg( 'elementor_tracker', 'opt_into' ), 'opt_into' );
214 $optout_url = wp_nonce_url( add_query_arg( 'elementor_tracker', 'opt_out' ), 'opt_out' );
215
216 $tracker_description_text = esc_html__( 'Become a super contributor by opting in to share non-sensitive plugin data and to receive periodic email updates from us.', 'elementor' );
217
218 /**
219 * Tracker admin description text.
220 *
221 * Filters the admin notice text for non-sensitive data collection.
222 *
223 * @since 1.0.0
224 *
225 * @param string $tracker_description_text Description text displayed in admin notice.
226 */
227 $tracker_description_text = apply_filters( 'elementor/tracker/admin_description_text', $tracker_description_text );
228
229 $message = esc_html( $tracker_description_text ) . ' <a href="https://go.elementor.com/usage-data-tracking/" target="_blank">' . esc_html__( 'Learn more.', 'elementor' ) . '</a>';
230
231 $options = [
232 'title' => esc_html__( 'Love using Elementor?', 'elementor' ),
233 'description' => $message,
234 'button' => [
235 'text' => esc_html__( 'Sure! I\'d love to help', 'elementor' ),
236 'url' => $optin_url,
237 'type' => 'cta',
238 ],
239 'button_secondary' => [
240 'text' => esc_html__( 'No thanks', 'elementor' ),
241 'url' => $optout_url,
242 'variant' => 'outline',
243 'type' => 'cta',
244 ],
245 ];
246
247 $this->print_admin_notice( $options );
248
249 return true;
250 }
251
252 private function notice_rate_us_feedback() {
253 $notice_id = 'rate_us_feedback';
254
255 if ( ! current_user_can( 'manage_options' ) ) {
256 return false;
257 }
258
259 if ( 'dashboard' !== $this->current_screen_id || User::is_user_notice_viewed( $notice_id ) ) {
260 return false;
261 }
262
263 if ( 10 >= $this->get_elementor_pages_count() ) {
264 return false;
265 }
266
267 $dismiss_url = add_query_arg( [
268 'action' => 'elementor_set_admin_notice_viewed',
269 'notice_id' => esc_attr( $notice_id ),
270 ], admin_url( 'admin-post.php' ) );
271
272 $options = [
273 'title' => esc_html__( 'Congrats!', 'elementor' ),
274 'description' => esc_html__( 'You created over 10 pages with Elementor. Great job! If you can spare a minute,
275 please help us by leaving a five star review on WordPress.org.', 'elementor' ),
276 'id' => $notice_id,
277 'button' => [
278 'text' => esc_html__( 'Happy To Help', 'elementor' ),
279 'url' => 'https://go.elementor.com/admin-review/',
280 'new_tab' => true,
281 'type' => 'cta',
282 ],
283 'button_secondary' => [
284 'text' => esc_html__( 'Hide Notification', 'elementor' ),
285 'classes' => [ 'e-notice-dismiss' ],
286 'url' => esc_url_raw( $dismiss_url ),
287 'new_tab' => true,
288 'type' => 'cta',
289 ],
290 ];
291
292 $this->print_admin_notice( $options );
293
294 return true;
295 }
296
297 private function notice_role_manager_promote() {
298 $notice_id = 'role_manager_promote';
299
300 if ( Utils::has_pro() ) {
301 return false;
302 }
303
304 if ( ! current_user_can( 'manage_options' ) ) {
305 return false;
306 }
307
308 if ( 'elementor_page_elementor-role-manager' !== $this->current_screen_id || User::is_user_notice_viewed( $notice_id ) ) {
309 return false;
310 }
311
312 $users = new \WP_User_Query( [
313 'fields' => 'ID',
314 'number' => 10,
315 ] );
316
317 if ( 5 > $users->get_total() ) {
318 return false;
319 }
320
321 $options = [
322 'title' => esc_html__( 'Managing a multi-user site?', 'elementor' ),
323 'description' => esc_html__( 'With Elementor Pro, you can control user access and make sure no one messes up your design.', 'elementor' ),
324 'id' => $notice_id,
325
326 'button' => [
327 'text' => esc_html__( 'Learn More', 'elementor' ),
328 'url' => 'https://go.elementor.com/plugin-promotion-role-manager/',
329 'new_tab' => true,
330 'type' => 'cta',
331 ],
332 ];
333
334 $this->print_admin_notice( $options );
335
336 return true;
337 }
338
339 private function notice_experiment_promotion() {
340 $notice_id = 'experiment_promotion';
341
342 if ( ! current_user_can( 'manage_options' ) || User::is_user_notice_viewed( $notice_id ) ) {
343 return false;
344 }
345
346 $experiments = Plugin::$instance->experiments;
347 $is_all_performance_features_active = (
348 $experiments->is_feature_active( 'e_dom_optimization' ) &&
349 $experiments->is_feature_active( 'additional_custom_breakpoints' ) &&
350 $experiments->is_feature_active( 'e_optimized_css_loading' ) &&
351 $experiments->is_feature_active( 'e_optimized_assets_loading' )
352 );
353
354 if ( $is_all_performance_features_active ) {
355 return false;
356 }
357
358 $options = [
359 'title' => esc_html__( 'Improve your site’s performance score.', 'elementor' ),
360 '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' ),
361 'id' => $notice_id,
362 'button' => [
363 'text' => esc_html__( 'Try it out', 'elementor' ),
364 'url' => admin_url( 'admin.php?page=elementor#tab-experiments' ),
365 'type' => 'cta',
366 ],
367 'button_secondary' => [
368 'text' => esc_html__( 'Learn more', 'elementor' ),
369 'url' => 'https://go.elementor.com/wp-dash-experiment-promotion/',
370 'new_tab' => true,
371 'type' => 'cta',
372 ],
373 ];
374
375 $this->print_admin_notice( $options );
376
377 return true;
378 }
379
380 public function print_admin_notice( array $options ) {
381 global $pagenow;
382
383 if ( in_array( $pagenow, self::EXCLUDE_PAGES ) ) {
384 return;
385 }
386
387 $default_options = [
388 'id' => null,
389 'title' => '',
390 'description' => '',
391 'classes' => [ 'notice', 'e-notice' ], // We include WP's default notice class so it will be properly handled by WP's js handler
392 'type' => '',
393 'dismissible' => true,
394 'icon' => 'eicon-elementor',
395 'button' => [],
396 'button_secondary' => [],
397 ];
398
399 $options = array_replace_recursive( $default_options, $options );
400
401 $notice_classes = $options['classes'];
402 $dismiss_button = '';
403 $icon = '';
404
405 if ( $options['type'] ) {
406 $notice_classes[] = 'e-notice--' . $options['type'];
407 }
408
409 if ( $options['dismissible'] ) {
410 $label = esc_html__( 'Dismiss this notice.', 'elementor' );
411 $notice_classes[] = 'e-notice--dismissible';
412 $dismiss_button = '<i class="e-notice__dismiss" role="button" aria-label="' . $label . '" tabindex="0"></i>';
413 }
414
415 if ( $options['icon'] ) {
416 $notice_classes[] = 'e-notice--extended';
417 $icon = '<div class="e-notice__icon-wrapper"><i class="' . esc_attr( $options['icon'] ) . '" aria-hidden="true"></i></div>';
418 }
419
420 $wrapper_attributes = [
421 'class' => $notice_classes,
422 ];
423
424 if ( $options['id'] ) {
425 $wrapper_attributes['data-notice_id'] = $options['id'];
426 }
427 ?>
428 <div <?php Utils::print_html_attributes( $wrapper_attributes ); ?>>
429 <?php echo $dismiss_button; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
430 <div class="e-notice__aside">
431 <?php echo $icon; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
432 </div>
433 <div class="e-notice__content">
434 <?php if ( $options['title'] ) { ?>
435 <h3><?php echo wp_kses_post( $options['title'] ); ?></h3>
436 <?php } ?>
437
438 <?php if ( $options['description'] ) { ?>
439 <p><?php echo wp_kses_post( $options['description'] ); ?></p>
440 <?php } ?>
441
442 <?php if ( ! empty( $options['button']['text'] ) || ! empty( $options['button_secondary']['text'] ) ) { ?>
443 <div class="e-notice__actions">
444 <?php
445 foreach ( [ $options['button'], $options['button_secondary'] ] as $index => $button_settings ) {
446 if ( empty( $button_settings['variant'] ) && $index ) {
447 $button_settings['variant'] = 'outline';
448 }
449
450 if ( empty( $button_settings['text'] ) ) {
451 continue;
452 }
453
454 $button = new Button( $button_settings );
455 $button->print_button();
456 } ?>
457 </div>
458 <?php } ?>
459 </div>
460 </div>
461 <?php }
462
463 public function admin_notices() {
464 $this->install_time = Plugin::$instance->get_install_time();
465 $this->current_screen_id = get_current_screen()->id;
466
467 foreach ( $this->plain_notices as $notice ) {
468 $method_callback = "notice_{$notice}";
469 if ( $this->$method_callback() ) {
470 return;
471 }
472 }
473
474 /** @var Base_Notice $notice_instance */
475 foreach ( $this->get_notices() as $notice_instance ) {
476 if ( ! $notice_instance->should_print() ) {
477 continue;
478 }
479
480 $this->print_admin_notice( $notice_instance->get_config() );
481
482 // It exits the method to make sure it prints only one notice.
483 return;
484 }
485 }
486
487 /**
488 * @since 2.9.0
489 * @access public
490 */
491 public function __construct() {
492 add_action( 'admin_notices', [ $this, 'admin_notices' ], 20 );
493 }
494
495 /**
496 * Get module name.
497 *
498 * Retrieve the module name.
499 *
500 * @since 2.9.0
501 * @access public
502 *
503 * @return string Module name.
504 */
505 public function get_name() {
506 return 'admin-notices';
507 }
508 }
509