| 1 |
<?php |
| 2 |
/** |
| 3 |
* A simple maintenance mode |
| 4 |
* |
| 5 |
* @package BoldBlocks |
| 6 |
* @author Phi Phan <mrphipv@gmail.com> |
| 7 |
* @copyright Copyright (c) 2023, Phi Phan |
| 8 |
*/ |
| 9 |
|
| 10 |
namespace BoldBlocks; |
| 11 |
|
| 12 |
// Exit if accessed directly. |
| 13 |
defined( 'ABSPATH' ) || exit; |
| 14 |
|
| 15 |
if ( ! class_exists( Maintenance::class ) ) : |
| 16 |
/** |
| 17 |
* A simple maitenance mode for deploying or coming soon message |
| 18 |
*/ |
| 19 |
class Maintenance extends CoreComponent { |
| 20 |
/** |
| 21 |
* Run main hooks |
| 22 |
* |
| 23 |
* @return void |
| 24 |
*/ |
| 25 |
public function run() { |
| 26 |
// Register setting fields. |
| 27 |
add_action( 'init', [ $this, 'register_settings' ] ); |
| 28 |
|
| 29 |
// Starting point. |
| 30 |
add_action( 'init', [ $this, 'run_maintenance_mode' ] ); |
| 31 |
|
| 32 |
// Add a notice for maintenance mode warning. |
| 33 |
add_action( 'admin_notices', [ $this, 'add_the_admin_notice_for_maintenance_mode' ] ); |
| 34 |
} |
| 35 |
|
| 36 |
/** |
| 37 |
* Register setting fields |
| 38 |
* |
| 39 |
* @return void |
| 40 |
*/ |
| 41 |
public function register_settings() { |
| 42 |
// phpcs:disable PluginCheck.CodeAnalysis.SettingSanitization.register_settingDynamic |
| 43 |
register_setting( |
| 44 |
'cbb', |
| 45 |
'cbb_is_maintenance', |
| 46 |
[ |
| 47 |
'type' => 'boolean', |
| 48 |
'sanitize_callback' => 'rest_sanitize_boolean', |
| 49 |
'show_in_rest' => [ |
| 50 |
'name' => 'IsMaintenance', |
| 51 |
], |
| 52 |
'default' => false, |
| 53 |
] |
| 54 |
); |
| 55 |
|
| 56 |
register_setting( |
| 57 |
'cbb', |
| 58 |
'cbb_maintenance_ignore_slug', |
| 59 |
[ |
| 60 |
'type' => 'string', |
| 61 |
'sanitize_callback' => 'sanitize_text_field', |
| 62 |
'show_in_rest' => [ |
| 63 |
'name' => 'MaintenanceSlug', |
| 64 |
], |
| 65 |
'default' => 'wp-login.php', |
| 66 |
] |
| 67 |
); |
| 68 |
|
| 69 |
register_setting( |
| 70 |
'cbb', |
| 71 |
'cbb_maintenance_enable_custom_page', |
| 72 |
[ |
| 73 |
'type' => 'boolean', |
| 74 |
'sanitize_callback' => 'rest_sanitize_boolean', |
| 75 |
'show_in_rest' => [ |
| 76 |
'name' => 'MaintananceEnableCustomPage', |
| 77 |
], |
| 78 |
'default' => false, |
| 79 |
] |
| 80 |
); |
| 81 |
|
| 82 |
register_setting( |
| 83 |
'cbb', |
| 84 |
'cbb_maintenance_page_id', |
| 85 |
[ |
| 86 |
'type' => 'integer', |
| 87 |
'sanitize_callback' => 'absint', |
| 88 |
'show_in_rest' => [ |
| 89 |
'name' => 'MaintanancePageId', |
| 90 |
], |
| 91 |
'default' => 0, |
| 92 |
] |
| 93 |
); |
| 94 |
// phpcs:enable PluginCheck.CodeAnalysis.SettingSanitization.register_settingDynamic |
| 95 |
} |
| 96 |
|
| 97 |
/** |
| 98 |
* Starting point |
| 99 |
* |
| 100 |
* @return void |
| 101 |
*/ |
| 102 |
public function run_maintenance_mode() { |
| 103 |
// Bail if the setting is disabled. |
| 104 |
if ( ! get_option( 'cbb_is_maintenance' ) ) { |
| 105 |
return; |
| 106 |
} |
| 107 |
|
| 108 |
// Ignore cron job and ajax. |
| 109 |
if ( wp_doing_cron() || wp_doing_ajax() ) { |
| 110 |
return; |
| 111 |
} |
| 112 |
|
| 113 |
$ignore_slug = get_option( 'cbb_maintenance_ignore_slug' ); |
| 114 |
|
| 115 |
if ( ! $ignore_slug ) { |
| 116 |
$ignore_slug = [ 'wp-login.php' ]; |
| 117 |
} else { |
| 118 |
$ignore_slug = preg_split( "/\r\n|\n|\r/", $ignore_slug ); |
| 119 |
$ignore_slug = array_filter( |
| 120 |
$ignore_slug, |
| 121 |
function ( $item ) { |
| 122 |
return trim( $item, ' /' ); |
| 123 |
} |
| 124 |
); |
| 125 |
} |
| 126 |
|
| 127 |
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
| 128 |
$request_uri = isset( $_SERVER['REQUEST_URI'] ) ? trim( wp_unslash( $_SERVER['REQUEST_URI'] ) ?? '', '/' ) : ''; |
| 129 |
|
| 130 |
// Ignore administrator and the default login page. |
| 131 |
if ( current_user_can( 'manage_options' ) || in_array( $request_uri, $ignore_slug, true ) ) { |
| 132 |
return; |
| 133 |
} |
| 134 |
|
| 135 |
// Handle custom page. |
| 136 |
$enable_custom_page = get_option( 'cbb_maintenance_enable_custom_page' ); |
| 137 |
$page_id = get_option( 'cbb_maintenance_page_id' ); |
| 138 |
if ( $enable_custom_page && $page_id ) { |
| 139 |
$custom_page_url = get_permalink( $page_id ); |
| 140 |
if ( $custom_page_url ) { |
| 141 |
$parsed_url = wp_parse_url( $custom_page_url ); |
| 142 |
if ( $parsed_url && in_array( trim( $parsed_url['path'] ?? '', '/' ), $ignore_slug, true ) ) { |
| 143 |
return; |
| 144 |
} |
| 145 |
} |
| 146 |
} |
| 147 |
|
| 148 |
$page_title = __( 'Maintenance', 'content-blocks-builder' ); |
| 149 |
$page_content = __( 'The site is currently under maintenance. <br/>Please check back in a few minutes!', 'content-blocks-builder' ); |
| 150 |
|
| 151 |
$site_icon = get_site_icon_url( 64 ); |
| 152 |
if ( $site_icon ) { |
| 153 |
// phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage |
| 154 |
$site_icon = sprintf( '<img class="site-icon" width="64" src="%1$s" alt="%2$s"/>', $site_icon, get_bloginfo( 'name' ) ); |
| 155 |
} else { |
| 156 |
$site_icon = sprintf( '<h1 class="site-icon site-title">%s</h1>', get_bloginfo( 'name' ) ); |
| 157 |
} |
| 158 |
|
| 159 |
if ( ! headers_sent() ) { |
| 160 |
header( 'Content-Type: text/html; charset=utf-8; Retry-After: 600;' ); |
| 161 |
status_header( 503 ); |
| 162 |
nocache_headers(); |
| 163 |
} |
| 164 |
|
| 165 |
$text_direction = 'ltr'; |
| 166 |
if ( function_exists( 'is_rtl' ) && is_rtl() ) { |
| 167 |
$text_direction = 'rtl'; |
| 168 |
} |
| 169 |
|
| 170 |
if ( $enable_custom_page && $page_id ) { |
| 171 |
$custom_page_url = get_permalink( $page_id ); |
| 172 |
if ( $custom_page_url ) { |
| 173 |
wp_safe_redirect( $custom_page_url ); |
| 174 |
die(); |
| 175 |
} |
| 176 |
} |
| 177 |
|
| 178 |
ob_start(); |
| 179 |
?> |
| 180 |
<!DOCTYPE html> |
| 181 |
<html dir="<?php echo esc_attr( $text_direction ); ?>"> |
| 182 |
<head> |
| 183 |
<meta charset="utf-8"> |
| 184 |
<?php |
| 185 |
if ( function_exists( 'wp_robots' ) && function_exists( 'wp_robots_no_robots' ) && function_exists( 'add_filter' ) ) { |
| 186 |
add_filter( 'wp_robots', 'wp_robots_no_robots' ); |
| 187 |
wp_robots(); |
| 188 |
} |
| 189 |
?> |
| 190 |
<title><?php echo esc_html( $page_title ); ?></title> |
| 191 |
<style> |
| 192 |
body { font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif; font-size:1.25rem; color: #333; text-align:center; } |
| 193 |
.site-icon { margin-bottom: 1rem; } |
| 194 |
.container { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); max-width: 600px; width:clamp(320px,50vw,600px); margin: auto; } |
| 195 |
.message { padding: 2rem 2rem 2.5rem; border:1px solid #ddd; border-radius: 4px; } |
| 196 |
.message h1 { |
| 197 |
margin-top: 0; |
| 198 |
margin-top: 0; |
| 199 |
} |
| 200 |
h1 { font-size: 2.5rem;} |
| 201 |
</style> |
| 202 |
</head> |
| 203 |
<body class="maintenance"> |
| 204 |
<div class="container"> |
| 205 |
<?php |
| 206 |
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
| 207 |
echo $site_icon; |
| 208 |
?> |
| 209 |
<div class="message"> |
| 210 |
<h1><?php echo esc_html( $page_title ); ?></h1> |
| 211 |
<div> |
| 212 |
<?php |
| 213 |
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
| 214 |
echo $page_content; |
| 215 |
?> |
| 216 |
</div> |
| 217 |
</div> |
| 218 |
</div> |
| 219 |
</body> |
| 220 |
</html> |
| 221 |
<?php |
| 222 |
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
| 223 |
die( ob_get_clean() ); |
| 224 |
} |
| 225 |
|
| 226 |
/** |
| 227 |
* Add the admin notice for the maintenance mode |
| 228 |
* |
| 229 |
* @return void |
| 230 |
*/ |
| 231 |
public function add_the_admin_notice_for_maintenance_mode() { |
| 232 |
// Bail if the setting is disabled. |
| 233 |
if ( ! get_option( 'cbb_is_maintenance' ) ) { |
| 234 |
return; |
| 235 |
} |
| 236 |
|
| 237 |
// Get the current screen. |
| 238 |
$screen = get_current_screen(); |
| 239 |
|
| 240 |
if ( ! $screen ) { |
| 241 |
return; |
| 242 |
} |
| 243 |
|
| 244 |
if ( ! ( in_array( $screen->base, [ 'dashboard', 'plugins', 'themes' ], true ) || 'edit.php?post_type=boldblocks_block' === $screen->parent_file ) ) { |
| 245 |
return; |
| 246 |
} |
| 247 |
|
| 248 |
$settings_link = sprintf( '<a href="%1$s">%2$s</a>', admin_url( '/edit.php?post_type=boldblocks_block&page=cbb-settings&tab=developer' ), __( 'Turn it off.', 'content-blocks-builder' ) ); |
| 249 |
|
| 250 |
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
| 251 |
echo '<div class="notice notice-warning is-dismissible"><p>' . __( 'The site is currently under maintenance. Please remember to turn off this mode when the site is ready. You can do this from the settings page.', 'content-blocks-builder' ) . ' ' . $settings_link . '</p></div>'; |
| 252 |
} |
| 253 |
} |
| 254 |
endif; |
| 255 |
|