Completed
Pull Request — master (#11082)
by Jeff
07:47
created

WC_Rest_Settings_Controller::group_defaults()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
cc 1
eloc 7
nc 1
nop 0
dl 0
loc 9
rs 9.6666
c 3
b 1
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
	 * @since 2.7.0
33
	 */
34 View Code Duplication
	public function register_routes() {
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...
35
		register_rest_route( $this->namespace, '/' . $this->rest_base, array(
36
			array(
37
				'methods'             => WP_REST_Server::READABLE,
38
				'callback'            => array( $this, 'get_items' ),
39
				'permission_callback' => array( $this, 'get_items_permissions_check' ),
40
			),
41
			'schema' => array( $this, 'get_public_item_schema' ),
42
		) );
43
	}
44
45
	/**
46
	 * Get all settings groups items.
47
	 *
48
	 * @since  2.7.0
49
	 * @param  WP_REST_Request $request
50
	 * @return WP_Error|WP_REST_Response
51
	 */
52
	public function get_items( $request ) {
53
		$groups = apply_filters( 'woocommerce_settings_groups', array() );
54
		if ( empty( $groups ) ) {
55
			return new WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce' ), array( 'status' => 500 ) );
56
		}
57
58
		$defaults        = $this->group_defaults();
59
		$filtered_groups = array();
60
		foreach ( $groups as $group ) {
61
			$sub_groups = array();
62
			foreach ( $groups as $_group ) {
63
				if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) {
64
					$sub_groups[] = $_group['id'];
65
				}
66
			}
67
			$group['sub_groups'] = $sub_groups;
68
69
			$group = wp_parse_args( $group, $defaults );
70
			if ( ! is_null( $group['id'] ) && ! is_null( $group['label'] ) ) {
71
				$group_obj  = $this->filter_group( $group );
72
				$group_data = $this->prepare_item_for_response( $group_obj, $request );
73
				$group_data = $this->prepare_response_for_collection( $group_data );
74
75
				$filtered_groups[] = $group_data;
76
			}
77
		}
78
79
		$response = rest_ensure_response( $filtered_groups );
80
		return $response;
81
	}
82
83
	/**
84
	 * Prepare links for the request.
85
	 *
86
	 * @param string $group_id Group ID.
87
	 * @return array Links for the given group.
88
	 */
89
	protected function prepare_links( $group_id ) {
90
		$base  = '/' . $this->namespace . '/' . $this->rest_base;
91
		$links = array(
92
			'item' => array(
93
				'href'       => rest_url( trailingslashit( $base ) . $group_id ),
94
				'embeddable' => true,
95
			),
96
		);
97
98
		return $links;
99
	}
100
101
	/**
102
	 * Prepare a report sales object for serialization.
103
	 *
104
	 * @param array $item Group object.
105
	 * @param WP_REST_Request $request Request object.
106
	 * @return WP_REST_Response $response Response data.
107
	 */
108
	public function prepare_item_for_response( $item, $request ) {
109
		$context = empty( $request['context'] ) ? 'view' : $request['context'];
110
		$data    = $this->add_additional_fields_to_object( $item, $request );
111
		$data    = $this->filter_response_by_context( $data, $context );
112
113
		$response = rest_ensure_response( $data );
114
115
		$response->add_links( $this->prepare_links( $item['id'] ) );
116
117
		return $response;
118
	}
119
120
	/**
121
	 * Filters out bad values from the groups array/filter so we
122
	 * only return known values via the API.
123
	 *
124
	 * @since 2.7.0
125
	 * @param  array $group
126
	 * @return array
127
	 */
128
	public function filter_group( $group ) {
129
		return array_intersect_key(
130
			$group,
131
			array_flip( array_filter( array_keys( $group ), array( $this, 'allowed_group_keys' ) ) )
132
		);
133
	}
134
135
	/**
136
	 * Callback for allowed keys for each group response.
137
	 *
138
	 * @since  2.7.0
139
	 * @param  string $key Key to check
140
	 * @return boolean
141
	 */
142
	public function allowed_group_keys( $key ) {
143
		return in_array( $key, array( 'id', 'label', 'description', 'parent_id', 'sub_groups' ) );
144
	}
145
146
	/**
147
	 * Returns default settings for groups. null means the field is required.
148
	 *
149
	 * @since  2.7.0
150
	 * @return array
151
	 */
152
	protected function group_defaults() {
153
		return array(
154
			'id'          => null,
155
			'label'       => null,
156
			'description' => '',
157
			'parent_id'   => '',
158
			'sub_groups'  => array(),
159
		);
160
	}
161
162
	/**
163
	 * Makes sure the current user has access to READ the settings APIs.
164
	 *
165
	 * @since  2.7.0
166
	 * @param WP_REST_Request $request Full data about the request.
167
	 * @return WP_Error|boolean
168
	 */
169 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...
170
		if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) {
171
			return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
172
		}
173
174
		return true;
175
	}
176
177
	/**
178
	 * Get the groups schema, conforming to JSON Schema.
179
	 *
180
	 * @since  2.7.0
181
	 * @return array
182
	 */
183
	public function get_item_schema() {
184
		$schema = array(
185
			'$schema'              => 'http://json-schema.org/draft-04/schema#',
186
			'title'                => 'settings-group',
187
			'type'                 => 'object',
188
			'properties'           => array(
189
				'id'               => array(
190
					'description'  => __( 'A unique identifier that can be used to link settings together.', 'woocommerce' ),
191
					'type'         => 'string',
192
					'arg_options'  => array(
193
						'sanitize_callback' => 'sanitize_title',
194
					),
195
				),
196
				'label'            => array(
197
					'description'  => __( 'A human readable label. This is a translated string that can be used in interfaces.', 'woocommerce' ),
198
					'type'         => 'string',
199
					'arg_options'  => array(
200
						'sanitize_callback' => 'sanitize_text_field',
201
					),
202
				),
203
				'description'      => array(
204
					'description'  => __( 'A human readable description. This is a translated string that can be used in interfaces.', 'woocommerce' ),
205
					'type'         => 'string',
206
					'arg_options'  => array(
207
						'sanitize_callback' => 'sanitize_text_field',
208
					),
209
				),
210
				'parent_id'        => array(
211
					'description'  => __( 'ID of parent grouping.', 'woocommerce' ),
212
					'type'         => 'string',
213
					'arg_options'  => array(
214
						'sanitize_callback' => 'sanitize_text_field',
215
					),
216
				),
217
				'sub_groups'        => array(
218
					'description'  => __( 'IDs for settings sub groups.', 'woocommerce' ),
219
					'type'         => 'string',
220
					'arg_options'  => array(
221
						'sanitize_callback' => 'sanitize_text_field',
222
					),
223
				),
224
			),
225
		);
226
227
		return $this->add_additional_fields_schema( $schema );
228
	}
229
}
230