Webhooks   C
last analyzed

Complexity

Total Complexity 53

Size/Duplication

Total Lines 665
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 338
dl 0
loc 665
rs 6.96
c 0
b 0
f 0
wmc 53

14 Methods

Rating   Name   Duplication   Size   Complexity  
B register_routes() 0 78 1
A prepare_links() 0 11 1
B get_items() 0 50 7
A get_object() 0 8 3
A delete_item() 0 40 6
A get_hook_suffix() 0 2 1
B get_item_schema() 0 90 1
A get_collection_params() 0 69 1
B create_item() 0 52 9
A prepare_item_for_database() 0 45 6
C update_item() 0 66 12
A get_item() 0 8 3
A get_default_api_version() 0 2 1
A get_data_for_response() 0 14 1

How to fix   Complexity   

Complex Class

Complex classes like Webhooks often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Webhooks, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * REST API Webhooks controller
4
 *
5
 * Handles requests to the /webhooks endpoint.
6
 *
7
 * @package Automattic/WooCommerce/RestApi
8
 */
9
10
namespace Automattic\WooCommerce\RestApi\Controllers\Version4;
11
12
defined( 'ABSPATH' ) || exit;
13
14
use Automattic\WooCommerce\RestApi\Controllers\Version4\Utilities\Pagination;
15
16
/**
17
 * REST API Webhooks controller class.
18
 */
19
class Webhooks extends AbstractController {
20
21
	/**
22
	 * Route base.
23
	 *
24
	 * @var string
25
	 */
26
	protected $rest_base = 'webhooks';
27
28
	/**
29
	 * Permission to check.
30
	 *
31
	 * @var string
32
	 */
33
	protected $resource_type = 'webhooks';
34
35
	/**
36
	 * Post type.
37
	 *
38
	 * @var string
39
	 */
40
	protected $post_type = 'shop_webhook';
41
42
	/**
43
	 * Register the routes for webhooks.
44
	 */
45
	public function register_routes() {
46
		register_rest_route(
47
			$this->namespace,
48
			'/' . $this->rest_base,
49
			array(
50
				array(
51
					'methods'             => \WP_REST_Server::READABLE,
52
					'callback'            => array( $this, 'get_items' ),
53
					'permission_callback' => array( $this, 'get_items_permissions_check' ),
54
					'args'                => $this->get_collection_params(),
55
				),
56
				array(
57
					'methods'             => \WP_REST_Server::CREATABLE,
58
					'callback'            => array( $this, 'create_item' ),
59
					'permission_callback' => array( $this, 'create_item_permissions_check' ),
60
					'args'                => array_merge(
61
						$this->get_endpoint_args_for_item_schema( \WP_REST_Server::CREATABLE ),
62
						array(
63
							'topic'        => array(
64
								'required'    => true,
65
								'type'        => 'string',
66
								'description' => __( 'Webhook topic.', 'woocommerce-rest-api' ),
67
							),
68
							'delivery_url' => array(
69
								'required'    => true,
70
								'type'        => 'string',
71
								'description' => __( 'Webhook delivery URL.', 'woocommerce-rest-api' ),
72
							),
73
						)
74
					),
75
				),
76
				'schema' => array( $this, 'get_public_item_schema' ),
77
			),
78
			true
79
		);
80
81
		register_rest_route(
82
			$this->namespace,
83
			'/' . $this->rest_base . '/(?P<id>[\d]+)',
84
			array(
85
				'args'   => array(
86
					'id' => array(
87
						'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ),
88
						'type'        => 'integer',
89
					),
90
				),
91
				array(
92
					'methods'             => \WP_REST_Server::READABLE,
93
					'callback'            => array( $this, 'get_item' ),
94
					'permission_callback' => array( $this, 'get_item_permissions_check' ),
95
					'args'                => array(
96
						'context' => $this->get_context_param( array( 'default' => 'view' ) ),
97
					),
98
				),
99
				array(
100
					'methods'             => \WP_REST_Server::EDITABLE,
101
					'callback'            => array( $this, 'update_item' ),
102
					'permission_callback' => array( $this, 'update_item_permissions_check' ),
103
					'args'                => $this->get_endpoint_args_for_item_schema( \WP_REST_Server::EDITABLE ),
104
				),
105
				array(
106
					'methods'             => \WP_REST_Server::DELETABLE,
107
					'callback'            => array( $this, 'delete_item' ),
108
					'permission_callback' => array( $this, 'delete_item_permissions_check' ),
109
					'args'                => array(
110
						'force' => array(
111
							'default'     => false,
112
							'type'        => 'boolean',
113
							'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce-rest-api' ),
114
						),
115
					),
116
				),
117
				'schema' => array( $this, 'get_public_item_schema' ),
118
			),
119
			true
120
		);
121
122
		$this->register_batch_route();
123
	}
124
125
	/**
126
	 * Get the default REST API version.
127
	 *
128
	 * @since  3.0.0
129
	 * @return string
130
	 */
131
	protected function get_default_api_version() {
132
		return 'wp_api_v4';
133
	}
134
135
	/**
136
	 * Get all webhooks.
137
	 *
138
	 * @param \WP_REST_Request $request Full details about the request.
139
	 * @return \WP_Error|\WP_REST_Response
140
	 */
141
	public function get_items( $request ) {
142
		$args            = array();
143
		$args['order']   = $request['order'];
144
		$args['orderby'] = $request['orderby'];
145
		$args['status']  = 'all' === $request['status'] ? '' : $request['status'];
146
		$args['include'] = implode( ',', $request['include'] );
0 ignored issues
show
Bug introduced by
It seems like $request['include'] can also be of type null; however, parameter $pieces of implode() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

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

146
		$args['include'] = implode( ',', /** @scrutinizer ignore-type */ $request['include'] );
Loading history...
147
		$args['exclude'] = implode( ',', $request['exclude'] );
148
		$args['limit']   = $request['per_page'];
149
		$args['search']  = $request['search'];
150
		$args['before']  = $request['before'];
151
		$args['after']   = $request['after'];
152
153
		if ( empty( $request['offset'] ) ) {
154
			$args['offset'] = 1 < $request['page'] ? ( $request['page'] - 1 ) * $args['limit'] : 0;
155
		}
156
157
		/**
158
		 * Filter arguments, before passing to WC_Webhook_Data_Store->search_webhooks, when querying webhooks via the REST API.
159
		 *
160
		 * @param array           $args    Array of arguments for $wpdb->get_results().
161
		 * @param \WP_REST_Request $request The current request.
162
		 */
163
		$prepared_args = apply_filters( 'woocommerce_rest_webhook_query', $args, $request );
164
		unset( $prepared_args['page'] );
165
		$prepared_args['paginate'] = true;
166
167
		// Get the webhooks.
168
		$webhooks    = array();
169
		$data_store  = \WC_Data_Store::load( 'webhook' );
170
		$results     = $data_store->search_webhooks( $prepared_args );
171
		$webhook_ids = $results->webhooks;
172
173
		foreach ( $webhook_ids as $webhook_id ) {
174
			$object = $this->get_object( $webhook_id );
175
176
			if ( ! $object || 0 === $object->get_id() ) {
177
				continue;
178
			}
179
180
			$data       = $this->prepare_item_for_response( $object, $request );
181
			$webhooks[] = $this->prepare_response_for_collection( $data );
182
		}
183
184
185
		$total_webhooks = $results->total;
186
		$max_pages      = $results->max_num_pages;
187
		$response       = rest_ensure_response( $webhooks );
188
		$response       = Pagination::add_pagination_headers( $response, $request, $total_webhooks, $max_pages );
0 ignored issues
show
Bug introduced by
It seems like $response can also be of type array and array<mixed,array>; however, parameter $response of Automattic\WooCommerce\R...dd_pagination_headers() does only seem to accept WP_REST_Response, maybe add an additional type check? ( Ignorable by Annotation )

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

188
		$response       = Pagination::add_pagination_headers( /** @scrutinizer ignore-type */ $response, $request, $total_webhooks, $max_pages );
Loading history...
189
190
		return $response;
191
	}
192
193
	/**
194
	 * Get object.
195
	 *
196
	 * @param  int $id Object ID.
197
	 * @return \WC_Webhook|bool
198
	 */
199
	protected function get_object( $id ) {
200
		$webhook = wc_get_webhook( $id );
201
202
		if ( empty( $webhook ) || is_null( $webhook ) ) {
203
			return false;
204
		}
205
206
		return $webhook;
207
	}
208
209
	/**
210
	 * Get a single item.
211
	 *
212
	 * @param \WP_REST_Request $request Full details about the request.
213
	 * @return \WP_Error|\WP_REST_Response
214
	 */
215
	public function get_item( $request ) {
216
		$object = $this->get_object( (int) $request['id'] );
217
218
		if ( ! $object || 0 === $object->get_id() ) {
219
			return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) );
220
		}
221
222
		return $this->prepare_item_for_response( $object, $request );
223
	}
224
225
	/**
226
	 * Create a single webhook.
227
	 *
228
	 * @param \WP_REST_Request $request Full details about the request.
229
	 * @return \WP_Error|\WP_REST_Response
230
	 */
231
	public function create_item( $request ) {
232
		if ( ! empty( $request['id'] ) ) {
233
			/* translators: %s: post type */
234
			return new \WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 400 ) );
235
		}
236
237
		// Validate topic.
238
		if ( empty( $request['topic'] ) || ! wc_is_webhook_valid_topic( strtolower( $request['topic'] ) ) ) {
239
			return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic is required and must be valid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) );
240
		}
241
242
		// Validate delivery URL.
243
		if ( empty( $request['delivery_url'] ) || ! wc_is_valid_url( $request['delivery_url'] ) ) {
244
			return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce-rest-api' ), array( 'status' => 400 ) );
245
		}
246
247
		$post = $this->prepare_item_for_database( $request );
248
		if ( is_wp_error( $post ) ) {
249
			return $post;
250
		}
251
252
		$webhook = new \WC_Webhook();
253
		$webhook->set_name( $post->post_title );
0 ignored issues
show
Bug introduced by
The property post_title does not seem to exist on WP_Error.
Loading history...
254
		$webhook->set_user_id( $post->post_author );
0 ignored issues
show
Bug introduced by
The property post_author does not seem to exist on WP_Error.
Loading history...
255
		$webhook->set_status( 'publish' === $post->post_status ? 'active' : 'disabled' );
0 ignored issues
show
Bug introduced by
The property post_status does not seem to exist on WP_Error.
Loading history...
256
		$webhook->set_topic( $request['topic'] );
257
		$webhook->set_delivery_url( $request['delivery_url'] );
258
		$webhook->set_secret( ! empty( $request['secret'] ) ? $request['secret'] : wp_generate_password( 50, true, true ) );
259
		$webhook->set_api_version( $this->get_default_api_version() );
260
		$webhook->save();
261
262
		$this->update_additional_fields_for_object( $webhook, $request );
0 ignored issues
show
Bug introduced by
$webhook of type WC_Webhook is incompatible with the type array expected by parameter $object of WP_REST_Controller::upda...nal_fields_for_object(). ( Ignorable by Annotation )

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

262
		$this->update_additional_fields_for_object( /** @scrutinizer ignore-type */ $webhook, $request );
Loading history...
263
264
		/**
265
		 * Fires after a single item is created or updated via the REST API.
266
		 *
267
		 * @param WC_Webhook      $webhook  Webhook data.
268
		 * @param \WP_REST_Request $request  Request object.
269
		 * @param bool            $creating True when creating item, false when updating.
270
		 */
271
		do_action( 'woocommerce_rest_insert_webhook_object', $webhook, $request, true );
272
273
		$request->set_param( 'context', 'edit' );
274
		$response = $this->prepare_item_for_response( $webhook, $request );
275
		$response = rest_ensure_response( $response );
276
		$response->set_status( 201 );
277
		$response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $webhook->get_id() ) ) );
278
279
		// Send ping.
280
		$webhook->deliver_ping();
281
282
		return $response;
283
	}
284
285
	/**
286
	 * Update a single webhook.
287
	 *
288
	 * @param \WP_REST_Request $request Full details about the request.
289
	 * @return \WP_Error|\WP_REST_Response
290
	 */
291
	public function update_item( $request ) {
292
		$id      = (int) $request['id'];
293
		$webhook = wc_get_webhook( $id );
294
295
		if ( empty( $webhook ) || is_null( $webhook ) ) {
296
			return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) );
297
		}
298
299
		// Update topic.
300
		if ( ! empty( $request['topic'] ) ) {
301
			if ( wc_is_webhook_valid_topic( strtolower( $request['topic'] ) ) ) {
302
				$webhook->set_topic( $request['topic'] );
303
			} else {
304
				return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic must be valid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) );
305
			}
306
		}
307
308
		// Update delivery URL.
309
		if ( ! empty( $request['delivery_url'] ) ) {
310
			if ( wc_is_valid_url( $request['delivery_url'] ) ) {
311
				$webhook->set_delivery_url( $request['delivery_url'] );
312
			} else {
313
				return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_delivery_url", __( 'Webhook delivery URL must be a valid URL starting with http:// or https://.', 'woocommerce-rest-api' ), array( 'status' => 400 ) );
314
			}
315
		}
316
317
		// Update secret.
318
		if ( ! empty( $request['secret'] ) ) {
319
			$webhook->set_secret( $request['secret'] );
320
		}
321
322
		// Update status.
323
		if ( ! empty( $request['status'] ) ) {
324
			if ( wc_is_webhook_valid_status( strtolower( $request['status'] ) ) ) {
325
				$webhook->set_status( $request['status'] );
326
			} else {
327
				return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_status", __( 'Webhook status must be valid.', 'woocommerce-rest-api' ), array( 'status' => 400 ) );
328
			}
329
		}
330
331
		$post = $this->prepare_item_for_database( $request );
332
		if ( is_wp_error( $post ) ) {
333
			return $post;
334
		}
335
336
		if ( isset( $post->post_title ) ) {
337
			$webhook->set_name( $post->post_title );
338
		}
339
340
		$webhook->save();
341
342
		$this->update_additional_fields_for_object( $webhook, $request );
0 ignored issues
show
Bug introduced by
$webhook of type WC_Webhook is incompatible with the type array expected by parameter $object of WP_REST_Controller::upda...nal_fields_for_object(). ( Ignorable by Annotation )

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

342
		$this->update_additional_fields_for_object( /** @scrutinizer ignore-type */ $webhook, $request );
Loading history...
343
344
		/**
345
		 * Fires after a single item is created or updated via the REST API.
346
		 *
347
		 * @param WC_Webhook      $webhook  Webhook data.
348
		 * @param \WP_REST_Request $request  Request object.
349
		 * @param bool            $creating True when creating item, false when updating.
350
		 */
351
		do_action( 'woocommerce_rest_insert_webhook_object', $webhook, $request, false );
352
353
		$request->set_param( 'context', 'edit' );
354
		$response = $this->prepare_item_for_response( $webhook, $request );
355
356
		return rest_ensure_response( $response );
357
	}
358
359
	/**
360
	 * Delete a single webhook.
361
	 *
362
	 * @param \WP_REST_Request $request Full details about the request.
363
	 * @return \WP_REST_Response|\WP_Error
364
	 */
365
	public function delete_item( $request ) {
366
		$id    = (int) $request['id'];
367
		$force = isset( $request['force'] ) ? (bool) $request['force'] : false;
368
369
		// We don't support trashing for this type, error out.
370
		if ( ! $force ) {
371
			return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce-rest-api' ), array( 'status' => 501 ) );
372
		}
373
374
		$webhook = wc_get_webhook( $id );
375
376
		if ( empty( $webhook ) || is_null( $webhook ) ) {
377
			return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce-rest-api' ), array( 'status' => 404 ) );
378
		}
379
380
		$request->set_param( 'context', 'edit' );
381
		$previous = $this->prepare_item_for_response( $webhook, $request );
382
		$result   = $webhook->delete( true );
383
		if ( ! $result ) {
384
			/* translators: %s: post type */
385
			return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce-rest-api' ), $this->post_type ), array( 'status' => 500 ) );
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...
386
		}
387
		$response = new \WP_REST_Response();
388
		$response->set_data(
389
			array(
390
				'deleted'  => true,
391
				'previous' => $previous->get_data(),
392
			)
393
		);
394
395
		/**
396
		 * Fires after a single item is deleted or trashed via the REST API.
397
		 *
398
		 * @param WC_Webhook       $webhook     The deleted or trashed item.
399
		 * @param \WP_REST_Response $response The response data.
400
		 * @param \WP_REST_Request  $request  The request sent to the API.
401
		 */
402
		do_action( 'woocommerce_rest_delete_webhook_object', $webhook, $response, $request );
403
404
		return $response;
405
	}
406
407
	/**
408
	 * Prepare a single webhook for create or update.
409
	 *
410
	 * @param \WP_REST_Request $request Request object.
411
	 * @return \WP_Error|stdClass $data Post object.
0 ignored issues
show
Bug introduced by
The type Automattic\WooCommerce\R...llers\Version4\stdClass was not found. Did you mean stdClass? If so, make sure to prefix the type with \.
Loading history...
412
	 */
413
	protected function prepare_item_for_database( $request ) {
414
		$data = new \stdClass();
415
416
		// Post ID.
417
		if ( isset( $request['id'] ) ) {
418
			$data->ID = absint( $request['id'] );
419
		}
420
421
		// Validate required POST fields.
422
		if ( 'POST' === $request->get_method() && empty( $data->ID ) ) {
423
			$data->post_title = ! empty( $request['name'] ) ? $request['name'] : sprintf( __( 'Webhook created on %s', 'woocommerce-rest-api' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Webhook created on date parsed by strftime', 'woocommerce-rest-api' ) ) ); // @codingStandardsIgnoreLine
424
425
			// Post author.
426
			$data->post_author = get_current_user_id();
427
428
			// Post password.
429
			$data->post_password = 'webhook_' . wp_generate_password();
430
431
			// Post status.
432
			$data->post_status = 'publish';
433
		} else {
434
435
			// Allow edit post title.
436
			if ( ! empty( $request['name'] ) ) {
437
				$data->post_title = $request['name'];
438
			}
439
		}
440
441
		// Comment status.
442
		$data->comment_status = 'closed';
443
444
		// Ping status.
445
		$data->ping_status = 'closed';
446
447
		/**
448
		 * Filter the query_vars used in `get_items` for the constructed query.
449
		 *
450
		 * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being
451
		 * prepared for insertion.
452
		 *
453
		 * @param \stdClass        $data An object representing a single item prepared
454
		 *                                       for inserting or updating the database.
455
		 * @param \WP_REST_Request $request       Request object.
456
		 */
457
		return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $data, $request );
458
	}
459
460
	/**
461
	 * Get data for this object in the format of this endpoint's schema.
462
	 *
463
	 * @param \WC_Webhook      $object Object to prepare.
464
	 * @param \WP_REST_Request $request Request object.
465
	 * @return array Array of data in the correct format.
466
	 */
467
	protected function get_data_for_response( $object, $request ) {
468
		return array(
469
			'id'                => $object->get_id(),
470
			'name'              => $object->get_name(),
471
			'status'            => $object->get_status(),
472
			'topic'             => $object->get_topic(),
473
			'resource'          => $object->get_resource(),
474
			'event'             => $object->get_event(),
475
			'hooks'             => $object->get_hooks(),
476
			'delivery_url'      => $object->get_delivery_url(),
477
			'date_created'      => wc_rest_prepare_date_response( $object->get_date_created(), false ),
478
			'date_created_gmt'  => wc_rest_prepare_date_response( $object->get_date_created() ),
479
			'date_modified'     => wc_rest_prepare_date_response( $object->get_date_modified(), false ),
480
			'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified() ),
481
		);
482
	}
483
484
	/**
485
	 * Prepare links for the request.
486
	 *
487
	 * @param mixed            $item Object to prepare.
488
	 * @param \WP_REST_Request $request Request object.
489
	 * @return array
490
	 */
491
	protected function prepare_links( $item, $request ) {
492
		$links = array(
493
			'self'       => array(
494
				'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $item->get_id() ) ),
495
			),
496
			'collection' => array(
497
				'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ),
498
			),
499
		);
500
501
		return $links;
502
	}
503
504
	/**
505
	 * Get the Webhook's schema, conforming to JSON Schema.
506
	 *
507
	 * @return array
508
	 */
509
	public function get_item_schema() {
510
		$schema = array(
511
			'$schema'    => 'http://json-schema.org/draft-04/schema#',
512
			'title'      => 'webhook',
513
			'type'       => 'object',
514
			'properties' => array(
515
				'id'                => array(
516
					'description' => __( 'Unique identifier for the resource.', 'woocommerce-rest-api' ),
517
					'type'        => 'integer',
518
					'context'     => array( 'view', 'edit' ),
519
					'readonly'    => true,
520
				),
521
				'name'              => array(
522
					'description' => __( 'A friendly name for the webhook.', 'woocommerce-rest-api' ),
523
					'type'        => 'string',
524
					'context'     => array( 'view', 'edit' ),
525
				),
526
				'status'            => array(
527
					'description' => __( 'Webhook status.', 'woocommerce-rest-api' ),
528
					'type'        => 'string',
529
					'default'     => 'active',
530
					'enum'        => array_keys( wc_get_webhook_statuses() ),
531
					'context'     => array( 'view', 'edit' ),
532
				),
533
				'topic'             => array(
534
					'description' => __( 'Webhook topic.', 'woocommerce-rest-api' ),
535
					'type'        => 'string',
536
					'context'     => array( 'view', 'edit' ),
537
				),
538
				'resource'          => array(
539
					'description' => __( 'Webhook resource.', 'woocommerce-rest-api' ),
540
					'type'        => 'string',
541
					'context'     => array( 'view', 'edit' ),
542
					'readonly'    => true,
543
				),
544
				'event'             => array(
545
					'description' => __( 'Webhook event.', 'woocommerce-rest-api' ),
546
					'type'        => 'string',
547
					'context'     => array( 'view', 'edit' ),
548
					'readonly'    => true,
549
				),
550
				'hooks'             => array(
551
					'description' => __( 'WooCommerce action names associated with the webhook.', 'woocommerce-rest-api' ),
552
					'type'        => 'array',
553
					'context'     => array( 'view', 'edit' ),
554
					'readonly'    => true,
555
					'items'       => array(
556
						'type' => 'string',
557
					),
558
				),
559
				'delivery_url'      => array(
560
					'description' => __( 'The URL where the webhook payload is delivered.', 'woocommerce-rest-api' ),
561
					'type'        => 'string',
562
					'format'      => 'uri',
563
					'context'     => array( 'view', 'edit' ),
564
					'readonly'    => true,
565
				),
566
				'secret'            => array(
567
					'description' => __( "Secret key used to generate a hash of the delivered webhook and provided in the request headers. This will default to a MD5 hash from the current user's ID|username if not provided.", 'woocommerce-rest-api' ),
568
					'type'        => 'string',
569
					'context'     => array( 'edit' ),
570
				),
571
				'date_created'      => array(
572
					'description' => __( "The date the webhook was created, in the site's timezone.", 'woocommerce-rest-api' ),
573
					'type'        => 'date-time',
574
					'context'     => array( 'view', 'edit' ),
575
					'readonly'    => true,
576
				),
577
				'date_created_gmt'  => array(
578
					'description' => __( 'The date the webhook was created, as GMT.', 'woocommerce-rest-api' ),
579
					'type'        => 'date-time',
580
					'context'     => array( 'view', 'edit' ),
581
					'readonly'    => true,
582
				),
583
				'date_modified'     => array(
584
					'description' => __( "The date the webhook was last modified, in the site's timezone.", 'woocommerce-rest-api' ),
585
					'type'        => 'date-time',
586
					'context'     => array( 'view', 'edit' ),
587
					'readonly'    => true,
588
				),
589
				'date_modified_gmt' => array(
590
					'description' => __( 'The date the webhook was last modified, as GMT.', 'woocommerce-rest-api' ),
591
					'type'        => 'date-time',
592
					'context'     => array( 'view', 'edit' ),
593
					'readonly'    => true,
594
				),
595
			),
596
		);
597
598
		return $this->add_additional_fields_schema( $schema );
599
	}
600
601
	/**
602
	 * Get the query params for collections of attachments.
603
	 *
604
	 * @return array
605
	 */
606
	public function get_collection_params() {
607
		$params = parent::get_collection_params();
608
609
		$params['context']['default'] = 'view';
610
611
		$params['after']   = array(
612
			'description'       => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce-rest-api' ),
613
			'type'              => 'string',
614
			'format'            => 'date-time',
615
			'validate_callback' => 'rest_validate_request_arg',
616
		);
617
		$params['before']  = array(
618
			'description'       => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce-rest-api' ),
619
			'type'              => 'string',
620
			'format'            => 'date-time',
621
			'validate_callback' => 'rest_validate_request_arg',
622
		);
623
		$params['exclude'] = array(
624
			'description'       => __( 'Ensure result set excludes specific IDs.', 'woocommerce-rest-api' ),
625
			'type'              => 'array',
626
			'items'             => array(
627
				'type' => 'integer',
628
			),
629
			'default'           => array(),
630
			'sanitize_callback' => 'wp_parse_id_list',
631
		);
632
		$params['include'] = array(
633
			'description'       => __( 'Limit result set to specific ids.', 'woocommerce-rest-api' ),
634
			'type'              => 'array',
635
			'items'             => array(
636
				'type' > 'integer',
637
			),
638
			'default'           => array(),
639
			'sanitize_callback' => 'wp_parse_id_list',
640
		);
641
		$params['offset']  = array(
642
			'description'       => __( 'Offset the result set by a specific number of items.', 'woocommerce-rest-api' ),
643
			'type'              => 'integer',
644
			'sanitize_callback' => 'absint',
645
			'validate_callback' => 'rest_validate_request_arg',
646
		);
647
		$params['order']   = array(
648
			'description'       => __( 'Order sort attribute ascending or descending.', 'woocommerce-rest-api' ),
649
			'type'              => 'string',
650
			'default'           => 'desc',
651
			'enum'              => array( 'asc', 'desc' ),
652
			'validate_callback' => 'rest_validate_request_arg',
653
		);
654
		$params['orderby'] = array(
655
			'description'       => __( 'Sort collection by object attribute.', 'woocommerce-rest-api' ),
656
			'type'              => 'string',
657
			'default'           => 'date',
658
			'enum'              => array(
659
				'date',
660
				'id',
661
				'title',
662
			),
663
			'validate_callback' => 'rest_validate_request_arg',
664
		);
665
		$params['status']  = array(
666
			'default'           => 'all',
667
			'description'       => __( 'Limit result set to webhooks assigned a specific status.', 'woocommerce-rest-api' ),
668
			'type'              => 'string',
669
			'enum'              => array( 'all', 'active', 'paused', 'disabled' ),
670
			'sanitize_callback' => 'sanitize_key',
671
			'validate_callback' => 'rest_validate_request_arg',
672
		);
673
674
		return $params;
675
	}
676
677
	/**
678
	 * Return suffix for item action hooks.
679
	 *
680
	 * @return string
681
	 */
682
	protected function get_hook_suffix() {
683
		return $this->post_type;
684
	}
685
}
686