Merge pull request #11082 from woothemes/settings-api
Add REST API Endpoints for Settings
This commit is contained in:
commit
ef2715b237
|
@ -662,10 +662,14 @@ class WC_Admin_Settings {
|
|||
* Loops though the woocommerce options array and outputs each field.
|
||||
*
|
||||
* @param array $options Options array to output
|
||||
* @param array $data Optional. Data to use for saving. Defaults to $_POST.
|
||||
* @return bool
|
||||
*/
|
||||
public static function save_fields( $options ) {
|
||||
if ( empty( $_POST ) ) {
|
||||
public static function save_fields( $options, $data = null ) {
|
||||
if ( is_null( $data ) ) {
|
||||
$data = $_POST;
|
||||
}
|
||||
if ( empty( $data ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -683,17 +687,17 @@ class WC_Admin_Settings {
|
|||
parse_str( $option['id'], $option_name_array );
|
||||
$option_name = current( array_keys( $option_name_array ) );
|
||||
$setting_name = key( $option_name_array[ $option_name ] );
|
||||
$raw_value = isset( $_POST[ $option_name ][ $setting_name ] ) ? wp_unslash( $_POST[ $option_name ][ $setting_name ] ) : null;
|
||||
$raw_value = isset( $data[ $option_name ][ $setting_name ] ) ? wp_unslash( $data[ $option_name ][ $setting_name ] ) : null;
|
||||
} else {
|
||||
$option_name = $option['id'];
|
||||
$setting_name = '';
|
||||
$raw_value = isset( $_POST[ $option['id'] ] ) ? wp_unslash( $_POST[ $option['id'] ] ) : null;
|
||||
$raw_value = isset( $data[ $option['id'] ] ) ? wp_unslash( $data[ $option['id'] ] ) : null;
|
||||
}
|
||||
|
||||
// Format the value based on option type.
|
||||
switch ( $option['type'] ) {
|
||||
case 'checkbox' :
|
||||
$value = is_null( $raw_value ) ? 'no' : 'yes';
|
||||
$value = in_array( $raw_value, array( 'yes', 'no' ) ) ? $raw_value : 'no';
|
||||
break;
|
||||
case 'textarea' :
|
||||
$value = wp_kses_post( trim( $raw_value ) );
|
||||
|
@ -714,6 +718,15 @@ class WC_Admin_Settings {
|
|||
$value['crop'] = $option['default']['crop'];
|
||||
}
|
||||
break;
|
||||
case 'select':
|
||||
$allowed_values = empty( $option['options'] ) ? array() : array_keys( $option['options'] );
|
||||
if ( empty( $option['default'] ) && empty( $allowed_values ) ) {
|
||||
$value = null;
|
||||
break;
|
||||
}
|
||||
$default = ( empty( $option['default'] ) ? $allowed_values[0] : $option['default'] );
|
||||
$value = in_array( $raw_value, $allowed_values ) ? $raw_value : $default;
|
||||
break;
|
||||
default :
|
||||
$value = wc_clean( $raw_value );
|
||||
break;
|
||||
|
|
|
@ -43,6 +43,24 @@ abstract class WC_Settings_Page {
|
|||
add_action( 'woocommerce_settings_save_' . $this->id, array( $this, 'save' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get settings page ID.
|
||||
* @since 2.7.0
|
||||
* @return string
|
||||
*/
|
||||
public function get_id() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get settings page label.
|
||||
* @since 2.7.0
|
||||
* @return string
|
||||
*/
|
||||
public function get_label() {
|
||||
return $this->label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add this page to settings.
|
||||
*/
|
||||
|
|
|
@ -145,14 +145,15 @@ function woocommerce_admin_fields( $options ) {
|
|||
* Update all settings which are passed.
|
||||
*
|
||||
* @param array $options
|
||||
* @param array $data
|
||||
*/
|
||||
function woocommerce_update_options( $options ) {
|
||||
function woocommerce_update_options( $options, $data = null ) {
|
||||
|
||||
if ( ! class_exists( 'WC_Admin_Settings' ) ) {
|
||||
include 'class-wc-admin-settings.php';
|
||||
}
|
||||
|
||||
WC_Admin_Settings::save_fields( $options );
|
||||
WC_Admin_Settings::save_fields( $options, $data );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,231 @@
|
|||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* REST API Settings Groups Controller.
|
||||
* Handles requests to the /settings and /settings/<group> endpoints.
|
||||
*
|
||||
* @author WooThemes
|
||||
* @category API
|
||||
* @package WooCommerce/API
|
||||
* @version 2.7.0
|
||||
* @since 2.7.0
|
||||
*/
|
||||
class WC_Rest_Settings_Controller extends WC_REST_Controller {
|
||||
|
||||
/**
|
||||
* WP REST API namespace/version.
|
||||
*/
|
||||
protected $namespace = 'wc/v1';
|
||||
|
||||
/**
|
||||
* Route base.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $rest_base = 'settings';
|
||||
|
||||
/**
|
||||
* Register routes.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function register_routes() {
|
||||
register_rest_route( $this->namespace, '/' . $this->rest_base, array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'get_items' ),
|
||||
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
||||
),
|
||||
'schema' => array( $this, 'get_public_item_schema' ),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all settings groups items.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param WP_REST_Request $request
|
||||
* @return WP_Error|WP_REST_Response
|
||||
*/
|
||||
public function get_items( $request ) {
|
||||
$groups = apply_filters( 'woocommerce_settings_groups', array() );
|
||||
if ( empty( $groups ) ) {
|
||||
return new WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce' ), array( 'status' => 500 ) );
|
||||
}
|
||||
|
||||
$defaults = $this->group_defaults();
|
||||
$filtered_groups = array();
|
||||
foreach ( $groups as $group ) {
|
||||
$sub_groups = array();
|
||||
foreach ( $groups as $_group ) {
|
||||
if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) {
|
||||
$sub_groups[] = $_group['id'];
|
||||
}
|
||||
}
|
||||
$group['sub_groups'] = $sub_groups;
|
||||
|
||||
$group = wp_parse_args( $group, $defaults );
|
||||
if ( ! is_null( $group['id'] ) && ! is_null( $group['label'] ) ) {
|
||||
$group_obj = $this->filter_group( $group );
|
||||
$group_data = $this->prepare_item_for_response( $group_obj, $request );
|
||||
$group_data = $this->prepare_response_for_collection( $group_data );
|
||||
|
||||
$filtered_groups[] = $group_data;
|
||||
}
|
||||
}
|
||||
|
||||
$response = rest_ensure_response( $filtered_groups );
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare links for the request.
|
||||
*
|
||||
* @param string $group_id Group ID.
|
||||
* @return array Links for the given group.
|
||||
*/
|
||||
protected function prepare_links( $group_id ) {
|
||||
$base = '/' . $this->namespace . '/' . $this->rest_base;
|
||||
$links = array(
|
||||
'item' => array(
|
||||
'href' => rest_url( trailingslashit( $base ) . $group_id ),
|
||||
'embeddable' => true,
|
||||
),
|
||||
);
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare a report sales object for serialization.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param array $item Group object.
|
||||
* @param WP_REST_Request $request Request object.
|
||||
* @return WP_REST_Response $response Response data.
|
||||
*/
|
||||
public function prepare_item_for_response( $item, $request ) {
|
||||
$context = empty( $request['context'] ) ? 'view' : $request['context'];
|
||||
$data = $this->add_additional_fields_to_object( $item, $request );
|
||||
$data = $this->filter_response_by_context( $data, $context );
|
||||
|
||||
$response = rest_ensure_response( $data );
|
||||
|
||||
$response->add_links( $this->prepare_links( $item['id'] ) );
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out bad values from the groups array/filter so we
|
||||
* only return known values via the API.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param array $group
|
||||
* @return array
|
||||
*/
|
||||
public function filter_group( $group ) {
|
||||
return array_intersect_key(
|
||||
$group,
|
||||
array_flip( array_filter( array_keys( $group ), array( $this, 'allowed_group_keys' ) ) )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for allowed keys for each group response.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param string $key Key to check
|
||||
* @return boolean
|
||||
*/
|
||||
public function allowed_group_keys( $key ) {
|
||||
return in_array( $key, array( 'id', 'label', 'description', 'parent_id', 'sub_groups' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns default settings for groups. null means the field is required.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @return array
|
||||
*/
|
||||
protected function group_defaults() {
|
||||
return array(
|
||||
'id' => null,
|
||||
'label' => null,
|
||||
'description' => '',
|
||||
'parent_id' => '',
|
||||
'sub_groups' => array(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure the current user has access to READ the settings APIs.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param WP_REST_Request $request Full data about the request.
|
||||
* @return WP_Error|boolean
|
||||
*/
|
||||
public function get_items_permissions_check( $request ) {
|
||||
if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) {
|
||||
return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the groups schema, conforming to JSON Schema.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @return array
|
||||
*/
|
||||
public function get_item_schema() {
|
||||
$schema = array(
|
||||
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||
'title' => 'settings-group',
|
||||
'type' => 'object',
|
||||
'properties' => array(
|
||||
'id' => array(
|
||||
'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'arg_options' => array(
|
||||
'sanitize_callback' => 'sanitize_title',
|
||||
),
|
||||
),
|
||||
'label' => array(
|
||||
'description' => __( 'A human readable translation wrapped label. Meant to be used in interfaces.', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'arg_options' => array(
|
||||
'sanitize_callback' => 'sanitize_text_field',
|
||||
),
|
||||
),
|
||||
'description' => array(
|
||||
'description' => __( 'A human readable translation wrapped description. Meant to be used in interfaces', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'arg_options' => array(
|
||||
'sanitize_callback' => 'sanitize_text_field',
|
||||
),
|
||||
),
|
||||
'parent_id' => array(
|
||||
'description' => __( 'ID of parent grouping.', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'arg_options' => array(
|
||||
'sanitize_callback' => 'sanitize_text_field',
|
||||
),
|
||||
),
|
||||
'sub_groups' => array(
|
||||
'description' => __( 'IDs for settings sub groups.', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'arg_options' => array(
|
||||
'sanitize_callback' => 'sanitize_text_field',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $this->add_additional_fields_schema( $schema );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,423 @@
|
|||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* REST API Settings Controller.
|
||||
* Handles requests to the /settings/$group/$setting endpoints.
|
||||
*
|
||||
* @author WooThemes
|
||||
* @category API
|
||||
* @package WooCommerce/API
|
||||
* @version 2.7.0
|
||||
* @since 2.7.0
|
||||
*/
|
||||
class WC_Rest_Settings_Options_Controller extends WC_REST_Controller {
|
||||
|
||||
/**
|
||||
* WP REST API namespace/version.
|
||||
*/
|
||||
protected $namespace = 'wc/v1';
|
||||
|
||||
/**
|
||||
* Route base.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $rest_base = 'settings';
|
||||
|
||||
/**
|
||||
* Register routes.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function register_routes() {
|
||||
register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<group>[\w-]+)', array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'get_items' ),
|
||||
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
||||
),
|
||||
'schema' => array( $this, 'get_public_item_schema' ),
|
||||
) );
|
||||
|
||||
register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<group>[\w-]+)/batch', array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::EDITABLE,
|
||||
'callback' => array( $this, 'batch_items' ),
|
||||
'permission_callback' => array( $this, 'update_items_permissions_check' ),
|
||||
'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
|
||||
),
|
||||
'schema' => array( $this, 'get_public_batch_schema' ),
|
||||
) );
|
||||
|
||||
register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<group>[\w-]+)/(?P<id>[\w-]+)', array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'get_item' ),
|
||||
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
||||
),
|
||||
array(
|
||||
'methods' => WP_REST_Server::EDITABLE,
|
||||
'callback' => array( $this, 'update_item' ),
|
||||
'permission_callback' => array( $this, 'update_items_permissions_check' ),
|
||||
'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
|
||||
),
|
||||
'schema' => array( $this, 'get_public_item_schema' ),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a single setting.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param WP_REST_Request $request
|
||||
* @return WP_Error|WP_REST_Response
|
||||
*/
|
||||
public function get_item( $request ) {
|
||||
$setting = $this->get_setting( $request['group'], $request['id'] );
|
||||
|
||||
if ( is_wp_error( $setting ) ) {
|
||||
return $setting;
|
||||
}
|
||||
|
||||
$response = $this->prepare_item_for_response( $setting, $request );
|
||||
|
||||
return rest_ensure_response( $response );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all settings in a group.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param WP_REST_Request $request
|
||||
* @return WP_Error|WP_REST_Response
|
||||
*/
|
||||
public function get_items( $request ) {
|
||||
$settings = $this->get_group_settings( $request['group'] );
|
||||
|
||||
if ( is_wp_error( $settings ) ) {
|
||||
return $settings;
|
||||
}
|
||||
|
||||
$data = array();
|
||||
|
||||
foreach ( $settings as $setting_obj ) {
|
||||
$setting = $this->prepare_item_for_response( $setting_obj, $request );
|
||||
$setting = $this->prepare_response_for_collection( $setting );
|
||||
$data[] = $setting;
|
||||
}
|
||||
|
||||
return rest_ensure_response( $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all settings in a group.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param string $group_id Group ID.
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
public function get_group_settings( $group_id ) {
|
||||
if ( empty( $group_id ) ) {
|
||||
return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) );
|
||||
}
|
||||
|
||||
$settings = apply_filters( 'woocommerce_settings-' . $group_id, array() );
|
||||
|
||||
if ( empty( $settings ) ) {
|
||||
return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) );
|
||||
}
|
||||
|
||||
$filtered_settings = array();
|
||||
|
||||
foreach ( $settings as $setting ) {
|
||||
$setting = $this->filter_setting( $setting );
|
||||
if ( $this->is_setting_type_valid( $setting['type'] ) ) {
|
||||
$setting['value'] = WC_Admin_Settings::get_option( $setting['id'] );
|
||||
$filtered_settings[] = $setting;
|
||||
}
|
||||
}
|
||||
|
||||
return $filtered_settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get setting data.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param string $group_id Group ID.
|
||||
* @param string $setting_id Setting ID.
|
||||
* @return stdClass|WP_Error
|
||||
*/
|
||||
public function get_setting( $group_id, $setting_id ) {
|
||||
if ( empty( $setting_id ) ) {
|
||||
return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) );
|
||||
}
|
||||
|
||||
$settings = $this->get_group_settings( $group_id );
|
||||
|
||||
if ( is_wp_error( $settings ) ) {
|
||||
return $settings;
|
||||
}
|
||||
|
||||
$array_key = array_keys( wp_list_pluck( $settings, 'id' ), $setting_id );
|
||||
|
||||
if ( empty( $array_key ) ) {
|
||||
return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) );
|
||||
}
|
||||
|
||||
$setting = $settings[ $array_key[0] ];
|
||||
|
||||
if ( ! $this->is_setting_type_valid( $setting['type'] ) ) {
|
||||
return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) );
|
||||
}
|
||||
|
||||
return $setting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk create, update and delete items.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
* @return array Of WP_Error or WP_REST_Response.
|
||||
*/
|
||||
public function batch_items( $request ) {
|
||||
// Get the request params.
|
||||
$items = array_filter( $request->get_params() );
|
||||
|
||||
/*
|
||||
* Since our batch settings update is group-specific and matches based on the route,
|
||||
* we inject the URL parameters (containing group) into the batch items
|
||||
*/
|
||||
if ( ! empty( $items['update'] ) ) {
|
||||
$to_update = array();
|
||||
foreach ( $items['update'] as $item ) {
|
||||
$to_update[] = array_merge( $request->get_url_params(), $item );
|
||||
}
|
||||
$request = new WP_REST_Request( $request->get_method() );
|
||||
$request->set_body_params( array( 'update' => $to_update ) );
|
||||
}
|
||||
|
||||
return parent::batch_items( $request );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a single setting in a group.
|
||||
|
||||
* @since 2.7.0
|
||||
* @param WP_REST_Request $request
|
||||
* @return WP_Error|WP_REST_Response
|
||||
*/
|
||||
public function update_item( $request ) {
|
||||
$setting = $this->get_setting( $request['group'], $request['id'] );
|
||||
|
||||
if ( is_wp_error( $setting ) ) {
|
||||
return $setting;
|
||||
}
|
||||
|
||||
$update_data = array();
|
||||
$update_data[ $setting['id'] ] = $request['value'];
|
||||
|
||||
WC_Admin_Settings::save_fields( array( $setting ), $update_data );
|
||||
|
||||
$response = $this->prepare_item_for_response( $setting, $request );
|
||||
|
||||
return rest_ensure_response( $response );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare a single setting object for response.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param object $item Setting object.
|
||||
* @param WP_REST_Request $request Request object.
|
||||
* @return WP_REST_Response $response Response data.
|
||||
*/
|
||||
public function prepare_item_for_response( $item, $request ) {
|
||||
$data = $this->filter_setting( $item );
|
||||
$data['value'] = WC_Admin_Settings::get_option( $data['id'] );
|
||||
|
||||
$context = empty( $request['context'] ) ? 'view' : $request['context'];
|
||||
$data = $this->add_additional_fields_to_object( $data, $request );
|
||||
$data = $this->filter_response_by_context( $data, $context );
|
||||
|
||||
$response = rest_ensure_response( $data );
|
||||
|
||||
$response->add_links( $this->prepare_links( $data['id'], $request['group'] ) );
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare links for the request.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param string $setting_id Setting ID.
|
||||
* @param string $group_id Group ID.
|
||||
* @return array Links for the given setting.
|
||||
*/
|
||||
protected function prepare_links( $setting_id, $group_id ) {
|
||||
$base = '/' . $this->namespace . '/' . $this->rest_base . '/' . $group_id;
|
||||
$links = array(
|
||||
'self' => array(
|
||||
'href' => rest_url( trailingslashit( $base ) . $setting_id ),
|
||||
),
|
||||
'collection' => array(
|
||||
'href' => rest_url( $base ),
|
||||
),
|
||||
);
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure the current user has access to READ the settings APIs.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param WP_REST_Request $request Full data about the request.
|
||||
* @return WP_Error|boolean
|
||||
*/
|
||||
public function get_items_permissions_check( $request ) {
|
||||
if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) {
|
||||
return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure the current user has access to WRITE the settings APIs.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param WP_REST_Request $request Full data about the request.
|
||||
* @return WP_Error|boolean
|
||||
*/
|
||||
public function update_items_permissions_check( $request ) {
|
||||
if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) {
|
||||
return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out bad values from the settings array/filter so we
|
||||
* only return known values via the API.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param array $setting
|
||||
* @return array
|
||||
*/
|
||||
public function filter_setting( $setting ) {
|
||||
$setting = array_intersect_key(
|
||||
$setting,
|
||||
array_flip( array_filter( array_keys( $setting ), array( $this, 'allowed_setting_keys' ) ) )
|
||||
);
|
||||
|
||||
if ( empty( $setting['options'] ) ) {
|
||||
unset( $setting['options'] );
|
||||
}
|
||||
|
||||
return $setting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for allowed keys for each setting response.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param string $key Key to check
|
||||
* @return boolean
|
||||
*/
|
||||
public function allowed_setting_keys( $key ) {
|
||||
return in_array( $key, array(
|
||||
'id', 'label', 'description', 'default', 'tip',
|
||||
'placeholder', 'type', 'options', 'value',
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Boolean for if a setting type is a valid supported setting type.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param string $type
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_setting_type_valid( $type ) {
|
||||
return in_array( $type, array(
|
||||
'text', 'email', 'number', 'color', 'password',
|
||||
'textarea', 'select', 'multiselect', 'radio', 'checkbox',
|
||||
'multi_select_countries', 'image_width',
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the settings schema, conforming to JSON Schema.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @return array
|
||||
*/
|
||||
public function get_item_schema() {
|
||||
$schema = array(
|
||||
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||
'title' => 'settings',
|
||||
'type' => 'object',
|
||||
'properties' => array(
|
||||
'id' => array(
|
||||
'description' => __( 'A unique identifier for the setting.', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'arg_options' => array(
|
||||
'sanitize_callback' => 'sanitize_title',
|
||||
),
|
||||
),
|
||||
'label' => array(
|
||||
'description' => __( 'A human readable translation wrapped label. Meant to be used in interfaces.', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'arg_options' => array(
|
||||
'sanitize_callback' => 'sanitize_text_field',
|
||||
),
|
||||
),
|
||||
'description' => array(
|
||||
'description' => __( 'A human readable translation wrapped description. Meant to be used in interfaces.', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'arg_options' => array(
|
||||
'sanitize_callback' => 'sanitize_text_field',
|
||||
),
|
||||
),
|
||||
'default' => array(
|
||||
'description' => __( 'Default value for the setting.', 'woocommerce' ),
|
||||
'type' => 'mixed',
|
||||
),
|
||||
'tip' => array(
|
||||
'description' => __( 'Extra help text explaining the setting.', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'arg_options' => array(
|
||||
'sanitize_callback' => 'sanitize_text_field',
|
||||
),
|
||||
),
|
||||
'placeholder' => array(
|
||||
'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'arg_options' => array(
|
||||
'sanitize_callback' => 'sanitize_text_field',
|
||||
),
|
||||
),
|
||||
'type' => array(
|
||||
'description' => __( 'Type of setting. Allowed values: text, email, number, color, password, textarea, select, multiselect, radio, image_width, checkbox.', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'arg_options' => array(
|
||||
'sanitize_callback' => 'sanitize_text_field',
|
||||
),
|
||||
),
|
||||
'options' => array(
|
||||
'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce' ),
|
||||
'type' => 'array',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $this->add_additional_fields_schema( $schema );
|
||||
}
|
||||
}
|
|
@ -144,6 +144,7 @@ class WC_API extends WC_Legacy_API {
|
|||
include_once( 'abstracts/abstract-wc-rest-controller.php' );
|
||||
include_once( 'abstracts/abstract-wc-rest-posts-controller.php' );
|
||||
include_once( 'abstracts/abstract-wc-rest-terms-controller.php' );
|
||||
include_once( 'abstracts/abstract-wc-settings-api.php' );
|
||||
|
||||
// REST API controllers.
|
||||
include_once( 'api/class-wc-rest-coupons-controller.php' );
|
||||
|
@ -162,6 +163,8 @@ class WC_API extends WC_Legacy_API {
|
|||
include_once( 'api/class-wc-rest-report-sales-controller.php' );
|
||||
include_once( 'api/class-wc-rest-report-top-sellers-controller.php' );
|
||||
include_once( 'api/class-wc-rest-reports-controller.php' );
|
||||
include_once( 'api/class-wc-rest-settings-controller.php' );
|
||||
include_once( 'api/class-wc-rest-settings-options-controller.php' );
|
||||
include_once( 'api/class-wc-rest-tax-classes-controller.php' );
|
||||
include_once( 'api/class-wc-rest-taxes-controller.php' );
|
||||
include_once( 'api/class-wc-rest-webhook-deliveries.php' );
|
||||
|
@ -173,6 +176,9 @@ class WC_API extends WC_Legacy_API {
|
|||
* @since 2.6.0
|
||||
*/
|
||||
public function register_rest_routes() {
|
||||
// Register settings to the REST API.
|
||||
$this->register_wp_admin_settings();
|
||||
|
||||
$controllers = array(
|
||||
'WC_REST_Coupons_Controller',
|
||||
'WC_REST_Customer_Downloads_Controller',
|
||||
|
@ -190,6 +196,8 @@ class WC_API extends WC_Legacy_API {
|
|||
'WC_REST_Report_Sales_Controller',
|
||||
'WC_REST_Report_Top_Sellers_Controller',
|
||||
'WC_REST_Reports_Controller',
|
||||
'WC_Rest_Settings_Controller',
|
||||
'WC_Rest_Settings_Options_Controller',
|
||||
'WC_REST_Tax_Classes_Controller',
|
||||
'WC_REST_Taxes_Controller',
|
||||
'WC_REST_Webhook_Deliveries_Controller',
|
||||
|
@ -201,4 +209,16 @@ class WC_API extends WC_Legacy_API {
|
|||
$this->$controller->register_routes();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register WC settings from WP-API to the REST API.
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function register_wp_admin_settings() {
|
||||
$pages = WC_Admin_Settings::get_settings_pages();
|
||||
foreach ( $pages as $page ) {
|
||||
new WC_Register_WP_Admin_Settings( $page );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take settings registered for WP-Admin and hooks them up to the REST API.
|
||||
*
|
||||
* @version 2.7.0
|
||||
* @since 2.7.0
|
||||
* @package WooCommerce/Classes
|
||||
* @category Class
|
||||
*/
|
||||
class WC_Register_WP_Admin_Settings {
|
||||
|
||||
/** @var class Current settings class. Used to pull settings. */
|
||||
protected $page;
|
||||
|
||||
/**
|
||||
* Hooks into the settings API and starts registering our settings.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function __construct( $page ) {
|
||||
$this->page = $page;
|
||||
add_filter( 'woocommerce_settings_groups', array( $this, 'register_group' ) );
|
||||
add_filter( 'woocommerce_settings-' . $this->page->get_id(), array( $this, 'register_settings' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a setting group, based on admin page ID & label as parent group.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param array $groups Array of previously registered groups.
|
||||
* @return array
|
||||
*/
|
||||
public function register_group( $groups ) {
|
||||
$groups[] = array(
|
||||
'id' => $this->page->get_id(),
|
||||
'label' => $this->page->get_label(),
|
||||
);
|
||||
return $groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers settings to a specific group.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param array $settings Existing registered settings
|
||||
* @return array
|
||||
*/
|
||||
public function register_settings( $settings ) {
|
||||
/**
|
||||
* wp-admin settings can be broken down into separate sections from
|
||||
* a UI standpoint. This will grab all the sections associated with
|
||||
* a particular setting group (like 'products') and register them
|
||||
* to the REST API.
|
||||
*/
|
||||
$sections = $this->page->get_sections();
|
||||
if ( empty( $sections ) ) {
|
||||
// Default section is just an empty string, per admin page classes
|
||||
$sections = array( '' );
|
||||
}
|
||||
|
||||
foreach ( $sections as $section => $section_label ) {
|
||||
$settings_from_section = $this->page->get_settings( $section );
|
||||
foreach ( $settings_from_section as $setting ) {
|
||||
$new_setting = $this->register_setting( $setting );
|
||||
if ( $new_setting ) {
|
||||
$settings[] = $new_setting;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register's a specific setting (from WC_Settings_Page::get_settings() )
|
||||
* into the format expected for the REST API Settings Controller.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param array $setting Settings array, as produced by a subclass of WC_Settings_Page.
|
||||
* @return array|bool boolean False if setting has no ID or converted array.
|
||||
*/
|
||||
public function register_setting( $setting ) {
|
||||
if ( ! isset( $setting['id'] ) ) {
|
||||
return false;
|
||||
}
|
||||
$new_setting = array(
|
||||
'id' => $setting['id'],
|
||||
'label' => ( ! empty( $setting['title'] ) ? $setting['title'] : '' ),
|
||||
'description' => ( ! empty( $setting['desc'] ) ? $setting['desc'] : '' ),
|
||||
'type' => $setting['type'],
|
||||
);
|
||||
if ( isset( $setting['default'] ) ) {
|
||||
$new_setting['default'] = $setting['default'];
|
||||
}
|
||||
if ( isset( $setting['options'] ) ) {
|
||||
$new_setting['options'] = $setting['options'];
|
||||
}
|
||||
if ( isset( $setting['desc_tip'] ) ) {
|
||||
if ( true === $setting['desc_tip'] ) {
|
||||
$new_setting['tip'] = $setting['desc'];
|
||||
} else if ( ! empty( $setting['desc_tip'] ) ) {
|
||||
$new_setting['tip'] = $setting['desc_tip'];
|
||||
}
|
||||
}
|
||||
|
||||
return $new_setting;
|
||||
}
|
||||
}
|
|
@ -114,6 +114,7 @@ class WC_Unit_Tests_Bootstrap {
|
|||
require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-order.php' );
|
||||
require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-shipping-zones.php' );
|
||||
require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-payment-token.php' );
|
||||
require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-settings.php' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Class WC_Helper_Settings.
|
||||
*
|
||||
* This helper class should ONLY be used for unit tests!
|
||||
*/
|
||||
class WC_Helper_Settings {
|
||||
|
||||
/**
|
||||
* Hooks in some dummy data for testing the settings REST API.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public static function register() {
|
||||
add_filter( 'woocommerce_settings_groups', array( 'WC_Helper_Settings', 'register_groups' ) );
|
||||
add_filter( 'woocommerce_settings-test', array( 'WC_Helper_Settings', 'register_test_settings' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers some example setting groups, including invalid ones that should not show up in JSON responses.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param array $groups
|
||||
* @return array
|
||||
*/
|
||||
public static function register_groups( $groups ) {
|
||||
$groups[] = array(
|
||||
'id' => 'test',
|
||||
'bad' => 'value',
|
||||
'label' => __( 'Test Extension', 'woocommerce' ),
|
||||
'description' => __( 'My awesome test settings.', 'woocommerce' ),
|
||||
);
|
||||
$groups[] = array(
|
||||
'id' => 'sub-test',
|
||||
'parent_id' => 'test',
|
||||
'label' => __( 'Sub test', 'woocommerce' ),
|
||||
'description' => '',
|
||||
);
|
||||
$groups[] = array(
|
||||
'id' => 'coupon-data',
|
||||
'label' => __( 'Coupon Data', 'woocommerce' ),
|
||||
);
|
||||
$groups[] = array(
|
||||
'id' => 'invalid',
|
||||
);
|
||||
return $groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers some example settings.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @param array $settings
|
||||
* @return array
|
||||
*/
|
||||
public static function register_test_settings( $settings ) {
|
||||
$settings[] = array(
|
||||
'id' => 'woocommerce_shop_page_display',
|
||||
'label' => __( 'Shop Page Display', 'woocommerce' ),
|
||||
'description' => __( 'This controls what is shown on the product archive.', 'woocommerce' ),
|
||||
'default' => '',
|
||||
'type' => 'select',
|
||||
'options' => array(
|
||||
'' => __( 'Show products', 'woocommerce' ),
|
||||
'subcategories' => __( 'Show categories & subcategories', 'woocommerce' ),
|
||||
'both' => __( 'Show both', 'woocommerce' ),
|
||||
),
|
||||
);
|
||||
$settings[] = array(
|
||||
'id' => 'woocommerce_enable_lightbox',
|
||||
'label' => __( 'Product Image Gallery', 'woocommerce' ),
|
||||
'description' => __( 'Enable Lightbox for product images', 'woocommerce' ),
|
||||
'default' => 'yes',
|
||||
'tip' => __( 'Product gallery images will open in a lightbox.', 'woocommerce' ),
|
||||
'type' => 'checkbox',
|
||||
);
|
||||
return $settings;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,541 @@
|
|||
<?php
|
||||
/**
|
||||
* Settings API Tests.
|
||||
*
|
||||
* @package WooCommerce\Tests\API
|
||||
* @since 2.7.0
|
||||
*/
|
||||
|
||||
class Settings extends WC_REST_Unit_Test_Case {
|
||||
|
||||
protected $server;
|
||||
|
||||
/**
|
||||
* Setup our test server, endpoints, and user info.
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
$this->endpoint = new WC_Rest_Settings_Options_Controller();
|
||||
WC_Helper_Settings::register();
|
||||
$this->user = $this->factory->user->create( array(
|
||||
'role' => 'administrator',
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test route registration.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_register_routes() {
|
||||
$routes = $this->server->get_routes();
|
||||
$this->assertArrayHasKey( '/wc/v1/settings', $routes );
|
||||
$this->assertArrayHasKey( '/wc/v1/settings/(?P<group>[\w-]+)', $routes );
|
||||
$this->assertArrayHasKey( '/wc/v1/settings/(?P<group>[\w-]+)/(?P<id>[\w-]+)', $routes );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getting all groups.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_get_groups() {
|
||||
wp_set_current_user( $this->user );
|
||||
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings' ) );
|
||||
$data = $response->get_data();
|
||||
|
||||
$this->assertEquals( 200, $response->get_status() );
|
||||
|
||||
$this->assertContains( array(
|
||||
'id' => 'test',
|
||||
'label' => 'Test Extension',
|
||||
'parent_id' => '',
|
||||
'description' => 'My awesome test settings.',
|
||||
'sub_groups' => array( 'sub-test' ),
|
||||
'_links' => array(
|
||||
'item' => array(
|
||||
array(
|
||||
'href' => rest_url( '/wc/v1/settings/test' ),
|
||||
'embeddable' => true,
|
||||
),
|
||||
),
|
||||
),
|
||||
), $data );
|
||||
|
||||
$this->assertContains( array(
|
||||
'id' => 'sub-test',
|
||||
'label' => 'Sub test',
|
||||
'parent_id' => 'test',
|
||||
'description' => '',
|
||||
'sub_groups' => array(),
|
||||
'_links' => array(
|
||||
'item' => array(
|
||||
array(
|
||||
'href' => rest_url( '/wc/v1/settings/sub-test' ),
|
||||
'embeddable' => true,
|
||||
),
|
||||
),
|
||||
),
|
||||
), $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test /settings without valid permissions/creds.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_get_groups_without_permission() {
|
||||
wp_set_current_user( 0 );
|
||||
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings' ) );
|
||||
$this->assertEquals( 401, $response->get_status() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test /settings without valid permissions/creds.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @covers WC_Rest_Settings_Controller::get_items
|
||||
*/
|
||||
public function test_get_groups_none_registered() {
|
||||
wp_set_current_user( $this->user );
|
||||
|
||||
remove_all_filters( 'woocommerce_settings_groups' );
|
||||
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings' ) );
|
||||
$this->assertEquals( 500, $response->get_status() );
|
||||
|
||||
WC_Helper_Settings::register();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test groups schema.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_get_group_schema() {
|
||||
$request = new WP_REST_Request( 'OPTIONS', '/wc/v1/settings' );
|
||||
$response = $this->server->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
$properties = $data['schema']['properties'];
|
||||
$this->assertEquals( 5, count( $properties ) );
|
||||
$this->assertArrayHasKey( 'id', $properties );
|
||||
$this->assertArrayHasKey( 'parent_id', $properties );
|
||||
$this->assertArrayHasKey( 'label', $properties );
|
||||
$this->assertArrayHasKey( 'description', $properties );
|
||||
$this->assertArrayHasKey( 'sub_groups', $properties );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test settings schema.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_get_setting_schema() {
|
||||
$request = new WP_REST_Request( 'OPTIONS', '/wc/v1/settings/test/woocommerce_shop_page_display' );
|
||||
$response = $this->server->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
$properties = $data['schema']['properties'];
|
||||
$this->assertEquals( 8, count( $properties ) );
|
||||
$this->assertArrayHasKey( 'id', $properties );
|
||||
$this->assertArrayHasKey( 'label', $properties );
|
||||
$this->assertArrayHasKey( 'description', $properties );
|
||||
$this->assertArrayHasKey( 'default', $properties );
|
||||
$this->assertArrayHasKey( 'tip', $properties );
|
||||
$this->assertArrayHasKey( 'placeholder', $properties );
|
||||
$this->assertArrayHasKey( 'type', $properties );
|
||||
$this->assertArrayHasKey( 'options', $properties );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getting a single group.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_get_group() {
|
||||
wp_set_current_user( $this->user );
|
||||
|
||||
// test route callback receiving an empty group id
|
||||
$result = $this->endpoint->get_group_settings( '' );
|
||||
$this->assertIsWPError( $result );
|
||||
|
||||
// test getting a group that does not exist
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/not-real' ) );
|
||||
$this->assertEquals( 404, $response->get_status() );
|
||||
|
||||
// test getting the 'invalid' group
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/invalid' ) );
|
||||
$this->assertEquals( 404, $response->get_status() );
|
||||
|
||||
// test getting a valid group
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/general' ) );
|
||||
$data = $response->get_data();
|
||||
|
||||
$this->assertEquals( 200, $response->get_status() );
|
||||
$this->assertContains( array(
|
||||
'id' => 'woocommerce_demo_store',
|
||||
'label' => 'Store Notice',
|
||||
'description' => 'Enable site-wide store notice text',
|
||||
'type' => 'checkbox',
|
||||
'default' => 'no',
|
||||
'value' => 'no',
|
||||
'_links' => array(
|
||||
'self' => array(
|
||||
array(
|
||||
'href' => rest_url( '/wc/v1/settings/general/woocommerce_demo_store' ),
|
||||
),
|
||||
),
|
||||
'collection' => array(
|
||||
array(
|
||||
'href' => rest_url( '/wc/v1/settings/general' ),
|
||||
),
|
||||
),
|
||||
)
|
||||
), $data );
|
||||
|
||||
// test getting a valid group with settings attached to it
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/test' ) );
|
||||
$data = $response->get_data();
|
||||
$this->assertEquals( 2, count( $data ) );
|
||||
$this->assertEquals( 'woocommerce_shop_page_display', $data[0]['id'] );
|
||||
$this->assertEmpty( $data[0]['value'] );
|
||||
$this->assertEquals( 'woocommerce_enable_lightbox', $data[1]['id'] );
|
||||
$this->assertEquals( 'yes', $data[1]['value'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getting a single group without permission.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_get_group_without_permission() {
|
||||
wp_set_current_user( 0 );
|
||||
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/coupon-data' ) );
|
||||
$this->assertEquals( 401, $response->get_status() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test updating a single setting.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_update_setting() {
|
||||
wp_set_current_user( $this->user );
|
||||
|
||||
// test defaults first
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_shop_page_display' ) );
|
||||
$data = $response->get_data();
|
||||
$this->assertEquals( '', $data['value'] );
|
||||
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_enable_lightbox' ) );
|
||||
$data = $response->get_data();
|
||||
$this->assertEquals( 'yes', $data['value'] );
|
||||
|
||||
// test updating shop display setting
|
||||
$request = new WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) );
|
||||
$request->set_body_params( array(
|
||||
'value' => 'both',
|
||||
) );
|
||||
$response = $this->server->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
|
||||
$this->assertEquals( 'both', $data['value'] );
|
||||
$this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) );
|
||||
|
||||
$request = new WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) );
|
||||
$request->set_body_params( array(
|
||||
'value' => 'subcategories',
|
||||
) );
|
||||
$response = $this->server->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
|
||||
$this->assertEquals( 'subcategories', $data['value'] );
|
||||
$this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) );
|
||||
|
||||
$request = new WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) );
|
||||
$request->set_body_params( array(
|
||||
'value' => '',
|
||||
) );
|
||||
$response = $this->server->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
|
||||
$this->assertEquals( '', $data['value'] );
|
||||
$this->assertEquals( '', get_option( 'woocommerce_shop_page_display' ) );
|
||||
|
||||
// test updating ligtbox
|
||||
$request = new WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_enable_lightbox' ) );
|
||||
$request->set_body_params( array(
|
||||
'value' => 'no',
|
||||
) );
|
||||
$response = $this->server->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
|
||||
$this->assertEquals( 'no', $data['value'] );
|
||||
$this->assertEquals( 'no', get_option( 'woocommerce_enable_lightbox' ) );
|
||||
|
||||
$request = new WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_enable_lightbox' ) );
|
||||
$request->set_body_params( array(
|
||||
'value' => 'yes',
|
||||
) );
|
||||
$response = $this->server->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
|
||||
$this->assertEquals( 'yes', $data['value'] );
|
||||
$this->assertEquals( 'yes', get_option( 'woocommerce_enable_lightbox' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test updating multiple settings at once.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_update_settings() {
|
||||
wp_set_current_user( $this->user );
|
||||
|
||||
// test defaults first
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/test' ) );
|
||||
$data = $response->get_data();
|
||||
$this->assertEquals( '', $data[0]['value'] );
|
||||
$this->assertEquals( 'yes', $data[1]['value'] );
|
||||
|
||||
// test setting both at once
|
||||
$request = new WP_REST_Request( 'POST', '/wc/v1/settings/test/batch' );
|
||||
$request->set_body_params( array(
|
||||
'update' => array(
|
||||
array(
|
||||
'id' => 'woocommerce_shop_page_display',
|
||||
'value' => 'both',
|
||||
),
|
||||
array(
|
||||
'id' => 'woocommerce_enable_lightbox',
|
||||
'value' => 'no',
|
||||
),
|
||||
),
|
||||
) );
|
||||
$response = $this->server->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
$this->assertEquals( 'both', $data['update'][0]['value'] );
|
||||
$this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) );
|
||||
$this->assertEquals( 'no', $data['update'][1]['value'] );
|
||||
$this->assertEquals( 'no', get_option( 'woocommerce_enable_lightbox' ) );
|
||||
|
||||
// test updating one, but making sure the other value stays the same
|
||||
$request = new WP_REST_Request( 'POST', '/wc/v1/settings/test/batch' );
|
||||
$request->set_body_params( array(
|
||||
'update' => array(
|
||||
array(
|
||||
'id' => 'woocommerce_shop_page_display',
|
||||
'value' => 'subcategories',
|
||||
),
|
||||
),
|
||||
) );
|
||||
$response = $this->server->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
$this->assertEquals( 'subcategories', $data['update'][0]['value'] );
|
||||
$this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) );
|
||||
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/test' ) );
|
||||
$data = $response->get_data();
|
||||
$this->assertEquals( 'no', $data[1]['value'] );
|
||||
$this->assertEquals( 'no', get_option( 'woocommerce_enable_lightbox' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getting a single setting.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_get_setting() {
|
||||
wp_set_current_user( $this->user );
|
||||
|
||||
// test getting an invalid setting from a group that does not exist
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/not-real/woocommerce_enable_lightbox' ) );
|
||||
$data = $response->get_data();
|
||||
$this->assertEquals( 404, $response->get_status() );
|
||||
|
||||
// test getting an invalid setting from a group that does exist
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/invalid/invalid' ) );
|
||||
$data = $response->get_data();
|
||||
$this->assertEquals( 404, $response->get_status() );
|
||||
|
||||
// test getting a valid setting
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_enable_lightbox' ) );
|
||||
$data = $response->get_data();
|
||||
|
||||
$this->assertEquals( 200, $response->get_status() );
|
||||
|
||||
$this->assertEquals( 'woocommerce_enable_lightbox', $data['id'] );
|
||||
$this->assertEquals( 'Product Image Gallery', $data['label'] );
|
||||
$this->assertEquals( 'yes', $data['default'] );
|
||||
$this->assertEquals( 'Product gallery images will open in a lightbox.', $data['tip'] );
|
||||
$this->assertEquals( 'checkbox', $data['type'] );
|
||||
$this->assertEquals( 'yes', $data['value'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getting a single setting without valid user permissions.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_get_setting_without_permission() {
|
||||
wp_set_current_user( 0 );
|
||||
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_enable_lightbox' ) );
|
||||
$this->assertEquals( 401, $response->get_status() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the GET single setting route handler receiving an empty setting ID.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_get_setting_empty_setting_id() {
|
||||
$result = $this->endpoint->get_setting( 'test', '' );
|
||||
|
||||
$this->assertIsWPError( $result );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the GET single setting route handler receiving an invalid setting ID.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_get_setting_invalid_setting_id() {
|
||||
$result = $this->endpoint->get_setting( 'test', 'invalid' );
|
||||
|
||||
$this->assertIsWPError( $result );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the GET single setting route handler encountering an invalid setting type.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_get_setting_invalid_setting_type() {
|
||||
$controller = $this->getMock( 'WC_Rest_Settings_Options_Controller', array( 'get_group_settings', 'is_setting_type_valid' ) );
|
||||
|
||||
$controller
|
||||
->expects( $this->any() )
|
||||
->method( 'get_group_settings' )
|
||||
->will( $this->returnValue( WC_Helper_Settings::register_test_settings( array() ) ) );
|
||||
|
||||
$controller
|
||||
->expects( $this->any() )
|
||||
->method( 'is_setting_type_valid' )
|
||||
->will( $this->returnValue( false ) );
|
||||
|
||||
$result = $controller->get_setting( 'test', 'woocommerce_enable_lightbox' );
|
||||
|
||||
$this->assertIsWPError( $result );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test updating a single setting without valid user permissions.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_update_setting_without_permission() {
|
||||
wp_set_current_user( 0 );
|
||||
|
||||
$request = new WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_enable_lightbox' ) );
|
||||
$request->set_body_params( array(
|
||||
'value' => 'yes',
|
||||
) );
|
||||
$response = $this->server->dispatch( $request );
|
||||
$this->assertEquals( 401, $response->get_status() );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test updating multiple settings without valid user permissions.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_update_settings_without_permission() {
|
||||
wp_set_current_user( 0 );
|
||||
|
||||
$request = new WP_REST_Request( 'POST', '/wc/v1/settings/test/batch' );
|
||||
$request->set_body_params( array(
|
||||
'update' => array(
|
||||
array(
|
||||
'id' => 'woocommerce_shop_page_display',
|
||||
'value' => 'subcategories',
|
||||
),
|
||||
),
|
||||
) );
|
||||
$response = $this->server->dispatch( $request );
|
||||
$this->assertEquals( 401, $response->get_status() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test updating a bad setting ID.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @covers WC_Rest_Settings_Options_Controller::update_item
|
||||
*/
|
||||
public function test_update_setting_bad_setting_id() {
|
||||
wp_set_current_user( $this->user );
|
||||
|
||||
$request = new WP_REST_Request( 'PUT', '/wc/v1/settings/test/invalid' );
|
||||
$request->set_body_params( array(
|
||||
'value' => 'test',
|
||||
) );
|
||||
$response = $this->server->dispatch( $request );
|
||||
$this->assertEquals( 404, $response->get_status() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests our classic setting registration to make sure settings added for WP-Admin are available over the API.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_classic_settings() {
|
||||
wp_set_current_user( $this->user );
|
||||
|
||||
// Make sure the group is properly registered
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/products' ) );
|
||||
$data = $response->get_data();
|
||||
$this->assertTrue( is_array( $data ) );
|
||||
$this->assertContains( array(
|
||||
'id' => 'woocommerce_downloads_require_login',
|
||||
'label' => 'Access Restriction',
|
||||
'description' => 'Downloads require login',
|
||||
'type' => 'checkbox',
|
||||
'default' => 'no',
|
||||
'tip' => 'This setting does not apply to guest purchases.',
|
||||
'value' => 'no',
|
||||
'_links' => array(
|
||||
'self' => array(
|
||||
array(
|
||||
'href' => rest_url( '/wc/v1/settings/products/woocommerce_downloads_require_login' ),
|
||||
),
|
||||
),
|
||||
'collection' => array(
|
||||
array(
|
||||
'href' => rest_url( '/wc/v1/settings/products' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
), $data );
|
||||
|
||||
// test get single
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/products/woocommerce_dimension_unit' ) );
|
||||
$data = $response->get_data();
|
||||
|
||||
$this->assertEquals( 'cm', $data['default'] );
|
||||
|
||||
// test update
|
||||
$request = new WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'products', 'woocommerce_dimension_unit' ) );
|
||||
$request->set_body_params( array(
|
||||
'value' => 'yd',
|
||||
) );
|
||||
$response = $this->server->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
|
||||
$this->assertEquals( 'yd', $data['value'] );
|
||||
$this->assertEquals( 'yd', get_option(' woocommerce_dimension_unit' ) );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,241 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Settings API: WP-Admin Helper Tests
|
||||
* Tests the helper class that makes settings (currently present in wp-admin)
|
||||
* avaiable to the REST API.
|
||||
*
|
||||
* @package WooCommerce\Tests\Settings
|
||||
* @since 2.7.0
|
||||
*/
|
||||
class WC_Tests_Register_WP_Admin_Settings extends WC_Unit_Test_Case {
|
||||
|
||||
/**
|
||||
* @var WC_Settings_Page $page
|
||||
*/
|
||||
protected $page;
|
||||
|
||||
/**
|
||||
* Initialize a WC_Settings_Page for testing
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$mock_page = $this->getMock( 'WC_Settings_General' );
|
||||
|
||||
$mock_page
|
||||
->expects( $this->any() )
|
||||
->method( 'get_id' )
|
||||
->will( $this->returnValue( 'page-id' ) );
|
||||
|
||||
$mock_page
|
||||
->expects( $this->any() )
|
||||
->method( 'get_label' )
|
||||
->will( $this->returnValue( 'Page Label' ) );
|
||||
|
||||
$this->page = $mock_page;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.7.0
|
||||
* @covers WC_Register_WP_Admin_Settings::__construct
|
||||
*/
|
||||
public function test_constructor() {
|
||||
$settings = new WC_Register_WP_Admin_Settings( $this->page );
|
||||
|
||||
$this->assertEquals( has_filter( 'woocommerce_settings_groups', array( $settings, 'register_group' ) ), 10 );
|
||||
$this->assertEquals( has_filter( 'woocommerce_settings-' . $this->page->get_id(), array( $settings, 'register_settings' ) ), 10 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.7.0
|
||||
* @covers WC_Register_WP_Admin_Settings::register_group
|
||||
*/
|
||||
public function test_register_group() {
|
||||
$settings = new WC_Register_WP_Admin_Settings( $this->page );
|
||||
|
||||
$existing = array(
|
||||
'id' => 'existing-id',
|
||||
'label' => 'Existing Group',
|
||||
);
|
||||
$initial = array( $existing );
|
||||
$expected = array(
|
||||
$existing,
|
||||
array(
|
||||
'id' => $this->page->get_id(),
|
||||
'label' => $this->page->get_label(),
|
||||
),
|
||||
);
|
||||
$actual = $settings->register_group( $initial );
|
||||
|
||||
$this->assertEquals( $expected, $actual );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function register_setting_provider() {
|
||||
return array(
|
||||
// No "id" case
|
||||
array(
|
||||
array(
|
||||
'type' => 'some-type-with-no-id',
|
||||
),
|
||||
false,
|
||||
),
|
||||
// All optional properties except 'desc_tip'
|
||||
array(
|
||||
array(
|
||||
'id' => 'setting-id',
|
||||
'type' => 'select',
|
||||
'title' => 'Setting Name',
|
||||
'desc' => 'Setting Description',
|
||||
'default' => 'one',
|
||||
'options' => array( 'one', 'two' ),
|
||||
),
|
||||
array(
|
||||
'id' => 'setting-id',
|
||||
'type' => 'select',
|
||||
'label' => 'Setting Name',
|
||||
'description' => 'Setting Description',
|
||||
'default' => 'one',
|
||||
'options' => array( 'one', 'two' ),
|
||||
),
|
||||
),
|
||||
// Boolean 'desc_tip' defaulting to 'desc' value
|
||||
array(
|
||||
array(
|
||||
'id' => 'setting-id',
|
||||
'type' => 'select',
|
||||
'title' => 'Setting Name',
|
||||
'desc' => 'Setting Description',
|
||||
'desc_tip' => true,
|
||||
),
|
||||
array(
|
||||
'id' => 'setting-id',
|
||||
'type' => 'select',
|
||||
'label' => 'Setting Name',
|
||||
'description' => 'Setting Description',
|
||||
'tip' => 'Setting Description',
|
||||
),
|
||||
),
|
||||
// String 'desc_tip'
|
||||
array(
|
||||
array(
|
||||
'id' => 'setting-id',
|
||||
'type' => 'select',
|
||||
'title' => 'Setting Name',
|
||||
'desc' => 'Setting Description',
|
||||
'desc_tip' => 'Setting Tip',
|
||||
),
|
||||
array(
|
||||
'id' => 'setting-id',
|
||||
'type' => 'select',
|
||||
'label' => 'Setting Name',
|
||||
'description' => 'Setting Description',
|
||||
'tip' => 'Setting Tip',
|
||||
),
|
||||
),
|
||||
// Empty 'title' and 'desc'
|
||||
array(
|
||||
array(
|
||||
'id' => 'setting-id',
|
||||
'type' => 'select',
|
||||
),
|
||||
array(
|
||||
'id' => 'setting-id',
|
||||
'type' => 'select',
|
||||
'label' => '',
|
||||
'description' => '',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.7.0
|
||||
* @dataProvider register_setting_provider
|
||||
* @covers WC_Register_WP_Admin_Settings::register_setting
|
||||
*/
|
||||
public function test_register_setting( $input, $expected ) {
|
||||
$settings = new WC_Register_WP_Admin_Settings( $this->page );
|
||||
|
||||
$actual = $settings->register_setting( $input );
|
||||
|
||||
$this->assertEquals( $expected, $actual );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.7.0
|
||||
* @covers WC_Register_WP_Admin_Settings::register_settings
|
||||
*/
|
||||
public function test_register_settings_one_section() {
|
||||
$this->page
|
||||
->expects( $this->any() )
|
||||
->method( 'get_sections' )
|
||||
->will( $this->returnValue( array() ) );
|
||||
|
||||
$this->page
|
||||
->expects( $this->once() )
|
||||
->method( 'get_settings' )
|
||||
->with( $this->equalTo( 0 ) )
|
||||
->will( $this->returnValue( array() ) );
|
||||
|
||||
$settings = new WC_Register_WP_Admin_Settings( $this->page );
|
||||
|
||||
$expected = array();
|
||||
$actual = $settings->register_settings( array() );
|
||||
|
||||
$this->assertEquals( $expected, $actual );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.7.0
|
||||
* @covers WC_Register_WP_Admin_Settings::register_settings
|
||||
*/
|
||||
public function test_register_settings() {
|
||||
$this->page
|
||||
->expects( $this->any() )
|
||||
->method( 'get_sections' )
|
||||
->will( $this->returnValue( array() ) );
|
||||
|
||||
$settings = array(
|
||||
array(
|
||||
'id' => 'setting-1',
|
||||
'type' => 'text',
|
||||
),
|
||||
array(
|
||||
'type' => 'no-id',
|
||||
),
|
||||
array(
|
||||
'id' => 'setting-2',
|
||||
'type' => 'textarea',
|
||||
),
|
||||
);
|
||||
|
||||
$this->page
|
||||
->expects( $this->any() )
|
||||
->method( 'get_settings' )
|
||||
->will( $this->returnValue( $settings ) );
|
||||
|
||||
$settings = new WC_Register_WP_Admin_Settings( $this->page );
|
||||
|
||||
$expected = array(
|
||||
array(
|
||||
'id' => 'setting-1',
|
||||
'type' => 'text',
|
||||
'label' => '',
|
||||
'description' => '',
|
||||
),
|
||||
array(
|
||||
'id' => 'setting-2',
|
||||
'type' => 'textarea',
|
||||
'label' => '',
|
||||
'description' => '',
|
||||
),
|
||||
);
|
||||
$actual = $settings->register_settings( array() );
|
||||
|
||||
$this->assertEquals( $expected, $actual );
|
||||
}
|
||||
}
|
|
@ -226,6 +226,7 @@ final class WooCommerce {
|
|||
public function includes() {
|
||||
include_once( 'includes/class-wc-autoloader.php' );
|
||||
include_once( 'includes/wc-core-functions.php' );
|
||||
include_once( 'includes/class-wc-register-wp-admin-settings.php' );
|
||||
include_once( 'includes/wc-widget-functions.php' );
|
||||
include_once( 'includes/wc-webhook-functions.php' );
|
||||
include_once( 'includes/class-wc-install.php' );
|
||||
|
|
Loading…
Reference in New Issue