route( '/settings', array( array( 'methods' => 'GET', 'callback' => array( $this, 'get' ), 'permission_callback' => array( $this, 'permission' ), ), array( 'methods' => 'POST, PATCH', 'callback' => array( $this, 'save' ), 'permission_callback' => array( $this, 'permission' ), 'args' => self::save_args(), ), ) ); $this->route( '/settings/loader', array( 'methods' => 'DELETE', 'callback' => array( $this, 'remove_loader' ), 'permission_callback' => array( $this, 'permission' ), ) ); } /** * Arguments accepted when saving. Every one is optional; numbers outside their range are clamped * by Settings::sanitize(). * * @return array> */ private static function save_args(): array { $typed = static function ( string $type, array $extra = array() ): array { return array_merge( array( 'type' => $type, 'sanitize_callback' => 'rest_sanitize_request_arg', 'validate_callback' => 'rest_validate_request_arg', ), $extra ); }; $strings = array( 'items' => array( 'type' => 'string' ) ); return array( 'passes' => $typed( 'integer' ), 'timeout' => $typed( 'integer' ), 'history' => $typed( 'integer' ), 'cookie_ttl' => $typed( 'integer' ), 'mode' => $typed( 'string', array( 'enum' => array( 'auto', 'browse' ) ) ), 'remote_head' => $typed( 'boolean' ), 'warmup' => $typed( 'boolean' ), 'keep_data' => $typed( 'boolean' ), 'urls' => $typed( 'array', $strings ), 'expected_slugs' => $typed( 'array', $strings ), 'overrides' => $typed( 'object', array( 'additionalProperties' => array( 'type' => 'string' ) ) ), ); } /** * View. */ private function view(): array { if ( ! function_exists( 'get_plugins' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; // Lists installed but inactive plugins as owners too. } $owner = new Owner(); $owners = array(); foreach ( $owner->all() as $k => $d ) { if ( in_array( $d['type'], array( 'plugin', 'inactive', 'theme', 'mu' ), true ) ) { $owners[] = array( 'key' => $k, 'name' => $d['name'], ); } } return Settings::get_all() + LoaderInstaller::status() + array( 'overrides' => (array) get_option( 'bloatwright_overrides', array() ), 'owners' => $owners, 'default_urls' => UrlSet::defaults(), 'registry_version' => PrefixRegistry::version(), ); } /** * Get. */ public function get(): \WP_REST_Response { return new \WP_REST_Response( $this->view() ); } /** * Remove the must-use loader (it is written again when the next profiling run starts). */ public function remove_loader(): \WP_REST_Response { LoaderInstaller::remove(); return new \WP_REST_Response( $this->view() ); } /** * Save. * * @param \WP_REST_Request $request Request. */ public function save( \WP_REST_Request $request ): \WP_REST_Response { $params = $request->get_json_params(); $params = $params ? $params : $request->get_body_params(); if ( isset( $params['overrides'] ) ) { $clean = array(); foreach ( (array) $params['overrides'] as $dir => $key ) { $dir = sanitize_text_field( (string) $dir ); $key = sanitize_text_field( (string) $key ); if ( '' !== $dir && '' !== $key ) { $clean[ $dir ] = $key; } } update_option( 'bloatwright_overrides', $clean, false ); unset( $params['overrides'] ); } Settings::update( (array) $params ); return new \WP_REST_Response( $this->view() ); } }