ตัวอย่างสคริปต์ php ปิด WordPress register / และอนุญาตให้ comment ได้เฉพาะสมาชิกเท่านั้น แล้วให้ส่งอีเมลแจ้งเตือนว่าสคริปต์ได้ทำอะไรไปบ้าง

  1. ล็อกอินด้วยสิทธิ์ root สร้างไฟล์แล้วเพิ่มคำสั่ง
nano /root/scripts/manage_wp_settings.php

2. ใส่โค๊ด

<?php
// manage_wp_settings.php (Version 5.0 - E-Commerce Structure Detection - FULL)

// รายการตรวจสอบจาก "โครงสร้าง" ของเว็บ E-Commerce
$ecommerce_post_types = [
    'product',              // WooCommerce, WP eCommerce, etc.
    'download',             // Easy Digital Downloads
    'wpsc-product',         // WP eCommerce (older)
    'give_forms',           // GiveWP (Donation, often needs registration)
    'edd_payment'           // EDD Payments
];

$ecommerce_db_tables_patterns = [
    '%_woocommerce_order_items', // WooCommerce
    '%_wc_customer_lookup',      // WooCommerce
    '%_edd_customers',           // Easy Digital Downloads
    '%_give_donationmeta'        // GiveWP
];

// การตั้งค่าสำหรับเว็บทั่วไป
$db_settings_to_update_normal = [
    'users_can_register' => '0',
    'comment_registration' => '1',
    'default_comment_status' => 'closed',
];


$users_dir = '/home/';
$report = "รายงานการอัปเดต WordPress Settings (Structure Detection) โดยสคริปต์อัตโนมัติ:\n\n";
$report .= "วันที่: " . date('Y-m-d H:i:s') . "\n";
$report .= "-------------------------------------------------------\n\n";

echo "เริ่มต้นการสแกนและอัปเดตการตั้งค่า WordPress (ตรวจจับ E-Commerce จากโครงสร้าง)...\n\n";

function find_wp_configs($dir) {
    $wp_configs = [];
    if (!is_dir($dir)) return [];
    $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST);
    foreach ($iterator as $file) {
        if ($file->getFilename() === 'wp-config.php') {
            $wp_configs[] = $file->getPathname();
        }
    }
    return $wp_configs;
}

function get_db_connection($db_host, $db_user, $db_password, $db_name) {
    mysqli_report(MYSQLI_REPORT_OFF);
    $mysqli = new mysqli($db_host, $db_user, $db_password, $db_name);
    if ($mysqli->connect_error) return [null, $mysqli->connect_error];
    $mysqli->set_charset("utf8mb4");
    return [$mysqli, null];
}

// ฟังก์ชันใหม่สำหรับตรวจสอบโครงสร้าง E-Commerce
function is_ecommerce_by_structure($mysqli, $table_prefix, $post_types, $table_patterns) {
    // วิธีที่ 1: ตรวจสอบ Custom Post Types
    foreach ($post_types as $pt) {
        $stmt = $mysqli->prepare("SELECT 1 FROM {$table_prefix}posts WHERE post_type = ? LIMIT 1");
        if ($stmt) {
            $stmt->bind_param("s", $pt);
            $stmt->execute();
            if ($stmt->get_result()->num_rows > 0) {
                $stmt->close();
                return true; // พบ Post Type, ยืนยันว่าเป็น E-Commerce
            }
            $stmt->close();
        }
    }

    // วิธีที่ 2: ตรวจสอบ Custom Database Tables
    foreach ($table_patterns as $pattern) {
        // แทนที่ % ด้วย table_prefix เพื่อให้ค้นหาได้ถูกต้อง
        $full_pattern = str_replace('%', $table_prefix, $pattern);
        $stmt = $mysqli->prepare("SHOW TABLES LIKE ?");
        if ($stmt) {
            $stmt->bind_param("s", $full_pattern);
            $stmt->execute();
            if ($stmt->get_result()->num_rows > 0) {
                $stmt->close();
                return true; // พบ Table, ยืนยันว่าเป็น E-Commerce
            }
            $stmt->close();
        }
    }

    return false; // ไม่พบร่องรอย, สันนิษฐานว่าไม่ใช่ E-Commerce
}


$user_folders = @scandir($users_dir);
if (!$user_folders) {
    $report .= "ข้อผิดพลาด: ไม่สามารถเข้าถึงไดเรกทอรีผู้ใช้งาน: {$users_dir}\n";
    die($report);
}

foreach ($user_folders as $user_folder) {
    if ($user_folder == '.' || $user_folder == '..' || !is_dir($users_dir . $user_folder) || strpos($user_folder, '.') !== false) continue;

    $domain_base_path = $users_dir . $user_folder . '/domains/';
    if (!is_dir($domain_base_path)) continue;

    echo "กำลังตรวจสอบผู้ใช้: **{$user_folder}**\n";
    $report .= "--- ผู้ใช้: {$user_folder} ---\n";

    $domain_folders = @scandir($domain_base_path);
    if (!$domain_folders) continue;

    foreach ($domain_folders as $domain_folder) {
        if ($domain_folder == '.' || $domain_folder == '..' || !is_dir($domain_base_path . $domain_folder)) continue;

        $public_html_path = $domain_base_path . $domain_folder . '/public_html/';
        echo "  - กำลังตรวจสอบโดเมน: **{$domain_folder}**\n";
        $report .= "  โดเมน: {$domain_folder}\n";

        $wp_config_paths = find_wp_configs($public_html_path);
        if (empty($wp_config_paths)) {
            $report .= "    - ไม่พบ wp-config.php (ข้าม).\n\n";
            continue;
        }

        foreach ($wp_config_paths as $wp_config_path) {
            $install_path = dirname($wp_config_path);
            echo "    - พบ WordPress ที่: {$install_path}\n";
            $report_domain_detail = "    - Path: {$install_path}\n";

            $db_name = $db_user = $db_password = '';
            $db_host = 'localhost';
            $table_prefix = 'wp_';

            $config_lines = file($wp_config_path);
            foreach ($config_lines as $line) {
                if (preg_match("/define\(\s*'DB_NAME',\s*'(.*?)'\s*\);/", $line, $matches)) $db_name = $matches[1];
                if (preg_match("/define\(\s*'DB_USER',\s*'(.*?)'\s*\);/", $line, $matches)) $db_user = $matches[1];
                if (preg_match("/define\(\s*'DB_PASSWORD',\s*'(.*?)'\s*\);/", $line, $matches)) $db_password = $matches[1];
                if (preg_match("/define\(\s*'DB_HOST',\s*'(.*?)'\s*\);/", $line, $matches)) $db_host = $matches[1];
                if (preg_match("/\\\$table_prefix\s*=\s*'(.*?)';/", $line, $matches)) $table_prefix = $matches[1];
            }

            if ($db_name && $db_user && $db_password) {
                list($mysqli, $connect_error_msg) = get_db_connection($db_host, $db_user, $db_password, $db_name);

                if ($mysqli) {
                    $is_ecommerce_site = is_ecommerce_by_structure($mysqli, $table_prefix, $ecommerce_post_types, $ecommerce_db_tables_patterns);

                    if ($is_ecommerce_site) {
                        echo "      * ตรวจพบโครงสร้าง E-Commerce, กำลังตรวจสอบสถานะการลงทะเบียน...\n";
                        $report_domain_detail .= "      * ตรวจพบโครงสร้าง E-Commerce, กำลังตรวจสอบสถานะ...\n";
                        
                        $stmt_check_reg = $mysqli->prepare("SELECT option_value FROM {$table_prefix}options WHERE option_name = 'users_can_register'");
                        $stmt_check_reg->execute();
                        $result_reg = $stmt_check_reg->get_result();
                        $current_reg_status = $result_reg->fetch_assoc()['option_value'] ?? '0';
                        $stmt_check_reg->close();

                        if ($current_reg_status === '0') {
                            echo "        - สถานะถูกปิด, กำลังเปิดการลงทะเบียน (users_can_register -> 1)\n";
                            $stmt_open_reg = $mysqli->prepare("UPDATE {$table_prefix}options SET option_value = '1' WHERE option_name = 'users_can_register'");
                            $stmt_open_reg->execute();
                            if ($stmt_open_reg->affected_rows > 0) {
                                $report_domain_detail .= "        + แก้ไข: เปิดระบบลงทะเบียนเรียบร้อยแล้ว\n";
                            }
                            $stmt_open_reg->close();
                        } else {
                            echo "        - สถานะเปิดอยู่แล้ว, ไม่มีการเปลี่ยนแปลง\n";
                            $report_domain_detail .= "        * สถานะการลงทะเบียนถูกต้อง (เปิดอยู่)\n";
                        }

                    } else {
                        echo "      * ไม่พบโครงสร้าง E-Commerce, ดำเนินการตั้งค่าความปลอดภัยตามปกติ\n";
                        $report_domain_detail .= "      * ไม่ใช่เว็บ E-Commerce, ดำเนินการตั้งค่าตามปกติ\n";
                        
                        foreach ($db_settings_to_update_normal as $option_name => $option_value) {
                            $stmt_check = $mysqli->prepare("SELECT option_value FROM {$table_prefix}options WHERE option_name = ?");
                            $stmt_check->bind_param("s", $option_name);
                            $stmt_check->execute();
                            $result_check = $stmt_check->get_result();
                            $current_value = $result_check->fetch_assoc()['option_value'] ?? null;
                            $stmt_check->close();

                            if ($current_value != $option_value) {
                                $stmt_update = $mysqli->prepare("UPDATE {$table_prefix}options SET option_value = ? WHERE option_name = ?");
                                $stmt_update->bind_param("ss", $option_value, $option_name);
                                $stmt_update->execute();
                                if ($stmt_update->affected_rows > 0) {
                                     $report_domain_detail .= "        + อัปเดตค่า: {$option_name} เป็น '{$option_value}'\n";
                                }
                                $stmt_update->close();
                            }
                        }
                    }
                    $mysqli->close();
                } else {
                     $report_domain_detail .= "    ! ไม่สามารถเชื่อมต่อฐานข้อมูลได้: " . ($connect_error_msg ?: "ไม่ทราบสาเหตุ") . ".\n";
                }
            } else {
                 $report_domain_detail .= "    - ไม่สามารถดึงข้อมูลฐานข้อมูล (ข้าม).\n";
            }
            $report .= $report_domain_detail . "\n";
        }
    }
    $report .= "-------------------------------------------------------\n\n";
}

echo "\nการดำเนินการสคริปต์เสร็จสิ้น.\n";
$report .= "\n\nการดำเนินการสคริปต์เสร็จสิ้น.";

$to = 'service24x7@hosttook.com';
$subject = 's3 รายงานการอัปเดต WordPress (Structure Detection)';
$headers = "From: s3 Automated Report <fail2ban@hosttook.com>\r\n";
$headers .= "Content-Type: text/plain; charset=UTF-8\r\n";

if (mail($to, $subject, $report, $headers)) {
    echo "ส่งอีเมลรายงานสำเร็จไปยัง {$to}\n";
} else {
    echo "เกิดข้อผิดพลาดในการส่งอีเมลรายงาน.\n";
}

?>

3. ให้สิทธิ์รัน: ตรวจสอบให้แน่ใจว่าไฟล์สคริปต์มีสิทธิ์ในการรัน:

Bash

chmod +x /root/scripts/manage_wp_settings.php

4. รันสคริปต์:

Bash

php /root/scripts/manage_wp_settings.php

5. ตรวจสอบอีเมลดูผลลัพท์การทำงานของสคริปต์

## คำสั่ง Crontab ใช้สำหรับสั่งให้รันสคริปทุกวันตอนเที่ยงคืน

นี่คือบรรทัดคำสั่งที่คุณต้องเพิ่มเข้าไปใน crontab :

Bash

0 0 * * * /usr/bin/php /root/scripts/manage_wp_settings.php > /dev/null 2>&1

สำคัญ: คุณต้องเปลี่ยน /root/scripts/manage_wp_settings.php ให้เป็น path แบบเต็ม ของไฟล์สคริปต์ที่คุณใช้งานจริงบนเซิร์ฟเวอร์ค่ะ


## วิธีการเพิ่ม Crontab

  1. เปิด Terminal หรือ SSH เข้าไปยังเซิร์ฟเวอร์ของคุณ
  2. พิมพ์คำสั่งเพื่อแก้ไข crontab พิมพ์ crontab -e
  3. กด i เพื่อ insert แทรกเนื้อหา
  4. คัดลอกคำสั่ง crontab ด้านบนไปวาง
  5. กด Esc เพื่อออกจากสถานะ insert แล้วกดโคลอน :wq จะเป็นการบันทึกและออกจากโปรแกรม
  6. เมื่อบันทึกสำเร็จ คุณจะเห็นข้อความแจ้งว่า crontab: installing new crontab เป็นอันเสร็จสิ้นค่ะ!

## คำอธิบายคำสั่ง

เพื่อให้เข้าใจมากขึ้น อธิบายแต่ละส่วนของคำสั่งดังนี้ค่ะ 🧐

  • 0 0 * * * คือการกำหนดเวลาทำงาน ซึ่งหมายถึง:
    • 0: นาทีที่ 0
    • 0: ชั่วโมงที่ 0 (เที่ยงคืน)
    • *: ทุกๆ วันในเดือน
    • *: ทุกๆ เดือน
    • *: ทุกๆ วันในสัปดาห์
    • รวมกันเป็น: “เวลาเที่ยงคืน ของทุกๆ วัน”
  • /usr/bin/php คือการระบุ path แบบเต็มของโปรแกรม PHP interpreter (แนะนำให้ใช้ path เต็มเสมอใน cron job)
    • คุณสามารถตรวจสอบ path ที่ถูกต้องบนเซิร์ฟเวอร์ของคุณได้ด้วยคำสั่ง which php
  • /root/scripts/manage_wp_settings.php คือ path แบบเต็มไปยังไฟล์สคริปต์ของคุณ
  • > /dev/null 2>&1 เป็นส่วนเสริมที่มีประโยชน์มากค่ะ
    • มันหมายถึง “ไม่ต้องแสดงผลลัพธ์หรือ error ใดๆ ออกมา”
    • เนื่องจากสคริปต์ของคุณมีการส่งอีเมลรายงานผลด้วยตัวเองอยู่แล้ว เราจึงไม่จำเป็นต้องให้ cron job ส่งอีเมลแจ้งเตือนการทำงานซ้ำซ้อนกันค่ะ