PluginProbe
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 4.4.2
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v4.4.2
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 / Models / LineItem.php
LineItem.php
384 lines 8.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace SureCart\Models;
4
5 use SureCart\Models\Traits\HasCheckout;
6 use SureCart\Models\Traits\HasFees;
7 use SureCart\Models\Traits\HasPrice;
8 use SureCart\Support\Currency;
9 use SureCart\Models\Traits\HasProduct;
10 use SureCart\Models\Traits\HasSwap;
11 /**
12 * Price model
13 */
14 class LineItem extends Model {
15 use HasPrice;
16 use HasCheckout;
17 use HasProduct;
18 use HasFees;
19 use HasSwap;
20
21 /**
22 * Rest API endpoint
23 *
24 * @var string
25 */
26 protected $endpoint = 'line_items';
27
28 /**
29 * Object name
30 *
31 * @var string
32 */
33 protected $object_name = 'line_item';
34
35 /**
36 * Set the variant attribute.
37 *
38 * @param string $value Variant properties.
39 * @return void
40 */
41 public function setVariantAttribute( $value ) {
42 $this->setRelation( 'variant', $value, Variant::class );
43 }
44
45 /**
46 * Get the variant attribute.
47 *
48 * @return string
49 */
50 public function getVariantDisplayOptionsAttribute() {
51 if ( empty( $this->variant_options ) ) {
52 return null;
53 }
54 return implode( ' / ', array_filter( $this->variant_options ) );
55 }
56
57 /**
58 * Upsell a line item.
59 *
60 * @param array $attributes The attributes to update.
61 * @return \WP_Error|mixed
62 */
63 protected function upsell( $attributes = [] ) {
64 if ( $this->fireModelEvent( 'upselling' ) === false ) {
65 return false;
66 }
67
68 $updated = $this->makeRequest(
69 [
70 'method' => 'POST',
71 'query' => $this->query,
72 'body' => [
73 $this->object_name => $attributes,
74 ],
75 ],
76 'line_items/upsell'
77 );
78
79 if ( $this->isError( $updated ) ) {
80 return $updated;
81 }
82
83 $this->resetAttributes();
84
85 $this->fill( $updated );
86
87 $this->fireModelEvent( 'upsold' );
88
89 // clear account cache.
90 if ( $this->cachable || $this->clears_account_cache ) {
91 \SureCart::account()->clearCache();
92 }
93
94 return $this;
95 }
96
97 /**
98 * Swap Line Item
99 *
100 * @param string $id LineItem ID.
101 *
102 * @return $this|\WP_Error
103 */
104 protected function swap( $id = null ) {
105 if ( $this->fireModelEvent( 'swaping' ) === false ) {
106 return $this;
107 }
108
109 $this->id = $id ? $id : $this->id;
110
111 if ( empty( $this->id ) ) {
112 return new \WP_Error( 'not_saved', 'No Line Item Id passed.' );
113 }
114
115 $swapped = \SureCart::request(
116 $this->endpoint . '/' . $this->id . '/swap',
117 [
118 'method' => 'PATCH',
119 'query' => $this->query,
120 ]
121 );
122
123 if ( is_wp_error( $swapped ) ) {
124 return $swapped;
125 }
126
127 $this->resetAttributes();
128
129 $this->fill( $swapped );
130
131 $this->fireModelEvent( 'swapped' );
132
133 return $this;
134 }
135
136 /**
137 * Swap Line Item
138 *
139 * @param string $id LineItem ID.
140 *
141 * @return $this|\WP_Error
142 */
143 protected function unswap( $id = null ) {
144 if ( $this->fireModelEvent( 'unswaping' ) === false ) {
145 return $this;
146 }
147
148 $this->id = $id ? $id : $this->id;
149
150 if ( empty( $this->id ) ) {
151 return new \WP_Error( 'not_saved', 'No Line Item Id passed.' );
152 }
153
154 $unswapped = \SureCart::request(
155 $this->endpoint . '/' . $this->id . '/unswap',
156 [
157 'method' => 'PATCH',
158 'query' => $this->query,
159 ]
160 );
161
162 if ( is_wp_error( $unswapped ) ) {
163 return $unswapped;
164 }
165
166 $this->resetAttributes();
167
168 $this->fill( $unswapped );
169
170 $this->fireModelEvent( 'unswapped' );
171
172 return $this;
173 }
174
175 /**
176 * Get the is_swappable attribute.
177 *
178 * @return string
179 */
180 public function getIsSwappableAttribute() {
181 return ! empty( $this->swap ) || ! empty( $this->price->current_swap );
182 }
183
184 /**
185 * Get the currency attribute.
186 *
187 * TODO: Remove this method once currency added on line item.
188 *
189 * @return string
190 */
191 public function getCurrencyAttribute() {
192 return $this->checkout->currency ?? \SureCart::account()->currency;
193 }
194
195 /**
196 * Get the display ad hoc amount attribute.
197 *
198 * @return string
199 */
200 public function getAdHocDisplayAmountAttribute() {
201 return ! empty( $this->ad_hoc_amount ) ? Currency::format( $this->ad_hoc_amount, $this->currency ) : '';
202 }
203
204 /**
205 * Get the bump amount display attribute.
206 *
207 * @return string
208 */
209 public function getBumpDisplayAmountAttribute() {
210 return ! empty( $this->bump_amount ) ? Currency::format( $this->bump_amount, $this->currency ) : '';
211 }
212
213 /**
214 * Get the display scratch amount attribute.
215 *
216 * @return string
217 */
218 public function getScratchDisplayAmountAttribute() {
219 return ! empty( $this->scratch_amount ) ? Currency::format( $this->scratch_amount, $this->currency ) : '';
220 }
221
222 /**
223 * Get the SKU text attribute.
224 *
225 * @return string
226 */
227 public function getSkuAttribute() {
228 if ( ! empty( $this->variant ) && ! empty( $this->variant->sku ) ) {
229 return $this->variant->sku;
230 }
231 return $this->price->product->sku ?? '';
232 }
233
234 /**
235 * Get the display tax amount attribute.
236 *
237 * @return string
238 */
239 public function getTaxDisplayAmountAttribute() {
240 return ! empty( $this->tax_amount ) ? Currency::format( $this->tax_amount, $this->currency ) : '';
241 }
242
243 /**
244 * Get the display subtotal amount attribute.
245 *
246 * @return string
247 */
248 public function getSubtotalDisplayAmountAttribute() {
249 return Currency::format( (int) $this->subtotal_amount, $this->currency );
250 }
251
252 /**
253 * Get the display total amount attribute.
254 *
255 * @return string
256 */
257 public function getTotalDisplayAmountAttribute() {
258 return Currency::format( (int) $this->total_amount, $this->currency );
259 }
260
261 /**
262 * Get the display subtotal amount + upsell discount amount attribute.
263 *
264 * @return string
265 */
266 public function getSubtotalWithUpsellDiscountDisplayAmountAttribute() {
267 return Currency::format( (int) $this->subtotal_with_upsell_discount_amount, $this->currency );
268 }
269
270 /**
271 * Get the subtotal amount + upsell discount amount attribute.
272 *
273 * @return string
274 */
275 public function getSubtotalWithUpsellDiscountAmountAttribute() {
276 if ( empty( $this->fees->data ) || ! is_array( $this->fees->data ) ) {
277 return (int) $this->subtotal_amount;
278 }
279
280 $total_upsell_discount = 0;
281
282 foreach ( $this->fees->data as $fee ) {
283 if ( 'upsell' === $fee->fee_type ) {
284 $total_upsell_discount += $fee->amount ?? 0;
285 }
286 }
287
288 return (int) $this->subtotal_amount + (int) ( $total_upsell_discount ?? 0 );
289 }
290
291 /**
292 * Get the display full amount attribute.
293 *
294 * @return string
295 */
296 public function getFullDisplayAmountAttribute() {
297 return ! empty( $this->full_amount ) ? Currency::format( $this->full_amount, $this->currency ) : '';
298 }
299
300 /**
301 * Get the display trial amount attribute.
302 *
303 * @return string
304 */
305 public function getTrialDisplayAmountAttribute() {
306 return ! empty( $this->trial_amount ) ? Currency::format( $this->trial_amount, $this->currency ) : '';
307 }
308
309 /**
310 * Get the line item image.
311 */
312 public function getImageAttribute() {
313 // if we have a variant, use the variant image.
314 if ( ! empty( $this->variant ) && is_a( $this->variant, Variant::class ) && ! empty( (array) $this->variant->line_item_image ) ) {
315 return $this->variant->line_item_image;
316 }
317
318 // if we have a product, use the product image.
319 if ( isset( $this->price->product->line_item_image ) ) {
320 return $this->price->product->line_item_image;
321 }
322
323 return null;
324 }
325
326 /**
327 * Get the converted discount amount attribute.
328 *
329 * @return string
330 */
331 public function getConvertedDiscountAmountAttribute() {
332 if ( $this->is_zero_decimal || empty( $this->discount_amount ) ) {
333 return $this->discount_amount;
334 }
335 return $this->discount_amount / 100;
336 }
337
338 /**
339 * Get the total default currency display amount attribute.
340 *
341 * @return string
342 */
343 public function getTotalDefaultCurrencyDisplayAmountAttribute() {
344 return Currency::format( (int) $this->total_amount, $this->currency, [ 'convert' => false ] );
345 }
346
347 /**
348 * Get the note display attribute by strip out HTML tags.
349 *
350 * @return string
351 */
352 public function getDisplayNoteAttribute() {
353 return ! empty( $this->note ) ? wp_strip_all_tags( $this->note, true ) : '';
354 }
355
356 /**
357 * Purchasable status display
358 *
359 * @return string
360 */
361 public function getPurchasableStatusDisplayAttribute() {
362 if ( 'purchasable' === $this->purchasable_status ) {
363 return;
364 }
365
366 // translations for purchaseable status.
367 $translations = array(
368 'price_gone' => __( 'No longer available', 'surecart' ),
369 'price_old_version' => __( 'Price has changed', 'surecart' ),
370 'variant_missing' => __( 'Options no longer available', 'surecart' ),
371 'variant_old_version' => __( 'Price has changed', 'surecart' ),
372 'variant_gone' => __( 'Item no longer available', 'surecart' ),
373 'out_of_stock' => __( 'Out of stock', 'surecart' ),
374 'exceeds_purchase_limit' => __( 'Exceeds purchase limit', 'surecart' ),
375 );
376
377 if ( $this->quantity > 1 ) {
378 $translations['out_of_stock'] = __( 'Quantity unavailable', 'surecart' );
379 }
380
381 return $translations[ $this->purchasable_status ] ?? '';
382 }
383 }
384