WordPress の動作を一時的に完全に止める方法(2)

先日、「WordPress の動作を一時的に完全に止める方法」を index.php のリネーム shell script で実現したが、やっぱり、ssh ログインして shell script 実行だと不便だったため、Web 上から php でリネームする方法を考えてみた。

実装コードは以下のとおり。

Filename: maintenance.php

<?php
// パスワード設定
$correctPassword = 'password';
$wordpressDir = __DIR__;

function setMaintenanceMode($enable) {
    global $wordpressDir;
    $indexPhp = $wordpressDir . '/index.php';
    $index2Php = $wordpressDir . '/index2.php';
    $indexHtml = $wordpressDir . '/index.html';
    $index2Html = $wordpressDir . '/index2.html';

    if ($enable) {
        // メンテナンスモードを有効化
        if (!file_exists($indexPhp)) {
            return "index.php が存在しないため、メンテナンスモードを有効化できません。";
        }
        if (!file_exists($index2Html)) {
            return "index2.html が存在しないため、メンテナンスモードを有効化できません。";
        }
        rename($indexPhp, $index2Php);
        rename($index2Html, $indexHtml);
        return "メンテナンスモードが有効になりました。";
    } else {
        // メンテナンスモードを無効化
        if (!file_exists($index2Php)) {
            return "index2.php が存在しないため、メンテナンスモードを無効化できません。";
        }
        if (!file_exists($indexHtml)) {
            return "index.html が存在しないため、メンテナンスモードを無効化できません。";
        }
        rename($indexHtml, $index2Html);
        rename($index2Php, $indexPhp);
        return "メンテナンスモードが無効になりました。";
    }
}

// メッセージを格納する変数
$message = '';

// POSTリクエストが送信された場合の処理
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $password = $_POST['password'] ?? '';
    $action = $_POST['action'] ?? '';

    if ($password === $correctPassword) {
        if ($action === 'enable') {
            $message = setMaintenanceMode(true);
        } elseif ($action === 'disable') {
            $message = setMaintenanceMode(false);
        } else {
            $message = "無効な操作です。";
        }
    } else {
        $message = "パスワードが一致しません。";
    }

    // メッセージをセッションに保存してリダイレクト
    session_start();
    $_SESSION['message'] = $message;
    header('Location: ' . $_SERVER['PHP_SELF']);
    exit;
}

// セッションからメッセージを取得
session_start();
if (isset($_SESSION['message'])) {
    $message = $_SESSION['message'];
    unset($_SESSION['message']);
}

// 現在のメンテナンスモードの状態を確認
$isMaintenanceMode = !file_exists($wordpressDir . '/index.php') && file_exists($wordpressDir . '/index2.php');

?>
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>メンテナンスモード管理</title>
</head>
<body>
    <h1>メンテナンスモード管理</h1>
    <p>現在の状態: <strong><?php echo $isMaintenanceMode ? '有効' : '無効'; ?></strong></p>
    <form method="POST">
        <label for="password">パスワード:</label>
        <input type="password" name="password" id="password" required>
        <br><br>
        <button type="submit" name="action" value="enable" <?php echo $isMaintenanceMode ? 'disabled' : ''; ?>>メンテナンスモードを有効化</button>
        <button type="submit" name="action" value="disable" <?php echo !$isMaintenanceMode ? 'disabled' : ''; ?>>メンテナンスモードを無効化</button>
    </form>
    <p><?php echo htmlspecialchars($message, ENT_QUOTES, 'UTF-8'); ?></p>
</body>
</html>

このスクリプトを index.php のある WordPress のディレクトリに置くことで、アクセスできる。

パスワードを入力して、「メンテナンスモードを有効化」を押すと、カレントディレクトリの index.php を index2.php にリネームし、index2.html を index.html にリネームする。


メンテナンスモード有効化

メンテナンス中に表示される index.html

改善点

動作を完全に止め、安心してバックアップスクリプトを走らせられるようになったが、この方法だと、トップページしかメンテナンスモード表示にならない。

WordPress は、.htaccess のRewriteRule で index.php にリダイレクトされるため、index2.html のリネームの代わりに、index.php をメンテナンスモード版に差し替えるようにすれば何とかなりそうだが、ひとまずは、これで良しとした。