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

WC_Rest_Settings_Groups_Controller::get_items()   C

Complexity

Conditions 8
Paths 8

Size

Total Lines 30
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

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