Загрузка...

Включаем режим обслуживания сайта

В заметке будет рассмотрен вопрос (и показано решение) о том, как на сайте, под управлением WordPress, включить режим «технических работ» таким способом, чтобы он легко переключался из админки, без всяких плагинов. Причем для админа будет доступен весь сайт, админка и публичная часть, а всем остальным — показана заглушка


Очень полезная штука, если вам понадобилось закрыть посещаемый сайт на некоторое время от всех, кроме админа системы, чтобы что то протестить или починить. Итак, начнем:

Сперва нужно создать файл .maintenance в корне сайта:

function is_user_logged_in()
{
    $loggedin = false;
    foreach ((array)$_COOKIE as $cookie => $value) {
        if (stristr($cookie, 'wordpress_logged_in_'))
            $loggedin = true;
    }
    return $loggedin;
}

if (!stristr($_SERVER['REQUEST_URI'], '/wp-admin/')
    && !stristr($_SERVER['REQUEST_URI'], '/wp-login.php')
    && !is_user_logged_in()
)
    $upgrading = time();

В каталоге wp-content создаем заглушку (ее оформляете как душе угодно) — maintenance.php:

<!doctype html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Ведутся тех. работы</title>
</head>
<body>
    <p>Я — заглушка</p>
</body>
</html>

В файле functions.php:

define("themeSettings", serialize(get_option('myThemeName-theme-settings')));

function myThemeNameSetupAdminMenus()
{
    require get_template_directory() . '/inc/theme-settings.php';
    add_submenu_page('themes.php',
        'Настройки темы', 'Настройки темы', 'manage_options',
        'myThemeName-theme-settings', 'myThemeNameThemeSettings'
    );
}

function get_theme_option($option)
{
    $unserialized = unserialize(themeSettings);
    if (array_key_exists($option, $unserialized)) {
        return $unserialized[$option];
    } else {
        return null;
    }
}

/* Настройки темы */
add_action("admin_menu", "myThemeNameSetupAdminMenus");

function go_tech()
{
    $themeSettings = get_option('myThemeName-theme-settings');
    $tech = $themeSettings['tech'];
    if ($tech == 'n') {
        $file_new = ABSPATH . '.maintenance1';
        $file_cur = ABSPATH . '.maintenance';
        if (file_exists($file_new) && file_exists($file_cur))
            unlink($file_cur);
        if (file_exists($file_new) && !file_exists($file_cur))
            return;
        if (!file_exists($file_new) && file_exists($file_cur))
            rename($file_cur, $file_new);
        if (!file_exists($file_new) && !file_exists($file_cur)) {
            return;
        }
    } else {
        $file_new = ABSPATH . '.maintenance';
        $file_cur = ABSPATH . '.maintenance1';
        if (file_exists($file_new) && file_exists($file_cur))
            unlink($file_cur);
        if (file_exists($file_new) && !file_exists($file_cur))
            return;
        if (!file_exists($file_new) && file_exists($file_cur))
            rename($file_cur, $file_new);
        if (!file_exists($file_new) && !file_exists($file_cur)) {
            return;
        }
    }
}

/* Режим обслуживания */
add_action('init', 'go_tech');

В папке с темой создаем inc/theme-settings.php:

<?php
if (!current_user_can('manage_options')) {
    wp_die('Недостаточно прав для просмотра настроек.');
}
function myThemeNameThemeSettings() {
    $themeSettings = get_option('myThemeName-theme-settings');
    ?>
    <div class="wrap" xmlns="http://www.w3.org/1999/html">
        <h2>Настройки темы</h2>
        <form method="post" action="options.php" novalidate="novalidate">
            <?php wp_nonce_field('update-options'); ?>
            <input type="hidden" name="action" value="update"/>
            <table class="form-table">
                <tr>
                    <th>Служебные параметры:</th>
                </tr>
                <tr>
                    <th scope="row">
                        <label>Перевести сайт в режим тех. обслуж. (по умолчанинию: НЕТ)</label>
                    </th>
                    <td>
                        <input type="radio" name="myThemeName-theme-settings[tech]" value="y" <?php if($themeSettings['tech'] == 'y') echo 'checked'; ?>/> ДА
                        <input type="radio" name="myThemeName-theme-settings[tech]" value="n" <?php if($themeSettings['tech'] == 'n') echo 'checked'; ?>/> НЕТ
                    </td>
                </tr>
            </table>
            <p class="submit">
                <input type="hidden" name="page_options" value="myThemeName-theme-settings"/>
                <input name="submit" id="submit" class="button button-primary" value="Сохранить" type="submit">
            </p>
        </form>
    </div>
<?php
}

В принципе, все. В админке, Внешний вид » Настройки темы будет переключалка.



Похожие заметки:

Вывод комментариев с пагинацией

Выводим все комменты на WordPress из базы данных с пагинацией

Открыть здесь

Веб-разработка

Займусь вашим проектом, если вам нужен специалист в области веб-разработки

Открыть здесь

Прикручиваем Sphinx к своему поиску на сайте

Установка, задание конфигурации и запуск службы на Ubuntu для высокоскоростного поиска. Быстрый гайд

Открыть здесь


Перед тем как писать комментарии, рекомендую ознакомиться:

Markdown синтаксис »

Оформление кода »

Нужна аватарка »

Комментарии


5
avatar

Олег сказал 20-02-2017 в 11:15


Поясни по файлу .maintenance.

Зачем в нём какая-то непонятная функция, названная о проверке авторизации, с проверкой на существование куки, которую с лёгкостью можно подделать.

Зачем объявляется переменная $upgrading?


avatar

Админ

Роман Жариков сказал 20-02-2017 в 23:28

   В ответ на комментарии автора Олег

Зачем объявляется переменная $upgrading?

Дело в том, что при старте, вордпресс автоматически ищет файл .maintenance в корне. Этот файл содержит переменную $upgrading, с данными, когда он был создан. Если файл был создан меньше 10 минут назад, WP выведет сообщение о техническом обслуживании сайта.

Зачем в нём какая-то непонятная функция, названная о проверке авторизации, с проверкой на существование куки, которую с лёгкостью можно подделать

Верное замечание насчет куки. Это проверка авторизации, если кука есть, значит юзер вошел и для его режим тех. обсл. не вкл. И наоборот. Согласен, что это костыль (с кукой), но тут все дело в том, что проверка maintenance идет на очень ранней стадии, когда большинство функции вп еще не работают. Поэтому, в файле .maintenance нельзя к примеру заюзать более лучшую функцию вп на проверку авторизации, допустим админа:

if(current_user_can("administrator") {
   // user is admin
}

avatar

Олег сказал 21-02-2017 в 01:28

   В ответ на комментарии автора Роман Жариков

Если файл был создан меньше 10 минут назад, WP выведет сообщение о техническом обслуживании сайта.

А если больше?

Согласен, что это костыль (с кукой), но тут все дело в том, что проверка maintenance идет на очень ранней стадии, когда большинство функции вп еще не работают.

Почему бы не подключить нужные функции руками?


avatar

Админ

Роман Жариков сказал 21-02-2017 в 07:26

   В ответ на комментарии автора Олег

А если больше?

Вот код главной функции, отвечающей за режим введения сайта в техническое обслуживание. Из него ты можешь с легкостью понять сам, что будет по истечению 10 мин. Версия wp — 4.7.2, wp-includes/load.php стр. 175:

/**
 * Die with a maintenance message when conditions are met.
 *
 * Checks for a file in the WordPress root directory named ".maintenance".
 * This file will contain the variable $upgrading, set to the time the file
 * was created. If the file was created less than 10 minutes ago, WordPress
 * enters maintenance mode and displays a message.
 *
 * The default message can be replaced by using a drop-in (maintenance.php in
 * the wp-content directory).
 *
 * @since 3.0.0
 * @access private
 *
 * @global int $upgrading the unix timestamp marking when upgrading WordPress began.
 */
function wp_maintenance() {
	if ( ! file_exists( ABSPATH . '.maintenance' ) || wp_installing() )
		return;

	global $upgrading;

	include( ABSPATH . '.maintenance' );
	// If the $upgrading timestamp is older than 10 minutes, don't die.
	if ( ( time() - $upgrading ) >= 600 )
		return;

	/**
	 * Filters whether to enable maintenance mode.
	 *
	 * This filter runs before it can be used by plugins. It is designed for
	 * non-web runtimes. If this filter returns true, maintenance mode will be
	 * active and the request will end. If false, the request will be allowed to
	 * continue processing even if maintenance mode should be active.
	 *
	 * @since 4.6.0
	 *
	 * @param bool $enable_checks Whether to enable maintenance mode. Default true.
	 * @param int  $upgrading     The timestamp set in the .maintenance file.
	 */
	if ( ! apply_filters( 'enable_maintenance_mode', true, $upgrading ) ) {
		return;
	}

	if ( file_exists( WP_CONTENT_DIR . '/maintenance.php' ) ) {
		require_once( WP_CONTENT_DIR . '/maintenance.php' );
		die();
	}

	wp_load_translations_early();

	$protocol = wp_get_server_protocol();
	header( "$protocol 503 Service Unavailable", true, 503 );
	header( 'Content-Type: text/html; charset=utf-8' );
	header( 'Retry-After: 600' );
?>
	<!DOCTYPE html>
	<html xmlns="http://www.w3.org/1999/xhtml"<?php if ( is_rtl() ) echo ' dir="rtl"'; ?>>
	<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<title><?php _e( 'Maintenance' ); ?></title>

	</head>
	<body>
		<h1><?php _e( 'Briefly unavailable for scheduled maintenance. Check back in a minute.' ); ?></h1>
	</body>
	</html>
<?php
	die();
}

avatar

Админ

Роман Жариков сказал 21-02-2017 в 08:33

   В ответ на комментарии автора Олег

Почему бы не подключить нужные функции руками?

Можно заморочиться на эту тему и, возможно, когда нибудь, я обновлю эту заметку.