PluginProbe ʕ •ᴥ•ʔ
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments / 2.13.0
SureCart – Ecommerce Made Easy For Selling Physical Products, Digital Downloads, Subscriptions, Donations, & Payments v2.13.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 / Product.php
surecart / app / src / Models Last commit date
Traits 2 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 BuyLink.php 3 years ago CancellationAct.php 3 years ago CancellationReason.php 3 years ago Charge.php 3 years ago Checkout.php 2 years ago Collection.php 3 years ago Component.php 3 years ago Coupon.php 3 years ago Customer.php 2 years ago CustomerLink.php 3 years ago CustomerNotificationProtocol.php 3 years ago DatabaseModel.php 2 years ago Download.php 3 years ago Event.php 3 years ago Form.php 3 years ago Fulfillment.php 3 years ago FulfillmentItem.php 3 years ago IncomingWebhook.php 2 years ago Integration.php 3 years ago Invoice.php 3 years ago License.php 3 years ago LineItem.php 2 years ago ManualPaymentMethod.php 3 years ago Media.php 3 years ago Model.php 2 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 2 years ago ProductCollection.php 2 years ago ProductGroup.php 2 years ago ProductMedia.php 3 years ago Promotion.php 3 years ago ProvisionalAccount.php 3 years ago Purchase.php 3 years ago Refund.php 3 years ago RegisteredWebhook.php 2 years ago ReturnItem.php 2 years ago ReturnReason.php 2 years ago ReturnRequest.php 2 years ago ShippingMethod.php 3 years ago ShippingProfile.php 3 years ago ShippingProtocol.php 3 years ago ShippingRate.php 3 years ago ShippingZone.php 3 years ago Statistic.php 3 years ago Subscription.php 2 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 2 years ago Variant.php 2 years ago VariantOption.php 2 years ago VariantValue.php 2 years ago VerificationCode.php 3 years ago Webhook.php 2 years ago WebhookRegistration.php 2 years ago
Product.php
374 lines
1 <?php
2
3 namespace SureCart\Models;
4
5 use SureCart\Support\Contracts\PageModel;
6 use SureCart\Support\Currency;
7
8 /**
9 * Price model
10 */
11 class Product extends Model implements PageModel {
12 use Traits\HasImageSizes;
13
14 /**
15 * Rest API endpoint
16 *
17 * @var string
18 */
19 protected $endpoint = 'products';
20
21 /**
22 * Object name
23 *
24 * @var string
25 */
26 protected $object_name = 'product';
27
28 /**
29 * Is this cachable?
30 *
31 * @var boolean
32 */
33 protected $cachable = true;
34
35 /**
36 * Clear cache when products are updated.
37 *
38 * @var string
39 */
40 protected $cache_key = 'products_updated_at';
41
42 /**
43 * Create a new model
44 *
45 * @param array $attributes Attributes to create.
46 *
47 * @return $this|false
48 */
49 protected function create( $attributes = [] ) {
50 if ( ! wp_is_block_theme() ) {
51 $attributes['metadata'] = [
52 ...$attributes['metadata'] ?? [],
53 'wp_template_id' => apply_filters( 'surecart/templates/products/default', 'pages/template-surecart-product.php' ),
54 ];
55 }
56
57 return parent::create( $attributes );
58 }
59
60 /**
61 * Image srcset.
62 *
63 * @return string
64 */
65 public function getImageSrcsetAttribute() {
66 if ( empty( $this->attributes['image_url'] ) ) {
67 return '';
68 }
69 return $this->imageSrcSet( $this->attributes['image_url'] );
70 }
71
72 /**
73 * Get the image url for a specific size.
74 *
75 * @param integer $size The size.
76 *
77 * @return string
78 */
79 public function getImageUrl( $size = 0 ) {
80 if ( empty( $this->attributes['image_url'] ) ) {
81 return '';
82 }
83 return $size ? $this->imageUrl( $this->attributes['image_url'], $size ) : $this->attributes['image_url'];
84 }
85
86 /**
87 * Set the prices attribute.
88 *
89 * @param object $value Array of price objects.
90 * @return void
91 */
92 public function setPricesAttribute( $value ) {
93 $this->setCollection( 'prices', $value, Price::class );
94 }
95
96 /**
97 * Set the product collections attribute
98 *
99 * @param object $value Product collections.
100 * @return void
101 */
102 public function setProductCollectionsAttribute( $value ) {
103 $this->setCollection( 'product_collections', $value, ProductCollection::class );
104 }
105
106 /**
107 * Set the variants attribute.
108 *
109 * @param object $value Array of price objects.
110 * @return void
111 */
112 public function setVariantsAttribute( $value ) {
113 $this->setCollection( 'variants', $value, Variant::class );
114 }
115
116 /**
117 * Set the product attribute
118 *
119 * @param string $value Product properties.
120 * @return void
121 */
122 public function setPurchaseAttribute( $value ) {
123 $this->setRelation( 'purchase', $value, Purchase::class );
124 }
125
126 /**
127 * Set the product media attribute
128 *
129 * @param string $value ProductMedia properties.
130 * @return void
131 */
132 public function setProductMediasAttribute( $value ) {
133 $this->setCollection( 'product_medias', $value, ProductMedia::class );
134 }
135
136 /**
137 * Buy link model
138 *
139 * @return \SureCart\Models\BuyLink
140 */
141 public function buyLink() {
142 return new BuyLink( $this );
143 }
144
145 /**
146 * Checkout Permalink.
147 *
148 * @return string
149 */
150 public function getCheckoutPermalinkAttribute() {
151 return $this->buyLink()->url();
152 }
153
154 /**
155 * Get the product permalink.
156 *
157 * @return string
158 */
159 public function getPermalinkAttribute(): string {
160 if ( empty( $this->attributes['id'] ) ) {
161 return '';
162 }
163 // permalinks off.
164 if ( ! get_option( 'permalink_structure' ) ) {
165 return add_query_arg( 'sc_product_page_id', $this->slug, get_home_url() );
166 }
167 // permalinks on.
168 return trailingslashit( get_home_url() ) . trailingslashit( \SureCart::settings()->permalinks()->getBase( 'product_page' ) ) . $this->slug;
169 }
170
171 /**
172 * Get the page title.
173 *
174 * @return string
175 */
176 public function getPageTitleAttribute(): string {
177 return $this->metadata->page_title ?? $this->name ?? '';
178 }
179
180 /**
181 * Get the meta description.
182 *
183 * @return string
184 */
185 public function getMetaDescriptionAttribute(): string {
186 return $this->metadata->meta_description ?? $this->description ?? '';
187 }
188
189 /**
190 * Return attached active prices.
191 *
192 * @return array
193 */
194 public function activePrices() {
195 $active_prices = array_values(
196 array_filter(
197 $this->prices->data ?? [],
198 function( $price ) {
199 return ! $price->archived;
200 }
201 )
202 );
203
204 usort(
205 $active_prices,
206 function( $a, $b ) {
207 if ( $a->position == $b->position ) {
208 return 0;
209 }
210 return ( $a->position < $b->position ) ? -1 : 1;
211 }
212 );
213
214 return $active_prices;
215 }
216
217 /**
218 * Returns the product media image attributes.
219 *
220 * @return object
221 */
222 public function getFeaturedMediaAttribute() {
223 $featured_product_media = $this->featured_product_media;
224
225 return (object) array(
226 'alt' => $featured_product_media->media->alt ?? $this->title ?? $this->name ?? '',
227 'title' => $featured_product_media->media->title ?? '',
228 'url' => $featured_product_media->media->url ?? $this->image_url,
229 );
230 }
231
232 /**
233 * Get the JSON Schema Array
234 *
235 * @return array
236 */
237 public function getJsonSchemaArray(): array {
238 $active_prices = (array) $this->activePrices();
239
240 $offers = array_map(
241 function( $price ) {
242 return [
243 '@type' => 'Offer',
244 'price' => Currency::maybeConvertAmount( $price->amount, $price->currency ),
245 'priceCurrency' => $price->currency,
246 'availability' => 'https://schema.org/InStock',
247 ];
248 },
249 $active_prices ?? []
250 );
251
252 return apply_filters(
253 'surecart/product/json_schema',
254 [
255 '@context' => 'http://schema.org',
256 '@type' => 'Product',
257 'name' => $this->name,
258 'image' => $this->image_url ?? '',
259 'description' => sanitize_text_field( $this->description ),
260 'offers' => $offers,
261 ],
262 $this
263 );
264 }
265
266 /**
267 * Get the product template id.
268 *
269 * @return string
270 */
271 public function getTemplateIdAttribute(): string {
272 if ( ! empty( $this->attributes['metadata']->wp_template_id ) ) {
273 // we have a php file, switch to default.
274 if ( wp_is_block_theme() && false !== strpos( $this->attributes['metadata']->wp_template_id, '.php' ) ) {
275 return 'surecart/surecart//single-product';
276 }
277
278 // this is acceptable.
279 return $this->attributes['metadata']->wp_template_id;
280 }
281 return 'surecart/surecart//single-product';
282 }
283
284 /**
285 * Get product with acgive and sorted prices.
286 *
287 * @return this
288 */
289 public function withActiveAndSortedPrices() {
290 $filtered = clone $this;
291
292 // Filter out archived prices.
293 $filtered->prices->data = array_values(
294 array_filter(
295 $filtered->prices->data,
296 function( $price ) {
297 return ! $price->archived;
298 }
299 )
300 );
301
302 // Sort prices by position.
303 usort(
304 $filtered->prices->data,
305 function( $a, $b ) {
306 return $a->position - $b->position;
307 }
308 );
309
310 return $filtered;
311 }
312
313 /**
314 * Get the first variant with stock.
315 *
316 * @return \SureCart\Models\Variant;
317 */
318 public function getFirstVariantWithStock() {
319 $first_variant_with_stock = $this->variants->data[0] ?? null;
320
321 // stock is enabled.
322 if ( $this->stock_enabled ) {
323 foreach ( $this->variants->data as $variant ) {
324 if ( $variant->available_stock > 0 ) {
325 $first_variant_with_stock = $variant;
326 break;
327 }
328 }
329 }
330 return $first_variant_with_stock;
331 }
332
333 /**
334 * Get the product template
335 *
336 * @return \WP_Template
337 */
338 public function getTemplateAttribute() {
339 return get_block_template( $this->getTemplateIdAttribute() );
340 }
341
342 /**
343 * Get the product template id.
344 *
345 * @return string
346 */
347 public function getTemplatePartIdAttribute(): string {
348 if ( ! empty( $this->attributes['metadata']->wp_template_part_id ) ) {
349 return $this->attributes['metadata']->wp_template_part_id;
350 }
351 return 'surecart/surecart//product-info';
352 }
353
354 /**
355 * Get the product template part template.
356 *
357 * @return \WP_Template
358 */
359 public function getTemplatePartAttribute() {
360 return get_block_template( $this->getTemplatePartIdAttribute(), 'wp_template_part' );
361 }
362
363 /**
364 * Get Template Content.
365 *
366 * @return string
367 */
368 public function getTemplateContent() : string {
369 return wp_is_block_theme() ?
370 $this->template->content ?? '' :
371 $this->template_part->content ?? '';
372 }
373 }
374