Passed
Push — master ( 5bd17a...71a32c )
by Mike
04:53
created

Webhooks::get_data_for_response()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

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

144
		$args['include'] = implode( ',', /** @scrutinizer ignore-type */ $request['include'] );
Loading history...
145
		$args['exclude'] = implode( ',', $request['exclude'] );
146
		$args['limit']   = $request['per_page'];
147
		$args['search']  = $request['search'];
148
		$args['before']  = $request['before'];
149
		$args['after']   = $request['after'];
150
151
		if ( empty( $request['offset'] ) ) {
152
			$args['offset'] = 1 < $request['page'] ? ( $request['page'] - 1 ) * $args['limit'] : 0;
153
		}
154
155
		/**
156
		 * Filter arguments, before passing to WC_Webhook_Data_Store->search_webhooks, when querying webhooks via the REST API.
157
		 *
158
		 * @param array           $args    Array of arguments for $wpdb->get_results().
159
		 * @param \WP_REST_Request $request The current request.
160
		 */
161
		$prepared_args = apply_filters( 'woocommerce_rest_webhook_query', $args, $request );
162
		unset( $prepared_args['page'] );
163
		$prepared_args['paginate'] = true;
164
165
		// Get the webhooks.
166
		$webhooks    = array();
167
		$data_store  = \WC_Data_Store::load( 'webhook' );
168
		$results     = $data_store->search_webhooks( $prepared_args );
169
		$webhook_ids = $results->webhooks;
170
171
		foreach ( $webhook_ids as $webhook_id ) {
172
			$object = $this->get_object( $webhook_id );
173
174
			if ( ! $object || 0 === $object->get_id() ) {
175
				continue;
176
			}
177
178
			$data       = $this->prepare_item_for_response( $object, $request );
179
			$webhooks[] = $this->prepare_response_for_collection( $data );
180
		}
181
182
		$response       = rest_ensure_response( $webhooks );
183
		$per_page       = (int) $prepared_args['limit'];
184
		$page           = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 );
185
		$total_webhooks = $results->total;
186
		$max_pages      = $results->max_num_pages;
187
		$base           = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) );
188
189
		$response->header( 'X-WP-Total', $total_webhooks );
190
		$response->header( 'X-WP-TotalPages', $max_pages );
191
192
		if ( $page > 1 ) {
193
			$prev_page = $page - 1;
194
			if ( $prev_page > $max_pages ) {
195
				$prev_page = $max_pages;
196
			}
197
			$prev_link = add_query_arg( 'page', $prev_page, $base );
198
			$response->link_header( 'prev', $prev_link );
199
		}
200
		if ( $max_pages > $page ) {
201
			$next_page = $page + 1;
202
			$next_link = add_query_arg( 'page', $next_page, $base );
203
			$response->link_header( 'next', $next_link );
204
		}
205
206
		return $response;
207
	}
208
209
	/**
210
	 * Get object.
211
	 *
212
	 * @param  int $id Object ID.
213
	 * @return \WC_Webhook|bool
214
	 */
215
	protected function get_object( $id ) {
216
		$webhook = wc_get_webhook( $id );
217
218
		if ( empty( $webhook ) || is_null( $webhook ) ) {
219
			return false;
220
		}
221
222
		return $webhook;
223
	}
224
225
	/**
226
	 * Get a single item.
227
	 *
228
	 * @param \WP_REST_Request $request Full details about the request.
229
	 * @return \WP_Error|\WP_REST_Response
230
	 */
231
	public function get_item( $request ) {
232
		$object = $this->get_object( (int) $request['id'] );
233
234
		if ( ! $object || 0 === $object->get_id() ) {
235
			return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) );
236
		}
237
238
		return $this->prepare_item_for_response( $object, $request );
239
	}
240
241
	/**
242
	 * Create a single webhook.
243
	 *
244
	 * @param \WP_REST_Request $request Full details about the request.
245
	 * @return \WP_Error|\WP_REST_Response
246
	 */
247
	public function create_item( $request ) {
248
		if ( ! empty( $request['id'] ) ) {
249
			/* translators: %s: post type */
250
			return new \WP_Error( "woocommerce_rest_{$this->post_type}_exists", sprintf( __( 'Cannot create existing %s.', 'woocommerce' ), $this->post_type ), array( 'status' => 400 ) );
251
		}
252
253
		// Validate topic.
254
		if ( empty( $request['topic'] ) || ! wc_is_webhook_valid_topic( strtolower( $request['topic'] ) ) ) {
255
			return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic is required and must be valid.', 'woocommerce' ), array( 'status' => 400 ) );
256
		}
257
258
		// Validate delivery URL.
259
		if ( empty( $request['delivery_url'] ) || ! wc_is_valid_url( $request['delivery_url'] ) ) {
260
			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' ), array( 'status' => 400 ) );
261
		}
262
263
		$post = $this->prepare_item_for_database( $request );
264
		if ( is_wp_error( $post ) ) {
265
			return $post;
266
		}
267
268
		$webhook = new \WC_Webhook();
269
		$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...
270
		$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...
271
		$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...
272
		$webhook->set_topic( $request['topic'] );
273
		$webhook->set_delivery_url( $request['delivery_url'] );
274
		$webhook->set_secret( ! empty( $request['secret'] ) ? $request['secret'] : wp_generate_password( 50, true, true ) );
275
		$webhook->set_api_version( $this->get_default_api_version() );
276
		$webhook->save();
277
278
		$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

278
		$this->update_additional_fields_for_object( /** @scrutinizer ignore-type */ $webhook, $request );
Loading history...
279
280
		/**
281
		 * Fires after a single item is created or updated via the REST API.
282
		 *
283
		 * @param WC_Webhook      $webhook  Webhook data.
284
		 * @param \WP_REST_Request $request  Request object.
285
		 * @param bool            $creating True when creating item, false when updating.
286
		 */
287
		do_action( 'woocommerce_rest_insert_webhook_object', $webhook, $request, true );
288
289
		$request->set_param( 'context', 'edit' );
290
		$response = $this->prepare_item_for_response( $webhook, $request );
291
		$response = rest_ensure_response( $response );
292
		$response->set_status( 201 );
293
		$response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $webhook->get_id() ) ) );
294
295
		// Send ping.
296
		$webhook->deliver_ping();
297
298
		return $response;
299
	}
300
301
	/**
302
	 * Update a single webhook.
303
	 *
304
	 * @param \WP_REST_Request $request Full details about the request.
305
	 * @return \WP_Error|\WP_REST_Response
306
	 */
307
	public function update_item( $request ) {
308
		$id      = (int) $request['id'];
309
		$webhook = wc_get_webhook( $id );
310
311
		if ( empty( $webhook ) || is_null( $webhook ) ) {
312
			return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'ID is invalid.', 'woocommerce' ), array( 'status' => 400 ) );
313
		}
314
315
		// Update topic.
316
		if ( ! empty( $request['topic'] ) ) {
317
			if ( wc_is_webhook_valid_topic( strtolower( $request['topic'] ) ) ) {
318
				$webhook->set_topic( $request['topic'] );
319
			} else {
320
				return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_topic", __( 'Webhook topic must be valid.', 'woocommerce' ), array( 'status' => 400 ) );
321
			}
322
		}
323
324
		// Update delivery URL.
325
		if ( ! empty( $request['delivery_url'] ) ) {
326
			if ( wc_is_valid_url( $request['delivery_url'] ) ) {
327
				$webhook->set_delivery_url( $request['delivery_url'] );
328
			} else {
329
				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' ), array( 'status' => 400 ) );
330
			}
331
		}
332
333
		// Update secret.
334
		if ( ! empty( $request['secret'] ) ) {
335
			$webhook->set_secret( $request['secret'] );
336
		}
337
338
		// Update status.
339
		if ( ! empty( $request['status'] ) ) {
340
			if ( wc_is_webhook_valid_status( strtolower( $request['status'] ) ) ) {
341
				$webhook->set_status( $request['status'] );
342
			} else {
343
				return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_status", __( 'Webhook status must be valid.', 'woocommerce' ), array( 'status' => 400 ) );
344
			}
345
		}
346
347
		$post = $this->prepare_item_for_database( $request );
348
		if ( is_wp_error( $post ) ) {
349
			return $post;
350
		}
351
352
		if ( isset( $post->post_title ) ) {
353
			$webhook->set_name( $post->post_title );
354
		}
355
356
		$webhook->save();
357
358
		$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

358
		$this->update_additional_fields_for_object( /** @scrutinizer ignore-type */ $webhook, $request );
Loading history...
359
360
		/**
361
		 * Fires after a single item is created or updated via the REST API.
362
		 *
363
		 * @param WC_Webhook      $webhook  Webhook data.
364
		 * @param \WP_REST_Request $request  Request object.
365
		 * @param bool            $creating True when creating item, false when updating.
366
		 */
367
		do_action( 'woocommerce_rest_insert_webhook_object', $webhook, $request, false );
368
369
		$request->set_param( 'context', 'edit' );
370
		$response = $this->prepare_item_for_response( $webhook, $request );
371
372
		return rest_ensure_response( $response );
373
	}
374
375
	/**
376
	 * Delete a single webhook.
377
	 *
378
	 * @param \WP_REST_Request $request Full details about the request.
379
	 * @return \WP_REST_Response|\WP_Error
380
	 */
381
	public function delete_item( $request ) {
382
		$id    = (int) $request['id'];
383
		$force = isset( $request['force'] ) ? (bool) $request['force'] : false;
384
385
		// We don't support trashing for this type, error out.
386
		if ( ! $force ) {
387
			return new \WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Webhooks do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) );
388
		}
389
390
		$webhook = wc_get_webhook( $id );
391
392
		if ( empty( $webhook ) || is_null( $webhook ) ) {
393
			return new \WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) );
394
		}
395
396
		$request->set_param( 'context', 'edit' );
397
		$previous = $this->prepare_item_for_response( $webhook, $request );
398
		$result   = $webhook->delete( true );
399
		if ( ! $result ) {
400
			/* translators: %s: post type */
401
			return new WP_Error( 'woocommerce_rest_cannot_delete', sprintf( __( 'The %s cannot be deleted.', 'woocommerce' ), $this->post_type ), array( 'status' => 500 ) );
0 ignored issues
show
Bug introduced by
The type WooCommerce\RestApi\Controllers\Version4\WP_Error was not found. Did you mean WP_Error? If so, make sure to prefix the type with \.
Loading history...
402
		}
403
		$response = new \WP_REST_Response();
404
		$response->set_data(
405
			array(
406
				'deleted'  => true,
407
				'previous' => $previous->get_data(),
408
			)
409
		);
410
411
		/**
412
		 * Fires after a single item is deleted or trashed via the REST API.
413
		 *
414
		 * @param WC_Webhook       $webhook     The deleted or trashed item.
415
		 * @param \WP_REST_Response $response The response data.
416
		 * @param \WP_REST_Request  $request  The request sent to the API.
417
		 */
418
		do_action( 'woocommerce_rest_delete_webhook_object', $webhook, $response, $request );
419
420
		return $response;
421
	}
422
423
	/**
424
	 * Prepare a single webhook for create or update.
425
	 *
426
	 * @param \WP_REST_Request $request Request object.
427
	 * @return \WP_Error|stdClass $data Post object.
0 ignored issues
show
Bug introduced by
The type WooCommerce\RestApi\Controllers\Version4\stdClass was not found. Did you mean stdClass? If so, make sure to prefix the type with \.
Loading history...
428
	 */
429
	protected function prepare_item_for_database( $request ) {
430
		$data = new \stdClass();
431
432
		// Post ID.
433
		if ( isset( $request['id'] ) ) {
434
			$data->ID = absint( $request['id'] );
435
		}
436
437
		// Validate required POST fields.
438
		if ( 'POST' === $request->get_method() && empty( $data->ID ) ) {
439
			$data->post_title = ! empty( $request['name'] ) ? $request['name'] : sprintf( __( 'Webhook created on %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Webhook created on date parsed by strftime', 'woocommerce' ) ) ); // @codingStandardsIgnoreLine
440
441
			// Post author.
442
			$data->post_author = get_current_user_id();
443
444
			// Post password.
445
			$data->post_password = 'webhook_' . wp_generate_password();
446
447
			// Post status.
448
			$data->post_status = 'publish';
449
		} else {
450
451
			// Allow edit post title.
452
			if ( ! empty( $request['name'] ) ) {
453
				$data->post_title = $request['name'];
454
			}
455
		}
456
457
		// Comment status.
458
		$data->comment_status = 'closed';
459
460
		// Ping status.
461
		$data->ping_status = 'closed';
462
463
		/**
464
		 * Filter the query_vars used in `get_items` for the constructed query.
465
		 *
466
		 * The dynamic portion of the hook name, $this->post_type, refers to post_type of the post being
467
		 * prepared for insertion.
468
		 *
469
		 * @param \stdClass        $data An object representing a single item prepared
470
		 *                                       for inserting or updating the database.
471
		 * @param \WP_REST_Request $request       Request object.
472
		 */
473
		return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}", $data, $request );
474
	}
475
476
	/**
477
	 * Get data for this object in the format of this endpoint's schema.
478
	 *
479
	 * @param \WP_Comment      $object Object to prepare.
480
	 * @param \WP_REST_Request $request Request object.
481
	 * @return array Array of data in the correct format.
482
	 */
483
	protected function get_data_for_response( $object, $request ) {
484
		return array(
485
			'id'                => $object->get_id(),
0 ignored issues
show
Bug introduced by
The method get_id() does not exist on WP_Comment. Did you maybe mean get_child()? ( Ignorable by Annotation )

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

485
			'id'                => $object->/** @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...
486
			'name'              => $object->get_name(),
0 ignored issues
show
Bug introduced by
The method get_name() does not exist on WP_Comment. ( Ignorable by Annotation )

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

486
			'name'              => $object->/** @scrutinizer ignore-call */ get_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...
487
			'status'            => $object->get_status(),
0 ignored issues
show
Bug introduced by
The method get_status() does not exist on WP_Comment. ( Ignorable by Annotation )

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

487
			'status'            => $object->/** @scrutinizer ignore-call */ get_status(),

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...
488
			'topic'             => $object->get_topic(),
0 ignored issues
show
Bug introduced by
The method get_topic() does not exist on WP_Comment. ( Ignorable by Annotation )

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

488
			'topic'             => $object->/** @scrutinizer ignore-call */ get_topic(),

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...
489
			'resource'          => $object->get_resource(),
0 ignored issues
show
Bug introduced by
The method get_resource() does not exist on WP_Comment. ( Ignorable by Annotation )

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

489
			'resource'          => $object->/** @scrutinizer ignore-call */ get_resource(),

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...
490
			'event'             => $object->get_event(),
0 ignored issues
show
Bug introduced by
The method get_event() does not exist on WP_Comment. ( Ignorable by Annotation )

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

490
			'event'             => $object->/** @scrutinizer ignore-call */ get_event(),

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...
491
			'hooks'             => $object->get_hooks(),
0 ignored issues
show
Bug introduced by
The method get_hooks() does not exist on WP_Comment. ( Ignorable by Annotation )

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

491
			'hooks'             => $object->/** @scrutinizer ignore-call */ get_hooks(),

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...
492
			'delivery_url'      => $object->get_delivery_url(),
0 ignored issues
show
Bug introduced by
The method get_delivery_url() does not exist on WP_Comment. ( Ignorable by Annotation )

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

492
			'delivery_url'      => $object->/** @scrutinizer ignore-call */ get_delivery_url(),

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...
493
			'date_created'      => wc_rest_prepare_date_response( $object->get_date_created(), false ),
0 ignored issues
show
Bug introduced by
The method get_date_created() does not exist on WP_Comment. ( Ignorable by Annotation )

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

493
			'date_created'      => wc_rest_prepare_date_response( $object->/** @scrutinizer ignore-call */ get_date_created(), false ),

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...
494
			'date_created_gmt'  => wc_rest_prepare_date_response( $object->get_date_created() ),
495
			'date_modified'     => wc_rest_prepare_date_response( $object->get_date_modified(), false ),
0 ignored issues
show
Bug introduced by
The method get_date_modified() does not exist on WP_Comment. ( Ignorable by Annotation )

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

495
			'date_modified'     => wc_rest_prepare_date_response( $object->/** @scrutinizer ignore-call */ get_date_modified(), false ),

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...
496
			'date_modified_gmt' => wc_rest_prepare_date_response( $object->get_date_modified() ),
497
		);
498
	}
499
500
	/**
501
	 * Prepare links for the request.
502
	 *
503
	 * @param mixed            $item Object to prepare.
504
	 * @param \WP_REST_Request $request Request object.
505
	 * @return array
506
	 */
507
	protected function prepare_links( $item, $request ) {
508
		$links = array(
509
			'self'       => array(
510
				'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $item->get_id() ) ),
511
			),
512
			'collection' => array(
513
				'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ),
514
			),
515
		);
516
517
		return $links;
518
	}
519
520
	/**
521
	 * Get the Webhook's schema, conforming to JSON Schema.
522
	 *
523
	 * @return array
524
	 */
525
	public function get_item_schema() {
526
		$schema = array(
527
			'$schema'    => 'http://json-schema.org/draft-04/schema#',
528
			'title'      => 'webhook',
529
			'type'       => 'object',
530
			'properties' => array(
531
				'id'                => array(
532
					'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
533
					'type'        => 'integer',
534
					'context'     => array( 'view', 'edit' ),
535
					'readonly'    => true,
536
				),
537
				'name'              => array(
538
					'description' => __( 'A friendly name for the webhook.', 'woocommerce' ),
539
					'type'        => 'string',
540
					'context'     => array( 'view', 'edit' ),
541
				),
542
				'status'            => array(
543
					'description' => __( 'Webhook status.', 'woocommerce' ),
544
					'type'        => 'string',
545
					'default'     => 'active',
546
					'enum'        => array_keys( wc_get_webhook_statuses() ),
547
					'context'     => array( 'view', 'edit' ),
548
				),
549
				'topic'             => array(
550
					'description' => __( 'Webhook topic.', 'woocommerce' ),
551
					'type'        => 'string',
552
					'context'     => array( 'view', 'edit' ),
553
				),
554
				'resource'          => array(
555
					'description' => __( 'Webhook resource.', 'woocommerce' ),
556
					'type'        => 'string',
557
					'context'     => array( 'view', 'edit' ),
558
					'readonly'    => true,
559
				),
560
				'event'             => array(
561
					'description' => __( 'Webhook event.', 'woocommerce' ),
562
					'type'        => 'string',
563
					'context'     => array( 'view', 'edit' ),
564
					'readonly'    => true,
565
				),
566
				'hooks'             => array(
567
					'description' => __( 'WooCommerce action names associated with the webhook.', 'woocommerce' ),
568
					'type'        => 'array',
569
					'context'     => array( 'view', 'edit' ),
570
					'readonly'    => true,
571
					'items'       => array(
572
						'type' => 'string',
573
					),
574
				),
575
				'delivery_url'      => array(
576
					'description' => __( 'The URL where the webhook payload is delivered.', 'woocommerce' ),
577
					'type'        => 'string',
578
					'format'      => 'uri',
579
					'context'     => array( 'view', 'edit' ),
580
					'readonly'    => true,
581
				),
582
				'secret'            => array(
583
					'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' ),
584
					'type'        => 'string',
585
					'context'     => array( 'edit' ),
586
				),
587
				'date_created'      => array(
588
					'description' => __( "The date the webhook was created, in the site's timezone.", 'woocommerce' ),
589
					'type'        => 'date-time',
590
					'context'     => array( 'view', 'edit' ),
591
					'readonly'    => true,
592
				),
593
				'date_created_gmt'  => array(
594
					'description' => __( 'The date the webhook was created, as GMT.', 'woocommerce' ),
595
					'type'        => 'date-time',
596
					'context'     => array( 'view', 'edit' ),
597
					'readonly'    => true,
598
				),
599
				'date_modified'     => array(
600
					'description' => __( "The date the webhook was last modified, in the site's timezone.", 'woocommerce' ),
601
					'type'        => 'date-time',
602
					'context'     => array( 'view', 'edit' ),
603
					'readonly'    => true,
604
				),
605
				'date_modified_gmt' => array(
606
					'description' => __( 'The date the webhook was last modified, as GMT.', 'woocommerce' ),
607
					'type'        => 'date-time',
608
					'context'     => array( 'view', 'edit' ),
609
					'readonly'    => true,
610
				),
611
			),
612
		);
613
614
		return $this->add_additional_fields_schema( $schema );
615
	}
616
617
	/**
618
	 * Get the query params for collections of attachments.
619
	 *
620
	 * @return array
621
	 */
622
	public function get_collection_params() {
623
		$params = parent::get_collection_params();
624
625
		$params['context']['default'] = 'view';
626
627
		$params['after']   = array(
628
			'description'       => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'woocommerce' ),
629
			'type'              => 'string',
630
			'format'            => 'date-time',
631
			'validate_callback' => 'rest_validate_request_arg',
632
		);
633
		$params['before']  = array(
634
			'description'       => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'woocommerce' ),
635
			'type'              => 'string',
636
			'format'            => 'date-time',
637
			'validate_callback' => 'rest_validate_request_arg',
638
		);
639
		$params['exclude'] = array(
640
			'description'       => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ),
641
			'type'              => 'array',
642
			'items'             => array(
643
				'type' => 'integer',
644
			),
645
			'default'           => array(),
646
			'sanitize_callback' => 'wp_parse_id_list',
647
		);
648
		$params['include'] = array(
649
			'description'       => __( 'Limit result set to specific ids.', 'woocommerce' ),
650
			'type'              => 'array',
651
			'items'             => array(
652
				'type' > 'integer',
653
			),
654
			'default'           => array(),
655
			'sanitize_callback' => 'wp_parse_id_list',
656
		);
657
		$params['offset']  = array(
658
			'description'       => __( 'Offset the result set by a specific number of items.', 'woocommerce' ),
659
			'type'              => 'integer',
660
			'sanitize_callback' => 'absint',
661
			'validate_callback' => 'rest_validate_request_arg',
662
		);
663
		$params['order']   = array(
664
			'description'       => __( 'Order sort attribute ascending or descending.', 'woocommerce' ),
665
			'type'              => 'string',
666
			'default'           => 'desc',
667
			'enum'              => array( 'asc', 'desc' ),
668
			'validate_callback' => 'rest_validate_request_arg',
669
		);
670
		$params['orderby'] = array(
671
			'description'       => __( 'Sort collection by object attribute.', 'woocommerce' ),
672
			'type'              => 'string',
673
			'default'           => 'date',
674
			'enum'              => array(
675
				'date',
676
				'id',
677
				'title',
678
			),
679
			'validate_callback' => 'rest_validate_request_arg',
680
		);
681
		$params['status']  = array(
682
			'default'           => 'all',
683
			'description'       => __( 'Limit result set to webhooks assigned a specific status.', 'woocommerce' ),
684
			'type'              => 'string',
685
			'enum'              => array( 'all', 'active', 'paused', 'disabled' ),
686
			'sanitize_callback' => 'sanitize_key',
687
			'validate_callback' => 'rest_validate_request_arg',
688
		);
689
690
		return $params;
691
	}
692
693
	/**
694
	 * Return suffix for item action hooks.
695
	 *
696
	 * @return string
697
	 */
698
	protected function get_hook_suffix() {
699
		return $this->post_type;
700
	}
701
}
702