balmet.com

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

maintenance-mode.php (11400B)


      1 <?php
      2 namespace Elementor;
      3 
      4 use Elementor\TemplateLibrary\Source_Local;
      5 
      6 if ( ! defined( 'ABSPATH' ) ) {
      7 	exit; // Exit if accessed directly.
      8 }
      9 
     10 /**
     11  * Elementor maintenance mode.
     12  *
     13  * Elementor maintenance mode handler class is responsible for the Elementor
     14  * "Maintenance Mode" and the "Coming Soon" features.
     15  *
     16  * @since 1.4.0
     17  */
     18 class Maintenance_Mode {
     19 
     20 	/**
     21 	 * The options prefix.
     22 	 */
     23 	const OPTION_PREFIX = 'elementor_maintenance_mode_';
     24 
     25 	/**
     26 	 * The maintenance mode.
     27 	 */
     28 	const MODE_MAINTENANCE = 'maintenance';
     29 
     30 	/**
     31 	 * The coming soon mode.
     32 	 */
     33 	const MODE_COMING_SOON = 'coming_soon';
     34 
     35 	/**
     36 	 * Get elementor option.
     37 	 *
     38 	 * Retrieve elementor option from the database.
     39 	 *
     40 	 * @since 1.4.0
     41 	 * @access public
     42 	 * @static
     43 	 *
     44 	 * @param string $option  Option name. Expected to not be SQL-escaped.
     45 	 * @param mixed  $default Optional. Default value to return if the option
     46 	 *                        does not exist. Default is false.
     47 	 *
     48 	 * @return bool False if value was not updated and true if value was updated.
     49 	 */
     50 	public static function get( $option, $default = false ) {
     51 		return get_option( self::OPTION_PREFIX . $option, $default );
     52 	}
     53 
     54 	/**
     55 	 * Set elementor option.
     56 	 *
     57 	 * Update elementor option in the database.
     58 	 *
     59 	 * @since 1.4.0
     60 	 * @access public
     61 	 * @static
     62 	 *
     63 	 * @param string $option Option name. Expected to not be SQL-escaped.
     64 	 * @param mixed  $value  Option value. Must be serializable if non-scalar.
     65 	 *                       Expected to not be SQL-escaped.
     66 	 *
     67 	 * @return bool False if value was not updated and true if value was updated.
     68 	 */
     69 	public static function set( $option, $value ) {
     70 		return update_option( self::OPTION_PREFIX . $option, $value );
     71 	}
     72 
     73 	/**
     74 	 * Body class.
     75 	 *
     76 	 * Add "Maintenance Mode" CSS classes to the body tag.
     77 	 *
     78 	 * Fired by `body_class` filter.
     79 	 *
     80 	 * @since 1.4.0
     81 	 * @access public
     82 	 *
     83 	 * @param array $classes An array of body classes.
     84 	 *
     85 	 * @return array An array of body classes.
     86 	 */
     87 	public function body_class( $classes ) {
     88 		$classes[] = 'elementor-maintenance-mode';
     89 
     90 		return $classes;
     91 	}
     92 
     93 	/**
     94 	 * Template redirect.
     95 	 *
     96 	 * Redirect to the "Maintenance Mode" template.
     97 	 *
     98 	 * Fired by `template_redirect` action.
     99 	 *
    100 	 * @since 1.4.0
    101 	 * @access public
    102 	 */
    103 	public function template_redirect() {
    104 		if ( Plugin::$instance->preview->is_preview_mode() ) {
    105 			return;
    106 		}
    107 
    108 		$user = wp_get_current_user();
    109 
    110 		$exclude_mode = self::get( 'exclude_mode', [] );
    111 
    112 		$is_login_page = false;
    113 
    114 		/**
    115 		 * Is login page
    116 		 *
    117 		 * Filters whether the maintenance mode displaying the login page or a regular page.
    118 		 *
    119 		 * @since 1.0.4
    120 		 *
    121 		 * @param bool $is_login_page Whether its a login page.
    122 		 */
    123 		$is_login_page = apply_filters( 'elementor/maintenance_mode/is_login_page', $is_login_page );
    124 
    125 		if ( $is_login_page ) {
    126 			return;
    127 		}
    128 
    129 		if ( 'logged_in' === $exclude_mode && is_user_logged_in() ) {
    130 			return;
    131 		}
    132 
    133 		if ( 'custom' === $exclude_mode ) {
    134 			$exclude_roles = self::get( 'exclude_roles', [] );
    135 			$user_roles = $user->roles;
    136 
    137 			if ( is_multisite() && is_super_admin() ) {
    138 				$user_roles[] = 'super_admin';
    139 			}
    140 
    141 			$compare_roles = array_intersect( $user_roles, $exclude_roles );
    142 
    143 			if ( ! empty( $compare_roles ) ) {
    144 				return;
    145 			}
    146 		}
    147 
    148 		add_filter( 'body_class', [ $this, 'body_class' ] );
    149 
    150 		if ( 'maintenance' === self::get( 'mode' ) ) {
    151 			$protocol = wp_get_server_protocol();
    152 			header( "$protocol 503 Service Unavailable", true, 503 );
    153 			header( 'Content-Type: text/html; charset=utf-8' );
    154 			header( 'Retry-After: 600' );
    155 		}
    156 
    157 		// Setup global post for Elementor\frontend so `_has_elementor_in_page = true`.
    158 		$GLOBALS['post'] = get_post( self::get( 'template_id' ) ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
    159 
    160 		// Set the template as `$wp_query->current_object` for `wp_title` and etc.
    161 		query_posts( [
    162 			'p' => self::get( 'template_id' ),
    163 			'post_type' => Source_Local::CPT,
    164 		] );
    165 	}
    166 
    167 	/**
    168 	 * Register settings fields.
    169 	 *
    170 	 * Adds new "Maintenance Mode" settings fields to Elementor admin page.
    171 	 *
    172 	 * The method need to receive the an instance of the Tools settings page
    173 	 * to add the new maintenance mode functionality.
    174 	 *
    175 	 * Fired by `elementor/admin/after_create_settings/{$page_id}` action.
    176 	 *
    177 	 * @since 1.4.0
    178 	 * @access public
    179 	 *
    180 	 * @param Tools $tools An instance of the Tools settings page.
    181 	 */
    182 	public function register_settings_fields( Tools $tools ) {
    183 		$templates = Plugin::$instance->templates_manager->get_source( 'local' )->get_items( [
    184 			'type' => 'page',
    185 		] );
    186 
    187 		$templates_options = [];
    188 
    189 		foreach ( $templates as $template ) {
    190 			$templates_options[ $template['template_id'] ] = esc_html( $template['title'] );
    191 		}
    192 
    193 		ob_start();
    194 
    195 		$this->print_template_description();
    196 
    197 		$template_description = ob_get_clean();
    198 
    199 		$tools->add_tab(
    200 			'maintenance_mode', [
    201 				'label' => esc_html__( 'Maintenance Mode', 'elementor' ),
    202 				'sections' => [
    203 					'maintenance_mode' => [
    204 						'callback' => function() {
    205 							echo '<h2>' . esc_html__( 'Maintenance Mode', 'elementor' ) . '</h2>';
    206 							echo '<div>' . esc_html__( 'Set your entire website as MAINTENANCE MODE, meaning the site is offline temporarily for maintenance, or set it as COMING SOON mode, meaning the site is offline until it is ready to be launched.', 'elementor' ) . '</div>';
    207 						},
    208 						'fields' => [
    209 							'maintenance_mode_mode' => [
    210 								'label' => esc_html__( 'Choose Mode', 'elementor' ),
    211 								'field_args' => [
    212 									'type' => 'select',
    213 									'std' => '',
    214 									'options' => [
    215 										'' => esc_html__( 'Disabled', 'elementor' ),
    216 										self::MODE_COMING_SOON => esc_html__( 'Coming Soon', 'elementor' ),
    217 										self::MODE_MAINTENANCE => esc_html__( 'Maintenance', 'elementor' ),
    218 									],
    219 									'desc' => '<div class="elementor-maintenance-mode-description" data-value="" style="display: none">' .
    220 												esc_html__( 'Choose between Coming Soon mode (returning HTTP 200 code) or Maintenance Mode (returning HTTP 503 code).', 'elementor' ) .
    221 												'</div>' .
    222 												'<div class="elementor-maintenance-mode-description" data-value="maintenance" style="display: none">' .
    223 												esc_html__( 'Maintenance Mode returns HTTP 503 code, so search engines know to come back a short time later. It is not recommended to use this mode for more than a couple of days.', 'elementor' ) .
    224 												'</div>' .
    225 												'<div class="elementor-maintenance-mode-description" data-value="coming_soon" style="display: none">' .
    226 												esc_html__( 'Coming Soon returns HTTP 200 code, meaning the site is ready to be indexed.', 'elementor' ) .
    227 												'</div>',
    228 								],
    229 							],
    230 							'maintenance_mode_exclude_mode' => [
    231 								'label' => esc_html__( 'Who Can Access', 'elementor' ),
    232 								'field_args' => [
    233 									'class' => 'elementor-default-hide',
    234 									'type' => 'select',
    235 									'std' => 'logged_in',
    236 									'options' => [
    237 										'logged_in' => esc_html__( 'Logged In', 'elementor' ),
    238 										'custom' => esc_html__( 'Custom', 'elementor' ),
    239 									],
    240 								],
    241 							],
    242 							'maintenance_mode_exclude_roles' => [
    243 								'label' => esc_html__( 'Roles', 'elementor' ),
    244 								'field_args' => [
    245 									'class' => 'elementor-default-hide',
    246 									'type' => 'checkbox_list_roles',
    247 								],
    248 								'setting_args' => [ __NAMESPACE__ . '\Settings_Validations', 'checkbox_list' ],
    249 							],
    250 							'maintenance_mode_template_id' => [
    251 								'label' => esc_html__( 'Choose Template', 'elementor' ),
    252 								'field_args' => [
    253 									'class' => 'elementor-default-hide',
    254 									'type' => 'select',
    255 									'std' => '',
    256 									'show_select' => true,
    257 									'options' => $templates_options,
    258 									'desc' => $template_description,
    259 								],
    260 							],
    261 						],
    262 					],
    263 				],
    264 			]
    265 		);
    266 	}
    267 
    268 	/**
    269 	 * Add menu in admin bar.
    270 	 *
    271 	 * Adds "Maintenance Mode" items to the WordPress admin bar.
    272 	 *
    273 	 * Fired by `admin_bar_menu` filter.
    274 	 *
    275 	 * @since 1.4.0
    276 	 * @access public
    277 	 *
    278 	 * @param \WP_Admin_Bar $wp_admin_bar WP_Admin_Bar instance, passed by reference.
    279 	 */
    280 	public function add_menu_in_admin_bar( \WP_Admin_Bar $wp_admin_bar ) {
    281 		$wp_admin_bar->add_node( [
    282 			'id' => 'elementor-maintenance-on',
    283 			'title' => esc_html__( 'Maintenance Mode ON', 'elementor' ),
    284 			'href' => Tools::get_url() . '#tab-maintenance_mode',
    285 		] );
    286 
    287 		$document = Plugin::$instance->documents->get( self::get( 'template_id' ) );
    288 
    289 		$wp_admin_bar->add_node( [
    290 			'id' => 'elementor-maintenance-edit',
    291 			'parent' => 'elementor-maintenance-on',
    292 			'title' => esc_html__( 'Edit Template', 'elementor' ),
    293 			'href' => $document ? $document->get_edit_url() : '',
    294 		] );
    295 	}
    296 
    297 	/**
    298 	 * Print style.
    299 	 *
    300 	 * Adds custom CSS to the HEAD html tag. The CSS that emphasise the maintenance
    301 	 * mode with red colors.
    302 	 *
    303 	 * Fired by `admin_head` and `wp_head` filters.
    304 	 *
    305 	 * @since 1.4.0
    306 	 * @access public
    307 	 */
    308 	public function print_style() {
    309 		?>
    310 		<style>#wp-admin-bar-elementor-maintenance-on > a { background-color: #dc3232; }
    311 			#wp-admin-bar-elementor-maintenance-on > .ab-item:before { content: "\f160"; top: 2px; }</style>
    312 		<?php
    313 	}
    314 
    315 	public function on_update_mode( $old_value, $value ) {
    316 		if ( $old_value !== $value ) {
    317 			do_action( 'elementor/maintenance_mode/mode_changed', $old_value, $value );
    318 		}
    319 	}
    320 
    321 	/**
    322 	 * Maintenance mode constructor.
    323 	 *
    324 	 * Initializing Elementor maintenance mode.
    325 	 *
    326 	 * @since 1.4.0
    327 	 * @access public
    328 	 */
    329 	public function __construct() {
    330 		add_action( 'update_option_elementor_maintenance_mode_mode', [ $this, 'on_update_mode' ], 10, 2 );
    331 
    332 		$is_enabled = (bool) self::get( 'mode' ) && (bool) self::get( 'template_id' );
    333 
    334 		if ( is_admin() ) {
    335 			$page_id = Tools::PAGE_ID;
    336 			add_action( "elementor/admin/after_create_settings/{$page_id}", [ $this, 'register_settings_fields' ] );
    337 		}
    338 
    339 		if ( ! $is_enabled ) {
    340 			return;
    341 		}
    342 
    343 		add_action( 'admin_bar_menu', [ $this, 'add_menu_in_admin_bar' ], 300 );
    344 		add_action( 'admin_head', [ $this, 'print_style' ] );
    345 		add_action( 'wp_head', [ $this, 'print_style' ] );
    346 
    347 		// Priority = 11 that is *after* WP default filter `redirect_canonical` in order to avoid redirection loop.
    348 		add_action( 'template_redirect', [ $this, 'template_redirect' ], 11 );
    349 	}
    350 
    351 	/**
    352 	 * Print Template Description
    353 	 *
    354 	 * Prints the template description
    355 	 *
    356 	 * @since 2.2.0
    357 	 * @access private
    358 	 */
    359 	private function print_template_description() {
    360 		$template_id = self::get( 'template_id' );
    361 
    362 		$edit_url = '';
    363 
    364 		if ( $template_id && get_post( $template_id ) ) {
    365 			$edit_url = Plugin::$instance->documents->get( $template_id )->get_edit_url();
    366 		}
    367 
    368 		?>
    369 		<a target="_blank" class="elementor-edit-template" style="display: none" href="<?php echo esc_url( $edit_url ); ?>"><?php echo esc_html__( 'Edit Template', 'elementor' ); ?></a>
    370 		<div class="elementor-maintenance-mode-error"><?php echo esc_html__( 'To enable maintenance mode you have to set a template for the maintenance mode page.', 'elementor' ); ?></div>
    371 		<div class="elementor-maintenance-mode-error">
    372 			<?php
    373 				printf(
    374 					/* translators: %1$s Link open tag, %2$s: Link close tag. */
    375 					esc_html__( 'Select one or go ahead and %1$screate one%2$s now.', 'elementor' ),
    376 					'<a target="_blank" href="' . esc_url( admin_url( 'post-new.php?post_type=' . Source_Local::CPT ) ) . '">',
    377 					'</a>'
    378 				);
    379 			?>
    380 		</div>
    381 		<?php
    382 	}
    383 }