PluginProbe
Elementor Website Builder – more than just a page builder / 3.0.7
Elementor Website Builder – more than just a page builder v3.0.7
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 / includes / maintenance-mode.php

maintenance-mode.php in Elementor Website Builder – more than just a page builder 3.0.7, at includes/maintenance-mode.php

362 lines 10.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 = apply_filters( 'elementor/maintenance_mode/is_login_page', false );
113
114 if ( $is_login_page ) {
115 return;
116 }
117
118 if ( 'logged_in' === $exclude_mode && is_user_logged_in() ) {
119 return;
120 }
121
122 if ( 'custom' === $exclude_mode ) {
123 $exclude_roles = self::get( 'exclude_roles', [] );
124 $user_roles = $user->roles;
125
126 if ( is_multisite() && is_super_admin() ) {
127 $user_roles[] = 'super_admin';
128 }
129
130 $compare_roles = array_intersect( $user_roles, $exclude_roles );
131
132 if ( ! empty( $compare_roles ) ) {
133 return;
134 }
135 }
136
137 add_filter( 'body_class', [ $this, 'body_class' ] );
138
139 if ( 'maintenance' === self::get( 'mode' ) ) {
140 $protocol = wp_get_server_protocol();
141 header( "$protocol 503 Service Unavailable", true, 503 );
142 header( 'Content-Type: text/html; charset=utf-8' );
143 header( 'Retry-After: 600' );
144 }
145
146 // Setup global post for Elementor\frontend so `_has_elementor_in_page = true`.
147 $GLOBALS['post'] = get_post( self::get( 'template_id' ) ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
148
149 // Set the template as `$wp_query->current_object` for `wp_title` and etc.
150 query_posts( [
151 'p' => self::get( 'template_id' ),
152 'post_type' => Source_Local::CPT,
153 ] );
154 }
155
156 /**
157 * Register settings fields.
158 *
159 * Adds new "Maintenance Mode" settings fields to Elementor admin page.
160 *
161 * The method need to receive the an instance of the Tools settings page
162 * to add the new maintenance mode functionality.
163 *
164 * Fired by `elementor/admin/after_create_settings/{$page_id}` action.
165 *
166 * @since 1.4.0
167 * @access public
168 *
169 * @param Tools $tools An instance of the Tools settings page.
170 */
171 public function register_settings_fields( Tools $tools ) {
172 $templates = Plugin::$instance->templates_manager->get_source( 'local' )->get_items( [
173 'type' => 'page',
174 ] );
175
176 $templates_options = [];
177
178 foreach ( $templates as $template ) {
179 $templates_options[ $template['template_id'] ] = esc_html( $template['title'] );
180 }
181
182 ob_start();
183
184 $this->print_template_description();
185
186 $template_description = ob_get_clean();
187
188 $tools->add_tab(
189 'maintenance_mode', [
190 'label' => __( 'Maintenance Mode', 'elementor' ),
191 'sections' => [
192 'maintenance_mode' => [
193 'callback' => function() {
194 echo '<h2>' . esc_html__( 'Maintenance Mode', 'elementor' ) . '</h2>';
195 echo '<div>' . __( '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>';
196 },
197 'fields' => [
198 'maintenance_mode_mode' => [
199 'label' => __( 'Choose Mode', 'elementor' ),
200 'field_args' => [
201 'type' => 'select',
202 'options' => [
203 '' => __( 'Disabled', 'elementor' ),
204 self::MODE_COMING_SOON => __( 'Coming Soon', 'elementor' ),
205 self::MODE_MAINTENANCE => __( 'Maintenance', 'elementor' ),
206 ],
207 'desc' => '<div class="elementor-maintenance-mode-description" data-value="" style="display: none">' .
208 __( 'Choose between Coming Soon mode (returning HTTP 200 code) or Maintenance Mode (returning HTTP 503 code).', 'elementor' ) .
209 '</div>' .
210 '<div class="elementor-maintenance-mode-description" data-value="maintenance" style="display: none">' .
211 __( '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' ) .
212 '</div>' .
213 '<div class="elementor-maintenance-mode-description" data-value="coming_soon" style="display: none">' .
214 __( 'Coming Soon returns HTTP 200 code, meaning the site is ready to be indexed.', 'elementor' ) .
215 '</div>',
216 ],
217 ],
218 'maintenance_mode_exclude_mode' => [
219 'label' => __( 'Who Can Access', 'elementor' ),
220 'field_args' => [
221 'class' => 'elementor-default-hide',
222 'type' => 'select',
223 'std' => 'logged_in',
224 'options' => [
225 'logged_in' => __( 'Logged In', 'elementor' ),
226 'custom' => __( 'Custom', 'elementor' ),
227 ],
228 ],
229 ],
230 'maintenance_mode_exclude_roles' => [
231 'label' => __( 'Roles', 'elementor' ),
232 'field_args' => [
233 'class' => 'elementor-default-hide',
234 'type' => 'checkbox_list_roles',
235 ],
236 'setting_args' => [ __NAMESPACE__ . '\Settings_Validations', 'checkbox_list' ],
237 ],
238 'maintenance_mode_template_id' => [
239 'label' => __( 'Choose Template', 'elementor' ),
240 'field_args' => [
241 'class' => 'elementor-default-hide',
242 'type' => 'select',
243 'show_select' => true,
244 'options' => $templates_options,
245 'desc' => $template_description,
246 ],
247 ],
248 ],
249 ],
250 ],
251 ]
252 );
253 }
254
255 /**
256 * Add menu in admin bar.
257 *
258 * Adds "Maintenance Mode" items to the WordPress admin bar.
259 *
260 * Fired by `admin_bar_menu` filter.
261 *
262 * @since 1.4.0
263 * @access public
264 *
265 * @param \WP_Admin_Bar $wp_admin_bar WP_Admin_Bar instance, passed by reference.
266 */
267 public function add_menu_in_admin_bar( \WP_Admin_Bar $wp_admin_bar ) {
268 $wp_admin_bar->add_node( [
269 'id' => 'elementor-maintenance-on',
270 'title' => __( 'Maintenance Mode ON', 'elementor' ),
271 'href' => Tools::get_url() . '#tab-maintenance_mode',
272 ] );
273
274 $document = Plugin::$instance->documents->get( self::get( 'template_id' ) );
275
276 $wp_admin_bar->add_node( [
277 'id' => 'elementor-maintenance-edit',
278 'parent' => 'elementor-maintenance-on',
279 'title' => __( 'Edit Template', 'elementor' ),
280 'href' => $document ? $document->get_edit_url() : '',
281 ] );
282 }
283
284 /**
285 * Print style.
286 *
287 * Adds custom CSS to the HEAD html tag. The CSS that emphasise the maintenance
288 * mode with red colors.
289 *
290 * Fired by `admin_head` and `wp_head` filters.
291 *
292 * @since 1.4.0
293 * @access public
294 */
295 public function print_style() {
296 ?>
297 <style>#wp-admin-bar-elementor-maintenance-on > a { background-color: #dc3232; }
298 #wp-admin-bar-elementor-maintenance-on > .ab-item:before { content: "\f160"; top: 2px; }</style>
299 <?php
300 }
301
302 public function on_update_mode( $old_value, $value ) {
303 if ( $old_value !== $value ) {
304 do_action( 'elementor/maintenance_mode/mode_changed', $old_value, $value );
305 }
306 }
307
308 /**
309 * Maintenance mode constructor.
310 *
311 * Initializing Elementor maintenance mode.
312 *
313 * @since 1.4.0
314 * @access public
315 */
316 public function __construct() {
317 add_action( 'update_option_elementor_maintenance_mode_mode', [ $this, 'on_update_mode' ], 10, 2 );
318
319 $is_enabled = (bool) self::get( 'mode' ) && (bool) self::get( 'template_id' );
320
321 if ( is_admin() ) {
322 $page_id = Tools::PAGE_ID;
323 add_action( "elementor/admin/after_create_settings/{$page_id}", [ $this, 'register_settings_fields' ] );
324 }
325
326 if ( ! $is_enabled ) {
327 return;
328 }
329
330 add_action( 'admin_bar_menu', [ $this, 'add_menu_in_admin_bar' ], 300 );
331 add_action( 'admin_head', [ $this, 'print_style' ] );
332 add_action( 'wp_head', [ $this, 'print_style' ] );
333
334 // Priority = 11 that is *after* WP default filter `redirect_canonical` in order to avoid redirection loop.
335 add_action( 'template_redirect', [ $this, 'template_redirect' ], 11 );
336 }
337
338 /**
339 * Print Template Description
340 *
341 * Prints the template description
342 *
343 * @since 2.2.0
344 * @access private
345 */
346 private function print_template_description() {
347 $template_id = self::get( 'template_id' );
348
349 $edit_url = '';
350
351 if ( $template_id && get_post( $template_id ) ) {
352 $edit_url = Plugin::$instance->documents->get( $template_id )->get_edit_url();
353 }
354
355 ?>
356 <a target="_blank" class="elementor-edit-template" style="display: none" href="<?php echo $edit_url; ?>"><?php echo __( 'Edit Template', 'elementor' ); ?></a>
357 <div class="elementor-maintenance-mode-error"><?php echo __( 'To enable maintenance mode you have to set a template for the maintenance mode page.', 'elementor' ); ?></div>
358 <div class="elementor-maintenance-mode-error"><?php echo sprintf( __( 'Select one or go ahead and <a target="_blank" href="%s">create one</a> now.', 'elementor' ), admin_url( 'post-new.php?post_type=' . Source_Local::CPT ) ); ?></div>
359 <?php
360 }
361 }
362