WP_REST_Server::READABLE, 'callback' => 'helix_get_settings', 'permission_callback' => 'helix_settings_permissions_check', 'args' => $get_schema, ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => 'helix_update_settings', 'permission_callback' => 'helix_settings_permissions_check', 'args' => $update_schema, ), ) ); // Individual setting endpoints. register_rest_route( 'helix/v1', '/settings/(?P[a-zA-Z0-9_-]+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => 'helix_get_single_setting', 'permission_callback' => 'helix_settings_permissions_check', 'args' => array( 'setting' => array( 'description' => __( 'Setting name to retrieve.', 'helix' ), 'type' => 'string', 'required' => true, ), ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => 'helix_update_single_setting', 'permission_callback' => 'helix_settings_permissions_check', 'args' => array( 'setting' => array( 'description' => __( 'Setting name to update.', 'helix' ), 'type' => 'string', 'required' => true, ), 'value' => array( 'description' => __( 'Setting value.', 'helix' ), 'type' => array( 'string', 'boolean', 'integer', 'number' ), 'required' => true, ), ), ), ) ); } /** * Permission callback for settings endpoints. * * @since 1.0.0 * @return bool True if the request has read access for the item, false otherwise. */ function helix_settings_permissions_check() { return current_user_can( 'manage_options' ); } /** * Get all WordPress settings. * * @since 1.0.0 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ function helix_get_settings() { $settings = helix_get_wordpress_settings(); if ( is_wp_error( $settings ) ) { return $settings; } return rest_ensure_response( $settings ); } /** * Update WordPress settings. * * @since 1.0.0 * @param WP_REST_Request $request Current request object. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ function helix_update_settings( $request ) { $params = $request->get_params(); $allowed_settings = helix_get_allowed_settings(); $updated_settings = array(); $errors = array(); // Process each setting foreach ( $params as $setting => $value ) { // Check if setting is allowed if ( ! in_array( $setting, $allowed_settings, true ) ) { $error_msg = sprintf( /* translators: %s: Setting name */ __( 'Setting "%s" is not allowed.', 'helix' ), $setting ); $errors[ $setting ] = $error_msg; continue; } // Validate and sanitize the value $sanitized_value = helix_sanitize_setting_value( $setting, $value ); if ( is_wp_error( $sanitized_value ) ) { $errors[ $setting ] = $sanitized_value->get_error_message(); continue; } // Get the WordPress option name for this setting $option_name = helix_get_wp_option_name( $setting ); // Handle special settings that need custom update logic $result = helix_update_setting( $setting, $sanitized_value ); // If special handling didn't apply, update normally if ( ! $result ) { $result = update_option( $option_name, $sanitized_value ); } if ( $result ) { $updated_settings[ $setting ] = $sanitized_value; } else { // Provide specific error messages for special settings if ( $setting === 'language' ) { $error_msg = sprintf( __( 'Language "%s" could not be installed automatically. Please install the language pack manually via WordPress Admin → Settings → General → Site Language.', 'helix' ), $sanitized_value ); } else { $error_msg = __( 'Failed to update setting.', 'helix' ); } $errors[ $setting ] = $error_msg; } } if ( ! empty( $errors ) && empty( $updated_settings ) ) { return new WP_Error( 'helix_settings_update_failed', __( 'Failed to update any settings.', 'helix' ), array( 'status' => 400, 'errors' => $errors, ) ); } $response_data = array( 'updated' => $updated_settings, ); if ( ! empty( $errors ) ) { $response_data['errors'] = $errors; } return rest_ensure_response( $response_data ); } /** * Get a single setting value. * * @since 1.0.0 * @param WP_REST_Request $request Current request object. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ function helix_get_single_setting( $request ) { $setting = $request->get_param( 'setting' ); if ( ! helix_is_setting_allowed( $setting ) ) { return new WP_Error( 'helix_setting_not_allowed', sprintf( /* translators: %s: Setting name */ __( 'Setting "%s" is not allowed.', 'helix' ), $setting ), array( 'status' => 403 ) ); } $option_name = helix_get_wp_option_name( $setting ); $value = get_option( $option_name ); return rest_ensure_response( array( 'setting' => $setting, 'value' => $value, ) ); } /** * Update a single setting value. * * @since 1.0.0 * @param WP_REST_Request $request Current request object. * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. */ function helix_update_single_setting( $request ) { $setting = $request->get_param( 'setting' ); $value = $request->get_param( 'value' ); if ( ! helix_is_setting_allowed( $setting ) ) { return new WP_Error( 'helix_setting_not_allowed', sprintf( /* translators: %s: Setting name */ __( 'Setting "%s" is not allowed to be updated.', 'helix' ), $setting ), array( 'status' => 403 ) ); } $sanitized_value = helix_sanitize_setting_value( $setting, $value ); if ( is_wp_error( $sanitized_value ) ) { return $sanitized_value; } $option_name = helix_get_wp_option_name( $setting ); $result = update_option( $option_name, $sanitized_value ); if ( ! $result && get_option( $option_name ) !== $sanitized_value ) { return new WP_Error( 'helix_setting_update_failed', sprintf( /* translators: %s: Setting name */ __( 'Failed to update setting "%s".', 'helix' ), $setting ), array( 'status' => 500 ) ); } return rest_ensure_response( array( 'setting' => $setting, 'value' => $sanitized_value, 'updated' => true, ) ); }