ShippingZones   A
last analyzed

Complexity

Total Complexity 21

Size/Duplication

Total Lines 288
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 143
dl 0
loc 288
rs 10
c 0
b 0
f 0
wmc 21

9 Methods

Rating   Name   Duplication   Size   Complexity  
A register_routes() 0 66 1
A get_item_schema() 0 29 1
A get_item() 0 12 2
A prepare_links() 0 15 1
A get_items() 0 14 2
A create_item() 0 21 4
A delete_item() 0 25 3
A get_data_for_response() 0 5 1
A update_item() 0 28 6
1
<?php
2
/**
3
 * REST API Shipping Zones controller
4
 *
5
 * Handles requests to the /shipping/zones endpoint.
6
 *
7
 * @package Automattic/WooCommerce/RestApi
8
 */
9
10
namespace Automattic\WooCommerce\RestApi\Controllers\Version4;
11
12
defined( 'ABSPATH' ) || exit;
13
14
/**
15
 * REST API Shipping Zones class.
16
 */
17
class ShippingZones extends AbstractShippingZonesController {
18
19
	/**
20
	 * Register the routes for Shipping Zones.
21
	 */
22
	public function register_routes() {
23
		register_rest_route(
24
			$this->namespace,
25
			'/' . $this->rest_base,
26
			array(
27
				array(
28
					'methods'             => \WP_REST_Server::READABLE,
29
					'callback'            => array( $this, 'get_items' ),
30
					'permission_callback' => array( $this, 'get_items_permissions_check' ),
31
				),
32
				array(
33
					'methods'             => \WP_REST_Server::CREATABLE,
34
					'callback'            => array( $this, 'create_item' ),
35
					'permission_callback' => array( $this, 'create_item_permissions_check' ),
36
					'args'                => array_merge(
37
						$this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ),
38
						array(
39
							'name' => array(
40
								'required'    => true,
41
								'type'        => 'string',
42
								'description' => __( 'Shipping zone name.', 'woocommerce-rest-api' ),
43
							),
44
						)
45
					),
46
				),
47
				'schema' => array( $this, 'get_public_item_schema' ),
48
			),
49
			true
50
		);
51
52
		register_rest_route(
53
			$this->namespace,
54
			'/' . $this->rest_base . '/(?P<id>[\d-]+)',
55
			array(
56
				'args'   => array(
57
					'id' => array(
58
						'description' => __( 'Unique ID for the resource.', 'woocommerce-rest-api' ),
59
						'type'        => 'integer',
60
					),
61
				),
62
				array(
63
					'methods'             => \WP_REST_Server::READABLE,
64
					'callback'            => array( $this, 'get_item' ),
65
					'permission_callback' => array( $this, 'get_items_permissions_check' ),
66
				),
67
				array(
68
					'methods'             => \WP_REST_Server::EDITABLE,
69
					'callback'            => array( $this, 'update_item' ),
70
					'permission_callback' => array( $this, 'update_item_permissions_check' ),
71
					'args'                => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ),
72
				),
73
				array(
74
					'methods'             => \WP_REST_Server::DELETABLE,
75
					'callback'            => array( $this, 'delete_item' ),
76
					'permission_callback' => array( $this, 'delete_item_permissions_check' ),
77
					'args'                => array(
78
						'force' => array(
79
							'default'     => false,
80
							'type'        => 'boolean',
81
							'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce-rest-api' ),
82
						),
83
					),
84
				),
85
				'schema' => array( $this, 'get_public_item_schema' ),
86
			),
87
			true
88
		);
89
	}
90
91
	/**
92
	 * Get a single Shipping Zone.
93
	 *
94
	 * @param \WP_REST_Request $request Request data.
95
	 * @return \WP_REST_Response|\WP_Error
96
	 */
97
	public function get_item( $request ) {
98
		$zone = $this->get_zone( $request->get_param( 'id' ) );
99
100
		if ( is_wp_error( $zone ) ) {
101
			return $zone;
102
		}
103
104
		$data = $zone->get_data();
0 ignored issues
show
Bug introduced by
The method get_data() does not exist on WP_Error. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

104
		/** @scrutinizer ignore-call */ 
105
  $data = $zone->get_data();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
105
		$data = $this->prepare_item_for_response( $data, $request );
106
		$data = $this->prepare_response_for_collection( $data );
107
108
		return rest_ensure_response( $data );
109
	}
110
111
	/**
112
	 * Get all Shipping Zones.
113
	 *
114
	 * @param \WP_REST_Request $request Request data.
115
	 * @return \WP_REST_Response
116
	 */
117
	public function get_items( $request ) {
118
		$rest_of_the_world = \WC_Shipping_Zones::get_zone_by( 'zone_id', 0 );
119
120
		$zones = \WC_Shipping_Zones::get_zones();
121
		array_unshift( $zones, $rest_of_the_world->get_data() );
122
		$data = array();
123
124
		foreach ( $zones as $zone_obj ) {
125
			$zone   = $this->prepare_item_for_response( $zone_obj, $request );
126
			$zone   = $this->prepare_response_for_collection( $zone );
127
			$data[] = $zone;
128
		}
129
130
		return rest_ensure_response( $data );
131
	}
132
133
	/**
134
	 * Create a single Shipping Zone.
135
	 *
136
	 * @param \WP_REST_Request $request Full details about the request.
137
	 * @return \WP_REST_Request|\WP_Error
138
	 */
139
	public function create_item( $request ) {
140
		$zone = new \WC_Shipping_Zone( null );
141
142
		if ( ! is_null( $request->get_param( 'name' ) ) ) {
143
			$zone->set_zone_name( $request->get_param( 'name' ) );
144
		}
145
146
		if ( ! is_null( $request->get_param( 'order' ) ) ) {
147
			$zone->set_zone_order( $request->get_param( 'order' ) );
148
		}
149
150
		$zone->save();
151
152
		if ( $zone->get_id() !== 0 ) {
153
			$request->set_param( 'id', $zone->get_id() );
154
			$response = $this->get_item( $request );
155
			$response->set_status( 201 );
0 ignored issues
show
Bug introduced by
The method set_status() does not exist on WP_Error. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

155
			$response->/** @scrutinizer ignore-call */ 
156
              set_status( 201 );

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
156
			$response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $zone->get_id() ) ) );
0 ignored issues
show
Bug introduced by
The method header() does not exist on WP_Error. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

156
			$response->/** @scrutinizer ignore-call */ 
157
              header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $zone->get_id() ) ) );

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
157
			return $response;
158
		} else {
159
			return new \WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( "Resource cannot be created. Check to make sure 'order' and 'name' are present.", 'woocommerce-rest-api' ), array( 'status' => 500 ) );
160
		}
161
	}
162
163
	/**
164
	 * Update a single Shipping Zone.
165
	 *
166
	 * @param \WP_REST_Request $request Full details about the request.
167
	 * @return \WP_REST_Request|\WP_Error
168
	 */
169
	public function update_item( $request ) {
170
		$zone = $this->get_zone( $request->get_param( 'id' ) );
171
172
		if ( is_wp_error( $zone ) ) {
173
			return $zone;
174
		}
175
176
		if ( 0 === $zone->get_id() ) {
0 ignored issues
show
Bug introduced by
The method get_id() does not exist on WP_Error. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

176
		if ( 0 === $zone->/** @scrutinizer ignore-call */ get_id() ) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
177
			return new \WP_Error( 'woocommerce_rest_shipping_zone_invalid_zone', __( 'The "locations not covered by your other zones" zone cannot be updated.', 'woocommerce-rest-api' ), array( 'status' => 403 ) );
178
		}
179
180
		$zone_changed = false;
181
182
		if ( ! is_null( $request->get_param( 'name' ) ) ) {
183
			$zone->set_zone_name( $request->get_param( 'name' ) );
0 ignored issues
show
Bug introduced by
The method set_zone_name() does not exist on WP_Error. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

183
			$zone->/** @scrutinizer ignore-call */ 
184
          set_zone_name( $request->get_param( 'name' ) );

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
184
			$zone_changed = true;
185
		}
186
187
		if ( ! is_null( $request->get_param( 'order' ) ) ) {
188
			$zone->set_zone_order( $request->get_param( 'order' ) );
0 ignored issues
show
Bug introduced by
The method set_zone_order() does not exist on WP_Error. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

188
			$zone->/** @scrutinizer ignore-call */ 
189
          set_zone_order( $request->get_param( 'order' ) );

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
189
			$zone_changed = true;
190
		}
191
192
		if ( $zone_changed ) {
193
			$zone->save();
0 ignored issues
show
Bug introduced by
The method save() does not exist on WP_Error. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

193
			$zone->/** @scrutinizer ignore-call */ 
194
          save();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
194
		}
195
196
		return $this->get_item( $request );
197
	}
198
199
	/**
200
	 * Delete a single Shipping Zone.
201
	 *
202
	 * @param \WP_REST_Request $request Full details about the request.
203
	 * @return \WP_REST_Request|\WP_Error
204
	 */
205
	public function delete_item( $request ) {
206
		$zone = $this->get_zone( $request->get_param( 'id' ) );
207
208
		if ( is_wp_error( $zone ) ) {
209
			return $zone;
210
		}
211
212
		$force = $request['force'];
213
214
		// We don't support trashing for this type, error out.
215
		if ( ! $force ) {
216
			return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Shipping zones do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) );
0 ignored issues
show
Bug introduced by
The type Automattic\WooCommerce\R...llers\Version4\WP_Error was not found. Did you mean WP_Error? If so, make sure to prefix the type with \.
Loading history...
217
		}
218
219
		$previous = $this->get_item( $request );
220
		$zone->delete();
0 ignored issues
show
Bug introduced by
The method delete() does not exist on WP_Error. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

220
		$zone->/** @scrutinizer ignore-call */ 
221
         delete();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
221
		$response = new \WP_REST_Response();
222
		$response->set_data(
223
			array(
224
				'deleted'  => true,
225
				'previous' => $previous->get_data(),
226
			)
227
		);
228
229
		return $response;
230
	}
231
232
	/**
233
	 * Get data for this object in the format of this endpoint's schema.
234
	 *
235
	 * @param object           $object Object to prepare.
236
	 * @param \WP_REST_Request $request Request object.
237
	 * @return array Array of data in the correct format.
238
	 */
239
	protected function get_data_for_response( $object, $request ) {
240
		return array(
241
			'id'    => (int) $object['id'],
242
			'name'  => $object['zone_name'],
243
			'order' => (int) $object['zone_order'],
244
		);
245
	}
246
247
	/**
248
	 * Prepare links for the request.
249
	 *
250
	 * @param mixed            $item Object to prepare.
251
	 * @param \WP_REST_Request $request Request object.
252
	 * @return array
253
	 */
254
	protected function prepare_links( $item, $request ) {
255
		$base  = '/' . $this->namespace . '/' . $this->rest_base;
256
		$links = array(
257
			'self'        => array(
258
				'href' => rest_url( trailingslashit( $base ) . $item['id'] ),
259
			),
260
			'collection'  => array(
261
				'href' => rest_url( $base ),
262
			),
263
			'describedby' => array(
264
				'href' => rest_url( trailingslashit( $base ) . $item['id'] . '/locations' ),
265
			),
266
		);
267
268
		return $links;
269
	}
270
271
	/**
272
	 * Get the Shipping Zones schema, conforming to JSON Schema
273
	 *
274
	 * @return array
275
	 */
276
	public function get_item_schema() {
277
		$schema = array(
278
			'$schema'    => 'http://json-schema.org/draft-04/schema#',
279
			'title'      => 'shipping_zone',
280
			'type'       => 'object',
281
			'properties' => array(
282
				'id'    => array(
283
					'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ),
284
					'type'        => 'integer',
285
					'context'     => array( 'view', 'edit' ),
286
					'readonly'    => true,
287
				),
288
				'name'  => array(
289
					'description' => __( 'Shipping zone name.', 'woocommerce-rest-api' ),
290
					'type'        => 'string',
291
					'context'     => array( 'view', 'edit' ),
292
					'arg_options' => array(
293
						'sanitize_callback' => 'sanitize_text_field',
294
					),
295
				),
296
				'order' => array(
297
					'description' => __( 'Shipping zone order.', 'woocommerce-rest-api' ),
298
					'type'        => 'integer',
299
					'context'     => array( 'view', 'edit' ),
300
				),
301
			),
302
		);
303
304
		return $this->add_additional_fields_schema( $schema );
305
	}
306
}
307