Completed
Push — master ( 4de8af...d756b9 )
by Mike
09:12
created

WC_REST_Settings_Controller::get_item_schema()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 46
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 32
nc 1
nop 0
dl 0
loc 46
rs 8.9411
c 0
b 0
f 0
1
<?php
2
if ( ! defined( 'ABSPATH' ) ) {
3
	exit;
4
}
5
6
/**
7
 * REST API Settings Groups Controller.
8
 * Handles requests to the /settings and /settings/<group> endpoints.
9
 *
10
 * @author   WooThemes
11
 * @category API
12
 * @package  WooCommerce/API
13
 * @version  2.7.0
14
 * @since    2.7.0
15
 */
16
class WC_REST_Settings_Controller extends WC_REST_Controller {
17
18
	/**
19
	 * WP REST API namespace/version.
20
	 */
21
	protected $namespace = 'wc/v1';
22
23
	/**
24
	 * Route base.
25
	 *
26
	 * @var string
27
	 */
28
	protected $rest_base = 'settings';
29
30
	/**
31
	 * Register routes.
32
	 *
33
	 * @since 2.7.0
34
	 */
35
	public function register_routes() {
36
		register_rest_route( $this->namespace, '/' . $this->rest_base, array(
37
			array(
38
				'methods'             => WP_REST_Server::READABLE,
39
				'callback'            => array( $this, 'get_items' ),
40
				'permission_callback' => array( $this, 'get_items_permissions_check' ),
41
			),
42
			'schema' => array( $this, 'get_public_item_schema' ),
43
		) );
44
	}
45
46
	/**
47
	 * Get all settings groups items.
48
	 *
49
	 * @since  2.7.0
50
	 * @param  WP_REST_Request $request
51
	 * @return WP_Error|WP_REST_Response
52
	 */
53
	public function get_items( $request ) {
54
		$groups = apply_filters( 'woocommerce_settings_groups', array() );
55
		if ( empty( $groups ) ) {
56
			return new WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce' ), array( 'status' => 500 ) );
57
		}
58
59
		$defaults        = $this->group_defaults();
60
		$filtered_groups = array();
61
		foreach ( $groups as $group ) {
62
			$sub_groups = array();
63
			foreach ( $groups as $_group ) {
64
				if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) {
65
					$sub_groups[] = $_group['id'];
66
				}
67
			}
68
			$group['sub_groups'] = $sub_groups;
69
70
			$group = wp_parse_args( $group, $defaults );
71
			if ( ! is_null( $group['id'] ) && ! is_null( $group['label'] ) ) {
72
				$group_obj  = $this->filter_group( $group );
73
				$group_data = $this->prepare_item_for_response( $group_obj, $request );
74
				$group_data = $this->prepare_response_for_collection( $group_data );
75
76
				$filtered_groups[] = $group_data;
77
			}
78
		}
79
80
		$response = rest_ensure_response( $filtered_groups );
81
		return $response;
82
	}
83
84
	/**
85
	 * Prepare links for the request.
86
	 *
87
	 * @param string $group_id Group ID.
88
	 * @return array Links for the given group.
89
	 */
90
	protected function prepare_links( $group_id ) {
91
		$base  = '/' . $this->namespace . '/' . $this->rest_base;
92
		$links = array(
93
			'item' => array(
94
				'href'       => rest_url( trailingslashit( $base ) . $group_id ),
95
				'embeddable' => true,
96
			),
97
		);
98
99
		return $links;
100
	}
101
102
	/**
103
	 * Prepare a report sales object for serialization.
104
	 *
105
	 * @since  2.7.0
106
	 * @param array $item Group object.
107
	 * @param WP_REST_Request $request Request object.
108
	 * @return WP_REST_Response $response Response data.
109
	 */
110
	public function prepare_item_for_response( $item, $request ) {
111
		$context = empty( $request['context'] ) ? 'view' : $request['context'];
112
		$data    = $this->add_additional_fields_to_object( $item, $request );
113
		$data    = $this->filter_response_by_context( $data, $context );
114
115
		$response = rest_ensure_response( $data );
116
117
		$response->add_links( $this->prepare_links( $item['id'] ) );
118
119
		return $response;
120
	}
121
122
	/**
123
	 * Filters out bad values from the groups array/filter so we
124
	 * only return known values via the API.
125
	 *
126
	 * @since 2.7.0
127
	 * @param  array $group
128
	 * @return array
129
	 */
130
	public function filter_group( $group ) {
131
		return array_intersect_key(
132
			$group,
133
			array_flip( array_filter( array_keys( $group ), array( $this, 'allowed_group_keys' ) ) )
134
		);
135
	}
136
137
	/**
138
	 * Callback for allowed keys for each group response.
139
	 *
140
	 * @since  2.7.0
141
	 * @param  string $key Key to check
142
	 * @return boolean
143
	 */
144
	public function allowed_group_keys( $key ) {
145
		return in_array( $key, array( 'id', 'label', 'description', 'parent_id', 'sub_groups' ) );
146
	}
147
148
	/**
149
	 * Returns default settings for groups. null means the field is required.
150
	 *
151
	 * @since  2.7.0
152
	 * @return array
153
	 */
154
	protected function group_defaults() {
155
		return array(
156
			'id'          => null,
157
			'label'       => null,
158
			'description' => '',
159
			'parent_id'   => '',
160
			'sub_groups'  => array(),
161
		);
162
	}
163
164
	/**
165
	 * Makes sure the current user has access to READ the settings APIs.
166
	 *
167
	 * @since  2.7.0
168
	 * @param WP_REST_Request $request Full data about the request.
169
	 * @return WP_Error|boolean
170
	 */
171 View Code Duplication
	public function get_items_permissions_check( $request ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
172
		if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) {
173
			return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
174
		}
175
176
		return true;
177
	}
178
179
	/**
180
	 * Get the groups schema, conforming to JSON Schema.
181
	 *
182
	 * @since  2.7.0
183
	 * @return array
184
	 */
185
	public function get_item_schema() {
186
		$schema = array(
187
			'$schema'              => 'http://json-schema.org/draft-04/schema#',
188
			'title'                => 'settings-group',
189
			'type'                 => 'object',
190
			'properties'           => array(
191
				'id'               => array(
192
					'description'  => __( 'A unique identifier that can be used to link settings together.', 'woocommerce' ),
193
					'type'         => 'string',
194
					'arg_options'  => array(
195
						'sanitize_callback' => 'sanitize_title',
196
					),
197
				),
198
				'label'            => array(
199
					'description'  => __( 'A human readable translation wrapped label. Meant to be used in interfaces.', 'woocommerce' ),
200
					'type'         => 'string',
201
					'arg_options'  => array(
202
						'sanitize_callback' => 'sanitize_text_field',
203
					),
204
				),
205
				'description'      => array(
206
					'description'  => __( 'A human readable translation wrapped description. Meant to be used in interfaces', 'woocommerce' ),
207
					'type'         => 'string',
208
					'arg_options'  => array(
209
						'sanitize_callback' => 'sanitize_text_field',
210
					),
211
				),
212
				'parent_id'        => array(
213
					'description'  => __( 'ID of parent grouping.', 'woocommerce' ),
214
					'type'         => 'string',
215
					'arg_options'  => array(
216
						'sanitize_callback' => 'sanitize_text_field',
217
					),
218
				),
219
				'sub_groups'        => array(
220
					'description'  => __( 'IDs for settings sub groups.', 'woocommerce' ),
221
					'type'         => 'string',
222
					'arg_options'  => array(
223
						'sanitize_callback' => 'sanitize_text_field',
224
					),
225
				),
226
			),
227
		);
228
229
		return $this->add_additional_fields_schema( $schema );
230
	}
231
}
232