Examples

Secure Form Processing

class SettingsController
{
    public function __construct(
        private Nonce $nonce,
        private Gate $gate,
        private Sanitizer $sanitizer
    ) {}

    public function save(): void
    {
        // 1. Check capability
        $this->gate->authorize('manage_options');

        // 2. Verify nonce
        if (!$this->nonce->verify($_POST['_wpnonce'], 'save_settings')) {
            wp_die('Security check failed');
        }

        // 3. Sanitize input
        $data = $this->sanitizer->sanitize($_POST, [
            'site_name' => 'text',
            'admin_email' => 'email',
            'enable_feature' => 'bool',
        ]);

        // 4. Save
        update_option('my_settings', $data);
    }

    public function form(): void
    {
        $settings = get_option('my_settings');
        ?>
        <form method="post">
            <?php echo $this->nonce->field('save_settings'); ?>

            <input name="site_name" value="<?php echo ea($settings['site_name']); ?>">
            <input name="admin_email" value="<?php echo ea($settings['admin_email']); ?>">
            <input type="checkbox" name="enable_feature" <?php checked($settings['enable_feature']); ?>>

            <button type="submit">Save</button>
        </form>
        <?php
    }
}

AJAX Handler

class AjaxController
{
    public function deleteItem(): void
    {
        // Verify nonce from AJAX
        if (!$this->nonce->verify($_POST['nonce'], 'delete_item')) {
            wp_send_json_error(['message' => 'Invalid token']);
        }

        // Check permission
        if (!$this->gate->can('delete_posts')) {
            wp_send_json_error(['message' => 'Unauthorized']);
        }

        $id = $this->sanitizer->int($_POST['item_id']);
        // Delete logic...

        wp_send_json_success(['deleted' => $id]);
    }
}

Middleware Pattern

class NonceMiddleware
{
    public function __construct(
        private Nonce $nonce,
        private string $action
    ) {}

    public function handle(Request $request, callable $next): Response
    {
        $token = $request->text('_wpnonce');

        if (!$this->nonce->verify($token, $this->action)) {
            return Response::json(['error' => 'Invalid nonce'], 403);
        }

        return $next($request);
    }
}