Completed
Pull Request — master (#11176)
by Mike
08:33
created

WC_REST_Shipping_Zones_Controller::update_item()   B

Complexity

Conditions 5
Paths 9

Size

Total Lines 25
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 5
eloc 14
c 1
b 0
f 1
nc 9
nop 1
dl 0
loc 25
rs 8.439
1
<?php
2
/**
3
 * REST API Shipping Zones controller
4
 *
5
 * Handles requests to the /shipping/zones endpoint.
6
 *
7
 * @author   WooThemes
8
 * @category API
9
 * @package  WooCommerce/API
10
 * @since    2.7.0
11
 */
12
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
/**
18
 * REST API Shipping Zones class.
19
 *
20
 * @package WooCommerce/API
21
 * @extends WC_REST_Shipping_Zones_Controller_Base
22
 */
23
class WC_REST_Shipping_Zones_Controller extends WC_REST_Shipping_Zones_Controller_Base {
24
25
	/**
26
	 * Register the routes for Shipping Zones.
27
	 */
28
	public function register_routes() {
29
		register_rest_route( $this->namespace, '/' . $this->rest_base, array(
30
			array(
31
				'methods'             => WP_REST_Server::READABLE,
32
				'callback'            => array( $this, 'get_items' ),
33
				'permission_callback' => array( $this, 'get_items_permissions_check' ),
34
			),
35
			array(
36
				'methods'             => WP_REST_Server::CREATABLE,
37
				'callback'            => array( $this, 'create_item' ),
38
				'permission_callback' => array( $this, 'create_item_permissions_check' ),
39
				'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),
40
			),
41
			'schema' => array( $this, 'get_public_item_schema' ),
42
		) );
43
44
		register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d-]+)', array(
45
			array(
46
				'methods'             => WP_REST_Server::READABLE,
47
				'callback'            => array( $this, 'get_item' ),
48
				'permission_callback' => array( $this, 'get_items_permissions_check' ),
49
			),
50
			array(
51
				'methods'             => WP_REST_Server::EDITABLE,
52
				'callback'            => array( $this, 'update_item' ),
53
				'permission_callback' => array( $this, 'update_items_permissions_check' ),
54
				'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
55
			),
56
			'schema' => array( $this, 'get_public_item_schema' ),
57
		) );
58
	}
59
60
	/**
61
	 * Get a single Shipping Zone.
62
	 *
63
	 * @param WP_REST_Request $request
64
	 * @return WP_REST_Response
65
	 */
66
	public function get_item( $request ) {
67
		$zone = $this->get_zone( $request->get_param( 'id' ) );
68
69
		if ( is_wp_error( $zone ) ) {
70
			return $zone;
71
		}
72
73
		$data = $zone->get_data();
74
		$data = $this->prepare_item_for_response( $data, $request );
75
		$data = $this->prepare_response_for_collection( $data );
76
77
		return rest_ensure_response( $data );
78
	}
79
80
	/**
81
	 * Get all Shipping Zones.
82
	 *
83
	 * @param WP_REST_Request $request
84
	 * @return WP_REST_Response
85
	 */
86
	public function get_items( $request ) {
87
		$rest_of_the_world = WC_Shipping_Zones::get_zone_by( 'zone_id', 0 );
88
89
		$zones = WC_Shipping_Zones::get_zones();
90
		array_unshift( $zones, $rest_of_the_world->get_data() );
91
		$data  = array();
92
93
		foreach ( $zones as $zone_obj ) {
94
			$zone   = $this->prepare_item_for_response( $zone_obj, $request );
95
			$zone   = $this->prepare_response_for_collection( $zone );
96
			$data[] = $zone;
97
		}
98
99
		return rest_ensure_response( $data );
100
	}
101
102
	/**
103
	 * Create a single Shipping Zone.
104
	 *
105
	 * @param WP_REST_Request $request Full details about the request.
106
	 * @return WP_REST_Request|WP_Error
107
	 */
108
	public function create_item( $request ) {
109
		$zone = new WC_Shipping_Zone( null );
110
111
		if ( ! is_null( $request->get_param( 'name' ) ) ) {
112
			$zone->set_zone_name( $request->get_param( 'name' ) );
113
		}
114
115
		if ( ! is_null( $request->get_param( 'order' ) ) ) {
116
			$zone->set_zone_order( $request->get_param( 'order' ) );
117
		}
118
119
		$zone->create();
120
121
		if ( $zone->get_id() !== 0 ) {
122
			$request->set_param( 'id', $zone->get_id() );
123
			$response = $this->get_item( $request );
124
			$response->set_status( 201 );
125
			$response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $zone->get_id() ) ) );
126
			return $response;
127
		} else {
128
			return new WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( "Resource cannot be created. Check to make sure 'order' and 'name' are present.", 'woocommerce' ), array( 'status' => 500 ) );
129
		}
130
	}
131
132
	/**
133
	 * Update a single Shipping Zone.
134
	 *
135
	 * @param WP_REST_Request $request Full details about the request.
136
	 * @return WP_REST_Request|WP_Error
137
	 */
138
	public function update_item( $request ) {
139
		$zone = $this->get_zone( $request->get_param( 'id' ) );
140
141
		if ( is_wp_error( $zone ) ) {
142
			return $zone;
143
		}
144
145
		$zone_changed = false;
146
147
		if ( ! is_null( $request->get_param( 'name' ) ) ) {
148
			$zone->set_zone_name( $request->get_param( 'name' ) );
149
			$zone_changed = true;
150
		}
151
152
		if ( ! is_null( $request->get_param( 'order' ) ) ) {
153
			$zone->set_zone_order( $request->get_param( 'order' ) );
154
			$zone_changed = true;
155
		}
156
157
		if ( $zone_changed ) {
158
			$zone->save();
159
		}
160
161
		return $this->get_item( $request );
162
	}
163
164
	/**
165
	 * Prepare the Shipping Zone for the REST response.
166
	 *
167
	 * @param array $item Shipping Zone.
168
	 * @param WP_REST_Request $request Request object.
169
	 * @return WP_REST_Response $response
170
	 */
171
	public function prepare_item_for_response( $item, $request ) {
172
		$data = array(
173
			'id'    => (int) $item['zone_id'],
174
			'name'  => $item['zone_name'],
175
			'order' => (int) $item['zone_order'],
176
		);
177
178
		$context = empty( $request['context'] ) ? 'view' : $request['context'];
179
		$data    = $this->add_additional_fields_to_object( $data, $request );
180
		$data    = $this->filter_response_by_context( $data, $context );
181
182
		// Wrap the data in a response object.
183
		$response = rest_ensure_response( $data );
184
185
		$response->add_links( $this->prepare_links( $data['id'] ) );
186
187
		return $response;
188
	}
189
190
	/**
191
	 * Prepare links for the request.
192
	 *
193
	 * @param int $zone_id Given Shipping Zone ID.
194
	 * @return array Links for the given Shipping Zone.
195
	 */
196
	protected function prepare_links( $zone_id ) {
197
		$base  = '/' . $this->namespace . '/' . $this->rest_base;
198
		$links = array(
199
			'self'       => array(
200
				'href' => rest_url( trailingslashit( $base ) . $zone_id ),
201
			),
202
			'collection' => array(
203
				'href' => rest_url( $base ),
204
			),
205
			'describedby' => array(
206
				'href' => rest_url( trailingslashit( $base ) . $zone_id . '/locations' ),
207
			),
208
		);
209
210
		return $links;
211
	}
212
213
	/**
214
	 * Get the Shipping Zones schema, conforming to JSON Schema
215
	 *
216
	 * @return array
217
	 */
218
	public function get_item_schema() {
219
		$schema = array(
220
			'$schema'    => 'http://json-schema.org/draft-04/schema#',
221
			'title'      => 'shipping_zone',
222
			'type'       => 'object',
223
			'properties' => array(
224
				'id' => array(
225
					'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
226
					'type'        => 'integer',
227
					'context'     => array( 'view', 'edit' ),
228
					'readonly'    => true,
229
				),
230
				'name' => array(
231
					'description' => __( 'Shipping zone name.', 'woocommerce' ),
232
					'type'        => 'string',
233
					'context'     => array( 'view', 'edit' ),
234
					'required'    => true,
235
					'arg_options' => array(
236
						'sanitize_callback' => 'sanitize_text_field',
237
					),
238
				),
239
				'order' => array(
240
					'description' => __( 'Shipping zone order.', 'woocommerce' ),
241
					'type'        => 'integer',
242
					'context'     => array( 'view', 'edit' ),
243
					'required'    => false,
244
					'arg_options' => array(
245
						'sanitize_callback' => 'absint',
246
					),
247
				),
248
			),
249
		);
250
251
		return $this->add_additional_fields_schema( $schema );
252
	}
253
}
254