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

373 lines 10.9 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' => esc_html__( 'Maintenance Mode', 'elementor' ),
191 'sections' => [
192 'maintenance_mode' => [
193 'callback' => function() {
194 echo '<h2>' . esc_html__( 'Maintenance Mode', 'elementor' ) . '</h2>';
195 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>';
196 },
197 'fields' => [
198 'maintenance_mode_mode' => [
199 'label' => esc_html__( 'Choose Mode', 'elementor' ),
200 'field_args' => [
201 'type' => 'select',
202 'std' => '',
203 'options' => [
204 '' => esc_html__( 'Disabled', 'elementor' ),
205 self::MODE_COMING_SOON => esc_html__( 'Coming Soon', 'elementor' ),
206 self::MODE_MAINTENANCE => esc_html__( 'Maintenance', 'elementor' ),
207 ],
208 'desc' => '<div class="elementor-maintenance-mode-description" data-value="" style="display: none">' .
209 esc_html__( 'Choose between Coming Soon mode (returning HTTP 200 code) or Maintenance Mode (returning HTTP 503 code).', 'elementor' ) .
210 '</div>' .
211 '<div class="elementor-maintenance-mode-description" data-value="maintenance" style="display: none">' .
212 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' ) .
213 '</div>' .
214 '<div class="elementor-maintenance-mode-description" data-value="coming_soon" style="display: none">' .
215 esc_html__( 'Coming Soon returns HTTP 200 code, meaning the site is ready to be indexed.', 'elementor' ) .
216 '</div>',
217 ],
218 ],
219 'maintenance_mode_exclude_mode' => [
220 'label' => esc_html__( 'Who Can Access', 'elementor' ),
221 'field_args' => [
222 'class' => 'elementor-default-hide',
223 'type' => 'select',
224 'std' => 'logged_in',
225 'options' => [
226 'logged_in' => esc_html__( 'Logged In', 'elementor' ),
227 'custom' => esc_html__( 'Custom', 'elementor' ),
228 ],
229 ],
230 ],
231 'maintenance_mode_exclude_roles' => [
232 'label' => esc_html__( 'Roles', 'elementor' ),
233 'field_args' => [
234 'class' => 'elementor-default-hide',
235 'type' => 'checkbox_list_roles',
236 ],
237 'setting_args' => [ __NAMESPACE__ . '\Settings_Validations', 'checkbox_list' ],
238 ],
239 'maintenance_mode_template_id' => [
240 'label' => esc_html__( 'Choose Template', 'elementor' ),
241 'field_args' => [
242 'class' => 'elementor-default-hide',
243 'type' => 'select',
244 'std' => '',
245 'show_select' => true,
246 'options' => $templates_options,
247 'desc' => $template_description,
248 ],
249 ],
250 ],
251 ],
252 ],
253 ]
254 );
255 }
256
257 /**
258 * Add menu in admin bar.
259 *
260 * Adds "Maintenance Mode" items to the WordPress admin bar.
261 *
262 * Fired by `admin_bar_menu` filter.
263 *
264 * @since 1.4.0
265 * @access public
266 *
267 * @param \WP_Admin_Bar $wp_admin_bar WP_Admin_Bar instance, passed by reference.
268 */
269 public function add_menu_in_admin_bar( \WP_Admin_Bar $wp_admin_bar ) {
270 $wp_admin_bar->add_node( [
271 'id' => 'elementor-maintenance-on',
272 'title' => esc_html__( 'Maintenance Mode ON', 'elementor' ),
273 'href' => Tools::get_url() . '#tab-maintenance_mode',
274 ] );
275
276 $document = Plugin::$instance->documents->get( self::get( 'template_id' ) );
277
278 $wp_admin_bar->add_node( [
279 'id' => 'elementor-maintenance-edit',
280 'parent' => 'elementor-maintenance-on',
281 'title' => esc_html__( 'Edit Template', 'elementor' ),
282 'href' => $document ? $document->get_edit_url() : '',
283 ] );
284 }
285
286 /**
287 * Print style.
288 *
289 * Adds custom CSS to the HEAD html tag. The CSS that emphasise the maintenance
290 * mode with red colors.
291 *
292 * Fired by `admin_head` and `wp_head` filters.
293 *
294 * @since 1.4.0
295 * @access public
296 */
297 public function print_style() {
298 ?>
299 <style>#wp-admin-bar-elementor-maintenance-on > a { background-color: #dc3232; }
300 #wp-admin-bar-elementor-maintenance-on > .ab-item:before { content: "\f160"; top: 2px; }</style>
301 <?php
302 }
303
304 public function on_update_mode( $old_value, $value ) {
305 if ( $old_value !== $value ) {
306 do_action( 'elementor/maintenance_mode/mode_changed', $old_value, $value );
307 }
308 }
309
310 /**
311 * Maintenance mode constructor.
312 *
313 * Initializing Elementor maintenance mode.
314 *
315 * @since 1.4.0
316 * @access public
317 */
318 public function __construct() {
319 add_action( 'update_option_elementor_maintenance_mode_mode', [ $this, 'on_update_mode' ], 10, 2 );
320
321 $is_enabled = (bool) self::get( 'mode' ) && (bool) self::get( 'template_id' );
322
323 if ( is_admin() ) {
324 $page_id = Tools::PAGE_ID;
325 add_action( "elementor/admin/after_create_settings/{$page_id}", [ $this, 'register_settings_fields' ] );
326 }
327
328 if ( ! $is_enabled ) {
329 return;
330 }
331
332 add_action( 'admin_bar_menu', [ $this, 'add_menu_in_admin_bar' ], 300 );
333 add_action( 'admin_head', [ $this, 'print_style' ] );
334 add_action( 'wp_head', [ $this, 'print_style' ] );
335
336 // Priority = 11 that is *after* WP default filter `redirect_canonical` in order to avoid redirection loop.
337 add_action( 'template_redirect', [ $this, 'template_redirect' ], 11 );
338 }
339
340 /**
341 * Print Template Description
342 *
343 * Prints the template description
344 *
345 * @since 2.2.0
346 * @access private
347 */
348 private function print_template_description() {
349 $template_id = self::get( 'template_id' );
350
351 $edit_url = '';
352
353 if ( $template_id && get_post( $template_id ) ) {
354 $edit_url = Plugin::$instance->documents->get( $template_id )->get_edit_url();
355 }
356
357 ?>
358 <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>
359 <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>
360 <div class="elementor-maintenance-mode-error">
361 <?php
362 printf(
363 /* translators: %1$s Link open tag, %2$s: Link close tag. */
364 esc_html__( 'Select one or go ahead and %1$screate one%2$s now.', 'elementor' ),
365 '<a target="_blank" href="' . esc_url( admin_url( 'post-new.php?post_type=' . Source_Local::CPT ) ) . '">',
366 '</a>'
367 );
368 ?>
369 </div>
370 <?php
371 }
372 }
373