PluginProbe
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 2.11.3
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v2.11.3
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
surecart / app / src / Integrations / IntegrationService.php
IntegrationService.php
387 lines 9.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace SureCart\Integrations;
4
5 use SureCart\Integrations\Contracts\IntegrationInterface;
6 use SureCart\Integrations\Contracts\PurchaseSyncInterface;
7 use SureCart\Models\Integration;
8 use SureCart\Models\Purchase;
9
10 /**
11 * Base class for integrations to extend.
12 */
13 abstract class IntegrationService extends AbstractIntegration implements IntegrationInterface {
14 /**
15 * Purchase model for the integration.
16 *
17 * @var \SureCart\Models\Purchase
18 */
19 protected $purchase = null;
20
21 /**
22 * The current user for the integration.
23 *
24 * @var \WP_User
25 */
26 protected $user = null;
27
28 /**
29 * Get the slug for the integration.
30 *
31 * @return string
32 */
33 public function getName() {
34 return '';
35 }
36
37 /**
38 * Get the model for the integration.
39 *
40 * @return string
41 */
42 public function getModel() {
43 return '';
44 }
45
46
47 /**
48 * Get the logo for the integration.
49 *
50 * @return string
51 */
52 public function getLogo() {
53 return '';
54 }
55
56 /**
57 * Get the name for the integration.
58 *
59 * @return string
60 */
61 public function getLabel() {
62 return '';
63 }
64
65 /**
66 * Get the item label for the integration.
67 *
68 * @return string
69 */
70 public function getItemLabel() {
71 return '';
72 }
73
74 /**
75 * Get the item help label for the integration.
76 *
77 * @return string
78 */
79 public function getItemHelp() {
80 return '';
81 }
82
83 /**
84 * Get item listing for the integration.
85 *
86 * @param array $items The integration items.
87 * @param string $search The search query.
88 *
89 * @return array The items for the integration.
90 */
91 public function getItems( $items = [], $search = '' ) {
92 return $items;
93 }
94
95 /**
96 * Get the individual item.
97 *
98 * @param string $id Id for the record.
99 *
100 * @return array The item for the integration.
101 */
102 public function getItem( $id ) {
103 return [];
104 }
105
106 /**
107 * Enable by default.
108 *
109 * @return boolean
110 */
111 public function enabled() {
112 return true;
113 }
114
115 /**
116 * Map this class methods to specific events.
117 *
118 * @var array
119 */
120 protected $methods_map = [
121 'surecart/purchase_created' => 'onPurchaseCreated',
122 'surecart/purchase_invoked' => 'onPurchaseInvoked',
123 'surecart/purchase_revoked' => 'onPurchaseRevoked',
124 ];
125
126 /**
127 * Bootstrap the integration.
128 */
129 public function bootstrap() {
130 // index and list.
131 add_filter( "surecart/integrations/providers/list/{$this->getModel()}", [ $this, 'indexProviders' ], 9 );
132 add_filter( "surecart/integrations/providers/find/{$this->getName()}", [ $this, 'findProvider' ], 9 );
133
134 // get items.
135 add_filter( "surecart/integrations/providers/{$this->getName()}/{$this->getModel()}/items", [ $this, 'getItems' ], 9, 2 );
136 add_filter( "surecart/integrations/providers/{$this->getName()}/item", [ $this, '_getItem' ], 9, 2 );
137
138 // implement purchase events if purchase sync interface is implemented.
139 if ( is_subclass_of( $this, PurchaseSyncInterface::class ) ) {
140 add_action( 'surecart/purchase_created', [ $this, 'callMethod' ], 9 );
141 add_action( 'surecart/purchase_invoked', [ $this, 'callMethod' ], 9 );
142 add_action( 'surecart/purchase_revoked', [ $this, 'callMethod' ], 9 );
143 add_action( 'surecart/purchase_updated', [ $this, 'onPurchaseUpdated' ], 9, 2 );
144 }
145 }
146
147 /**
148 * Get the current purchase.
149 *
150 * @return \SureCart\Models\Purchase|null;
151 */
152 public function getPurchase() {
153 return $this->purchase;
154 }
155
156 public function getPurchaseId() {
157 return $this->purchase->id ?? null;
158 }
159
160 /**
161 * Get the user.
162 *
163 * @return \WP_User|null;
164 */
165 public function getUser() {
166 return $this->purchase->getWPUser();
167 }
168
169 /**
170 * The purchase has been updated.
171 * This is extendable, but is also abtracted into
172 * invoke/revoke and quantity update methods.
173 *
174 * @param Purchase $purchase The purchase.
175 * @param object $request The request.
176 *
177 * @return void
178 */
179 public function onPurchaseUpdated( Purchase $purchase, $request ) {
180 $this->purchase = $purchase;
181
182 $data = $request->data->object ?? null;
183 $previous = $request->data->previous_attributes ?? null;
184
185 // we need data or a previous.
186 if ( empty( $data ) || empty( $previous ) ) {
187 return;
188 }
189
190 // product has changed, let's revoke access to the old one
191 // and provide access to the new one.
192 if ( ! empty( $previous->product ) && $data->product !== $previous->product ) {
193 $previous_purchase = new Purchase(
194 array_merge(
195 $purchase->toArray(),
196 [
197 'product' => $previous->product,
198 'quantity' => $previous->quantity ?? 1,
199 ]
200 )
201 );
202 $this->onPurchaseProductUpdated( $purchase, $previous_purchase, $request );
203 return;
204 }
205
206 // The quantity has not changed.
207 if ( (int) $data->quantity === (int) $previous->quantity ) {
208 return;
209 }
210
211 // run quantity updated method.
212 $integrations = (array) $this->getIntegrationData( $purchase ) ?? [];
213 foreach ( $integrations as $integration ) {
214 if ( ! $integration->id ) {
215 continue;
216 }
217 $this->onPurchaseQuantityUpdated( $data->quantity, $previous->quantity, $integration, $purchase->getWPUser() );
218 }
219 }
220
221 /**
222 * When the purchase product is updated
223 *
224 * @param \SureCart\Models\Purchase $purchase The purchase.
225 * @param \SureCart\Models\Purchase $previous_purchase The previous purchase.
226 * @param array $request The request.
227 *
228 * @return void
229 */
230 public function onPurchaseProductUpdated( \SureCart\Models\Purchase $purchase, \SureCart\Models\Purchase $previous_purchase, $request ) {
231 $this->purchase = $purchase;
232
233 // product added.
234 $integrations = (array) $this->getIntegrationData( $purchase ) ?? [];
235 foreach ( $integrations as $integration ) {
236 if ( ! $integration->id ) {
237 continue;
238 }
239 $this->onPurchaseProductAdded( $integration, $purchase->getWPUser(), $purchase );
240 }
241
242 // product removed.
243 $integrations = (array) $this->getIntegrationData( $previous_purchase ) ?? [];
244 foreach ( $integrations as $integration ) {
245 if ( ! $integration->id ) {
246 continue;
247 }
248 $this->onPurchaseProductRemoved( $integration, $previous_purchase->getWPUser(), $previous_purchase );
249 }
250 }
251
252 /**
253 * Method to run when the quantity updates.
254 *
255 * @param integer $quantity The new quantity.
256 * @param integer $previous The previous quantity.
257 * @param Purchase $purchase The purchase.
258 * @param array $request The request.
259 *
260 * @return void
261 */
262 public function onPurchaseQuantityUpdated( $quantity, $previous, $purchase, $request ) {
263 $this->purchase = $purchase;
264 // Allow this to be extended to provide functionality. Do nothing by default.
265 }
266
267 /**
268 * Get the item.
269 *
270 * @param string $id Id for the record.
271 *
272 * @return object
273 */
274 public function _getItem( $id ) {
275 if ( ! $this->enabled() ) {
276 return;
277 }
278 $item = (object) $this->getItem( $id );
279 $item->logo = esc_url_raw( $this->getLogo() );
280 return $item;
281 }
282
283 /**
284 * Call the method for the integration.
285 *
286 * @param \SureCart\Models\Purchase $purchase The purchase model.
287 *
288 * @return void
289 */
290 public function callMethod( $purchase ) {
291 // store the current purchase.
292 $this->purchase = $purchase;
293
294 $method = $this->methods_map[ $this->getCurrentAction() ] ?? null;
295 if ( ! $method || ! method_exists( $this, $method ) ) {
296 return;
297 }
298
299 $integrations = (array) $this->getIntegrationData( $purchase ) ?? [];
300 foreach ( $integrations as $integration ) {
301 if ( ! $integration->id ) {
302 continue;
303 }
304
305 $user = $purchase->getWPUser();
306 if ( ! $user ) {
307 // throw new \Exception( 'No WordPress user is linked to this customer. This means any integrations will not run. Please link this customer to a WordPress user.' );
308 continue;
309 }
310
311 $this->$method( $integration, $purchase->getWPUser(), $purchase );
312 }
313 }
314
315 /**
316 * Get the current called action.
317 *
318 * @return string
319 */
320 protected function getCurrentAction() {
321 return \current_action();
322 }
323
324 /**
325 * Get the Integration data from the purchase.
326 * This normalizes the integration data and the WP user.
327 *
328 * @param \SureCart\Models\Purchase $purchase Purchase model.
329 *
330 * @return array The integration data.
331 */
332 public function getIntegrationData( $purchase ) {
333 if ( is_string( $purchase ) ) {
334 $purchase = Purchase::find( $purchase );
335 }
336 if ( is_wp_error( $purchase ) ) {
337 return;
338 }
339
340 // Get the integrations from the purchase.
341 return $this->getIntegrationsFromPurchase( $purchase );
342 }
343
344 /**
345 * Add the provider to the list.
346 *
347 * @param array $list The list of providers.
348 * @return array
349 */
350 public function indexProviders( $list = [] ) {
351 $list[] = $this->findProvider();
352 return $list;
353 }
354
355 /**
356 * Find the provider.
357 *
358 * @return array
359 */
360 public function findProvider() {
361 return [
362 'name' => $this->getName(),
363 'label' => $this->getLabel(),
364 'disabled' => ! $this->enabled(),
365 'logo' => esc_url_raw( $this->getLogo() ),
366 'item_label' => $this->getItemLabel(),
367 'item_help' => $this->getItemHelp(),
368 ];
369 }
370
371 /**
372 * Get the integration based on the current purchase.
373 *
374 * @param \SureCart\Models\Purchase $purchase The purchase.
375 *
376 * @return array
377 */
378 public function getIntegrationsFromPurchase( $purchase ) {
379 // we need a product id.
380 $product_id = $purchase->product_id ?? null;
381 if ( ! $product_id ) {
382 return [];
383 }
384 return (array) Integration::where( 'model_id', $product_id )->andWhere( 'provider', $this->getName() )->get();
385 }
386 }
387