<?php
/**
 * Name: Disable XML-RPC
 * Description: Disable XML-RPC protocol to prevent brute force attacks, DDoS vulnerabilities, and pingback spam while blocking remote publishing access for security protection
 * Category: Security
 * Icon: -
 * UseCases: [
 *   {
 *     "title": "Brute Force Protection",
 *     "description": "Block XML-RPC attacks that attempt thousands of login combinations per minute through xmlrpc.php endpoint."
 *   },
 *   {
 *     "title": "DDoS Prevention",
 *     "description": "Disable XML-RPC to prevent it being used as attack vector in DDoS amplification attempts against your server."
 *   },
 *   {
 *     "title": "Legacy Feature Removal",
 *     "description": "Turn off outdated XML-RPC functionality on modern sites that only use REST API and don't need Pingbacks or remote publishing."
 *   }
 * ]
 * Added: 2025-06-05
 * Tags: xmlrpc, security, brute-force, ddos, disable, pingback
 * WhereToFind: {
 *   "location": "Works automatically",
 *   "url": "",
 *   "instructions": "XML-RPC completely disabled - returns 403 if accessed",
 *   "newTab": false
 * }
 */

// Prevent direct access
if (!defined('ABSPATH')) exit;

class SwitchboardDisableXmlrpc {

    public function __construct() {
        // Block XML-RPC access as early as possible
        $this->block_xmlrpc_access();

        // Disable XML-RPC functionality
        add_filter('xmlrpc_enabled', '__return_false');
        add_filter('wp_headers', [$this, 'remove_x_pingback']);
        add_filter('pings_open', '__return_false', 9999);

        // Remove RSD link and Windows Live Writer manifest
        remove_action('wp_head', 'rsd_link');
        remove_action('wp_head', 'wlwmanifest_link');
    }

    /**
     * Register data locations for cleanup system
     *
     * @return array Data storage locations
     */
    public function register_data_locations() {
        return [
            'options' => [],
            'option_patterns' => [],
            'tables' => [],
            'post_meta' => [],
            'user_meta' => [],
        ];
    }

    public function block_xmlrpc_access() {
        // Check if this is an XML-RPC request and block it immediately
        if (isset($_SERVER['SCRIPT_FILENAME']) &&
            basename(sanitize_text_field(wp_unslash($_SERVER['SCRIPT_FILENAME']))) === 'xmlrpc.php') {
            header('HTTP/1.1 403 Forbidden');
            header('Content-Type: text/plain; charset=UTF-8');
            die(esc_html__('XML-RPC services are disabled on this site.', 'wpswitchboard'));
        }
    }

    public function remove_x_pingback($headers) {
        unset($headers['X-Pingback']);
        return $headers;
    }
}

// Initialize and register with data system
$switchboard_instance = new SwitchboardDisableXmlrpc();
Switchboard_Data_Registry::get_instance()->auto_register($switchboard_instance, __FILE__);
