PluginProbe ʕ •ᴥ•ʔ
WooCommerce / 7.3.0-beta.1
WooCommerce v7.3.0-beta.1
10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 7.8.0-beta.1 7.8.0-beta.2 7.8.0-rc.1 7.8.0-rc.2 7.8.1 7.8.2 7.8.3 7.8.4 7.9.0 7.9.0-beta.1 7.9.0-beta.2 7.9.0-rc.2 7.9.0-rc.3 7.9.1 7.9.2 8.0.0 8.0.0-beta.1 8.0.0-beta.2 8.0.0-rc.1 8.0.0-rc.2 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.1.0 8.1.0-beta.1 8.1.0-rc.1 8.1.0-rc.2 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 8.2.0-beta.1 8.2.0-rc.1 8.2.0-rc.2 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.3.0 8.3.0-beta.1 8.3.0-rc.1 8.3.0-rc.2 8.3.1 8.3.2 8.3.3 8.3.4 8.4.0 8.4.0-beta.1 8.4.0-rc.1 8.4.1 8.4.2 8.4.3 8.5.0 8.5.0-beta.1 8.5.0-rc.1 8.5.1 8.5.2 8.5.3 8.5.4 8.5.5 8.6.0 8.6.0-beta.1 8.6.0-rc.1 8.6.1 8.6.2 8.6.3 8.6.4 8.7.0 8.7.0-beta.1 8.7.0-beta.2 8.7.0-rc.1 8.7.1 8.7.2 8.7.3 8.8.0 8.8.0-beta.1 8.8.0-rc.1 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.8.6 8.8.7 8.9.0 8.9.0-beta.1 8.9.0-rc.1 8.9.1 8.9.2 8.9.3 8.9.4 8.9.5 9.0.0 9.0.0-beta.1 9.0.0-beta.2 9.0.0-rc.1 9.0.1 9.0.2 9.0.3 9.0.4 9.1.0 9.1.0-beta.1 9.1.0-rc.1 9.1.1 9.1.2 9.1.3 9.1.4 9.1.5 9.1.6 9.2.0 9.2.0-beta.1 9.2.0-rc.1 9.2.1 9.2.2 9.2.3 9.2.4 9.2.5 9.3.0 9.3.0-beta.1 9.3.0-rc.1 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.3.6 9.4.0 9.4.0-beta.1 9.4.0-beta.2 9.4.0-rc.1 9.4.0-rc.2 9.4.0-rc.3 9.4.0-rc.4 9.4.1 9.4.2 9.4.3 9.4.4 9.4.5 9.5.0 9.5.0-beta.1 9.5.0-beta.2 9.5.0-rc.1 9.5.1 9.5.2 9.5.3 9.5.4 9.6.0 9.6.0-beta.1 9.6.0-beta.2 9.6.0-rc.1 9.6.1 9.6.2 9.6.3 9.6.4 9.7.0 9.7.0-beta.1 9.7.0-rc.1 9.7.1 9.7.2 9.7.3 9.8.0 9.8.0-beta.1 9.8.0-rc.1 9.8.1 9.8.2 9.8.3 9.8.4 9.8.5 9.8.6 9.8.7 9.9.0 9.9.0-beta.1 9.9.0-rc.1 9.9.1 9.9.2 9.9.3 9.9.4 9.9.5 9.9.6 9.9.7 3.7.3 7.1.2 3.8.0 7.2.0 3.8.0-beta.1 7.2.0-beta.1 3.8.0-rc.1 7.2.0-beta.2 3.8.0-rc.2 7.2.0-rc.1 3.8.1 7.2.0-rc.2 3.8.2 7.2.1 3.8.3 7.2.2 3.9.0 7.2.3 3.9.0-beta.1 7.2.4 3.9.0-beta.2 7.3.0 3.9.0-rc.1 7.3.0-beta.1 3.9.0-rc.2 7.3.0-beta.2 3.9.0-rc.3 7.3.0-rc.1 3.9.0-rc.4 7.3.0-rc.2 3.9.1 7.3.1 3.9.2 7.4.0 3.9.3 7.4.0-beta.1 3.9.4 7.4.0-beta.2 3.9.5 7.4.0-rc.1 4.0.0 7.4.0-rc.2 4.0.0-beta.1 7.4.1 4.0.0-rc.1 7.4.2 4.0.0-rc.2 7.5.0 4.0.1 7.5.0-beta.1 4.0.2 7.5.0-beta.2 4.0.3 7.5.0-rc.1 4.0.4 7.5.1 4.1.0 7.5.2 4.1.0-beta.1 7.6.0 4.1.0-beta.2 7.6.0-beta.1 4.1.0-rc.1 7.6.0-beta.2 4.1.0-rc.2 7.6.0-rc.1 4.1.1 7.6.0-rc.2 4.1.2 7.6.0-rc.3 4.1.3 7.6.1 4.1.4 7.6.2 4.2.0 7.7.0 4.2.0-RC.1 7.7.0-beta.1 4.2.0-RC.2 7.7.0-beta.2 4.2.0-beta.1 7.7.0-rc.1 4.2.1 7.7.1 4.2.2 7.7.2 4.2.3 7.7.3 4.2.4 7.8.0 4.2.5 4.3.0 4.3.0-beta.1 4.3.0-rc.1 4.3.0-rc.2 4.3.0-rc.3 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.4.0 4.4.0-beta.1 4.4.0-rc.1 4.4.1 4.4.2 4.4.3 4.4.4 4.5.0 4.5.0-beta.1 4.5.0-rc.1 4.5.0-rc.3 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.6.0-beta.1 4.6.0-rc.1 4.6.1 4.6.2 4.6.3 4.6.4 4.6.5 4.7.0 4.7.0-beta.1 4.7.0-beta.2 4.7.0-rc.1 4.7.1 4.7.1-beta.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.0-beta.1 4.8.0-rc.1 4.8.0-rc.2 4.8.1 4.8.2 4.8.3 4.9.0 4.9.0-beta.1 4.9.0-rc.1 4.9.0-rc.2 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 5.0.0 5.0.0-beta.1 5.0.0-beta.2 5.0.0-rc.1 5.0.0-rc.2 5.0.0-rc.3 5.0.1 5.0.2 5.0.3 5.1.0 5.1.0-beta.1 5.1.0-rc.1 trunk 5.1.1 10.0.0 5.1.2 10.0.0-rc.1 5.1.3 10.0.0-rc.2 5.2.0 10.0.1 5.2.0-beta.1 10.0.2 5.2.0-rc.1 10.0.3 5.2.0-rc.2 10.0.4 5.2.1 10.0.5 5.2.2 10.0.6 5.2.3 10.1.0 5.2.4 10.1.0-rc.1 5.2.5 10.1.0-rc.2 5.3.0 10.1.0-rc.3 5.3.0-beta.1 10.1.0-rc.4 5.3.0-rc.1 10.1.1 5.3.0-rc.2 10.1.2 5.3.1 10.1.3 5.3.2 10.1.4 5.3.3 10.2.0 5.4.0 10.2.0-beta.1 5.4.0-beta.1 10.2.0-beta.2 5.4.0-rc.1 10.2.0-rc.1 5.4.1 10.2.1 5.4.2 10.2.2 5.4.3 10.2.3 5.4.4 10.2.4 5.4.5 10.3.0 5.5.0 10.3.0-beta.1 5.5.0-beta.1 10.3.0-beta.2 5.5.0-rc.1 10.3.0-rc.1 5.5.0-rc.2 10.3.0-rc.2 5.5.1 10.3.1 5.5.2 10.3.2 5.5.3 10.3.3 5.5.4 10.3.4 5.5.5 10.3.5 5.6.0 10.3.6 5.6.0-beta.1 10.3.7 5.6.0-rc.1 10.3.8 5.6.0-rc.2 10.4.0 5.6.1 10.4.0-beta.1 5.6.2 10.4.0-beta.2 5.6.3 10.4.0-rc.1 5.7.0 10.4.1 5.7.0-beta.1 10.4.2 5.7.0-rc.1 10.4.3 5.7.1 10.4.4 5.7.2 10.5.0 5.7.3 10.5.0-beta.1 5.8.0 10.5.0-beta.2 5.8.0-beta.1 10.5.0-rc.1 5.8.0-beta.2 10.5.0-rc.2 5.8.0-rc.1 10.5.0-rc.3 5.8.1 10.5.1 5.8.2 10.5.2 5.9.0 10.5.3 5.9.0-beta.1 10.6.0 5.9.0-rc.1 10.6.0-beta.1 5.9.0-rc.2 10.6.0-beta.2 5.9.1 10.6.0-rc.1 5.9.2 10.6.1 6.0.0 10.6.2 6.0.0-beta.1 10.7.0 6.0.0-rc.1 10.7.0-beta.1 6.0.1 10.7.0-beta.2 6.0.2 10.7.0-rc.1 6.1.0 3.0.0 6.1.0-beta.1 3.0.1 6.1.0-rc.1 3.0.2 6.1.0-rc.2 3.0.3 6.1.1 3.0.4 6.1.2 3.0.5 6.1.3 3.0.6 6.2.0 3.0.7 6.2.0-beta.1 3.0.8 6.2.0-rc.1 3.0.9 6.2.0-rc.2 3.1.0 6.2.1 3.1.1 6.2.2 3.1.2 6.2.3 3.2.0 6.3.0 3.2.1 6.3.0-beta.1 3.2.2 6.3.0-rc.1 3.2.3 6.3.0-rc.2 3.2.4 6.3.1 3.2.5 6.3.2 3.2.6 6.4.0 3.3.0 6.4.0-beta.1 3.3.1 6.4.0-rc.1 3.3.2 6.4.1 3.3.2-rc.1 6.4.2 3.3.3 6.5.0 3.3.4 6.5.0-beta.1 3.3.5 6.5.0-rc.1 3.3.6 6.5.0-rc.2 3.4.0 6.5.1 3.4.0-beta.1 6.5.2 3.4.0-rc.2 6.6.0 3.4.1 6.6.0-beta.1 3.4.2 6.6.0-rc.1 3.4.3 6.6.0-rc.2 3.4.4 6.6.1 3.4.5 6.6.2 3.4.6 6.7.0 3.4.7 6.7.0-beta.1 3.4.8 6.7.0-beta.2 3.5.0 6.7.0-rc.1 3.5.0-beta.1 6.7.1 3.5.0-rc.1 6.8.0 3.5.0-rc.2 6.8.0-beta.1 3.5.1 6.8.0-beta.2 3.5.10 6.8.0-rc.1 3.5.2 6.8.1 3.5.3 6.8.2 3.5.4 6.8.3 3.5.5 6.9.0 3.5.6 6.9.0-beta.1 3.5.7 6.9.0-beta.2 3.5.8 6.9.0-rc.1 3.5.9 6.9.1 3.6.0 6.9.2 3.6.0-beta.1 6.9.3 3.6.0-rc.1 6.9.4 3.6.0-rc.2 6.9.5 3.6.0-rc.3 7.0.0 3.6.1 7.0.0-beta.1 3.6.2 7.0.0-beta.2 3.6.3 7.0.0-beta.3 3.6.4 7.0.0-rc.1 3.6.5 7.0.0-rc.2 3.6.6 7.0.1 3.6.7 7.0.2 3.7.0 7.1.0 3.7.0-beta.1 7.1.0-beta.1 3.7.0-rc.1 7.1.0-beta.2 3.7.0-rc.2 7.1.0-rc.1 3.7.1 7.1.0-rc.2 3.7.2 7.1.1
woocommerce / includes / legacy / api / v3 / class-wc-api-webhooks.php
woocommerce / includes / legacy / api / v3 Last commit date
class-wc-api-authentication.php 5 years ago class-wc-api-coupons.php 5 years ago class-wc-api-customers.php 5 years ago class-wc-api-exception.php 5 years ago class-wc-api-json-handler.php 5 years ago class-wc-api-orders.php 4 years ago class-wc-api-products.php 3 years ago class-wc-api-reports.php 5 years ago class-wc-api-resource.php 4 years ago class-wc-api-server.php 5 years ago class-wc-api-taxes.php 4 years ago class-wc-api-webhooks.php 3 years ago interface-wc-api-handler.php 5 years ago
class-wc-api-webhooks.php
510 lines
1 <?php
2 /**
3 * WooCommerce API Webhooks class
4 *
5 * Handles requests to the /webhooks endpoint
6 *
7 * @author WooThemes
8 * @category API
9 * @package WooCommerce\RestApi
10 * @since 2.2
11 */
12
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit; // Exit if accessed directly
15 }
16
17 class WC_API_Webhooks extends WC_API_Resource {
18
19 /** @var string $base the route base */
20 protected $base = '/webhooks';
21
22 /**
23 * Register the routes for this class
24 *
25 * @since 2.2
26 * @param array $routes
27 * @return array
28 */
29 public function register_routes( $routes ) {
30
31 # GET|POST /webhooks
32 $routes[ $this->base ] = array(
33 array( array( $this, 'get_webhooks' ), WC_API_Server::READABLE ),
34 array( array( $this, 'create_webhook' ), WC_API_Server::CREATABLE | WC_API_Server::ACCEPT_DATA ),
35 );
36
37 # GET /webhooks/count
38 $routes[ $this->base . '/count' ] = array(
39 array( array( $this, 'get_webhooks_count' ), WC_API_Server::READABLE ),
40 );
41
42 # GET|PUT|DELETE /webhooks/<id>
43 $routes[ $this->base . '/(?P<id>\d+)' ] = array(
44 array( array( $this, 'get_webhook' ), WC_API_Server::READABLE ),
45 array( array( $this, 'edit_webhook' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ),
46 array( array( $this, 'delete_webhook' ), WC_API_Server::DELETABLE ),
47 );
48
49 # GET /webhooks/<id>/deliveries
50 $routes[ $this->base . '/(?P<webhook_id>\d+)/deliveries' ] = array(
51 array( array( $this, 'get_webhook_deliveries' ), WC_API_Server::READABLE ),
52 );
53
54 # GET /webhooks/<webhook_id>/deliveries/<id>
55 $routes[ $this->base . '/(?P<webhook_id>\d+)/deliveries/(?P<id>\d+)' ] = array(
56 array( array( $this, 'get_webhook_delivery' ), WC_API_Server::READABLE ),
57 );
58
59 return $routes;
60 }
61
62 /**
63 * Get all webhooks
64 *
65 * @since 2.2
66 *
67 * @param array $fields
68 * @param array $filter
69 * @param string $status
70 * @param int $page
71 *
72 * @return array
73 */
74 public function get_webhooks( $fields = null, $filter = array(), $status = null, $page = 1 ) {
75
76 if ( ! empty( $status ) ) {
77 $filter['status'] = $status;
78 }
79
80 $filter['page'] = $page;
81
82 $query = $this->query_webhooks( $filter );
83
84 $webhooks = array();
85
86 foreach ( $query['results'] as $webhook_id ) {
87 $webhooks[] = current( $this->get_webhook( $webhook_id, $fields ) );
88 }
89
90 $this->server->add_pagination_headers( $query['headers'] );
91
92 return array( 'webhooks' => $webhooks );
93 }
94
95 /**
96 * Get the webhook for the given ID
97 *
98 * @since 2.2
99 * @param int $id webhook ID
100 * @param array $fields
101 * @return array|WP_Error
102 */
103 public function get_webhook( $id, $fields = null ) {
104
105 // ensure webhook ID is valid & user has permission to read
106 $id = $this->validate_request( $id, 'shop_webhook', 'read' );
107
108 if ( is_wp_error( $id ) ) {
109 return $id;
110 }
111
112 $webhook = wc_get_webhook( $id );
113
114 $webhook_data = array(
115 'id' => $webhook->get_id(),
116 'name' => $webhook->get_name(),
117 'status' => $webhook->get_status(),
118 'topic' => $webhook->get_topic(),
119 'resource' => $webhook->get_resource(),
120 'event' => $webhook->get_event(),
121 'hooks' => $webhook->get_hooks(),
122 'delivery_url' => $webhook->get_delivery_url(),
123 'created_at' => $this->server->format_datetime( $webhook->get_date_created() ? $webhook->get_date_created()->getTimestamp() : 0, false, false ), // API gives UTC times.
124 'updated_at' => $this->server->format_datetime( $webhook->get_date_modified() ? $webhook->get_date_modified()->getTimestamp() : 0, false, false ), // API gives UTC times.
125 );
126
127 return array( 'webhook' => apply_filters( 'woocommerce_api_webhook_response', $webhook_data, $webhook, $fields, $this ) );
128 }
129
130 /**
131 * Get the total number of webhooks
132 *
133 * @since 2.2
134 *
135 * @param string $status
136 * @param array $filter
137 *
138 * @return array|WP_Error
139 */
140 public function get_webhooks_count( $status = null, $filter = array() ) {
141 try {
142 if ( ! current_user_can( 'manage_woocommerce' ) ) {
143 throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_webhooks_count', __( 'You do not have permission to read the webhooks count', 'woocommerce' ), 401 );
144 }
145
146 if ( ! empty( $status ) ) {
147 $filter['status'] = $status;
148 }
149
150 $query = $this->query_webhooks( $filter );
151
152 return array( 'count' => $query['headers']->total );
153 } catch ( WC_API_Exception $e ) {
154 return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) );
155 }
156 }
157
158 /**
159 * Create an webhook
160 *
161 * @since 2.2
162 *
163 * @param array $data parsed webhook data
164 *
165 * @return array|WP_Error
166 */
167 public function create_webhook( $data ) {
168
169 try {
170 if ( ! isset( $data['webhook'] ) ) {
171 throw new WC_API_Exception( 'woocommerce_api_missing_webhook_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'webhook' ), 400 );
172 }
173
174 $data = $data['webhook'];
175
176 // permission check
177 if ( ! current_user_can( 'manage_woocommerce' ) ) {
178 throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_webhooks', __( 'You do not have permission to create webhooks.', 'woocommerce' ), 401 );
179 }
180
181 $data = apply_filters( 'woocommerce_api_create_webhook_data', $data, $this );
182
183 // validate topic
184 if ( empty( $data['topic'] ) || ! wc_is_webhook_valid_topic( strtolower( $data['topic'] ) ) ) {
185 throw new WC_API_Exception( 'woocommerce_api_invalid_webhook_topic', __( 'Webhook topic is required and must be valid.', 'woocommerce' ), 400 );
186 }
187
188 // validate delivery URL
189 if ( empty( $data['delivery_url'] ) || ! wc_is_valid_url( $data['delivery_url'] ) ) {
190 throw new WC_API_Exception( 'woocommerce_api_invalid_webhook_delivery_url', __( 'Webhook delivery URL must be a valid URL starting with http:// or https://', 'woocommerce' ), 400 );
191 }
192
193 $webhook_data = apply_filters( 'woocommerce_new_webhook_data', array(
194 'post_type' => 'shop_webhook',
195 'post_status' => 'publish',
196 'ping_status' => 'closed',
197 'post_author' => get_current_user_id(),
198 'post_password' => 'webhook_' . wp_generate_password(),
199 'post_title' => ! empty( $data['name'] ) ? $data['name'] : sprintf( __( 'Webhook created on %s', 'woocommerce' ), (new DateTime('now'))->format( _x( 'M d, Y @ h:i A', 'Webhook created on date parsed by DateTime::format', 'woocommerce' ) ) ),
200 ), $data, $this );
201
202 $webhook = new WC_Webhook();
203
204 $webhook->set_name( $webhook_data['post_title'] );
205 $webhook->set_user_id( $webhook_data['post_author'] );
206 $webhook->set_status( 'publish' === $webhook_data['post_status'] ? 'active' : 'disabled' );
207 $webhook->set_topic( $data['topic'] );
208 $webhook->set_delivery_url( $data['delivery_url'] );
209 $webhook->set_secret( ! empty( $data['secret'] ) ? $data['secret'] : wp_generate_password( 50, true, true ) );
210 $webhook->set_api_version( 'legacy_v3' );
211 $webhook->save();
212
213 $webhook->deliver_ping();
214
215 // HTTP 201 Created
216 $this->server->send_status( 201 );
217
218 do_action( 'woocommerce_api_create_webhook', $webhook->get_id(), $this );
219
220 return $this->get_webhook( $webhook->get_id() );
221
222 } catch ( WC_API_Exception $e ) {
223
224 return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) );
225 }
226 }
227
228 /**
229 * Edit a webhook
230 *
231 * @since 2.2
232 *
233 * @param int $id webhook ID
234 * @param array $data parsed webhook data
235 *
236 * @return array|WP_Error
237 */
238 public function edit_webhook( $id, $data ) {
239
240 try {
241 if ( ! isset( $data['webhook'] ) ) {
242 throw new WC_API_Exception( 'woocommerce_api_missing_webhook_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'webhook' ), 400 );
243 }
244
245 $data = $data['webhook'];
246
247 $id = $this->validate_request( $id, 'shop_webhook', 'edit' );
248
249 if ( is_wp_error( $id ) ) {
250 return $id;
251 }
252
253 $data = apply_filters( 'woocommerce_api_edit_webhook_data', $data, $id, $this );
254
255 $webhook = wc_get_webhook( $id );
256
257 // update topic
258 if ( ! empty( $data['topic'] ) ) {
259
260 if ( wc_is_webhook_valid_topic( strtolower( $data['topic'] ) ) ) {
261
262 $webhook->set_topic( $data['topic'] );
263
264 } else {
265 throw new WC_API_Exception( 'woocommerce_api_invalid_webhook_topic', __( 'Webhook topic must be valid.', 'woocommerce' ), 400 );
266 }
267 }
268
269 // update delivery URL
270 if ( ! empty( $data['delivery_url'] ) ) {
271 if ( wc_is_valid_url( $data['delivery_url'] ) ) {
272
273 $webhook->set_delivery_url( $data['delivery_url'] );
274
275 } else {
276 throw new WC_API_Exception( 'woocommerce_api_invalid_webhook_delivery_url', __( 'Webhook delivery URL must be a valid URL starting with http:// or https://', 'woocommerce' ), 400 );
277 }
278 }
279
280 // update secret
281 if ( ! empty( $data['secret'] ) ) {
282 $webhook->set_secret( $data['secret'] );
283 }
284
285 // update status
286 if ( ! empty( $data['status'] ) ) {
287 $webhook->set_status( $data['status'] );
288 }
289
290 // update name
291 if ( ! empty( $data['name'] ) ) {
292 $webhook->set_name( $data['name'] );
293 }
294
295 $webhook->save();
296
297 do_action( 'woocommerce_api_edit_webhook', $webhook->get_id(), $this );
298
299 return $this->get_webhook( $webhook->get_id() );
300
301 } catch ( WC_API_Exception $e ) {
302
303 return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) );
304 }
305 }
306
307 /**
308 * Delete a webhook
309 *
310 * @since 2.2
311 * @param int $id webhook ID
312 * @return array|WP_Error
313 */
314 public function delete_webhook( $id ) {
315
316 $id = $this->validate_request( $id, 'shop_webhook', 'delete' );
317
318 if ( is_wp_error( $id ) ) {
319 return $id;
320 }
321
322 do_action( 'woocommerce_api_delete_webhook', $id, $this );
323
324 $webhook = wc_get_webhook( $id );
325
326 return $webhook->delete( true );
327 }
328
329 /**
330 * Helper method to get webhook post objects
331 *
332 * @since 2.2
333 * @param array $args Request arguments for filtering query.
334 * @return array
335 */
336 private function query_webhooks( $args ) {
337 $args = $this->merge_query_args( array(), $args );
338
339 $args['limit'] = isset( $args['posts_per_page'] ) ? intval( $args['posts_per_page'] ) : intval( get_option( 'posts_per_page' ) );
340
341 if ( empty( $args['offset'] ) ) {
342 $args['offset'] = 1 < $args['paged'] ? ( $args['paged'] - 1 ) * $args['limit'] : 0;
343 }
344
345 $page = $args['paged'];
346 unset( $args['paged'], $args['posts_per_page'] );
347
348 if ( isset( $args['s'] ) ) {
349 $args['search'] = $args['s'];
350 unset( $args['s'] );
351 }
352
353 // Post type to webhook status.
354 if ( ! empty( $args['post_status'] ) ) {
355 $args['status'] = $args['post_status'];
356 unset( $args['post_status'] );
357 }
358
359 if ( ! empty( $args['post__in'] ) ) {
360 $args['include'] = $args['post__in'];
361 unset( $args['post__in'] );
362 }
363
364 if ( ! empty( $args['date_query'] ) ) {
365 foreach ( $args['date_query'] as $date_query ) {
366 if ( 'post_date_gmt' === $date_query['column'] ) {
367 $args['after'] = isset( $date_query['after'] ) ? $date_query['after'] : null;
368 $args['before'] = isset( $date_query['before'] ) ? $date_query['before'] : null;
369 } elseif ( 'post_modified_gmt' === $date_query['column'] ) {
370 $args['modified_after'] = isset( $date_query['after'] ) ? $date_query['after'] : null;
371 $args['modified_before'] = isset( $date_query['before'] ) ? $date_query['before'] : null;
372 }
373 }
374
375 unset( $args['date_query'] );
376 }
377
378 $args['paginate'] = true;
379
380 // Get the webhooks.
381 $data_store = WC_Data_Store::load( 'webhook' );
382 $results = $data_store->search_webhooks( $args );
383
384 // Get total items.
385 $headers = new stdClass;
386 $headers->page = $page;
387 $headers->total = $results->total;
388 $headers->is_single = $args['limit'] > $headers->total;
389 $headers->total_pages = $results->max_num_pages;
390
391 return array(
392 'results' => $results->webhooks,
393 'headers' => $headers,
394 );
395 }
396
397 /**
398 * Get deliveries for a webhook
399 *
400 * @since 2.2
401 * @deprecated 3.3.0 Webhooks deliveries logs now uses logging system.
402 * @param string $webhook_id webhook ID
403 * @param string|null $fields fields to include in response
404 * @return array|WP_Error
405 */
406 public function get_webhook_deliveries( $webhook_id, $fields = null ) {
407
408 // Ensure ID is valid webhook ID
409 $webhook_id = $this->validate_request( $webhook_id, 'shop_webhook', 'read' );
410
411 if ( is_wp_error( $webhook_id ) ) {
412 return $webhook_id;
413 }
414
415 return array( 'webhook_deliveries' => array() );
416 }
417
418 /**
419 * Get the delivery log for the given webhook ID and delivery ID
420 *
421 * @since 2.2
422 * @deprecated 3.3.0 Webhooks deliveries logs now uses logging system.
423 * @param string $webhook_id webhook ID
424 * @param string $id delivery log ID
425 * @param string|null $fields fields to limit response to
426 *
427 * @return array|WP_Error
428 */
429 public function get_webhook_delivery( $webhook_id, $id, $fields = null ) {
430 try {
431 // Validate webhook ID
432 $webhook_id = $this->validate_request( $webhook_id, 'shop_webhook', 'read' );
433
434 if ( is_wp_error( $webhook_id ) ) {
435 return $webhook_id;
436 }
437
438 $id = absint( $id );
439
440 if ( empty( $id ) ) {
441 throw new WC_API_Exception( 'woocommerce_api_invalid_webhook_delivery_id', __( 'Invalid webhook delivery ID.', 'woocommerce' ), 404 );
442 }
443
444 $webhook = new WC_Webhook( $webhook_id );
445
446 $log = 0;
447
448 if ( ! $log ) {
449 throw new WC_API_Exception( 'woocommerce_api_invalid_webhook_delivery_id', __( 'Invalid webhook delivery.', 'woocommerce' ), 400 );
450 }
451
452 return array( 'webhook_delivery' => apply_filters( 'woocommerce_api_webhook_delivery_response', array(), $id, $fields, $log, $webhook_id, $this ) );
453 } catch ( WC_API_Exception $e ) {
454 return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) );
455 }
456 }
457
458 /**
459 * Validate the request by checking:
460 *
461 * 1) the ID is a valid integer.
462 * 2) the ID returns a valid post object and matches the provided post type.
463 * 3) the current user has the proper permissions to read/edit/delete the post.
464 *
465 * @since 3.3.0
466 * @param string|int $id The post ID
467 * @param string $type The post type, either `shop_order`, `shop_coupon`, or `product`.
468 * @param string $context The context of the request, either `read`, `edit` or `delete`.
469 * @return int|WP_Error Valid post ID or WP_Error if any of the checks fails.
470 */
471 protected function validate_request( $id, $type, $context ) {
472 $id = absint( $id );
473
474 // Validate ID.
475 if ( empty( $id ) ) {
476 return new WP_Error( "woocommerce_api_invalid_webhook_id", sprintf( __( 'Invalid %s ID', 'woocommerce' ), $type ), array( 'status' => 404 ) );
477 }
478
479 $webhook = wc_get_webhook( $id );
480
481 if ( null === $webhook ) {
482 return new WP_Error( "woocommerce_api_no_webhook_found", sprintf( __( 'No %1$s found with the ID equal to %2$s', 'woocommerce' ), 'webhook', $id ), array( 'status' => 404 ) );
483 }
484
485 // Validate permissions.
486 switch ( $context ) {
487
488 case 'read':
489 if ( ! current_user_can( 'manage_woocommerce' ) ) {
490 return new WP_Error( "woocommerce_api_user_cannot_read_webhook", sprintf( __( 'You do not have permission to read this %s', 'woocommerce' ), 'webhook' ), array( 'status' => 401 ) );
491 }
492 break;
493
494 case 'edit':
495 if ( ! current_user_can( 'manage_woocommerce' ) ) {
496 return new WP_Error( "woocommerce_api_user_cannot_edit_webhook", sprintf( __( 'You do not have permission to edit this %s', 'woocommerce' ), 'webhook' ), array( 'status' => 401 ) );
497 }
498 break;
499
500 case 'delete':
501 if ( ! current_user_can( 'manage_woocommerce' ) ) {
502 return new WP_Error( "woocommerce_api_user_cannot_delete_webhook", sprintf( __( 'You do not have permission to delete this %s', 'woocommerce' ), 'webhook' ), array( 'status' => 401 ) );
503 }
504 break;
505 }
506
507 return $id;
508 }
509 }
510