'GET', 'callback' => array( $this, 'get_status' ), 'permission_callback' => array( $this, 'permissions' ), ) ); register_rest_route( self::NAMESPACE_V1, '/settings', array( array( 'methods' => 'GET', 'callback' => array( $this, 'get_settings' ), 'permission_callback' => array( $this, 'permissions' ), ), array( 'methods' => 'POST', 'callback' => array( $this, 'update_settings' ), 'permission_callback' => array( $this, 'permissions' ), ), ) ); register_rest_route( self::NAMESPACE_V1, '/cache/purge', array( 'methods' => 'POST', 'callback' => array( $this, 'purge' ), 'permission_callback' => array( $this, 'permissions' ), ) ); register_rest_route( self::NAMESPACE_V1, '/cache/toggle', array( 'methods' => 'POST', 'callback' => array( $this, 'toggle_cache' ), 'permission_callback' => array( $this, 'permissions' ), ) ); register_rest_route( self::NAMESPACE_V1, '/cache/benchmark', array( 'methods' => 'GET', 'callback' => array( $this, 'benchmark' ), 'permission_callback' => array( $this, 'permissions' ), ) ); register_rest_route( self::NAMESPACE_V1, '/audit/pro', array( 'methods' => 'GET', 'callback' => array( $this, 'pro_audit' ), 'permission_callback' => array( $this, 'permissions' ), ) ); } /** * Run the Pro audit — scans current settings + cache stats, * returns a personalized list of Pro features that would help * THIS site. See Pro_Audit::run() for the rule set. */ public function pro_audit( $request ) { unset( $request ); return rest_ensure_response( array( 'suggestions' => Pro_Audit::run() ) ); } /** * Cache before/after benchmark — fetches home_url() twice (with + * without the bypass header) and returns side-by-side timings for * the dashboard widget. */ public function benchmark( $request ) { unset( $request ); return rest_ensure_response( Cache_Benchmark::run() ); } public function permissions() { return current_user_can( 'manage_options' ); } public function get_status() { $opts = Settings::get(); $stats = Cache::get_stats(); return rest_ensure_response( array( 'enabled' => (bool) $opts['cache_enabled'], 'stats' => $stats, 'server' => array( 'type' => Server::type(), 'gzip_mode' => Server::gzip_mode(), 'gzip_active' => Gzip::probe_active(), 'nginx_snippet' => Gzip::nginx_snippet(), ), ) ); } public function get_settings() { return rest_ensure_response( Settings::get() ); } public function update_settings( \WP_REST_Request $request ) { $params = $request->get_json_params(); if ( ! is_array( $params ) ) { $params = $request->get_params(); } // `cache_enabled` is the trigger for drop-in install / wp-config.php // edit and must only flow through the dedicated /cache/toggle // endpoint. Strip it here so generic settings updates can never // implicitly write a drop-in or modify wp-config.php. unset( $params['cache_enabled'] ); $updated = Settings::update( $params ); return rest_ensure_response( $updated ); } public function purge() { Cache::purge_all(); return rest_ensure_response( array( 'stats' => Cache::get_stats() ) ); } public function toggle_cache( \WP_REST_Request $request ) { $params = $request->get_json_params(); $enabled = isset( $params['enabled'] ) ? (bool) $params['enabled'] : false; // User-explicit drop-in install / wp-config.php edit happens here. // permission_callback above already enforced current_user_can( // 'manage_options' ); the REST nonce is verified by core via the // X-WP-Nonce header. $state = Cache::toggle( $enabled ); $updated = Settings::update( array( 'cache_enabled' => $state['enabled'] ) ); return rest_ensure_response( array( 'enabled' => $updated['cache_enabled'], 'stats' => Cache::get_stats(), 'install_state' => $state, ) ); } }