balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

admin.php (23330B)


      1 <?php
      2 namespace Elementor\Core\Admin;
      3 
      4 use Elementor\Api;
      5 use Elementor\Beta_Testers;
      6 use Elementor\Core\Base\App;
      7 use Elementor\Plugin;
      8 use Elementor\Settings;
      9 use Elementor\User;
     10 use Elementor\Utils;
     11 
     12 if ( ! defined( 'ABSPATH' ) ) {
     13 	exit; // Exit if accessed directly.
     14 }
     15 
     16 class Admin extends App {
     17 
     18 	/**
     19 	 * Get module name.
     20 	 *
     21 	 * Retrieve the module name.
     22 	 *
     23 	 * @since 2.3.0
     24 	 * @access public
     25 	 *
     26 	 * @return string Module name.
     27 	 */
     28 	public function get_name() {
     29 		return 'admin';
     30 	}
     31 
     32 	/**
     33 	 * @since 2.2.0
     34 	 * @access public
     35 	 */
     36 	public function maybe_redirect_to_getting_started() {
     37 		if ( ! get_transient( 'elementor_activation_redirect' ) ) {
     38 			return;
     39 		}
     40 
     41 		if ( wp_doing_ajax() ) {
     42 			return;
     43 		}
     44 
     45 		delete_transient( 'elementor_activation_redirect' );
     46 
     47 		if ( is_network_admin() || isset( $_GET['activate-multi'] ) ) {
     48 			return;
     49 		}
     50 
     51 		global $wpdb;
     52 
     53 		$has_elementor_page = ! ! $wpdb->get_var( "SELECT `post_id` FROM `{$wpdb->postmeta}` WHERE `meta_key` = '_elementor_edit_mode' LIMIT 1;" );
     54 
     55 		if ( $has_elementor_page ) {
     56 			return;
     57 		}
     58 
     59 		wp_safe_redirect( admin_url( 'admin.php?page=elementor-getting-started' ) );
     60 
     61 		exit;
     62 	}
     63 
     64 	/**
     65 	 * Enqueue admin scripts.
     66 	 *
     67 	 * Registers all the admin scripts and enqueues them.
     68 	 *
     69 	 * Fired by `admin_enqueue_scripts` action.
     70 	 *
     71 	 * @since 1.0.0
     72 	 * @access public
     73 	 */
     74 	public function enqueue_scripts() {
     75 		wp_register_script(
     76 			'elementor-admin',
     77 			$this->get_js_assets_url( 'admin' ),
     78 			[
     79 				'elementor-common',
     80 			],
     81 			ELEMENTOR_VERSION,
     82 			true
     83 		);
     84 
     85 		wp_enqueue_script( 'elementor-admin' );
     86 
     87 		$this->print_config();
     88 	}
     89 
     90 	/**
     91 	 * Enqueue admin styles.
     92 	 *
     93 	 * Registers all the admin styles and enqueues them.
     94 	 *
     95 	 * Fired by `admin_enqueue_scripts` action.
     96 	 *
     97 	 * @since 1.0.0
     98 	 * @access public
     99 	 */
    100 	public function enqueue_styles() {
    101 		$direction_suffix = is_rtl() ? '-rtl' : '';
    102 
    103 		wp_register_style(
    104 			'elementor-admin',
    105 			$this->get_css_assets_url( 'admin' . $direction_suffix ),
    106 			[
    107 				'elementor-common',
    108 			],
    109 			ELEMENTOR_VERSION
    110 		);
    111 
    112 		wp_enqueue_style( 'elementor-admin' );
    113 
    114 		// It's for upgrade notice.
    115 		// TODO: enqueue this just if needed.
    116 		add_thickbox();
    117 	}
    118 
    119 	/**
    120 	 * Print switch mode button.
    121 	 *
    122 	 * Adds a switch button in post edit screen (which has cpt support). To allow
    123 	 * the user to switch from the native WordPress editor to Elementor builder.
    124 	 *
    125 	 * Fired by `edit_form_after_title` action.
    126 	 *
    127 	 * @since 1.0.0
    128 	 * @access public
    129 	 *
    130 	 * @param \WP_Post $post The current post object.
    131 	 */
    132 	public function print_switch_mode_button( $post ) {
    133 		// Exit if Gutenberg are active.
    134 		if ( did_action( 'enqueue_block_editor_assets' ) ) {
    135 			return;
    136 		}
    137 
    138 		$document = Plugin::$instance->documents->get( $post->ID );
    139 
    140 		if ( ! $document || ! $document->is_editable_by_current_user() ) {
    141 			return;
    142 		}
    143 
    144 		wp_nonce_field( basename( __FILE__ ), '_elementor_edit_mode_nonce' );
    145 		?>
    146 		<div id="elementor-switch-mode">
    147 			<input id="elementor-switch-mode-input" type="hidden" name="_elementor_post_mode" value="<?php echo esc_attr( $document->is_built_with_elementor() ); ?>" />
    148 			<button id="elementor-switch-mode-button" type="button" class="button button-primary button-hero">
    149 				<span class="elementor-switch-mode-on">
    150 					<i class="eicon-arrow-<?php echo ( is_rtl() ) ? 'right' : 'left'; ?>" aria-hidden="true"></i>
    151 					<?php echo esc_html__( 'Back to WordPress Editor', 'elementor' ); ?>
    152 				</span>
    153 				<span class="elementor-switch-mode-off">
    154 					<i class="eicon-elementor-square" aria-hidden="true"></i>
    155 					<?php echo esc_html__( 'Edit with Elementor', 'elementor' ); ?>
    156 				</span>
    157 			</button>
    158 		</div>
    159 		<div id="elementor-editor">
    160 			<a id="elementor-go-to-edit-page-link" href="<?php echo esc_url( $document->get_edit_url() ); ?>">
    161 				<div id="elementor-editor-button" class="button button-primary button-hero">
    162 					<i class="eicon-elementor-square" aria-hidden="true"></i>
    163 					<?php echo esc_html__( 'Edit with Elementor', 'elementor' ); ?>
    164 				</div>
    165 				<div class="elementor-loader-wrapper">
    166 					<div class="elementor-loader">
    167 						<div class="elementor-loader-boxes">
    168 							<div class="elementor-loader-box"></div>
    169 							<div class="elementor-loader-box"></div>
    170 							<div class="elementor-loader-box"></div>
    171 							<div class="elementor-loader-box"></div>
    172 						</div>
    173 					</div>
    174 					<div class="elementor-loading-title"><?php echo esc_html__( 'Loading', 'elementor' ); ?></div>
    175 				</div>
    176 			</a>
    177 		</div>
    178 		<?php
    179 	}
    180 
    181 	/**
    182 	 * Save post.
    183 	 *
    184 	 * Flag the post mode when the post is saved.
    185 	 *
    186 	 * Fired by `save_post` action.
    187 	 *
    188 	 * @since 1.0.0
    189 	 * @access public
    190 	 *
    191 	 * @param int $post_id Post ID.
    192 	 */
    193 	public function save_post( $post_id ) {
    194 		if ( ! isset( $_POST['_elementor_edit_mode_nonce'] ) || ! wp_verify_nonce( $_POST['_elementor_edit_mode_nonce'], basename( __FILE__ ) ) ) {
    195 			return;
    196 		}
    197 
    198 		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
    199 			return;
    200 		}
    201 
    202 		Plugin::$instance->documents->get( $post_id )->set_is_built_with_elementor( ! empty( $_POST['_elementor_post_mode'] ) );
    203 	}
    204 
    205 	/**
    206 	 * Add Elementor post state.
    207 	 *
    208 	 * Adds a new "Elementor" post state to the post table.
    209 	 *
    210 	 * Fired by `display_post_states` filter.
    211 	 *
    212 	 * @since 1.8.0
    213 	 * @access public
    214 	 *
    215 	 * @param array    $post_states An array of post display states.
    216 	 * @param \WP_Post $post        The current post object.
    217 	 *
    218 	 * @return array A filtered array of post display states.
    219 	 */
    220 	public function add_elementor_post_state( $post_states, $post ) {
    221 		$document = Plugin::$instance->documents->get( $post->ID );
    222 
    223 		if ( $document && $document->is_built_with_elementor() && $document->is_editable_by_current_user() ) {
    224 			$post_states['elementor'] = esc_html__( 'Elementor', 'elementor' );
    225 		}
    226 
    227 		return $post_states;
    228 	}
    229 
    230 	/**
    231 	 * Body status classes.
    232 	 *
    233 	 * Adds CSS classes to the admin body tag.
    234 	 *
    235 	 * Fired by `admin_body_class` filter.
    236 	 *
    237 	 * @since 1.0.0
    238 	 * @access public
    239 	 *
    240 	 * @param string $classes Space-separated list of CSS classes.
    241 	 *
    242 	 * @return string Space-separated list of CSS classes.
    243 	 */
    244 	public function body_status_classes( $classes ) {
    245 		global $pagenow;
    246 
    247 		if ( in_array( $pagenow, [ 'post.php', 'post-new.php' ], true ) && Utils::is_post_support() ) {
    248 			$post = get_post();
    249 
    250 			$document = Plugin::$instance->documents->get( $post->ID );
    251 
    252 			$mode_class = $document && $document->is_built_with_elementor() ? 'elementor-editor-active' : 'elementor-editor-inactive';
    253 
    254 			$classes .= ' ' . $mode_class;
    255 		}
    256 
    257 		return $classes;
    258 	}
    259 
    260 	/**
    261 	 * Plugin action links.
    262 	 *
    263 	 * Adds action links to the plugin list table
    264 	 *
    265 	 * Fired by `plugin_action_links` filter.
    266 	 *
    267 	 * @since 1.0.0
    268 	 * @access public
    269 	 *
    270 	 * @param array $links An array of plugin action links.
    271 	 *
    272 	 * @return array An array of plugin action links.
    273 	 */
    274 	public function plugin_action_links( $links ) {
    275 		$settings_link = sprintf( '<a href="%1$s">%2$s</a>', admin_url( 'admin.php?page=' . Settings::PAGE_ID ), esc_html__( 'Settings', 'elementor' ) );
    276 
    277 		array_unshift( $links, $settings_link );
    278 
    279 		$links['go_pro'] = sprintf( '<a href="%1$s" target="_blank" class="elementor-plugins-gopro">%2$s</a>', Utils::get_pro_link( 'https://elementor.com/pro/?utm_source=wp-plugins&utm_campaign=gopro&utm_medium=wp-dash' ), esc_html__( 'Go Pro', 'elementor' ) );
    280 
    281 		return $links;
    282 	}
    283 
    284 	/**
    285 	 * Plugin row meta.
    286 	 *
    287 	 * Adds row meta links to the plugin list table
    288 	 *
    289 	 * Fired by `plugin_row_meta` filter.
    290 	 *
    291 	 * @since 1.1.4
    292 	 * @access public
    293 	 *
    294 	 * @param array  $plugin_meta An array of the plugin's metadata, including
    295 	 *                            the version, author, author URI, and plugin URI.
    296 	 * @param string $plugin_file Path to the plugin file, relative to the plugins
    297 	 *                            directory.
    298 	 *
    299 	 * @return array An array of plugin row meta links.
    300 	 */
    301 	public function plugin_row_meta( $plugin_meta, $plugin_file ) {
    302 		if ( ELEMENTOR_PLUGIN_BASE === $plugin_file ) {
    303 			$row_meta = [
    304 				'docs' => '<a href="https://go.elementor.com/docs-admin-plugins/" aria-label="' . esc_attr( esc_html__( 'View Elementor Documentation', 'elementor' ) ) . '" target="_blank">' . esc_html__( 'Docs & FAQs', 'elementor' ) . '</a>',
    305 				'ideo' => '<a href="https://go.elementor.com/yt-admin-plugins/" aria-label="' . esc_attr( esc_html__( 'View Elementor Video Tutorials', 'elementor' ) ) . '" target="_blank">' . esc_html__( 'Video Tutorials', 'elementor' ) . '</a>',
    306 			];
    307 
    308 			$plugin_meta = array_merge( $plugin_meta, $row_meta );
    309 		}
    310 
    311 		return $plugin_meta;
    312 	}
    313 
    314 	/**
    315 	 * Admin footer text.
    316 	 *
    317 	 * Modifies the "Thank you" text displayed in the admin footer.
    318 	 *
    319 	 * Fired by `admin_footer_text` filter.
    320 	 *
    321 	 * @since 1.0.0
    322 	 * @access public
    323 	 *
    324 	 * @param string $footer_text The content that will be printed.
    325 	 *
    326 	 * @return string The content that will be printed.
    327 	 */
    328 	public function admin_footer_text( $footer_text ) {
    329 		$current_screen = get_current_screen();
    330 		$is_elementor_screen = ( $current_screen && false !== strpos( $current_screen->id, 'elementor' ) );
    331 
    332 		if ( $is_elementor_screen ) {
    333 			$footer_text = sprintf(
    334 				/* translators: 1: Elementor, 2: Link to plugin review */
    335 				__( 'Enjoyed %1$s? Please leave us a %2$s rating. We really appreciate your support!', 'elementor' ),
    336 				'<strong>' . esc_html__( 'Elementor', 'elementor' ) . '</strong>',
    337 				'<a href="https://go.elementor.com/admin-review/" target="_blank">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
    338 			);
    339 		}
    340 
    341 		return $footer_text;
    342 	}
    343 
    344 	/**
    345 	 * Register dashboard widgets.
    346 	 *
    347 	 * Adds a new Elementor widgets to WordPress dashboard.
    348 	 *
    349 	 * Fired by `wp_dashboard_setup` action.
    350 	 *
    351 	 * @since 1.9.0
    352 	 * @access public
    353 	 */
    354 	public function register_dashboard_widgets() {
    355 		wp_add_dashboard_widget( 'e-dashboard-overview', esc_html__( 'Elementor Overview', 'elementor' ), [ $this, 'elementor_dashboard_overview_widget' ] );
    356 
    357 		// Move our widget to top.
    358 		global $wp_meta_boxes;
    359 
    360 		$dashboard = $wp_meta_boxes['dashboard']['normal']['core'];
    361 		$ours = [
    362 			'e-dashboard-overview' => $dashboard['e-dashboard-overview'],
    363 		];
    364 
    365 		$wp_meta_boxes['dashboard']['normal']['core'] = array_merge( $ours, $dashboard ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
    366 	}
    367 
    368 	/**
    369 	 * Elementor dashboard widget.
    370 	 *
    371 	 * Displays the Elementor dashboard widget.
    372 	 *
    373 	 * Fired by `wp_add_dashboard_widget` function.
    374 	 *
    375 	 * @since 1.9.0
    376 	 * @access public
    377 	 */
    378 	public function elementor_dashboard_overview_widget() {
    379 		$elementor_feed = Api::get_feed_data();
    380 		$recently_edited_query = Utils::get_recently_edited_posts_query();
    381 
    382 		if ( User::is_current_user_can_edit_post_type( 'page' ) ) {
    383 			$create_new_label = esc_html__( 'Create New Page', 'elementor' );
    384 			$create_new_post_type = 'page';
    385 		} elseif ( User::is_current_user_can_edit_post_type( 'post' ) ) {
    386 			$create_new_label = esc_html__( 'Create New Post', 'elementor' );
    387 			$create_new_post_type = 'post';
    388 		}
    389 		?>
    390 		<div class="e-dashboard-widget">
    391 			<div class="e-overview__header">
    392 				<div class="e-overview__logo"><div class="e-logo-wrapper"><i class="eicon-elementor"></i></div></div>
    393 				<div class="e-overview__versions">
    394 					<span class="e-overview__version"><?php echo esc_html__( 'Elementor', 'elementor' ); ?> v<?php echo ELEMENTOR_VERSION; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></span>
    395 					<?php
    396 					/**
    397 					 * Elementor dashboard widget after the version.
    398 					 *
    399 					 * Fires after Elementor version display in the dashboard widget.
    400 					 *
    401 					 * @since 1.9.0
    402 					 */
    403 					do_action( 'elementor/admin/dashboard_overview_widget/after_version' );
    404 					?>
    405 				</div>
    406 				<?php if ( ! empty( $create_new_post_type ) ) : ?>
    407 					<div class="e-overview__create">
    408 						<a href="<?php echo esc_url( Plugin::$instance->documents->get_create_new_post_url( $create_new_post_type ) ); ?>" class="button"><span aria-hidden="true" class="dashicons dashicons-plus"></span> <?php echo esc_html( $create_new_label ); ?></a>
    409 					</div>
    410 				<?php endif; ?>
    411 			</div>
    412 			<?php if ( $recently_edited_query->have_posts() ) : ?>
    413 				<div class="e-overview__recently-edited">
    414 					<h3 class="e-heading e-divider_bottom"><?php echo esc_html__( 'Recently Edited', 'elementor' ); ?></h3>
    415 					<ul class="e-overview__posts">
    416 						<?php
    417 						while ( $recently_edited_query->have_posts() ) :
    418 							$recently_edited_query->the_post();
    419 							$document = Plugin::$instance->documents->get( get_the_ID() );
    420 
    421 							$date = date_i18n( _x( 'M jS', 'Dashboard Overview Widget Recently Date', 'elementor' ), get_the_modified_time( 'U' ) );
    422 							?>
    423 							<li class="e-overview__post">
    424 								<a href="<?php echo esc_attr( $document->get_edit_url() ); ?>" class="e-overview__post-link"><?php echo esc_html( get_the_title() ); ?> <span class="dashicons dashicons-edit"></span></a> <span><?php echo $date; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>, <?php the_time(); ?></span>
    425 							</li>
    426 						<?php endwhile; ?>
    427 					</ul>
    428 				</div>
    429 			<?php endif; ?>
    430 			<?php if ( ! empty( $elementor_feed ) ) : ?>
    431 				<div class="e-overview__feed">
    432 					<h3 class="e-heading e-divider_bottom"><?php echo esc_html__( 'News & Updates', 'elementor' ); ?></h3>
    433 					<ul class="e-overview__posts">
    434 						<?php foreach ( $elementor_feed as $feed_item ) : ?>
    435 							<li class="e-overview__post">
    436 								<a href="<?php echo esc_url( $feed_item['url'] ); ?>" class="e-overview__post-link" target="_blank">
    437 									<?php if ( ! empty( $feed_item['badge'] ) ) : ?>
    438 										<span class="e-overview__badge"><?php echo esc_html( $feed_item['badge'] ); ?></span>
    439 									<?php endif; ?>
    440 									<?php echo esc_html( $feed_item['title'] ); ?>
    441 								</a>
    442 								<p class="e-overview__post-description"><?php echo esc_html( $feed_item['excerpt'] ); ?></p>
    443 							</li>
    444 						<?php endforeach; ?>
    445 					</ul>
    446 				</div>
    447 			<?php endif; ?>
    448 			<div class="e-overview__footer e-divider_top">
    449 				<ul>
    450 					<?php foreach ( $this->get_dashboard_overview_widget_footer_actions() as $action_id => $action ) : ?>
    451 						<li class="e-overview__<?php echo esc_attr( $action_id ); ?>"><a href="<?php echo esc_attr( $action['link'] ); ?>" target="_blank"><?php echo esc_html( $action['title'] ); ?> <span class="screen-reader-text"><?php echo esc_html__( '(opens in a new window)', 'elementor' ); ?></span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></li>
    452 					<?php endforeach; ?>
    453 				</ul>
    454 			</div>
    455 		</div>
    456 		<?php
    457 	}
    458 
    459 	/**
    460 	 * Get elementor dashboard overview widget footer actions.
    461 	 *
    462 	 * Retrieves the footer action links displayed in elementor dashboard widget.
    463 	 *
    464 	 * @since 1.9.0
    465 	 * @access private
    466 	 */
    467 	private function get_dashboard_overview_widget_footer_actions() {
    468 		$base_actions = [
    469 			'blog' => [
    470 				'title' => esc_html__( 'Blog', 'elementor' ),
    471 				'link' => 'https://go.elementor.com/overview-widget-blog/',
    472 			],
    473 			'help' => [
    474 				'title' => esc_html__( 'Help', 'elementor' ),
    475 				'link' => 'https://go.elementor.com/overview-widget-docs/',
    476 			],
    477 		];
    478 
    479 		$additions_actions = [
    480 			'go-pro' => [
    481 				'title' => esc_html__( 'Go Pro', 'elementor' ),
    482 				'link' => Utils::get_pro_link( 'https://elementor.com/pro/?utm_source=wp-overview-widget&utm_campaign=gopro&utm_medium=wp-dash' ),
    483 			],
    484 		];
    485 
    486 		// Visible to all core users when Elementor Pro is not installed.
    487 		$additions_actions['find_an_expert'] = [
    488 			'title' => esc_html__( 'Find an Expert', 'elementor' ),
    489 			'link' => 'https://go.elementor.com/go-pro-find-an-expert',
    490 		];
    491 
    492 		/**
    493 		 * Dashboard widget footer actions.
    494 		 *
    495 		 * Filters the additions actions displayed in Elementor dashboard widget.
    496 		 *
    497 		 * Developers can add new action links to Elementor dashboard widget
    498 		 * footer using this filter.
    499 		 *
    500 		 * @since 1.9.0
    501 		 *
    502 		 * @param array $additions_actions Elementor dashboard widget footer actions.
    503 		 */
    504 		$additions_actions = apply_filters( 'elementor/admin/dashboard_overview_widget/footer_actions', $additions_actions );
    505 
    506 		$actions = $base_actions + $additions_actions;
    507 
    508 		return $actions;
    509 	}
    510 
    511 	/**
    512 	 * Admin action new post.
    513 	 *
    514 	 * When a new post action is fired the title is set to 'Elementor' and the post ID.
    515 	 *
    516 	 * Fired by `admin_action_elementor_new_post` action.
    517 	 *
    518 	 * @since 1.9.0
    519 	 * @access public
    520 	 */
    521 	public function admin_action_new_post() {
    522 		check_admin_referer( 'elementor_action_new_post' );
    523 
    524 		if ( empty( $_GET['post_type'] ) ) {
    525 			$post_type = 'post';
    526 		} else {
    527 			$post_type = $_GET['post_type'];
    528 		}
    529 
    530 		if ( ! User::is_current_user_can_edit_post_type( $post_type ) ) {
    531 			return;
    532 		}
    533 
    534 		if ( empty( $_GET['template_type'] ) ) {
    535 			$type = 'post';
    536 		} else {
    537 			$type = sanitize_text_field( $_GET['template_type'] );
    538 		}
    539 
    540 		$post_data = isset( $_GET['post_data'] ) ? $_GET['post_data'] : [];
    541 
    542 		$meta = [];
    543 
    544 		/**
    545 		 * Create new post meta data.
    546 		 *
    547 		 * Filters the meta data of any new post created.
    548 		 *
    549 		 * @since 2.0.0
    550 		 *
    551 		 * @param array $meta Post meta data.
    552 		 */
    553 		$meta = apply_filters( 'elementor/admin/create_new_post/meta', $meta );
    554 
    555 		$post_data['post_type'] = $post_type;
    556 
    557 		$document = Plugin::$instance->documents->create( $type, $post_data, $meta );
    558 
    559 		if ( is_wp_error( $document ) ) {
    560 			wp_die( $document ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    561 		}
    562 
    563 		wp_redirect( $document->get_edit_url() );
    564 
    565 		die;
    566 	}
    567 
    568 	/**
    569 	 * @since 2.3.0
    570 	 * @access public
    571 	 */
    572 	public function add_new_template_template() {
    573 		Plugin::$instance->common->add_template( ELEMENTOR_PATH . 'includes/admin-templates/new-template.php' );
    574 	}
    575 
    576 	/**
    577 	 * @access public
    578 	 */
    579 	public function enqueue_new_template_scripts() {
    580 		$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
    581 
    582 		wp_enqueue_script(
    583 			'elementor-new-template',
    584 			ELEMENTOR_ASSETS_URL . 'js/new-template' . $suffix . '.js',
    585 			[],
    586 			ELEMENTOR_VERSION,
    587 			true
    588 		);
    589 	}
    590 
    591 	/**
    592 	 * @since 2.6.0
    593 	 * @access public
    594 	 */
    595 	public function add_beta_tester_template() {
    596 		Plugin::$instance->common->add_template( ELEMENTOR_PATH . 'includes/admin-templates/beta-tester.php' );
    597 	}
    598 
    599 	/**
    600 	 * @access public
    601 	 */
    602 	public function enqueue_beta_tester_scripts() {
    603 		$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
    604 
    605 		wp_enqueue_script(
    606 			'elementor-beta-tester',
    607 			ELEMENTOR_ASSETS_URL . 'js/beta-tester' . $suffix . '.js',
    608 			[],
    609 			ELEMENTOR_VERSION,
    610 			true
    611 		);
    612 	}
    613 
    614 	/**
    615 	 * @access public
    616 	 */
    617 	public function init_new_template() {
    618 		if ( 'edit-elementor_library' !== get_current_screen()->id ) {
    619 			return;
    620 		}
    621 
    622 		// Allow plugins to add their templates on admin_head.
    623 		add_action( 'admin_head', [ $this, 'add_new_template_template' ] );
    624 		add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_new_template_scripts' ] );
    625 	}
    626 
    627 	public function version_update_warning( $current_version, $new_version ) {
    628 		$current_version_minor_part = explode( '.', $current_version )[1];
    629 		$new_version_minor_part = explode( '.', $new_version )[1];
    630 
    631 		if ( $current_version_minor_part === $new_version_minor_part ) {
    632 			return;
    633 		}
    634 		?>
    635 		<hr class="e-major-update-warning__separator" />
    636 		<div class="e-major-update-warning">
    637 			<div class="e-major-update-warning__icon">
    638 				<i class="eicon-info-circle"></i>
    639 			</div>
    640 			<div>
    641 				<div class="e-major-update-warning__title">
    642 					<?php echo esc_html__( 'Heads up, Please backup before upgrade!', 'elementor' ); ?>
    643 				</div>
    644 				<div class="e-major-update-warning__message">
    645 					<?php
    646 						printf(
    647 							/* translators: %1$s Link open tag, %2$s: Link close tag. */
    648 							esc_html__( 'The latest update includes some substantial changes across different areas of the plugin. We highly recommend you %1$sbackup your site before upgrading%2$s, and make sure you first update in a staging environment', 'elementor' ),
    649 							'<a href="https://go.elementor.com/wp-dash-update-backup/">',
    650 							'</a>'
    651 						);
    652 					?>
    653 				</div>
    654 			</div>
    655 		</div>
    656 		<?php
    657 	}
    658 
    659 	/**
    660 	 * @access public
    661 	 */
    662 	public function init_beta_tester( $current_screen ) {
    663 		if ( ( 'toplevel_page_elementor' === $current_screen->base ) || 'elementor_page_elementor-tools' === $current_screen->id ) {
    664 			add_action( 'admin_head', [ $this, 'add_beta_tester_template' ] );
    665 			add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_beta_tester_scripts' ] );
    666 		}
    667 	}
    668 
    669 	/**
    670 	 * Admin constructor.
    671 	 *
    672 	 * Initializing Elementor in WordPress admin.
    673 	 *
    674 	 * @since 1.0.0
    675 	 * @access public
    676 	 */
    677 	public function __construct() {
    678 		Plugin::$instance->init_common();
    679 
    680 		$this->add_component( 'feedback', new Feedback() );
    681 		$this->add_component( 'canary-deployment', new Canary_Deployment() );
    682 		$this->add_component( 'admin-notices', new Admin_Notices() );
    683 
    684 		add_action( 'admin_init', [ $this, 'maybe_redirect_to_getting_started' ] );
    685 
    686 		add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
    687 		add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_styles' ] );
    688 
    689 		add_action( 'edit_form_after_title', [ $this, 'print_switch_mode_button' ] );
    690 		add_action( 'save_post', [ $this, 'save_post' ] );
    691 
    692 		add_filter( 'display_post_states', [ $this, 'add_elementor_post_state' ], 10, 2 );
    693 
    694 		add_filter( 'plugin_action_links_' . ELEMENTOR_PLUGIN_BASE, [ $this, 'plugin_action_links' ] );
    695 		add_filter( 'plugin_row_meta', [ $this, 'plugin_row_meta' ], 10, 2 );
    696 
    697 		add_filter( 'admin_body_class', [ $this, 'body_status_classes' ] );
    698 		add_filter( 'admin_footer_text', [ $this, 'admin_footer_text' ] );
    699 
    700 		// Register Dashboard Widgets.
    701 		add_action( 'wp_dashboard_setup', [ $this, 'register_dashboard_widgets' ] );
    702 
    703 		// Admin Actions
    704 		add_action( 'admin_action_elementor_new_post', [ $this, 'admin_action_new_post' ] );
    705 
    706 		add_action( 'current_screen', [ $this, 'init_new_template' ] );
    707 		add_action( 'current_screen', [ $this, 'init_beta_tester' ] );
    708 
    709 		add_action( 'in_plugin_update_message-' . ELEMENTOR_PLUGIN_BASE, function( $plugin_data ) {
    710 			$this->version_update_warning( ELEMENTOR_VERSION, $plugin_data['new_version'] );
    711 		} );
    712 	}
    713 
    714 	/**
    715 	 * @since 2.3.0
    716 	 * @access protected
    717 	 */
    718 	protected function get_init_settings() {
    719 		$beta_tester_email = get_user_meta( get_current_user_id(), User::BETA_TESTER_META_KEY, true );
    720 		$elementor_beta = get_option( 'elementor_beta', 'no' );
    721 		$all_introductions = User::get_introduction_meta();
    722 		$beta_tester_signup_dismissed = array_key_exists( Beta_Testers::BETA_TESTER_SIGNUP, $all_introductions );
    723 
    724 		$settings = [
    725 			'home_url' => home_url(),
    726 			'settings_url' => Settings::get_url(),
    727 			'user' => [
    728 				'introduction' => User::get_introduction_meta(),
    729 			],
    730 			'beta_tester' => [
    731 				'beta_tester_signup' => Beta_Testers::BETA_TESTER_SIGNUP,
    732 				'has_email' => $beta_tester_email,
    733 				'option_enabled' => 'no' !== $elementor_beta,
    734 				'signup_dismissed' => $beta_tester_signup_dismissed,
    735 			],
    736 		];
    737 
    738 		/**
    739 		 * Localize settings.
    740 		 *
    741 		 * Filters the initial localize settings in the admin.
    742 		 *
    743 		 * WordPress has it's own way to pass localized data from PHP (backend) to
    744 		 * JS (frontend). Elementor uses this method to pass localize data in the
    745 		 * admin. This hook can be used to add more localized settings in addition
    746 		 * to the initial Elementor settings.
    747 		 *
    748 		 * @since 2.3.0
    749 		 *
    750 		 * @param array $settings Initial localize settings.
    751 		 */
    752 		$settings = apply_filters( 'elementor/admin/localize_settings', $settings );
    753 
    754 		return $settings;
    755 	}
    756 }