PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.3.21
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.3.21
1.6.6 1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 All 49 releases
fluent-cart / app / Modules / Templating / Bricks / Elements / ProductAddToCart.php

ProductAddToCart.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.3.21, at app/Modules/Templating/Bricks/Elements/ProductAddToCart.php

654 lines 23.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCart\App\Modules\Templating\Bricks\Elements;
4
5 use Bricks\Element;
6 use FluentCart\App\Modules\Data\ProductDataSetup;
7 use FluentCart\App\Modules\Templating\AssetLoader;
8 use FluentCart\App\Services\Renderer\ProductRenderer;
9
10 if (!defined('ABSPATH')) exit; // Exit if accessed directly
11
12 class ProductAddToCart extends Element
13 {
14 public $category = 'fluent_cart_product';
15 public $name = 'fct-product-buy-section';
16 public $icon = 'ti-shopping-cart';
17
18 public function enqueue_scripts()
19 {
20 AssetLoader::loadSingleProductAssets();
21 }
22
23 public function get_label()
24 {
25 return esc_html__('Buy Section', 'fluent-cart');
26 }
27
28 public function set_control_groups()
29 {
30 $this->control_groups['variation-swatches'] = [
31 'title' => esc_html__('Variation swatches', 'fluent-cart'),
32 'tab' => 'content',
33 ];
34
35 $this->control_groups['quantity'] = [
36 'title' => esc_html__('Quantity', 'fluent-cart'),
37 'tab' => 'content',
38 ];
39
40 $this->control_groups['buy_button'] = [
41 'title' => esc_html__('Direct Buy Button', 'fluent-cart'),
42 'tab' => 'content',
43 ];
44
45 $this->control_groups['button'] = [
46 'title' => esc_html__('Add to Cart Button', 'fluent-cart'),
47 'tab' => 'content',
48 ];
49
50 }
51
52 public function set_controls()
53 {
54
55 // Common swatch controls (for all types) (@since 2.0)
56 $this->controls['swatchesWrap'] = [
57 'group' => 'variation-swatches',
58 'label' => esc_html__('Wrap', 'fluent-cart'),
59 'type' => 'select',
60 'inline' => true,
61 'options' => [
62 'nowrap' => esc_html__('No wrap', 'fluent-cart'),
63 'wrap' => esc_html__('Wrap', 'fluent-cart'),
64 'wrap-reverse' => esc_html__('Wrap reverse', 'fluent-cart'),
65 ],
66 'css' => [
67 [
68 'property' => 'flex-wrap',
69 'selector' => '.bricks-fct-variation-swatches',
70 ],
71 ],
72 ];
73
74 $this->controls['swatchesDirection'] = [
75 'group' => 'variation-swatches',
76 'label' => esc_html__('Direction', 'fluent-cart'),
77 'type' => 'direction',
78 'css' => [
79 [
80 'property' => 'flex-direction',
81 'selector' => '.bricks-fct-variation-swatches',
82 ],
83 ],
84 'inline' => true,
85 ];
86
87 $this->controls['swatchesJustifyContent'] = [
88 'group' => 'variation-swatches',
89 'label' => esc_html__('Align main axis', 'fluent-cart'),
90 'type' => 'justify-content',
91 'css' => [
92 [
93 'property' => 'justify-content',
94 'selector' => '.bricks-fct-variation-swatches',
95 ],
96 ],
97 ];
98
99 $this->controls['swatchesAlignItems'] = [
100 'group' => 'variation-swatches',
101 'label' => esc_html__('Align cross axis', 'fluent-cart'),
102 'type' => 'align-items',
103 'css' => [
104 [
105 'property' => 'align-items',
106 'selector' => '.bricks-fct-variation-swatches',
107 ],
108 ],
109 ];
110
111 $this->controls['swatchesColumnGap'] = [
112 'group' => 'variation-swatches',
113 'label' => esc_html__('Column gap', 'fluent-cart'),
114 'type' => 'number',
115 'units' => true,
116 'css' => [
117 [
118 'property' => 'column-gap',
119 'selector' => '.bricks-fct-variation-swatches',
120 ],
121 ],
122 'placeholder' => '8px',
123 ];
124
125 $this->controls['swatchesRowGap'] = [
126 'group' => 'variation-swatches',
127 'label' => esc_html__('Row gap', 'fluent-cart'),
128 'type' => 'number',
129 'units' => true,
130 'css' => [
131 [
132 'property' => 'row-gap',
133 'selector' => '.bricks-fct-variation-swatches',
134 ],
135 ],
136 'placeholder' => '8px',
137 ];
138
139 $this->controls['colorSwatchBorder'] = [
140 'group' => 'variation-swatches',
141 'label' => esc_html__('Border', 'fluent-cart'),
142 'type' => 'border',
143 'css' => [
144 [
145 'property' => 'border',
146 'selector' => '.bricks-fct-variation-swatches .fct-product-variant-item',
147 ],
148 ],
149 ];
150
151 $this->controls['colorSwatchActiveBorder'] = [
152 'group' => 'variation-swatches',
153 'label' => esc_html__('Border', 'fluent-cart') . ' (' . esc_html__('Active', 'fluent-cart') . ')',
154 'type' => 'border',
155 'css' => [
156 [
157 'property' => 'border',
158 'selector' => '.bricks-fct-variation-swatches .fct-product-variant-item.selected',
159 ],
160 ],
161 ];
162
163 // Label swatch specific controls
164 $this->controls['labelSwatchSeparator'] = [
165 'group' => 'variation-swatches',
166 'label' => esc_html__('Type', 'fluent-cart') . ': ' . esc_html__('Label', 'fluent-cart'),
167 'type' => 'separator',
168 ];
169
170 $this->controls['labelSwatchPadding'] = [
171 'group' => 'variation-swatches',
172 'label' => esc_html__('Padding', 'fluent-cart'),
173 'type' => 'spacing',
174 'css' => [
175 [
176 'property' => 'padding',
177 'selector' => '.bricks-fct-variation-swatches .fct-product-variant-item .fct-product-variant-title',
178 ],
179 ],
180 'placeholder' => [
181 'top' => '0',
182 'right' => '10px',
183 'bottom' => '0',
184 'left' => '10px',
185 ],
186 ];
187
188 $this->controls['labelSwatchTypography'] = [
189 'group' => 'variation-swatches',
190 'label' => esc_html__('Typography', 'fluent-cart'),
191 'type' => 'typography',
192 'css' => [
193 [
194 'property' => 'font',
195 'selector' => '.bricks-fct-variation-swatches .fct-product-variant-item .fct-product-variant-title',
196 ],
197 ],
198 ];
199
200 $this->controls['labelSwatchActiveTypography'] = [
201 'group' => 'variation-swatches',
202 'label' => esc_html__('Typography', 'fluent-cart') . ' (' . esc_html__('Active', 'fluent-cart') . ')',
203 'type' => 'typography',
204 'css' => [
205 [
206 'property' => 'font',
207 'selector' => '.bricks-fct-variation-swatches .fct-product-variant-item.selected .fct-product-variant-title',
208 ],
209 ],
210 ];
211
212 $this->controls['labelSwatchBackgroundColor'] = [
213 'group' => 'variation-swatches',
214 'label' => esc_html__('Background color', 'fluent-cart'),
215 'type' => 'color',
216 'css' => [
217 [
218 'property' => 'background-color',
219 'selector' => '.bricks-fct-variation-swatches .fct-product-variant-item',
220 ],
221 ],
222 ];
223
224 $this->controls['labelSwatchActiveBackgroundColor'] = [
225 'group' => 'variation-swatches',
226 'label' => esc_html__('Background color', 'fluent-cart') . ' (' . esc_html__('Active', 'fluent-cart') . ')',
227 'type' => 'color',
228 'css' => [
229 [
230 'property' => 'background-color',
231 'selector' => '.bricks-fct-variation-swatches .fct-product-variant-item.selected',
232 ],
233 ],
234 ];
235
236 $this->controls['imageSwatchWidth'] = [
237 'group' => 'variation-swatches',
238 'label' => esc_html__('Swatch Image Width', 'fluent-cart'),
239 'type' => 'number',
240 'units' => true,
241 'css' => [
242 [
243 'property' => 'width',
244 'selector' => '.bricks-fct-variation-swatches .fct-product-variant-item img',
245 ],
246 ],
247 'placeholder' => '32px',
248 ];
249
250 $this->controls['imageSwatchHeight'] = [
251 'group' => 'variation-swatches',
252 'label' => esc_html__('Swatch Image Height', 'fluent-cart'),
253 'type' => 'number',
254 'units' => true,
255 'css' => [
256 [
257 'property' => 'height',
258 'selector' => '.bricks-fct-variation-swatches .fct-product-variant-item img',
259 ],
260 ],
261 'placeholder' => '32px',
262 ];
263
264 // QUANTITY
265 $this->controls['quantityWidth'] = [
266 'tab' => 'content',
267 'group' => 'quantity',
268 'type' => 'number',
269 'units' => true,
270 'label' => esc_html__('Width', 'fluent-cart'),
271 'css' => [
272 [
273 'selector' => '.fct-product-quantity',
274 'property' => 'width',
275 ],
276 ],
277 ];
278
279 $this->controls['quantityBackground'] = [
280 'tab' => 'content',
281 'group' => 'quantity',
282 'type' => 'color',
283 'label' => esc_html__('Background', 'fluent-cart'),
284 'css' => [
285 [
286 'selector' => '.fct-product-quantity',
287 'property' => 'background-color',
288 ],
289 ],
290 ];
291
292 $this->controls['quantityBorder'] = [
293 'tab' => 'content',
294 'group' => 'quantity',
295 'type' => 'border',
296 'label' => esc_html__('Border', 'fluent-cart'),
297 'css' => [
298 [
299 'selector' => '.fct-product-quantity .fct-quantity-input',
300 'property' => 'border',
301 ],
302 [
303 'selector' => '.fct-product-quantity .fct-quantity-decrease-button',
304 'property' => 'border',
305 ],
306 [
307 'selector' => '.fct-product-quantity .fct-quantity-increase-button',
308 'property' => 'border',
309 ],
310 ],
311 ];
312
313 // BUTTONS
314 $this->controls['buttonInfo'] = [
315 'tab' => 'content',
316 'group' => 'button',
317 'type' => 'info',
318 'content' => esc_html__('Add to Cart Button will be shown only for non-subscribable products.', 'fluent-cart'),
319 ];
320 $this->controls['buttonText'] = [
321 'tab' => 'content',
322 'group' => 'button',
323 'type' => 'text',
324 'inline' => true,
325 'label' => esc_html__('Button Text', 'fluent-cart'),
326 'placeholder' => esc_html__('Add To Cart', 'fluent-cart'),
327 ];
328 $this->controls['buttonMargin'] = [
329 'tab' => 'content',
330 'group' => 'button',
331 'label' => esc_html__('Buttons Margin', 'fluent-cart'),
332 'type' => 'spacing',
333 'css' => [
334 [
335 'selector' => '.fct-product-buttons-wrap .fluent-cart-add-to-cart-button',
336 'property' => 'margin',
337 ],
338 ],
339 ];
340 $this->controls['buttonPadding'] = [
341 'tab' => 'content',
342 'group' => 'button',
343 'label' => esc_html__('Padding', 'fluent-cart'),
344 'type' => 'spacing',
345 'css' => [
346 [
347 'selector' => '.fct-product-buttons-wrap .fluent-cart-add-to-cart-button',
348 'property' => 'padding',
349 ],
350 ],
351 ];
352 $this->controls['buttonWidth'] = [
353 'tab' => 'content',
354 'group' => 'button',
355 'label' => esc_html__('Width', 'fluent-cart'),
356 'type' => 'number',
357 'units' => true,
358 'css' => [
359 [
360 'selector' => '.fct-product-buttons-wrap .fluent-cart-add-to-cart-button',
361 'property' => 'min-width',
362 ],
363 ],
364 ];
365 $this->controls['buttonBackgroundColor'] = [
366 'tab' => 'content',
367 'group' => 'button',
368 'label' => esc_html__('Background color', 'fluent-cart'),
369 'type' => 'color',
370 'css' => [
371 [
372 'selector' => '.fct-product-buttons-wrap .fluent-cart-add-to-cart-button',
373 'property' => 'background-color',
374 ],
375 ],
376 ];
377 $this->controls['buttonBorder'] = [
378 'tab' => 'content',
379 'group' => 'button',
380 'label' => esc_html__('Border', 'fluent-cart'),
381 'type' => 'border',
382 'css' => [
383 [
384 'property' => 'border',
385 'selector' => '.fct-product-buttons-wrap .fluent-cart-add-to-cart-button',
386 ],
387 ],
388 ];
389 $this->controls['buttonTypography'] = [
390 'tab' => 'content',
391 'group' => 'button',
392 'label' => esc_html__('Typography', 'fluent-cart'),
393 'type' => 'typography',
394 'css' => [
395 [
396 'selector' => '.fct-product-buttons-wrap .',
397 'property' => 'font',
398 ],
399 ],
400 ];
401 // Button icon
402 $this->controls['icon'] = [
403 'tab' => 'content',
404 'group' => 'button',
405 'label' => esc_html__('Icon', 'fluent-cart'),
406 'type' => 'icon',
407 'rerender' => true,
408 ];
409 $this->controls['iconTypography'] = [
410 'tab' => 'content',
411 'group' => 'button',
412 'label' => esc_html__('Icon typography', 'fluent-cart'),
413 'type' => 'typography',
414 'css' => [
415 [
416 'property' => 'font',
417 'selector' => '.icon',
418 ],
419 ],
420 ];
421 $this->controls['iconOnly'] = [
422 'tab' => 'content',
423 'group' => 'button',
424 'label' => esc_html__('Icon only', 'fluent-cart'),
425 'type' => 'checkbox',
426 'inline' => true,
427 'placeholder' => esc_html__('Yes', 'fluent-cart'),
428 'required' => ['icon', '!=', ''],
429 ];
430 $this->controls['iconPosition'] = [
431 'tab' => 'content',
432 'group' => 'button',
433 'label' => esc_html__('Icon position', 'fluent-cart'),
434 'type' => 'select',
435 'options' => $this->control_options['iconPosition'],
436 'inline' => true,
437 'placeholder' => esc_html__('Left', 'fluent-cart'),
438 'required' => [
439 ['icon', '!=', ''],
440 ['iconOnly', '=', ''],
441 ],
442 ];
443
444 // Buy Now BUTTON
445 $this->controls['directButtonText'] = [
446 'tab' => 'content',
447 'group' => 'buy_button',
448 'type' => 'text',
449 'inline' => true,
450 'label' => esc_html__('Button Text', 'fluent-cart'),
451 'placeholder' => esc_html__('Buy Now', 'fluent-cart'),
452 ];
453 $this->controls['directButtonMargin'] = [
454 'tab' => 'content',
455 'group' => 'buy_button',
456 'label' => esc_html__('Buttons Margin', 'fluent-cart'),
457 'type' => 'spacing',
458 'css' => [
459 [
460 'selector' => '.fct-product-buttons-wrap .fluent-cart-direct-checkout-button',
461 'property' => 'margin',
462 ],
463 ],
464 ];
465 $this->controls['directButtonPadding'] = [
466 'tab' => 'content',
467 'group' => 'buy_button',
468 'label' => esc_html__('Padding', 'fluent-cart'),
469 'type' => 'spacing',
470 'css' => [
471 [
472 'selector' => '.fct-product-buttons-wrap .fluent-cart-direct-checkout-button',
473 'property' => 'padding',
474 ],
475 ],
476 ];
477 $this->controls['directButtonWidth'] = [
478 'tab' => 'content',
479 'group' => 'buy_button',
480 'label' => esc_html__('Width', 'fluent-cart'),
481 'type' => 'number',
482 'units' => true,
483 'css' => [
484 [
485 'selector' => '.fct-product-buttons-wrap .fluent-cart-direct-checkout-button',
486 'property' => 'min-width',
487 ],
488 ],
489 ];
490 $this->controls['directButtonBackgroundColor'] = [
491 'tab' => 'content',
492 'group' => 'buy_button',
493 'label' => esc_html__('Background color', 'fluent-cart'),
494 'type' => 'color',
495 'css' => [
496 [
497 'selector' => '.fct-product-buttons-wrap .fluent-cart-direct-checkout-button',
498 'property' => 'background-color',
499 ],
500 ],
501 ];
502 $this->controls['directButtonBorder'] = [
503 'tab' => 'content',
504 'group' => 'buy_button',
505 'label' => esc_html__('Border', 'fluent-cart'),
506 'type' => 'border',
507 'css' => [
508 [
509 'property' => 'border',
510 'selector' => '.fct-product-buttons-wrap .fluent-cart-direct-checkout-button',
511 ],
512 ],
513 ];
514 $this->controls['directButtonTypography'] = [
515 'tab' => 'content',
516 'group' => 'buy_button',
517 'label' => esc_html__('Typography', 'fluent-cart'),
518 'type' => 'typography',
519 'css' => [
520 [
521 'selector' => '.fct-product-buttons-wrap .fluent-cart-direct-checkout-button',
522 'property' => 'font',
523 ],
524 ],
525 ];
526 // Button icon
527 $this->controls['directButtonIcon'] = [
528 'tab' => 'content',
529 'group' => 'buy_button',
530 'label' => esc_html__('Icon', 'fluent-cart'),
531 'type' => 'icon',
532 'rerender' => true,
533 ];
534 $this->controls['directButtonIconTypography'] = [
535 'tab' => 'content',
536 'group' => 'buy_button',
537 'label' => esc_html__('Icon typography', 'fluent-cart'),
538 'type' => 'typography',
539 'css' => [
540 [
541 'property' => 'font',
542 'selector' => '.icon',
543 ],
544 ],
545 ];
546 $this->controls['directButtonIconOnly'] = [
547 'tab' => 'content',
548 'group' => 'buy_button',
549 'label' => esc_html__('Icon only', 'fluent-cart'),
550 'type' => 'checkbox',
551 'inline' => true,
552 'placeholder' => esc_html__('Yes', 'fluent-cart'),
553 'required' => ['icon', '!=', ''],
554 ];
555 $this->controls['directButtonIconPosition'] = [
556 'tab' => 'content',
557 'group' => 'buy_button',
558 'label' => esc_html__('Icon position', 'fluent-cart'),
559 'type' => 'select',
560 'options' => $this->control_options['iconPosition'],
561 'inline' => true,
562 'placeholder' => esc_html__('Left', 'fluent-cart'),
563 'required' => [
564 ['icon', '!=', ''],
565 ['iconOnly', '=', ''],
566 ],
567 ];
568 }
569
570 public function render()
571 {
572 $product = ProductDataSetup::getProductModel($this->post_id);
573 if (empty($product)) {
574 return $this->render_element_placeholder(
575 [
576 'title' => esc_html__('For better preview select content to show.', 'fluent-cart'),
577 'description' => esc_html__('Go to: Settings > Template Settings > Populate Content', 'fluent-cart'),
578 ]
579 );
580 }
581
582 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- render_attributes() handles escaping internally
583 echo "<div {$this->render_attributes( '_root' )}>";
584 (new ProductRenderer($product))->renderBuySection([
585 'button_atts' => array_filter([
586 'buy_now_text' => $this->getBuyNowText(),
587 'add_to_cart_text' => $this->getAddToCartText(),
588 ]),
589 'variation_atts' => [
590 'wrapper_class' => 'bricks-fct-variation-swatches'
591 ],
592 ]);
593 echo '</div>';
594 }
595
596 public function getAddToCartText()
597 {
598 $settings = $this->settings;
599 $buttonText = !empty($settings['buttonText']) ? $settings['buttonText'] : __('Add To Cart', 'fluent-cart');
600
601 $icon = !empty($settings['icon']) ? self::render_icon($settings['icon'], ['icon']) : false;
602 $icon_position = isset($settings['iconPosition']) ? $settings['iconPosition'] : 'left';
603 $icon_only = isset($settings['iconOnly']);
604
605 // Build HTML
606 $output = '';
607
608 if ($icon_only && $icon) {
609 // Icon only (@since 1.12.2)
610 $output = $icon;
611 } else {
612 if (!$icon) {
613 $output = $buttonText;
614 } else if ($icon_position === 'left') {
615 $output .= $icon;
616 $output .= "<span style='margin-left: 8px;'>$buttonText</span>";
617 } else if ($icon_position === 'right') {
618 $output .= "<span style='margin-right: 8px;'>$buttonText</span>" . $icon;
619 }
620 }
621
622 return $output;
623 }
624
625 public function getBuyNowText()
626 {
627 $settings = $this->settings;
628 $buttonText = !empty($settings['directButtonText']) ? $settings['directButtonText'] : __('Buy Now', 'fluent-cart');
629
630 $icon = !empty($settings['directButtonIcon']) ? self::render_icon($settings['directButtonIcon'], ['icon']) : false;
631 $icon_position = isset($settings['directButtonIconPosition']) ? $settings['directButtonIconPosition'] : 'left';
632 $icon_only = isset($settings['directButtonIconOnly']);
633
634 // Build HTML
635 $output = '';
636
637 if ($icon_only && $icon) {
638 // Icon only (@since 1.12.2)
639 $output = $icon;
640 } else {
641 if (!$icon) {
642 $output = $buttonText;
643 } else if ($icon_position === 'left') {
644 $output .= $icon;
645 $output .= "<span style='margin-left: 8px;'>$buttonText</span>";
646 } else if ($icon_position === 'right') {
647 $output .= "<span style='margin-right: 8px;'>$buttonText</span>" . $icon;
648 }
649 }
650
651 return $output;
652 }
653 }
654