PluginProbe ʕ •ᴥ•ʔ
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 1.4.0
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v1.4.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 1.0.6 1.1.0 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.11.0 1.11.1 1.11.2 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.9.0 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 2.0.0 2.0.1 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.10.0 2.10.1 2.11.0 2.11.1 2.11.2 2.11.3 2.11.4 2.12.0 2.13.0 2.14.0 2.14.1 2.15.0 2.15.1 2.16.0 2.16.1 2.16.2 2.16.3 2.17.0 2.17.1 2.17.2 2.18.0 2.19.0 2.19.2 2.19.3 2.19.4 2.2.0 2.2.1 2.20.0 2.20.1 2.20.2 2.20.3 2.20.4 2.20.5 2.20.6 2.21.0 2.22.0 2.22.1 2.23.0 2.24.0 2.25.0 2.25.1 2.25.2 2.26.0 2.27.0 2.27.1 2.28.0 2.29.0 2.29.1 2.29.2 2.29.3 2.29.4 2.3.0 2.3.1 2.30.0 2.31.0 2.31.1 2.31.2 2.31.3 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.40.0 2.40.1 2.5.0 2.5.1 2.5.2 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.9.0 3.0.0 3.0.0-RC1 3.0.0-RC2 3.0.0-beta1 3.0.0-beta2 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.10.0 3.10.1 3.11.0 3.12.0 3.13.0 3.13.1 3.13.2 3.13.3 3.13.4 3.14.0 3.15.0 3.15.1 3.15.2 3.15.3 3.15.4 3.15.5 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.16.6 3.16.7 3.16.8 3.17.0 3.17.1 3.17.2 3.17.3 3.17.4 3.17.5 3.17.6 3.18.0 3.19.0 3.19.1 3.19.2 3.2.0 3.2.1 3.2.2 3.20.0 3.20.1 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 4.0.0 4.0.1 4.0.2 4.0.3 trunk 4.1.0 0.2.19.1 4.1.1 1.0.0 4.2.0 1.0.1 1.0.2
surecart / app / src / Models / Subscription.php
surecart / app / src / Models Last commit date
Traits 3 years ago AbandonedCheckout.php 3 years ago AbandonedCheckoutProtocol.php 3 years ago Account.php 3 years ago AccountPortalSession.php 3 years ago Activation.php 3 years ago ApiToken.php 3 years ago BalanceTransaction.php 3 years ago Brand.php 3 years ago Bump.php 3 years ago Charge.php 3 years ago Checkout.php 3 years ago Collection.php 3 years ago Component.php 3 years ago Coupon.php 3 years ago Customer.php 3 years ago CustomerLink.php 3 years ago CustomerNotificationProtocol.php 3 years ago DatabaseModel.php 3 years ago Download.php 3 years ago Event.php 3 years ago Form.php 3 years ago Integration.php 3 years ago Invoice.php 3 years ago License.php 3 years ago LineItem.php 3 years ago ManualPaymentMethod.php 3 years ago Media.php 3 years ago Model.php 3 years ago ModelInterface.php 3 years ago Order.php 3 years ago OrderProtocol.php 3 years ago PaymentIntent.php 3 years ago PaymentMethod.php 3 years ago Period.php 3 years ago PortalProtocol.php 3 years ago PortalSession.php 3 years ago Price.php 3 years ago Processor.php 3 years ago Product.php 3 years ago ProductGroup.php 3 years ago Promotion.php 3 years ago Purchase.php 3 years ago Refund.php 3 years ago Statistic.php 3 years ago Subscription.php 3 years ago SubscriptionProtocol.php 3 years ago TaxProtocol.php 3 years ago TaxRegistration.php 3 years ago TaxZone.php 3 years ago Upload.php 3 years ago User.php 3 years ago VerificationCode.php 3 years ago Webhook.php 3 years ago
Subscription.php
387 lines
1 <?php
2
3 namespace SureCart\Models;
4
5 use SureCart\Models\Traits\HasCustomer;
6 use SureCart\Models\Traits\HasPrice;
7 use SureCart\Models\Traits\HasPurchase;
8
9 /**
10 * Subscription model
11 */
12 class Subscription extends Model {
13 use HasCustomer, HasPrice, HasPurchase;
14
15 /**
16 * Rest API endpoint
17 *
18 * @var string
19 */
20 protected $endpoint = 'subscriptions';
21
22 /**
23 * Object name
24 *
25 * @var string
26 */
27 protected $object_name = 'subscription';
28
29 /**
30 * Update the model.
31 *
32 * @param array $attributes Attributes to update.
33 * @return $this|false
34 */
35 protected function update( $attributes = [] ) {
36 // find existing subscription with purchase record.
37 $existing = ( new Subscription() )->with( [ 'purchase' ] )->find( $attributes['id'] ?? $this->attributes['id'] );
38
39 // do the update and also get the purchase record.
40 $this->with( [ 'purchase' ] );
41 $updated = parent::update( $attributes );
42 if ( is_wp_error( $updated ) ) {
43 return $updated;
44 }
45
46 // do the purchase updated event.
47 if ( ! empty( $updated->purchase ) ) {
48 do_action(
49 'surecart/purchase_updated',
50 $updated->purchase,
51 [
52 'data' => [
53 'object' => $updated->purchase->toArray(),
54 'previous_attributes' => array_filter(
55 [
56 // conditionally have the previous product and quantity as the previous attributes.
57 'product' => $updated->purchase->product_id !== $existing->purchase->product_id ? ( $existing->purchase->product_id ?? null ) : null,
58 'quantity' => $updated->purchase->quantity !== $existing->purchase->quantity ? ( $existing->purchase->quantity ?? 1 ) : null,
59 ]
60 ),
61 ],
62 ]
63 );
64 }
65
66 return $this;
67 }
68
69 /**
70 * Cancel a subscription
71 *
72 * @param string $id Model id.
73 * @return $this|\WP_Error
74 */
75 protected function cancel( $id = null ) {
76 if ( $id ) {
77 $this->setAttribute( 'id', $id );
78 }
79
80 if ( $this->fireModelEvent( 'canceling' ) === false ) {
81 return false;
82 }
83
84 if ( empty( $this->attributes['id'] ) ) {
85 return new \WP_Error( 'not_saved', 'Please create the subscription.' );
86 }
87
88 $canceled = $this->with(
89 [
90 'purchase',
91 ]
92 )->makeRequest(
93 [
94 'method' => 'PATCH',
95 'query' => $this->query,
96 ],
97 $this->endpoint . '/' . $this->attributes['id'] . '/cancel/'
98 );
99
100 if ( is_wp_error( $canceled ) ) {
101 return $canceled;
102 }
103
104 $this->resetAttributes();
105
106 $this->fill( $canceled );
107
108 $this->fireModelEvent( 'canceled' );
109
110 // purchase revoked event.
111 if ( ! empty( $this->purchase->revoked ) ) {
112 do_action( 'surecart/purchase_revoked', $this->purchase );
113 }
114
115 return $this;
116 }
117
118 /**
119 * Complete a subscription
120 *
121 * @param string $id Model id.
122 * @return $this|\WP_Error
123 */
124 protected function complete( $id = null ) {
125 if ( $id ) {
126 $this->setAttribute( 'id', $id );
127 }
128
129 if ( $this->fireModelEvent( 'completeing' ) === false ) {
130 return false;
131 }
132
133 if ( empty( $this->attributes['id'] ) ) {
134 return new \WP_Error( 'not_saved', 'Please create the subscription.' );
135 }
136
137 $completed = $this->with(
138 [
139 'purchase',
140 ]
141 )->makeRequest(
142 [
143 'method' => 'PATCH',
144 'query' => $this->query,
145 ],
146 $this->endpoint . '/' . $this->attributes['id'] . '/complete/'
147 );
148
149 if ( is_wp_error( $completed ) ) {
150 return $completed;
151 }
152
153 $this->resetAttributes();
154
155 $this->fill( $completed );
156
157 $this->fireModelEvent( 'completed' );
158
159 return $this;
160 }
161
162 /**
163 * Restore a subscription
164 *
165 * @param string $id Model id.
166 * @return $this|\WP_Error
167 */
168 protected function restore( $id = null ) {
169 if ( $id ) {
170 $this->setAttribute( 'id', $id );
171 }
172
173 if ( $this->fireModelEvent( 'restoring' ) === false ) {
174 return false;
175 }
176
177 if ( empty( $this->attributes['id'] ) ) {
178 return new \WP_Error( 'not_saved', 'Please create the subscription.' );
179 }
180
181 $restored = \SureCart::request(
182 $this->endpoint . '/' . $this->attributes['id'] . '/restore/',
183 [
184 'method' => 'PATCH',
185 'query' => $this->query,
186 ]
187 );
188
189 if ( is_wp_error( $restored ) ) {
190 return $restored;
191 }
192
193 $this->resetAttributes();
194
195 $this->fill( $restored );
196
197 $this->fireModelEvent( 'restored' );
198
199 return $this;
200 }
201
202 /**
203 * Renew a subscription.
204 *
205 * @param string $id Model id.
206 * @return $this|\WP_Error
207 */
208 protected function renew( $id = null ) {
209 if ( $id ) {
210 $this->setAttribute( 'id', $id );
211 }
212
213 if ( $this->fireModelEvent( 'renewing' ) === false ) {
214 return false;
215 }
216
217 if ( empty( $this->attributes['id'] ) ) {
218 return new \WP_Error( 'not_saved', 'Please create the subscription.' );
219 }
220
221 $renewed = \SureCart::request(
222 $this->endpoint . '/' . $this->attributes['id'],
223 [
224 'method' => 'PATCH',
225 'query' => $this->query,
226 'body' => [
227 $this->object_name => [
228 'cancel_at_period_end' => false,
229 ],
230 ],
231 ]
232 );
233
234 if ( is_wp_error( $renewed ) ) {
235 return $renewed;
236 }
237
238 $this->resetAttributes();
239
240 $this->fill( $renewed );
241
242 $this->fireModelEvent( 'renewed' );
243
244 return $this;
245 }
246
247 /**
248 * Preview the upcoming invoice.
249 *
250 * @param string $args Arguments
251 * @return $this|\WP_Error
252 */
253 protected function upcomingPeriod( $args = [] ) {
254 if ( $args['id'] ) {
255 $this->setAttribute( 'id', $args['id'] );
256 unset( $args['id'] );
257 }
258
259 if ( $this->fireModelEvent( 'previewingUpcomingPeriod' ) === false ) {
260 return false;
261 }
262
263 if ( empty( $this->attributes['id'] ) ) {
264 return new \WP_Error( 'not_saved', 'Please create the subscription' );
265 }
266
267 $upcoming_period = \SureCart::request(
268 $this->endpoint . '/' . $this->attributes['id'] . '/upcoming_period/',
269 [
270 'method' => 'PATCH',
271 'query' => array_merge(
272 $this->query,
273 ),
274 'body' => [
275 $this->object_name => $args,
276 ],
277 ]
278 );
279
280 if ( is_wp_error( $upcoming_period ) ) {
281 return $upcoming_period;
282 }
283
284 $this->resetAttributes();
285
286 $this->fill( $upcoming_period );
287
288 $this->fireModelEvent( 'previewedUpcomingPeriod' );
289
290 return $this;
291 }
292
293 /**
294 * Is this subscription a lifetime one?
295 *
296 * @return boolean
297 */
298 protected function isLifetime() {
299 return $this->attributes['id'] && empty( $this->attributes['current_period_end_at'] );
300 }
301
302 /**
303 * Can the user upgrade this subscription?
304 *
305 * @return boolean
306 */
307 protected function canBeSwitched() {
308 return apply_filters( 'surecart/subscription/can_be_changed', $this->checkIfCanBeSwitched(), $this );
309 }
310
311 /**
312 * Can the subscription be changed?
313 *
314 * @return boolean
315 */
316 private function checkIfCanBeSwitched() {
317 // updates are not enabled for the account.
318 if ( empty( \SureCart::account()->portal_protocol->subscription_updates_enabled ) ) {
319 return false;
320 }
321 // already set to canceling.
322 if ( $this->attributes['cancel_at_period_end'] ) {
323 return false;
324 }
325 // can't update canceled, incomplete, or past due subscriptions.
326 if ( in_array( $this->attributes['status'], [ 'canceled', 'incomplete', 'past_due' ] ) ) {
327 return false;
328 }
329 // must not be lifetime.
330 if ( $this->isLifetime() ) {
331 return false;
332 }
333 return true;
334 }
335
336 /**
337 * Can we cancel the subscription?
338 *
339 * @return boolean
340 */
341 public function canBeCanceled() {
342 return apply_filters( 'surecart/subscription/can_be_canceled', $this->checkIfCanBeSwitched(), $this );
343 }
344
345 /**
346 * Can the subscription be canceled?
347 *
348 * @return boolean
349 */
350 private function checkIfCanBeCanceled() {
351 // updates are not enabled for the account.
352 if ( empty( \SureCart::account()->portal_protocol->subscription_cancellations_enabled ) ) {
353 return false;
354 }
355
356 // can't cancel canceled, incomplete, or past due subscriptions.
357 if ( in_array( $this->attributes['status'], [ 'canceled', 'incomplete', 'past_due' ] ) ) {
358 return false;
359 }
360
361 return true;
362 }
363
364 /**
365 * Can we update the quantity?
366 *
367 * @return boolean
368 */
369 protected function canUpdateQuantity() {
370 return apply_filters( 'surecart/subscription/can_update_quantity', $this->checkIfCanBeSwitched(), $this );
371 }
372
373 /**
374 * Check if we can update the quantity.
375 *
376 * @return boolean
377 */
378 private function checkIfCanUpdateQuantity() {
379 // quantity changes are not enabled for this account.
380 if ( empty( \SureCart::account()->portal_protocol->subscription_quantity_updates_enabled ) ) {
381 return false;
382 }
383 return true;
384 }
385 }
386
387