PluginProbe
Elementor Website Builder – more than just a page builder / 3.17.0-dev3
Elementor Website Builder – more than just a page builder v3.17.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
elementor / core / admin / admin-notices.php

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

508 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, please help us by leaving a five star review on WordPress.org.', 'elementor' ),
275 'id' => $notice_id,
276 'button' => [
277 'text' => esc_html__( 'Happy To Help', 'elementor' ),
278 'url' => 'https://go.elementor.com/admin-review/',
279 'new_tab' => true,
280 'type' => 'cta',
281 ],
282 'button_secondary' => [
283 'text' => esc_html__( 'Hide Notification', 'elementor' ),
284 'classes' => [ 'e-notice-dismiss' ],
285 'url' => esc_url_raw( $dismiss_url ),
286 'new_tab' => true,
287 'type' => 'cta',
288 ],
289 ];
290
291 $this->print_admin_notice( $options );
292
293 return true;
294 }
295
296 private function notice_role_manager_promote() {
297 $notice_id = 'role_manager_promote';
298
299 if ( Utils::has_pro() ) {
300 return false;
301 }
302
303 if ( ! current_user_can( 'manage_options' ) ) {
304 return false;
305 }
306
307 if ( 'elementor_page_elementor-role-manager' !== $this->current_screen_id || User::is_user_notice_viewed( $notice_id ) ) {
308 return false;
309 }
310
311 $users = new \WP_User_Query( [
312 'fields' => 'ID',
313 'number' => 10,
314 ] );
315
316 if ( 5 > $users->get_total() ) {
317 return false;
318 }
319
320 $options = [
321 'title' => esc_html__( 'Managing a multi-user site?', 'elementor' ),
322 'description' => esc_html__( 'With Elementor Pro, you can control user access and make sure no one messes up your design.', 'elementor' ),
323 'id' => $notice_id,
324
325 'button' => [
326 'text' => esc_html__( 'Learn More', 'elementor' ),
327 'url' => 'https://go.elementor.com/plugin-promotion-role-manager/',
328 'new_tab' => true,
329 'type' => 'cta',
330 ],
331 ];
332
333 $this->print_admin_notice( $options );
334
335 return true;
336 }
337
338 private function notice_experiment_promotion() {
339 $notice_id = 'experiment_promotion';
340
341 if ( ! current_user_can( 'manage_options' ) || User::is_user_notice_viewed( $notice_id ) ) {
342 return false;
343 }
344
345 $experiments = Plugin::$instance->experiments;
346 $is_all_performance_features_active = (
347 $experiments->is_feature_active( 'e_dom_optimization' ) &&
348 $experiments->is_feature_active( 'additional_custom_breakpoints' ) &&
349 $experiments->is_feature_active( 'e_optimized_css_loading' ) &&
350 $experiments->is_feature_active( 'e_optimized_assets_loading' )
351 );
352
353 if ( $is_all_performance_features_active ) {
354 return false;
355 }
356
357 $options = [
358 'title' => esc_html__( 'Improve your site’s performance score.', 'elementor' ),
359 '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' ),
360 'id' => $notice_id,
361 'button' => [
362 'text' => esc_html__( 'Try it out', 'elementor' ),
363 'url' => admin_url( 'admin.php?page=elementor#tab-experiments' ),
364 'type' => 'cta',
365 ],
366 'button_secondary' => [
367 'text' => esc_html__( 'Learn more', 'elementor' ),
368 'url' => 'https://go.elementor.com/wp-dash-experiment-promotion/',
369 'new_tab' => true,
370 'type' => 'cta',
371 ],
372 ];
373
374 $this->print_admin_notice( $options );
375
376 return true;
377 }
378
379 public function print_admin_notice( array $options ) {
380 global $pagenow;
381
382 if ( in_array( $pagenow, self::EXCLUDE_PAGES ) ) {
383 return;
384 }
385
386 $default_options = [
387 'id' => null,
388 'title' => '',
389 'description' => '',
390 'classes' => [ 'notice', 'e-notice' ], // We include WP's default notice class so it will be properly handled by WP's js handler
391 'type' => '',
392 'dismissible' => true,
393 'icon' => 'eicon-elementor',
394 'button' => [],
395 'button_secondary' => [],
396 ];
397
398 $options = array_replace_recursive( $default_options, $options );
399
400 $notice_classes = $options['classes'];
401 $dismiss_button = '';
402 $icon = '';
403
404 if ( $options['type'] ) {
405 $notice_classes[] = 'e-notice--' . $options['type'];
406 }
407
408 if ( $options['dismissible'] ) {
409 $label = esc_html__( 'Dismiss this notice.', 'elementor' );
410 $notice_classes[] = 'e-notice--dismissible';
411 $dismiss_button = '<i class="e-notice__dismiss" role="button" aria-label="' . $label . '" tabindex="0"></i>';
412 }
413
414 if ( $options['icon'] ) {
415 $notice_classes[] = 'e-notice--extended';
416 $icon = '<div class="e-notice__icon-wrapper"><i class="' . esc_attr( $options['icon'] ) . '" aria-hidden="true"></i></div>';
417 }
418
419 $wrapper_attributes = [
420 'class' => $notice_classes,
421 ];
422
423 if ( $options['id'] ) {
424 $wrapper_attributes['data-notice_id'] = $options['id'];
425 }
426 ?>
427 <div <?php Utils::print_html_attributes( $wrapper_attributes ); ?>>
428 <?php echo $dismiss_button; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
429 <div class="e-notice__aside">
430 <?php echo $icon; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
431 </div>
432 <div class="e-notice__content">
433 <?php if ( $options['title'] ) { ?>
434 <h3><?php echo wp_kses_post( $options['title'] ); ?></h3>
435 <?php } ?>
436
437 <?php if ( $options['description'] ) { ?>
438 <p><?php echo wp_kses_post( $options['description'] ); ?></p>
439 <?php } ?>
440
441 <?php if ( ! empty( $options['button']['text'] ) || ! empty( $options['button_secondary']['text'] ) ) { ?>
442 <div class="e-notice__actions">
443 <?php
444 foreach ( [ $options['button'], $options['button_secondary'] ] as $index => $button_settings ) {
445 if ( empty( $button_settings['variant'] ) && $index ) {
446 $button_settings['variant'] = 'outline';
447 }
448
449 if ( empty( $button_settings['text'] ) ) {
450 continue;
451 }
452
453 $button = new Button( $button_settings );
454 $button->print_button();
455 } ?>
456 </div>
457 <?php } ?>
458 </div>
459 </div>
460 <?php }
461
462 public function admin_notices() {
463 $this->install_time = Plugin::$instance->get_install_time();
464 $this->current_screen_id = get_current_screen()->id;
465
466 foreach ( $this->plain_notices as $notice ) {
467 $method_callback = "notice_{$notice}";
468 if ( $this->$method_callback() ) {
469 return;
470 }
471 }
472
473 /** @var Base_Notice $notice_instance */
474 foreach ( $this->get_notices() as $notice_instance ) {
475 if ( ! $notice_instance->should_print() ) {
476 continue;
477 }
478
479 $this->print_admin_notice( $notice_instance->get_config() );
480
481 // It exits the method to make sure it prints only one notice.
482 return;
483 }
484 }
485
486 /**
487 * @since 2.9.0
488 * @access public
489 */
490 public function __construct() {
491 add_action( 'admin_notices', [ $this, 'admin_notices' ], 20 );
492 }
493
494 /**
495 * Get module name.
496 *
497 * Retrieve the module name.
498 *
499 * @since 2.9.0
500 * @access public
501 *
502 * @return string Module name.
503 */
504 public function get_name() {
505 return 'admin-notices';
506 }
507 }
508