PluginProbe
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 1.2.5
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v1.2.5
4.7.2 4.7.1 4.7.0 4.6.6 4.6.5 4.6.4 4.6.3 4.6.2 4.6.1 4.6.0 4.5.1 4.5.0 4.4.2 4.4.1 4.4.0 4.3.3 4.3.2 4.3.1 4.3.0 4.2.3 4.2.2 4.2.1 1.0.3 1.0.4 1.0.5 All 281 releases
← All changes | app/src/Controllers/Web/WebhookController.php +113 -114 4.5.01.2.5 View file →
@@ -1,11 +1,10 @@
1 1 <?php
2 -
3 2 namespace SureCart\Controllers\Web;
4 3
5 -use SureCart\Models\IncomingWebhook;
6 -use SureCart\Models\RegisteredWebhook;
7 -use SureCartVendors\Psr\Http\Message\ResponseInterface;
4 +use SureCart\Models\Webhook;
5 +use SureCart\Webhooks\WebhooksHistoryService;
6 +use SureCartCore\Responses\RedirectResponse;
8 7
9 8 /**
10 9 * Handles webhooks
11 10 */
@@ -10,83 +9,67 @@
10 9 * Handles webhooks
11 10 */
12 11 class WebhookController {
13 12 /**
14 - * Create new webhook for this site.
13 + * Map object names to their models.
15 14 *
16 - * @param \SureCartCore\Requests\RequestInterface $request Request.
17 - * @return ResponseInterface
15 + * @var array
18 16 */
19 - public function create( $request ) {
20 - // We'll create a webhook for this site register the webhooks.
21 - $registered = RegisteredWebhook::create();
17 + protected $models = [
18 + 'charge' => \SureCart\Models\Charge::class,
19 + 'coupon' => \SureCart\Models\Coupon::class,
20 + 'customer' => \SureCart\Models\Customer::class,
21 + 'purchase' => \SureCart\Models\Purchase::class,
22 + 'price' => \SureCart\Models\Price::class,
23 + 'product' => \SureCart\Models\Product::class,
24 + 'period' => \SureCart\Models\Period::class,
25 + 'order' => \SureCart\Models\Order::class,
26 + 'refund' => \SureCart\Models\Refund::class,
27 + 'subscription' => \SureCart\Models\Subscription::class,
28 + 'invoice' => \SureCart\Models\Invoice::class,
29 + ];
22 30
23 - // handle error and show notice to user.
24 - if ( is_wp_error( $registered ) ) {
25 - // show notice.
26 - \SureCart::notices()->add(
27 - [
28 - 'name' => 'webhooks_registration_error',
29 - 'type' => 'warning',
30 - 'title' => esc_html__( 'SureCart Webhook Creation Error', 'surecart' ),
31 - 'text' => sprintf( '<p>%s</p>', ( implode( '<br />', $registered->get_error_messages() ?? [] ) ) ),
32 - ]
33 - );
34 - }
35 -
36 - // test it.
37 - $registered->test();
38 -
39 - return \SureCart::redirect()->to( esc_url_raw( admin_url( 'admin.php?page=sc-dashboard' ) ) );
40 - }
41 -
42 31 /**
43 - * Update the webhook.
32 + * Remove the webhook.
44 33 *
45 34 * @param \SureCartCore\Requests\RequestInterface $request Request.
46 - * @return ResponseInterface
35 + * @return function
47 36 */
48 - public function update( $request ) {
49 - // Find the registered webhook.
50 - $webhook = RegisteredWebhook::find();
51 - if ( is_wp_error( $webhook ) ) {
52 - wp_die( wp_kses_post( $webhook->get_error_message() ) );
37 + public function remove( $request ) {
38 + $deleted = Webhook::delete( $request->query( 'id' ) );
39 + if ( is_wp_error( $deleted ) ) {
40 + wp_die( $deleted->get_error_message() );
53 41 }
54 -
55 - // update webhook.
56 - $updated = RegisteredWebhook::update();
57 -
58 - // handle error.
59 - if ( is_wp_error( $updated ) ) {
60 - wp_die( wp_kses_post( $updated->get_error_message() ) );
61 - }
62 -
63 - return \SureCart::redirect()->to( esc_url_raw( admin_url( 'admin.php?page=sc-dashboard' ) ) );
42 + return ( new RedirectResponse( $request ) )->back();
64 43 }
65 44
66 45 /**
67 - * This deletes and recreates the webhook
68 - * in case the signing secret is invalid for some reason.
46 + * Remove the webhook.
69 47 *
70 48 * @param \SureCartCore\Requests\RequestInterface $request Request.
71 - * @return ResponseInterface
49 + * @return function
72 50 */
73 - public function resync( $request ) {
74 - // Delete the registered webhook.
75 - $webhook = RegisteredWebhook::registration()->delete();
76 - if ( is_wp_error( $webhook ) ) {
77 - wp_die( wp_kses_post( $webhook->get_error_message() ) );
78 - }
51 + public function ignore( $request ) {
52 + $service = new WebHooksHistoryService();
53 + $service->deletePreviousWebhook();
54 + return ( new RedirectResponse( $request ) )->back();
55 + }
79 56
80 - // recreate.
81 - return $this->create( $request );
57 + /**
58 + * Create a webhook for this install.
59 + */
60 + public function create() {
61 + return Webhook::create(
62 + [
63 + 'description' => 'Main webhook for SureCart',
64 + 'enabled' => true,
65 + 'url' => \SureCart::routeUrl( 'webhooks.receive' ),
66 + ]
67 + );
82 68 }
83 69
84 70 /**
85 - * Recieve webhook.
86 - *
87 - * @param \SureCartCore\Requests\RequestInterface $request Request.
88 - * @return ResponseInterface
71 + * Recieve webhook
89 72 */
90 73 public function receive( $request ) {
91 74 // get json if sent.
92 75 if ( 'application/json' === $request->getHeaderLine( 'Content-Type' ) ) {
@@ -94,25 +77,13 @@
94 77 } else {
95 78 $body = $request->getParsedBody();
96 79 }
97 80
98 - // validate body.
99 - if ( empty( $body['type'] ) ) {
100 - return new \WP_Error( 'missing_type', 'Missing type.' );
101 - }
102 - if ( empty( $body['data'] ) ) {
103 - return new \WP_Error( 'missing_data', 'Missing data.' );
104 - }
105 - if ( empty( $body['id'] ) ) {
106 - return new \WP_Error( 'missing_id', 'Missing id.' );
107 - }
108 -
109 - // make sure we don't have a duplicate webhook.
110 - $webhook = IncomingWebhook::where( 'webhook_id', $body['id'] )->first();
111 - if ( ! empty( $webhook->id ) ) {
81 + // the model does not exist.
82 + if ( empty( $this->models[ $body['data']['object']['object'] ] ) ) {
112 83 return \SureCart::json(
113 84 [
114 - 'status' => 'already_handled',
85 + 'event_triggered' => 'none',
115 86 ]
116 87 )
117 88 ->withHeader( 'X-SURECART-WP-PLUGIN-VERSION', \SureCart::plugin()->version() )
118 89 ->withStatus( 200 );
@@ -117,46 +88,13 @@
117 88 ->withHeader( 'X-SURECART-WP-PLUGIN-VERSION', \SureCart::plugin()->version() )
118 89 ->withStatus( 200 );
119 90 }
120 91
121 - // create incoming webhook.
122 - $incoming = IncomingWebhook::create(
123 - [
124 - 'webhook_id' => $body['id'],
125 - 'data' => $body,
126 - 'source' => 'surecart',
127 - ]
128 - );
92 + // perform the action.
93 + $action = $this->doAction( $body );
129 94
130 - if ( is_wp_error( $incoming ) ) {
131 - return \SureCart::json(
132 - [
133 - 'error' => $incoming->get_error_message(),
134 - ]
135 - )
136 - ->withHeader( 'X-SURECART-WP-PLUGIN-VERSION', \SureCart::plugin()->version() )
137 - ->withStatus( 500 );
138 - }
139 -
140 - if ( empty( $incoming->id ) ) {
141 - return \SureCart::json(
142 - [
143 - 'error' => 'Failed to create webhook.',
144 - ]
145 - )
146 - ->withHeader( 'X-SURECART-WP-PLUGIN-VERSION', \SureCart::plugin()->version() )
147 - ->withStatus( 400 );
148 - }
149 -
150 - // dispatch an async request.
151 - \SureCart::async()->data(
152 - [
153 - 'id' => $incoming->id,
154 - ]
155 - )->dispatch();
156 -
157 95 // handle the response.
158 - return $this->handleResponse( $incoming->id, $incoming->toArray() );
96 + return $this->handleResponse( $action );
159 97 }
160 98
161 99 /**
162 100 * Handle the response back to the webhook.
@@ -163,9 +101,9 @@
163 101 *
164 102 * @param array|\WP_Error $data Data.
165 103 * @return function
166 104 */
167 - public function handleResponse( $id, $data ) {
105 + public function handleResponse( $data ) {
168 106 // handle the response.
169 107 if ( is_wp_error( $data ) ) {
170 108 return \SureCart::json( [ $data->get_error_code() => $data->get_error_message() ] )
171 109 ->withHeader( 'X-SURECART-WP-PLUGIN-VERSION', \SureCart::plugin()->version() )
@@ -179,9 +117,8 @@
179 117 }
180 118
181 119 return \SureCart::json(
182 120 [
183 - 'process_id' => $id,
184 121 'event_triggered' => $data['event'] ?? 'none',
185 122 'data' => $data,
186 123 ]
187 124 )
@@ -186,6 +123,68 @@
186 123 ]
187 124 )
188 125 ->withHeader( 'X-SURECART-WP-PLUGIN-VERSION', \SureCart::plugin()->version() )
189 126 ->withStatus( 200 );
127 + }
128 +
129 + /**
130 + * Perform the action.
131 + *
132 + * @param object $request Request.
133 + *
134 + * @return array|\WP_Error
135 + */
136 + public function doAction( $request ) {
137 + if ( empty( $request['type'] ) ) {
138 + return new \WP_Error( 'missing_type', 'Missing type.' );
139 + }
140 + if ( empty( $request['data'] ) ) {
141 + return new \WP_Error( 'missing_data', 'Missing data.' );
142 + }
143 +
144 + // create the event name.
145 + $event = $this->createEventName( $request['type'] );
146 + $id = $this->getObjectId( $request['data'] );
147 + $model = new $this->models[ $request['data']['object']['object'] ]( $request['data'] );
148 +
149 + // broadcast the webhook.
150 + do_action( $event, $model, $request );
151 +
152 + // return data.
153 + return [
154 + 'event' => $event,
155 + 'id' => $id,
156 + 'request' => $request,
157 + ];
158 + }
159 +
160 + /**
161 + * Replace our dot notation webhook with underscore.
162 + *
163 + * @param string $type The event type.
164 + * @return string
165 + */
166 + public function createEventName( $type = '' ) {
167 + $type = str_replace( '.', '_', $type );
168 + return "surecart/$type";
169 + }
170 +
171 + /**
172 + * Get the first object property in data.
173 + *
174 + * @param object $data Request data.
175 + * @return string
176 + */
177 + public function getObjectId( $data ) {
178 + return $data->object->id ?? '';
179 + }
180 +
181 + /**
182 + * Find the object name.
183 + *
184 + * @param object|array $data Request data.
185 + * @return string
186 + */
187 + public function getObjectName( $data ) {
188 + return array_key_first( (array) $data );
190 189 }
191 190 }