MaxtDesign

Developer Guide

Architecture

The plugin uses PHP namespaces (MaxtDesign\DisableRestApi) and strict typing throughout.

Class Structure

  • Plugin (class-plugin.php) — Singleton bootstrap. Manages activation, deactivation, and component initialization with dependency injection.
  • Rest_Controller (class-rest-controller.php) — Core logic. Hooks into rest_authentication_errors at priority 99. Handles authenticated vs unauthenticated request flow.
  • Settings (class-settings.php) — Admin settings page. Form handling, endpoint tree rendering, import/export, and input sanitization.
  • Role_Manager (class-role-manager.php) — Role queries and per-role restriction helpers.
  • Logger (class-logger.php) — Placeholder for future request logging (Tier 2 / Pro feature).
  • Constants

    MDRA_VERSION          // '1.0.0'
    MDRA_PLUGIN_FILE      // Main plugin file path
    MDRA_PLUGIN_DIR       // Plugin directory path
    MDRA_PLUGIN_URL       // Plugin URL for assets
    MDRA_PLUGIN_BASENAME  // Plugin basename for hooks

    Autoloader

    PSR-4 style autoloader maps MaxtDesign\DisableRestApi\ClassName to includes/class-classname.php.

    Settings Schema

    Stored as a single serialized option: mdra_settings (autoloaded)

    [
        'disable_rest_api'       => true,           // bool
        'error_message'          => 'REST API...',  // string
        'allow_logged_in'        => true,           // bool
        'whitelisted_endpoints'  => [],             // string[]
        'role_restrictions'      => [               // array
            'subscriber' => [
                'restricted'            => true,    // bool
                'whitelisted_endpoints' => [],      // string[]
            ],
        ],
    ]

    Filters

    mdra_is_route_whitelisted

    Programmatically whitelist routes that aren't in the settings UI.

    add_filter('mdra_is_route_whitelisted', function(bool $is_whitelisted, string $route, array $whitelist): bool {
        // Always allow a custom endpoint
        if (str_starts_with($route, 'my-plugin/v1/')) {
            return true;
        }
        return $is_whitelisted;
    }, 10, 3);

    mdra_rest_error_response

    Customize the error response returned to blocked requests.

    add_filter('mdra_rest_error_response', function(WP_Error $error, array $settings): WP_Error {
        // Change status code to 403
        return new WP_Error('forbidden', 'Access denied', ['status' => 403]);
    }, 10, 2);

    mdra_logging_enabled

    Enable request logging (future feature, Logger class is a placeholder).

    add_filter('mdra_logging_enabled', '__return_true');

    REST Authentication Flow

    The filter runs at priority 99 on rest_authentication_errors:

    Request → rest_authentication_errors (priority 99)
    ├── Previous auth error? → Pass through
    ├── API disabled? No → Allow
    ├── Can't determine route? → Allow
    ├── User logged in?
    │   ├── allow_logged_in enabled?
    │   │   ├── Check per-role restrictions
    │   │   │   ├── Role restricted + route whitelisted → Allow
    │   │   │   ├── Role restricted + not whitelisted → Block (401)
    │   │   │   └── Role not restricted → Allow
    │   │   └── No roles → Allow
    │   └── allow_logged_in disabled?
    │       ├── Role explicitly unrestricted → Allow
    │       ├── Role restricted + whitelisted → Allow
    │       └── Otherwise → Check global whitelist
    └── Not logged in?
        ├── Route in global whitelist → Allow
        └── Not whitelisted → Block (401)

    Route Matching

    The is_route_whitelisted method supports:

  • Exact match: contact-form-7 matches contact-form-7
  • Namespace/prefix match: wc/store matches wc/store/cart, wc/store/products, etc.
  • Routes are normalized by stripping leading slashes before comparison.

    Asset Loading

    Admin CSS and JS load only when $hook_suffix matches the plugin's settings page. No assets load on any other admin page or on the frontend.

    Asset handles:

  • mdra-settings (CSS)
  • mdra-settings (JS)
  • Uninstall

    uninstall.php deletes mdra_settings from wp_options. On multisite, iterates all sites and cleans each one.