// Bail early if this isn't a sitemap or stylesheet route. if ( ! ( $sitemap || $stylesheet_type ) ) { return; } if ( ! $this->sitemaps_enabled() ) { $wp_query->set_404(); status_header( 404 ); return; } // Render stylesheet if this is stylesheet route. if ( $stylesheet_type ) { $stylesheet = new WP_Sitemaps_Stylesheet(); $stylesheet->render_stylesheet( $stylesheet_type ); exit; } // Render the index. if ( 'index' === $sitemap ) { $sitemap_list = $this->index->get_sitemap_list(); $this->renderer->render_index( $sitemap_list ); exit; } $provider = $this->registry->get_provider( $sitemap ); if ( ! $provider ) { return; } if ( empty( $paged ) ) { $paged = 1; } $url_list = $provider->get_url_list( $paged, $object_subtype ); // Force a 404 and bail early if no URLs are present. if ( empty( $url_list ) ) { $wp_query->set_404(); status_header( 404 ); return; } $this->renderer->render_sitemap( $url_list ); exit; } /** * Redirects a URL to the wp-sitemap.xml * * @since 5.5.0 * @deprecated 6.7.0 Deprecated in favor of {@see WP_Rewrite::rewrite_rules()} * * @param bool $bypass Pass-through of the pre_handle_404 filter value. * @param WP_Query $query The WP_Query object. * @return bool Bypass value. */ public function redirect_sitemapxml( $bypass, $query ) { _deprecated_function( __FUNCTION__, '6.7.0' ); // If a plugin has already utilized the pre_handle_404 function, return without action to avoid conflicts. if ( $bypass ) { return $bypass; } // 'pagename' is for most permalink types, name is for when the %postname% is used as a top-level field. if ( 'sitemap-xml' === $query->get( 'pagename' ) || 'sitemap-xml' === $query->get( 'name' ) ) { wp_safe_redirect( $this->index->get_index_url() ); exit(); } return $bypass; } /** * Adds the sitemap index to robots.txt. * * @since 5.5.0 * * @param string $output robots.txt output. * @param bool $is_public Whether the site is public. * @return string The robots.txt output. */ public function add_robots( $output, $is_public ) { if ( $is_public ) { $output .= "\nSitemap: " . esc_url( $this->index->get_index_url() ) . "\n"; } return $output; } } * @return WP_REST_Response Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable $options = AMP_Options_Manager::get_options(); $properties = $this->get_item_schema()['properties']; $options = wp_array_slice_assoc( $options, array_keys( $properties ) ); // Add the preview permalink. The permalink can't be handled via AMP_Options_Manager::get_options because // amp_admin_get_preview_permalink calls AMP_Options_Manager::get_options, leading to infinite recursion. $options[ self::PREVIEW_PERMALINK ] = amp_admin_get_preview_permalink(); $options[ self::SUPPRESSIBLE_PLUGINS ] = $this->plugin_suppression->get_suppressible_plugins_with_details(); $options[ self::SUPPORTABLE_POST_TYPES ] = array_map( static function( $slug ) { $post_type = (array) get_post_type_object( $slug ); $post_type['supports_amp'] = post_type_supports( $post_type['name'], AMP_Post_Type_Support::SLUG ); return $post_type; }, AMP_Post_Type_Support::get_eligible_post_types() ); $options[ self::SUPPORTABLE_TEMPLATES ] = $this->get_nested_supportable_templates( AMP_Theme_Support::get_supportable_templates() ); $options[ Option::SUPPRESSED_PLUGINS ] = $this->plugin_suppression->prepare_suppressed_plugins_for_response( $options[ Option::SUPPRESSED_PLUGINS ] ); $options[ self::ONBOARDING_WIZARD_LINK ] = get_admin_url( null, add_query_arg( [ 'page' => OnboardingWizardSubmenu::SCREEN_ID ], 'admin.php' ) ); $options[ self::CUSTOMIZER_LINK ] = amp_get_customizer_url(); /** * Filters options for services to add additional REST items. * * @internal * * @param array $service_options REST Options for Services. */ $service_options = apply_filters( 'amp_rest_options', [] ); if ( ! is_array( $service_options ) ) { $service_options = []; } $options = array_merge( $options, $service_options ); return rest_ensure_response( $options ); } /** * Provides a hierarchical array of supportable templates. * * @param array[] $supportable_templates Template options. * @param string|null $parent_template_id The parent to provide templates for. * @return array[] Supportable templates with nesting. */ private function get_nested_supportable_templates( $supportable_templates, $parent_template_id = null ) { $nested_supportable_templates = []; foreach ( $supportable_templates as $id => $supportable_template ) { if ( $parent_template_id ? empty( $supportable_template['parent'] ) || $parent_template_id !== $supportable_template['parent'] : ! empty( $supportable_template['parent'] ) ) { continue; } // Skip showing an option if it doesn't have a label. if ( empty( $supportable_template['label'] ) ) { continue; } $supportable_template['id'] = $id; $supportable_template['children'] = $this->get_nested_supportable_templates( $supportable_templates, $id ); // Omit obsolete properties. unset( $supportable_template['supported'], $supportable_template['user_supported'], $supportable_template['immutable'] ); $nested_supportable_templates[] = $supportable_template; } return $nested_supportable_templates; } /** * Updates AMP plugin options. * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response Response object on success, or WP_Error object on failure. */ public function update_items( $request ) { $params = $request->get_params(); AMP_Options_Manager::update_options( wp_array_slice_assoc( $params, array_keys( $this->get_item_schema()['properties'] ) ) ); return rest_ensure_response( $this->get_items( $request ) ); } /** * Retrieves the schema for plugin options provided by the endpoint. * * @return array Item schema data. */ public function get_item_schema() { if ( ! $this->schema ) { $this->schema = [ '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'amp-wp-options', 'type' => 'object', 'properties' => [ // Note: The sanitize_callback from AMP_Options_Manager::register_settings() is applying to this option. Option::THEME_SUPPORT => [ 'type' => 'string', 'enum' => [ AMP_Theme_Support::READER_MODE_SLUG, AMP_Theme_Support::STANDARD_MODE_SLUG, AMP_Theme_Support::TRANSITIONAL_MODE_SLUG, ], ], Option::READER_THEME => [ 'type' => 'string', 'arg_options' => [ 'validate_callback' => function ( $value ) { // Note: The validate_callback is used instead of enum in order to prevent leaking the list of themes. return $this->reader_themes->theme_data_exists( $value ); }, ], ], Option::MOBILE_REDIRECT => [ 'type' => 'boolean', 'default' => false, ], self::PREVIEW_PERMALINK => [ 'type' => 'string', 'readonly' => true, 'format' => 'url', ], Option::PLUGIN_CONFIGURED => [ 'type' => 'boolean', 'default' => false, ], Option::ALL_TEMPLATES_SUPPORTED => [ 'type' => 'boolean', ], Option::SUPPRESSED_PLUGINS => [ 'type' => 'object', ], self::SUPPRESSIBLE_PLUGINS => [ 'type' => 'object', 'readonly' => true, ], Option::SUPPORTED_TEMPLATES => [ 'type' => 'array', 'items' => [ 'type' => 'string', ], ], Option::SUPPORTED_POST_TYPES => [ 'type' => 'array', 'items' => [ 'type' => 'string', ], ], Option::ANALYTICS => [ 'type' => 'object', ], Option::DELETE_DATA_AT_UNINSTALL => [ 'type' => 'boolean', 'default' => true, ], Option::USE_NATIVE_IMG_TAG => [ 'type' => 'boolean', 'default' => false, ], self::SUPPORTABLE_POST_TYPES => [ 'type' => 'array', 'readonly' => true, ], self::SUPPORTABLE_TEMPLATES => [ 'type' => 'array', 'readonly' => true, ], self::ONBOARDING_WIZARD_LINK => [ 'type' => 'url', 'readonly' => true, ], self::CUSTOMIZER_LINK => [ 'type' => 'url', 'readonly' => true, ], ], ]; /** * Filters schema for services to add additional items. * * @internal * * @param array $schema Schema. */ $services_schema = apply_filters( 'amp_rest_options_schema', [] ); if ( ! is_array( $services_schema ) ) { $services_schema = []; } $this->schema['properties'] = array_merge( $this->schema['properties'], $services_schema ); } return $this->schema; } } * @return WP_REST_Response Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable $options = AMP_Options_Manager::get_options(); $properties = $this->get_item_schema()['properties']; $options = wp_array_slice_assoc( $options, array_keys( $properties ) ); // Add the preview permalink. The permalink can't be handled via AMP_Options_Manager::get_options because // amp_admin_get_preview_permalink calls AMP_Options_Manager::get_options, leading to infinite recursion. $options[ self::PREVIEW_PERMALINK ] = amp_admin_get_preview_permalink(); $options[ self::SUPPRESSIBLE_PLUGINS ] = $this->plugin_suppression->get_suppressible_plugins_with_details(); $options[ self::SUPPORTABLE_POST_TYPES ] = array_map( static function( $slug ) { $post_type = (array) get_post_type_object( $slug ); $post_type['supports_amp'] = post_type_supports( $post_type['name'], AMP_Post_Type_Support::SLUG ); return $post_type; }, AMP_Post_Type_Support::get_eligible_post_types() ); $options[ self::SUPPORTABLE_TEMPLATES ] = $this->get_nested_supportable_templates( AMP_Theme_Support::get_supportable_templates() ); $options[ Option::SUPPRESSED_PLUGINS ] = $this->plugin_suppression->prepare_suppressed_plugins_for_response( $options[ Option::SUPPRESSED_PLUGINS ] ); $options[ self::ONBOARDING_WIZARD_LINK ] = get_admin_url( null, add_query_arg( [ 'page' => OnboardingWizardSubmenu::SCREEN_ID ], 'admin.php' ) ); $options[ self::CUSTOMIZER_LINK ] = amp_get_customizer_url(); /** * Filters options for services to add additional REST items. * * @internal * * @param array $service_options REST Options for Services. */ $service_options = apply_filters( 'amp_rest_options', [] ); if ( ! is_array( $service_options ) ) { $service_options = []; } $options = array_merge( $options, $service_options ); return rest_ensure_response( $options ); } /** * Provides a hierarchical array of supportable templates. * * @param array[] $supportable_templates Template options. * @param string|null $parent_template_id The parent to provide templates for. * @return array[] Supportable templates with nesting. */ private function get_nested_supportable_templates( $supportable_templates, $parent_template_id = null ) { $nested_supportable_templates = []; foreach ( $supportable_templates as $id => $supportable_template ) { if ( $parent_template_id ? empty( $supportable_template['parent'] ) || $parent_template_id !== $supportable_template['parent'] : ! empty( $supportable_template['parent'] ) ) { continue; } // Skip showing an option if it doesn't have a label. if ( empty( $supportable_template['label'] ) ) { continue; } $supportable_template['id'] = $id; $supportable_template['children'] = $this->get_nested_supportable_templates( $supportable_templates, $id ); // Omit obsolete properties. unset( $supportable_template['supported'], $supportable_template['user_supported'], $supportable_template['immutable'] ); $nested_supportable_templates[] = $supportable_template; } return $nested_supportable_templates; } /** * Updates AMP plugin options. * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response Response object on success, or WP_Error object on failure. */ public function update_items( $request ) { $params = $request->get_params(); AMP_Options_Manager::update_options( wp_array_slice_assoc( $params, array_keys( $this->get_item_schema()['properties'] ) ) ); return rest_ensure_response( $this->get_items( $request ) ); } /** * Retrieves the schema for plugin options provided by the endpoint. * * @return array Item schema data. */ public function get_item_schema() { if ( ! $this->schema ) { $this->schema = [ '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'amp-wp-options', 'type' => 'object', 'properties' => [ // Note: The sanitize_callback from AMP_Options_Manager::register_settings() is applying to this option. Option::THEME_SUPPORT => [ 'type' => 'string', 'enum' => [ AMP_Theme_Support::READER_MODE_SLUG, AMP_Theme_Support::STANDARD_MODE_SLUG, AMP_Theme_Support::TRANSITIONAL_MODE_SLUG, ], ], Option::READER_THEME => [ 'type' => 'string', 'arg_options' => [ 'validate_callback' => function ( $value ) { // Note: The validate_callback is used instead of enum in order to prevent leaking the list of themes. return $this->reader_themes->theme_data_exists( $value ); }, ], ], Option::MOBILE_REDIRECT => [ 'type' => 'boolean', 'default' => false, ], self::PREVIEW_PERMALINK => [ 'type' => 'string', 'readonly' => true, 'format' => 'url', ], Option::PLUGIN_CONFIGURED => [ 'type' => 'boolean', 'default' => false, ], Option::ALL_TEMPLATES_SUPPORTED => [ 'type' => 'boolean', ], Option::SUPPRESSED_PLUGINS => [ 'type' => 'object', ], self::SUPPRESSIBLE_PLUGINS => [ 'type' => 'object', 'readonly' => true, ], Option::SUPPORTED_TEMPLATES => [ 'type' => 'array', 'items' => [ 'type' => 'string', ], ], Option::SUPPORTED_POST_TYPES => [ 'type' => 'array', 'items' => [ 'type' => 'string', ], ], Option::ANALYTICS => [ 'type' => 'object', ], Option::DELETE_DATA_AT_UNINSTALL => [ 'type' => 'boolean', 'default' => true, ], Option::USE_NATIVE_IMG_TAG => [ 'type' => 'boolean', 'default' => false, ], self::SUPPORTABLE_POST_TYPES => [ 'type' => 'array', 'readonly' => true, ], self::SUPPORTABLE_TEMPLATES => [ 'type' => 'array', 'readonly' => true, ], self::ONBOARDING_WIZARD_LINK => [ 'type' => 'url', 'readonly' => true, ], self::CUSTOMIZER_LINK => [ 'type' => 'url', 'readonly' => true, ], ], ]; /** * Filters schema for services to add additional items. * * @internal * * @param array $schema Schema. */ $services_schema = apply_filters( 'amp_rest_options_schema', [] ); if ( ! is_array( $services_schema ) ) { $services_schema = []; } $this->schema['properties'] = array_merge( $this->schema['properties'], $services_schema ); } return $this->schema; } } * @return WP_REST_Response Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable $options = AMP_Options_Manager::get_options(); $properties = $this->get_item_schema()['properties']; $options = wp_array_slice_assoc( $options, array_keys( $properties ) ); // Add the preview permalink. The permalink can't be handled via AMP_Options_Manager::get_options because // amp_admin_get_preview_permalink calls AMP_Options_Manager::get_options, leading to infinite recursion. $options[ self::PREVIEW_PERMALINK ] = amp_admin_get_preview_permalink(); $options[ self::SUPPRESSIBLE_PLUGINS ] = $this->plugin_suppression->get_suppressible_plugins_with_details(); $options[ self::SUPPORTABLE_POST_TYPES ] = array_map( static function( $slug ) { $post_type = (array) get_post_type_object( $slug ); $post_type['supports_amp'] = post_type_supports( $post_type['name'], AMP_Post_Type_Support::SLUG ); return $post_type; }, AMP_Post_Type_Support::get_eligible_post_types() ); $options[ self::SUPPORTABLE_TEMPLATES ] = $this->get_nested_supportable_templates( AMP_Theme_Support::get_supportable_templates() ); $options[ Option::SUPPRESSED_PLUGINS ] = $this->plugin_suppression->prepare_suppressed_plugins_for_response( $options[ Option::SUPPRESSED_PLUGINS ] ); $options[ self::ONBOARDING_WIZARD_LINK ] = get_admin_url( null, add_query_arg( [ 'page' => OnboardingWizardSubmenu::SCREEN_ID ], 'admin.php' ) ); $options[ self::CUSTOMIZER_LINK ] = amp_get_customizer_url(); /** * Filters options for services to add additional REST items. * * @internal * * @param array $service_options REST Options for Services. */ $service_options = apply_filters( 'amp_rest_options', [] ); if ( ! is_array( $service_options ) ) { $service_options = []; } $options = array_merge( $options, $service_options ); return rest_ensure_response( $options ); } /** * Provides a hierarchical array of supportable templates. * * @param array[] $supportable_templates Template options. * @param string|null $parent_template_id The parent to provide templates for. * @return array[] Supportable templates with nesting. */ private function get_nested_supportable_templates( $supportable_templates, $parent_template_id = null ) { $nested_supportable_templates = []; foreach ( $supportable_templates as $id => $supportable_template ) { if ( $parent_template_id ? empty( $supportable_template['parent'] ) || $parent_template_id !== $supportable_template['parent'] : ! empty( $supportable_template['parent'] ) ) { continue; } // Skip showing an option if it doesn't have a label. if ( empty( $supportable_template['label'] ) ) { continue; } $supportable_template['id'] = $id; $supportable_template['children'] = $this->get_nested_supportable_templates( $supportable_templates, $id ); // Omit obsolete properties. unset( $supportable_template['supported'], $supportable_template['user_supported'], $supportable_template['immutable'] ); $nested_supportable_templates[] = $supportable_template; } return $nested_supportable_templates; } /** * Updates AMP plugin options. * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response Response object on success, or WP_Error object on failure. */ public function update_items( $request ) { $params = $request->get_params(); AMP_Options_Manager::update_options( wp_array_slice_assoc( $params, array_keys( $this->get_item_schema()['properties'] ) ) ); return rest_ensure_response( $this->get_items( $request ) ); } /** * Retrieves the schema for plugin options provided by the endpoint. * * @return array Item schema data. */ public function get_item_schema() { if ( ! $this->schema ) { $this->schema = [ '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'amp-wp-options', 'type' => 'object', 'properties' => [ // Note: The sanitize_callback from AMP_Options_Manager::register_settings() is applying to this option. Option::THEME_SUPPORT => [ 'type' => 'string', 'enum' => [ AMP_Theme_Support::READER_MODE_SLUG, AMP_Theme_Support::STANDARD_MODE_SLUG, AMP_Theme_Support::TRANSITIONAL_MODE_SLUG, ], ], Option::READER_THEME => [ 'type' => 'string', 'arg_options' => [ 'validate_callback' => function ( $value ) { // Note: The validate_callback is used instead of enum in order to prevent leaking the list of themes. return $this->reader_themes->theme_data_exists( $value ); }, ], ], Option::MOBILE_REDIRECT => [ 'type' => 'boolean', 'default' => false, ], self::PREVIEW_PERMALINK => [ 'type' => 'string', 'readonly' => true, 'format' => 'url', ], Option::PLUGIN_CONFIGURED => [ 'type' => 'boolean', 'default' => false, ], Option::ALL_TEMPLATES_SUPPORTED => [ 'type' => 'boolean', ], Option::SUPPRESSED_PLUGINS => [ 'type' => 'object', ], self::SUPPRESSIBLE_PLUGINS => [ 'type' => 'object', 'readonly' => true, ], Option::SUPPORTED_TEMPLATES => [ 'type' => 'array', 'items' => [ 'type' => 'string', ], ], Option::SUPPORTED_POST_TYPES => [ 'type' => 'array', 'items' => [ 'type' => 'string', ], ], Option::ANALYTICS => [ 'type' => 'object', ], Option::DELETE_DATA_AT_UNINSTALL => [ 'type' => 'boolean', 'default' => true, ], Option::USE_NATIVE_IMG_TAG => [ 'type' => 'boolean', 'default' => false, ], self::SUPPORTABLE_POST_TYPES => [ 'type' => 'array', 'readonly' => true, ], self::SUPPORTABLE_TEMPLATES => [ 'type' => 'array', 'readonly' => true, ], self::ONBOARDING_WIZARD_LINK => [ 'type' => 'url', 'readonly' => true, ], self::CUSTOMIZER_LINK => [ 'type' => 'url', 'readonly' => true, ], ], ]; /** * Filters schema for services to add additional items. * * @internal * * @param array $schema Schema. */ $services_schema = apply_filters( 'amp_rest_options_schema', [] ); if ( ! is_array( $services_schema ) ) { $services_schema = []; } $this->schema['properties'] = array_merge( $this->schema['properties'], $services_schema ); } return $this->schema; } } * @return WP_REST_Response Response object on success, or WP_Error object on failure. */ public function get_items( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable $options = AMP_Options_Manager::get_options(); $properties = $this->get_item_schema()['properties']; $options = wp_array_slice_assoc( $options, array_keys( $properties ) ); // Add the preview permalink. The permalink can't be handled via AMP_Options_Manager::get_options because // amp_admin_get_preview_permalink calls AMP_Options_Manager::get_options, leading to infinite recursion. $options[ self::PREVIEW_PERMALINK ] = amp_admin_get_preview_permalink(); $options[ self::SUPPRESSIBLE_PLUGINS ] = $this->plugin_suppression->get_suppressible_plugins_with_details(); $options[ self::SUPPORTABLE_POST_TYPES ] = array_map( static function( $slug ) { $post_type = (array) get_post_type_object( $slug ); $post_type['supports_amp'] = post_type_supports( $post_type['name'], AMP_Post_Type_Support::SLUG ); return $post_type; }, AMP_Post_Type_Support::get_eligible_post_types() ); $options[ self::SUPPORTABLE_TEMPLATES ] = $this->get_nested_supportable_templates( AMP_Theme_Support::get_supportable_templates() ); $options[ Option::SUPPRESSED_PLUGINS ] = $this->plugin_suppression->prepare_suppressed_plugins_for_response( $options[ Option::SUPPRESSED_PLUGINS ] ); $options[ self::ONBOARDING_WIZARD_LINK ] = get_admin_url( null, add_query_arg( [ 'page' => OnboardingWizardSubmenu::SCREEN_ID ], 'admin.php' ) ); $options[ self::CUSTOMIZER_LINK ] = amp_get_customizer_url(); /** * Filters options for services to add additional REST items. * * @internal * * @param array $service_options REST Options for Services. */ $service_options = apply_filters( 'amp_rest_options', [] ); if ( ! is_array( $service_options ) ) { $service_options = []; } $options = array_merge( $options, $service_options ); return rest_ensure_response( $options ); } /** * Provides a hierarchical array of supportable templates. * * @param array[] $supportable_templates Template options. * @param string|null $parent_template_id The parent to provide templates for. * @return array[] Supportable templates with nesting. */ private function get_nested_supportable_templates( $supportable_templates, $parent_template_id = null ) { $nested_supportable_templates = []; foreach ( $supportable_templates as $id => $supportable_template ) { if ( $parent_template_id ? empty( $supportable_template['parent'] ) || $parent_template_id !== $supportable_template['parent'] : ! empty( $supportable_template['parent'] ) ) { continue; } // Skip showing an option if it doesn't have a label. if ( empty( $supportable_template['label'] ) ) { continue; } $supportable_template['id'] = $id; $supportable_template['children'] = $this->get_nested_supportable_templates( $supportable_templates, $id ); // Omit obsolete properties. unset( $supportable_template['supported'], $supportable_template['user_supported'], $supportable_template['immutable'] ); $nested_supportable_templates[] = $supportable_template; } return $nested_supportable_templates; } /** * Updates AMP plugin options. * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response Response object on success, or WP_Error object on failure. */ public function update_items( $request ) { $params = $request->get_params(); AMP_Options_Manager::update_options( wp_array_slice_assoc( $params, array_keys( $this->get_item_schema()['properties'] ) ) ); return rest_ensure_response( $this->get_items( $request ) ); } /** * Retrieves the schema for plugin options provided by the endpoint. * * @return array Item schema data. */ public function get_item_schema() { if ( ! $this->schema ) { $this->schema = [ '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'amp-wp-options', 'type' => 'object', 'properties' => [ // Note: The sanitize_callback from AMP_Options_Manager::register_settings() is applying to this option. Option::THEME_SUPPORT => [ 'type' => 'string', 'enum' => [ AMP_Theme_Support::READER_MODE_SLUG, AMP_Theme_Support::STANDARD_MODE_SLUG, AMP_Theme_Support::TRANSITIONAL_MODE_SLUG, ], ], Option::READER_THEME => [ 'type' => 'string', 'arg_options' => [ 'validate_callback' => function ( $value ) { // Note: The validate_callback is used instead of enum in order to prevent leaking the list of themes. return $this->reader_themes->theme_data_exists( $value ); }, ], ], Option::MOBILE_REDIRECT => [ 'type' => 'boolean', 'default' => false, ], self::PREVIEW_PERMALINK => [ 'type' => 'string', 'readonly' => true, 'format' => 'url', ], Option::PLUGIN_CONFIGURED => [ 'type' => 'boolean', 'default' => false, ], Option::ALL_TEMPLATES_SUPPORTED => [ 'type' => 'boolean', ], Option::SUPPRESSED_PLUGINS => [ 'type' => 'object', ], self::SUPPRESSIBLE_PLUGINS => [ 'type' => 'object', 'readonly' => true, ], Option::SUPPORTED_TEMPLATES => [ 'type' => 'array', 'items' => [ 'type' => 'string', ], ], Option::SUPPORTED_POST_TYPES => [ 'type' => 'array', 'items' => [ 'type' => 'string', ], ], Option::ANALYTICS => [ 'type' => 'object', ], Option::DELETE_DATA_AT_UNINSTALL => [ 'type' => 'boolean', 'default' => true, ], Option::USE_NATIVE_IMG_TAG => [ 'type' => 'boolean', 'default' => false, ], self::SUPPORTABLE_POST_TYPES => [ 'type' => 'array', 'readonly' => true, ], self::SUPPORTABLE_TEMPLATES => [ 'type' => 'array', 'readonly' => true, ], self::ONBOARDING_WIZARD_LINK => [ 'type' => 'url', 'readonly' => true, ], self::CUSTOMIZER_LINK => [ 'type' => 'url', 'readonly' => true, ], ], ]; /** * Filters schema for services to add additional items. * * @internal * * @param array $schema Schema. */ $services_schema = apply_filters( 'amp_rest_options_schema', [] ); if ( ! is_array( $services_schema ) ) { $services_schema = []; } $this->schema['properties'] = array_merge( $this->schema['properties'], $services_schema ); } return $this->schema; } }