Skip to content
This repository was archived by the owner on Oct 4, 2019. It is now read-only.

Commit a5d37f9

Browse files
author
Justin Shreve
authored
Add a settings bulk update for updating settings in multiple groups. (#14)
1 parent 218cf54 commit a5d37f9

File tree

4 files changed

+212
-8
lines changed

4 files changed

+212
-8
lines changed

api/class-wc-rest-dev-setting-options-controller.php

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,140 @@ class WC_REST_Dev_Setting_Options_Controller extends WC_REST_Setting_Options_Con
7777
*/
7878
protected $namespace = 'wc/v3';
7979

80+
/**
81+
* Get setting data.
82+
*
83+
* @param string $group_id Group ID.
84+
* @param string $setting_id Setting ID.
85+
* @return stdClass|WP_Error
86+
*/
87+
public function get_setting( $group_id, $setting_id ) {
88+
$setting = parent::get_setting( $group_id, $setting_id );
89+
if ( is_wp_error( $setting ) ) {
90+
return $setting;
91+
}
92+
$setting['group_id'] = $group_id;
93+
return $setting;
94+
}
95+
96+
/**
97+
* Callback for allowed keys for each setting response.
98+
*
99+
* @param string $key Key to check
100+
* @return boolean
101+
*/
102+
public function allowed_setting_keys( $key ) {
103+
return in_array( $key, array(
104+
'id',
105+
'group_id',
106+
'label',
107+
'description',
108+
'default',
109+
'tip',
110+
'placeholder',
111+
'type',
112+
'options',
113+
'value',
114+
'option_key',
115+
) );
116+
}
117+
118+
/**
119+
* Get the settings schema, conforming to JSON Schema.
120+
*
121+
* @return array
122+
*/
123+
public function get_item_schema() {
124+
$schema = array(
125+
'$schema' => 'http://json-schema.org/draft-04/schema#',
126+
'title' => 'setting',
127+
'type' => 'object',
128+
'properties' => array(
129+
'id' => array(
130+
'description' => __( 'A unique identifier for the setting.', 'woocommerce' ),
131+
'type' => 'string',
132+
'arg_options' => array(
133+
'sanitize_callback' => 'sanitize_title',
134+
),
135+
'context' => array( 'view', 'edit' ),
136+
'readonly' => true,
137+
),
138+
'group_id' => array(
139+
'description' => __( 'An identifier for the group this setting belongs to.', 'woocommerce' ),
140+
'type' => 'string',
141+
'arg_options' => array(
142+
'sanitize_callback' => 'sanitize_title',
143+
),
144+
'context' => array( 'view', 'edit' ),
145+
'readonly' => true,
146+
),
147+
'label' => array(
148+
'description' => __( 'A human readable label for the setting used in interfaces.', 'woocommerce' ),
149+
'type' => 'string',
150+
'arg_options' => array(
151+
'sanitize_callback' => 'sanitize_text_field',
152+
),
153+
'context' => array( 'view', 'edit' ),
154+
'readonly' => true,
155+
),
156+
'description' => array(
157+
'description' => __( 'A human readable description for the setting used in interfaces.', 'woocommerce' ),
158+
'type' => 'string',
159+
'arg_options' => array(
160+
'sanitize_callback' => 'sanitize_text_field',
161+
),
162+
'context' => array( 'view', 'edit' ),
163+
'readonly' => true,
164+
),
165+
'value' => array(
166+
'description' => __( 'Setting value.', 'woocommerce' ),
167+
'type' => 'mixed',
168+
'context' => array( 'view', 'edit' ),
169+
),
170+
'default' => array(
171+
'description' => __( 'Default value for the setting.', 'woocommerce' ),
172+
'type' => 'mixed',
173+
'context' => array( 'view', 'edit' ),
174+
'readonly' => true,
175+
),
176+
'tip' => array(
177+
'description' => __( 'Additional help text shown to the user about the setting.', 'woocommerce' ),
178+
'type' => 'string',
179+
'arg_options' => array(
180+
'sanitize_callback' => 'sanitize_text_field',
181+
),
182+
'context' => array( 'view', 'edit' ),
183+
'readonly' => true,
184+
),
185+
'placeholder' => array(
186+
'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ),
187+
'type' => 'string',
188+
'arg_options' => array(
189+
'sanitize_callback' => 'sanitize_text_field',
190+
),
191+
'context' => array( 'view', 'edit' ),
192+
'readonly' => true,
193+
),
194+
'type' => array(
195+
'description' => __( 'Type of setting.', 'woocommerce' ),
196+
'type' => 'string',
197+
'arg_options' => array(
198+
'sanitize_callback' => 'sanitize_text_field',
199+
),
200+
'context' => array( 'view', 'edit' ),
201+
'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ),
202+
'readonly' => true,
203+
),
204+
'options' => array(
205+
'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce' ),
206+
'type' => 'object',
207+
'context' => array( 'view', 'edit' ),
208+
'readonly' => true,
209+
),
210+
),
211+
);
212+
213+
return $this->add_additional_fields_schema( $schema );
214+
}
215+
80216
}

api/class-wc-rest-dev-settings-controller.php

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44
*
55
* Handles requests to the /settings endpoints.
66
*
7-
* @author WooThemes
7+
* @author Automattic
88
* @category API
99
* @package WooCommerce/API
10-
* @since 3.0.0
1110
*/
1211

1312
if ( ! defined( 'ABSPATH' ) ) {
@@ -26,4 +25,46 @@ class WC_REST_Dev_Settings_Controller extends WC_REST_Settings_Controller {
2625
*/
2726
protected $namespace = 'wc/v3';
2827

28+
/**
29+
* Register routes.
30+
*
31+
*/
32+
public function register_routes() {
33+
parent::register_routes();
34+
register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array(
35+
array(
36+
'methods' => WP_REST_Server::EDITABLE,
37+
'callback' => array( $this, 'batch_items' ),
38+
'permission_callback' => array( $this, 'update_items_permissions_check' ),
39+
),
40+
'schema' => array( $this, 'get_public_batch_schema' ),
41+
) );
42+
}
43+
44+
/**
45+
* Makes sure the current user has access to WRITE the settings APIs.
46+
*
47+
* @param WP_REST_Request $request Full data about the request.
48+
* @return WP_Error|boolean
49+
*/
50+
public function update_items_permissions_check( $request ) {
51+
if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) {
52+
return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
53+
}
54+
55+
return true;
56+
}
57+
58+
/**
59+
* Update a setting.
60+
*
61+
* @param WP_REST_Request $request
62+
* @return WP_Error|WP_REST_Response
63+
*/
64+
public function update_item( $request ) {
65+
$options_controller = new WC_REST_Dev_Setting_Options_Controller;
66+
$response = $options_controller->update_item( $request );
67+
return $response;
68+
}
69+
2970
}

tests/unit-tests/functions.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public function test_wc_rest_validate_reports_request_arg() {
6464
* @since 2.6.0
6565
*/
6666
public function test_wc_rest_urlencode_rfc3986() {
67-
$this->assertEquals( 'https%253A%252F%252Fwoocommerce.com%252F', wc_rest_urlencode_rfc3986( 'https://woocommerce.com/' ) );
67+
$this->assertEquals( 'https%3A%2F%2Fwoocommerce.com%2F', wc_rest_urlencode_rfc3986( 'https://woocommerce.com/' ) );
6868
}
6969

7070
/**

tests/unit-tests/settings.php

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ public function setUp() {
2828
public function test_register_routes() {
2929
$routes = $this->server->get_routes();
3030
$this->assertArrayHasKey( '/wc/v3/settings', $routes );
31+
$this->assertArrayHasKey( '/wc/v3/settings/batch', $routes );
3132
$this->assertArrayHasKey( '/wc/v3/settings/(?P<group_id>[\w-]+)', $routes );
33+
$this->assertArrayHasKey( '/wc/v3/settings/(?P<group_id>[\w-]+)/batch', $routes );
3234
$this->assertArrayHasKey( '/wc/v3/settings/(?P<group_id>[\w-]+)/(?P<id>[\w-]+)', $routes );
3335
}
3436

@@ -133,8 +135,9 @@ public function test_get_setting_schema() {
133135
$response = $this->server->dispatch( $request );
134136
$data = $response->get_data();
135137
$properties = $data['schema']['properties'];
136-
$this->assertEquals( 9, count( $properties ) );
138+
$this->assertEquals( 10, count( $properties ) );
137139
$this->assertArrayHasKey( 'id', $properties );
140+
$this->assertArrayHasKey( 'group_id', $properties );
138141
$this->assertArrayHasKey( 'label', $properties );
139142
$this->assertArrayHasKey( 'description', $properties );
140143
$this->assertArrayHasKey( 'value', $properties );
@@ -285,6 +288,28 @@ public function test_update_settings() {
285288
$this->assertEquals( 'both', $data['update'][0]['value'] );
286289
$this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) );
287290

291+
// test bulk settings batch endpoint
292+
$request = new WP_REST_Request( 'POST', '/wc/v3/settings/batch' );
293+
$request->set_body_params( array(
294+
'update' => array(
295+
array(
296+
'group_id' => 'test',
297+
'id' => 'woocommerce_shop_page_display',
298+
'value' => 'subcategories',
299+
),
300+
array(
301+
'group_id' => 'products',
302+
'id' => 'woocommerce_dimension_unit',
303+
'value' => 'yd',
304+
),
305+
),
306+
) );
307+
$response = $this->server->dispatch( $request );
308+
$data = $response->get_data();
309+
$this->assertEquals( 'subcategories', $data['update'][0]['value'] );
310+
$this->assertEquals( 'yd', $data['update'][1]['value'] );
311+
$this->assertEquals( 'yd', get_option( 'woocommerce_dimension_unit' ) );
312+
288313
// test updating one, but making sure the other value stays the same
289314
$request = new WP_REST_Request( 'POST', '/wc/v3/settings/test/batch' );
290315
$request->set_body_params( array(
@@ -539,11 +564,12 @@ public function test_email_settings() {
539564
$this->assertEquals( array(
540565
'id' => 'subject',
541566
'label' => 'Subject',
542-
'description' => 'This controls the email subject line. Leave blank to use the default subject: <code>[{site_title}] New customer order ({order_number}) - {order_date}</code>.',
567+
'description' => 'Available placeholders: <code>{site_title}, {order_date}, {order_number}</code>',
543568
'type' => 'text',
544569
'default' => '',
545-
'tip' => 'This controls the email subject line. Leave blank to use the default subject: <code>[{site_title}] New customer order ({order_number}) - {order_date}</code>.',
570+
'tip' => 'Available placeholders: <code>{site_title}, {order_date}, {order_number}</code>',
546571
'value' => '',
572+
'group_id' => 'email_new_order',
547573
), $setting );
548574

549575
// test update
@@ -557,11 +583,12 @@ public function test_email_settings() {
557583
$this->assertEquals( array(
558584
'id' => 'subject',
559585
'label' => 'Subject',
560-
'description' => 'This controls the email subject line. Leave blank to use the default subject: <code>[{site_title}] New customer order ({order_number}) - {order_date}</code>.',
586+
'description' => 'Available placeholders: <code>{site_title}, {order_date}, {order_number}</code>',
561587
'type' => 'text',
562588
'default' => '',
563-
'tip' => 'This controls the email subject line. Leave blank to use the default subject: <code>[{site_title}] New customer order ({order_number}) - {order_date}</code>.',
589+
'tip' => 'Available placeholders: <code>{site_title}, {order_date}, {order_number}</code>',
564590
'value' => 'This is my subject',
591+
'group_id' => 'email_new_order',
565592
), $setting );
566593

567594
// test updating another subject and making sure it works with a "similar" id

0 commit comments

Comments
 (0)