PluginProbe
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder / 51.1.49
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder v51.1.49
51.1.86 51.1.84 51.1.85 51.1.83 51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 51.1.45 All 40 releases
king-addons / includes / widgets / WooCommerce_Floating_Cart_Icon / WooCommerce_Floating_Cart_Icon.php

WooCommerce_Floating_Cart_Icon.php in King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder 51.1.49, at includes/widgets/WooCommerce_Floating_Cart_Icon/WooCommerce_Floating_Cart_Icon.php

665 lines 21.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * WooCommerce Floating Cart Icon Widget (Free).
4 *
5 * @package King_Addons
6 */
7
8 namespace King_Addons;
9
10 use Elementor\Controls_Manager;
11 use Elementor\Group_Control_Border;
12 use Elementor\Group_Control_Box_Shadow;
13 use Elementor\Group_Control_Typography;
14 use Elementor\Icons_Manager;
15 use Elementor\Widget_Base;
16
17 if (!defined('ABSPATH')) {
18 exit;
19 }
20
21 /**
22 * Displays a floating cart icon with item count and quick summary.
23 */
24 class WooCommerce_Floating_Cart_Icon extends Widget_Base
25 {
26 /**
27 * Widget slug.
28 *
29 * @return string
30 */
31 public function get_name(): string
32 {
33 return 'king-addons-woocommerce-floating-cart-icon';
34 }
35
36 /**
37 * Widget title.
38 *
39 * @return string
40 */
41 public function get_title(): string
42 {
43 return esc_html__('WooCommerce Floating Cart Icon', 'king-addons');
44 }
45
46 /**
47 * Widget icon.
48 *
49 * @return string
50 */
51 public function get_icon(): string
52 {
53 return 'eicon-cart-medium';
54 }
55
56 /**
57 * Style dependencies.
58 *
59 * @return array<int, string>
60 */
61 public function get_style_depends(): array
62 {
63 return [
64 KING_ADDONS_ASSETS_UNIQUE_KEY . '-woocommerce-floating-cart-icon-style',
65 ];
66 }
67
68 /**
69 * Script dependencies.
70 *
71 * @return array<int, string>
72 */
73 public function get_script_depends(): array
74 {
75 return [
76 KING_ADDONS_ASSETS_UNIQUE_KEY . '-woocommerce-floating-cart-icon-script',
77 ];
78 }
79
80 /**
81 * Categories.
82 *
83 * @return array<int, string>
84 */
85 public function get_categories(): array
86 {
87 return ['king-addons'];
88 }
89
90 /**
91 * Keywords.
92 *
93 * @return array<int, string>
94 */
95 public function get_keywords(): array
96 {
97 return ['woocommerce', 'cart', 'floating', 'badge', 'checkout'];
98 }
99
100 /**
101 * Register Elementor controls.
102 *
103 * @return void
104 */
105 public function register_controls(): void
106 {
107 $this->register_content_controls();
108 $this->register_layout_controls();
109 $this->register_panel_controls();
110 $this->register_style_controls();
111 $this->register_pro_notice_controls();
112 }
113
114 /**
115 * Render widget output.
116 *
117 * @return void
118 */
119 public function render(): void
120 {
121 $cart = $this->get_cart();
122 if ($cart === null) {
123 return;
124 }
125
126 $settings = $this->get_settings_for_display();
127
128 $count = (int) $cart->get_cart_contents_count();
129 $subtotal = $cart->get_subtotal();
130 $cart_url = wc_get_cart_url();
131 $checkout_url = wc_get_checkout_url();
132
133 $position = $settings['kng_position'] ?? 'right';
134 $show_badge = ($settings['kng_show_badge'] ?? 'yes') === 'yes';
135 $show_label = ($settings['kng_show_label'] ?? 'yes') === 'yes';
136 $show_subtotal = ($settings['kng_show_subtotal'] ?? 'yes') === 'yes';
137
138 $icon = $settings['kng_icon'] ?? [
139 'value' => 'eicon-cart-medium',
140 'library' => 'elementor',
141 ];
142
143 $offset_x = isset($settings['kng_offset_x']['size'], $settings['kng_offset_x']['unit'])
144 ? $settings['kng_offset_x']['size'] . $settings['kng_offset_x']['unit']
145 : '18px';
146
147 $offset_y = isset($settings['kng_offset_y']['size'], $settings['kng_offset_y']['unit'])
148 ? $settings['kng_offset_y']['size'] . $settings['kng_offset_y']['unit']
149 : '18px';
150
151 $wrapper_classes = ['king-addons-floating-cart'];
152 $wrapper_classes[] = $position === 'left' ? 'king-addons-floating-cart--left' : 'king-addons-floating-cart--right';
153
154 $button_classes = ['king-addons-floating-cart__button'];
155 if ($count === 0) {
156 $button_classes[] = 'is-empty';
157 }
158
159 $style_attr = $position === 'left'
160 ? 'left:' . esc_attr($offset_x) . ';bottom:' . esc_attr($offset_y) . ';'
161 : 'right:' . esc_attr($offset_x) . ';bottom:' . esc_attr($offset_y) . ';';
162
163 $items = array_slice($cart->get_cart(), 0, 2, true);
164 $remaining = max(0, $count - count($items));
165
166 ?>
167 <div class="<?php echo esc_attr(implode(' ', $wrapper_classes)); ?>" style="<?php echo esc_attr($style_attr); ?>">
168 <button type="button"
169 class="<?php echo esc_attr(implode(' ', $button_classes)); ?>"
170 aria-expanded="false"
171 aria-label="<?php echo esc_attr__('Open cart preview', 'king-addons'); ?>"
172 data-trigger="click"
173 data-auto-open="no">
174 <span class="king-addons-floating-cart__icon" aria-hidden="true">
175 <?php Icons_Manager::render_icon($icon, ['aria-hidden' => 'true']); ?>
176 </span>
177 <?php if ($show_label) : ?>
178 <span class="king-addons-floating-cart__label"><?php echo esc_html($settings['kng_label'] ?? esc_html__('Cart', 'king-addons')); ?></span>
179 <?php endif; ?>
180 <?php if ($show_badge) : ?>
181 <span class="king-addons-floating-cart__badge" aria-label="<?php echo esc_attr(sprintf(_n('%d item in cart', '%d items in cart', $count, 'king-addons'), $count)); ?>">
182 <?php echo esc_html($count); ?>
183 </span>
184 <?php endif; ?>
185 </button>
186 <div class="king-addons-floating-cart__panel" hidden aria-hidden="true">
187 <div class="king-addons-floating-cart__panel-head">
188 <span class="king-addons-floating-cart__panel-title"><?php echo esc_html__('Cart summary', 'king-addons'); ?></span>
189 <span class="king-addons-floating-cart__count">
190 <?php echo esc_html(sprintf(_n('%d item', '%d items', $count, 'king-addons'), $count)); ?>
191 </span>
192 </div>
193 <div class="king-addons-floating-cart__panel-body">
194 <?php if ($count === 0) : ?>
195 <p class="king-addons-floating-cart__empty"><?php echo esc_html__('Your cart is empty.', 'king-addons'); ?></p>
196 <?php else : ?>
197 <ul class="king-addons-floating-cart__items">
198 <?php foreach ($items as $cart_item_key => $cart_item) : ?>
199 <?php
200 $product = $cart_item['data'] ?? null;
201 if (!$product) {
202 continue;
203 }
204 ?>
205 <li class="king-addons-floating-cart__item">
206 <span class="king-addons-floating-cart__item-name"><?php echo esc_html($product->get_name()); ?></span>
207 <span class="king-addons-floating-cart__item-qty"><?php echo esc_html('x ' . ($cart_item['quantity'] ?? 1)); ?></span>
208 </li>
209 <?php endforeach; ?>
210 </ul>
211 <?php if ($remaining > 0) : ?>
212 <p class="king-addons-floating-cart__more">
213 <?php echo esc_html(sprintf(_n('and %d more item', 'and %d more items', $remaining, 'king-addons'), $remaining)); ?>
214 </p>
215 <?php endif; ?>
216 <?php endif; ?>
217 </div>
218 <div class="king-addons-floating-cart__panel-footer">
219 <?php if ($show_subtotal) : ?>
220 <div class="king-addons-floating-cart__subtotal">
221 <span class="king-addons-floating-cart__subtotal-label"><?php echo esc_html__('Subtotal', 'king-addons'); ?></span>
222 <span class="king-addons-floating-cart__subtotal-value"><?php echo wp_kses_post(wc_price((float) $subtotal)); ?></span>
223 </div>
224 <?php endif; ?>
225 <div class="king-addons-floating-cart__actions">
226 <a class="king-addons-floating-cart__link king-addons-floating-cart__link--cart" href="<?php echo esc_url($cart_url); ?>">
227 <?php echo esc_html__('View cart', 'king-addons'); ?>
228 </a>
229 <a class="king-addons-floating-cart__link king-addons-floating-cart__link--checkout" href="<?php echo esc_url($checkout_url); ?>">
230 <?php echo esc_html__('Checkout', 'king-addons'); ?>
231 </a>
232 </div>
233 </div>
234 </div>
235 </div>
236 <?php
237 }
238
239 /**
240 * Content controls.
241 *
242 * @return void
243 */
244 protected function register_content_controls(): void
245 {
246 $this->start_controls_section(
247 'kng_content_section',
248 [
249 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Content', 'king-addons'),
250 'tab' => Controls_Manager::TAB_CONTENT,
251 ]
252 );
253
254 $this->add_control(
255 'kng_icon',
256 [
257 'label' => esc_html__('Icon', 'king-addons'),
258 'type' => Controls_Manager::ICONS,
259 'default' => [
260 'value' => 'eicon-cart-medium',
261 'library' => 'elementor',
262 ],
263 ]
264 );
265
266 $this->add_control(
267 'kng_label',
268 [
269 'label' => esc_html__('Label', 'king-addons'),
270 'type' => Controls_Manager::TEXT,
271 'default' => esc_html__('Cart', 'king-addons'),
272 ]
273 );
274
275 $this->add_control(
276 'kng_show_label',
277 [
278 'label' => esc_html__('Show Label', 'king-addons'),
279 'type' => Controls_Manager::SWITCHER,
280 'label_on' => esc_html__('Show', 'king-addons'),
281 'label_off' => esc_html__('Hide', 'king-addons'),
282 'return_value' => 'yes',
283 'default' => 'yes',
284 ]
285 );
286
287 $this->add_control(
288 'kng_show_badge',
289 [
290 'label' => esc_html__('Show Count Badge', 'king-addons'),
291 'type' => Controls_Manager::SWITCHER,
292 'label_on' => esc_html__('Show', 'king-addons'),
293 'label_off' => esc_html__('Hide', 'king-addons'),
294 'return_value' => 'yes',
295 'default' => 'yes',
296 ]
297 );
298
299 $this->end_controls_section();
300 }
301
302 /**
303 * Layout controls for floating placement.
304 *
305 * @return void
306 */
307 protected function register_layout_controls(): void
308 {
309 $this->start_controls_section(
310 'kng_layout_section',
311 [
312 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Floating Button', 'king-addons'),
313 'tab' => Controls_Manager::TAB_CONTENT,
314 ]
315 );
316
317 $this->add_control(
318 'kng_position',
319 [
320 'label' => esc_html__('Side', 'king-addons'),
321 'type' => Controls_Manager::CHOOSE,
322 'options' => [
323 'left' => [
324 'title' => esc_html__('Left', 'king-addons'),
325 'icon' => 'eicon-h-align-left',
326 ],
327 'right' => [
328 'title' => esc_html__('Right', 'king-addons'),
329 'icon' => 'eicon-h-align-right',
330 ],
331 ],
332 'default' => 'right',
333 ]
334 );
335
336 $this->add_control(
337 'kng_offset_x',
338 [
339 'label' => esc_html__('Horizontal Offset', 'king-addons'),
340 'type' => Controls_Manager::SLIDER,
341 'size_units' => ['px'],
342 'range' => [
343 'px' => [
344 'min' => 0,
345 'max' => 120,
346 ],
347 ],
348 'default' => [
349 'size' => 18,
350 'unit' => 'px',
351 ],
352 ]
353 );
354
355 $this->add_control(
356 'kng_offset_y',
357 [
358 'label' => esc_html__('Bottom Offset', 'king-addons'),
359 'type' => Controls_Manager::SLIDER,
360 'size_units' => ['px'],
361 'range' => [
362 'px' => [
363 'min' => 0,
364 'max' => 200,
365 ],
366 ],
367 'default' => [
368 'size' => 18,
369 'unit' => 'px',
370 ],
371 ]
372 );
373
374 $this->end_controls_section();
375 }
376
377 /**
378 * Quick view panel controls.
379 *
380 * @return void
381 */
382 protected function register_panel_controls(): void
383 {
384 $this->start_controls_section(
385 'kng_panel_section',
386 [
387 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Quick View', 'king-addons'),
388 'tab' => Controls_Manager::TAB_CONTENT,
389 ]
390 );
391
392 $this->add_control(
393 'kng_show_subtotal',
394 [
395 'label' => esc_html__('Show Subtotal', 'king-addons'),
396 'type' => Controls_Manager::SWITCHER,
397 'return_value' => 'yes',
398 'default' => 'yes',
399 ]
400 );
401
402 $this->add_control(
403 'kng_upgrade_hover',
404 [
405 'label' => sprintf(__('Hover to open %s', 'king-addons'), '<i class="eicon-pro-icon"></i>'),
406 'type' => Controls_Manager::SWITCHER,
407 'classes' => 'king-addons-pro-control no-distance',
408 ]
409 );
410
411 $this->add_control(
412 'kng_upgrade_drawer',
413 [
414 'label' => sprintf(__('Drawer layout %s', 'king-addons'), '<i class="eicon-pro-icon"></i>'),
415 'type' => Controls_Manager::SWITCHER,
416 'classes' => 'king-addons-pro-control no-distance',
417 ]
418 );
419
420 $this->end_controls_section();
421 }
422
423 /**
424 * Style controls.
425 *
426 * @return void
427 */
428 protected function register_style_controls(): void
429 {
430 $this->start_controls_section(
431 'kng_style_button',
432 [
433 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Button', 'king-addons'),
434 'tab' => Controls_Manager::TAB_STYLE,
435 ]
436 );
437
438 $this->add_group_control(
439 Group_Control_Typography::get_type(),
440 [
441 'name' => 'kng_button_typography',
442 'selector' => '{{WRAPPER}} .king-addons-floating-cart__button',
443 ]
444 );
445
446 $this->add_control(
447 'kng_button_text_color',
448 [
449 'label' => esc_html__('Text Color', 'king-addons'),
450 'type' => Controls_Manager::COLOR,
451 'selectors' => [
452 '{{WRAPPER}} .king-addons-floating-cart__button' => 'color: {{VALUE}};',
453 ],
454 ]
455 );
456
457 $this->add_control(
458 'kng_button_bg',
459 [
460 'label' => esc_html__('Background', 'king-addons'),
461 'type' => Controls_Manager::COLOR,
462 'selectors' => [
463 '{{WRAPPER}} .king-addons-floating-cart__button' => 'background-color: {{VALUE}};',
464 ],
465 ]
466 );
467
468 $this->add_control(
469 'kng_button_bg_hover',
470 [
471 'label' => esc_html__('Hover Background', 'king-addons'),
472 'type' => Controls_Manager::COLOR,
473 'selectors' => [
474 '{{WRAPPER}} .king-addons-floating-cart__button:hover' => 'background-color: {{VALUE}};',
475 ],
476 ]
477 );
478
479 $this->add_group_control(
480 Group_Control_Border::get_type(),
481 [
482 'name' => 'kng_button_border',
483 'selector' => '{{WRAPPER}} .king-addons-floating-cart__button',
484 ]
485 );
486
487 $this->add_group_control(
488 Group_Control_Box_Shadow::get_type(),
489 [
490 'name' => 'kng_button_shadow',
491 'selector' => '{{WRAPPER}} .king-addons-floating-cart__button',
492 ]
493 );
494
495 $this->add_responsive_control(
496 'kng_button_padding',
497 [
498 'label' => esc_html__('Padding', 'king-addons'),
499 'type' => Controls_Manager::DIMENSIONS,
500 'size_units' => ['px', 'em'],
501 'selectors' => [
502 '{{WRAPPER}} .king-addons-floating-cart__button' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
503 ],
504 ]
505 );
506
507 $this->end_controls_section();
508
509 $this->start_controls_section(
510 'kng_style_badge',
511 [
512 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Badge', 'king-addons'),
513 'tab' => Controls_Manager::TAB_STYLE,
514 ]
515 );
516
517 $this->add_control(
518 'kng_badge_bg',
519 [
520 'label' => esc_html__('Badge Background', 'king-addons'),
521 'type' => Controls_Manager::COLOR,
522 'selectors' => [
523 '{{WRAPPER}} .king-addons-floating-cart__badge' => 'background-color: {{VALUE}};',
524 ],
525 ]
526 );
527
528 $this->add_control(
529 'kng_badge_color',
530 [
531 'label' => esc_html__('Badge Text', 'king-addons'),
532 'type' => Controls_Manager::COLOR,
533 'selectors' => [
534 '{{WRAPPER}} .king-addons-floating-cart__badge' => 'color: {{VALUE}};',
535 ],
536 ]
537 );
538
539 $this->add_group_control(
540 Group_Control_Box_Shadow::get_type(),
541 [
542 'name' => 'kng_badge_shadow',
543 'selector' => '{{WRAPPER}} .king-addons-floating-cart__badge',
544 ]
545 );
546
547 $this->end_controls_section();
548
549 $this->start_controls_section(
550 'kng_style_panel',
551 [
552 'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Panel', 'king-addons'),
553 'tab' => Controls_Manager::TAB_STYLE,
554 ]
555 );
556
557 $this->add_group_control(
558 Group_Control_Typography::get_type(),
559 [
560 'name' => 'kng_panel_typography',
561 'selector' => '{{WRAPPER}} .king-addons-floating-cart__panel',
562 ]
563 );
564
565 $this->add_control(
566 'kng_panel_bg',
567 [
568 'label' => esc_html__('Background', 'king-addons'),
569 'type' => Controls_Manager::COLOR,
570 'selectors' => [
571 '{{WRAPPER}} .king-addons-floating-cart__panel' => 'background-color: {{VALUE}};',
572 ],
573 ]
574 );
575
576 $this->add_control(
577 'kng_panel_text',
578 [
579 'label' => esc_html__('Text Color', 'king-addons'),
580 'type' => Controls_Manager::COLOR,
581 'selectors' => [
582 '{{WRAPPER}} .king-addons-floating-cart__panel' => 'color: {{VALUE}};',
583 ],
584 ]
585 );
586
587 $this->add_group_control(
588 Group_Control_Border::get_type(),
589 [
590 'name' => 'kng_panel_border',
591 'selector' => '{{WRAPPER}} .king-addons-floating-cart__panel',
592 ]
593 );
594
595 $this->add_group_control(
596 Group_Control_Box_Shadow::get_type(),
597 [
598 'name' => 'kng_panel_shadow',
599 'selector' => '{{WRAPPER}} .king-addons-floating-cart__panel',
600 ]
601 );
602
603 $this->add_responsive_control(
604 'kng_panel_padding',
605 [
606 'label' => esc_html__('Padding', 'king-addons'),
607 'type' => Controls_Manager::DIMENSIONS,
608 'size_units' => ['px', 'em'],
609 'selectors' => [
610 '{{WRAPPER}} .king-addons-floating-cart__panel' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
611 ],
612 ]
613 );
614
615 $this->end_controls_section();
616 }
617
618 /**
619 * Render pro upgrade notice.
620 *
621 * @return void
622 */
623 public function register_pro_notice_controls(): void
624 {
625 if (!king_addons_freemius()->can_use_premium_code__premium_only()) {
626 Core::renderProFeaturesSection(
627 $this,
628 '',
629 Controls_Manager::RAW_HTML,
630 'woocommerce-floating-cart-icon',
631 [
632 'Hover trigger and auto-open after add to cart',
633 'Drawer layout with slide animation',
634 'Show thumbnails, subtotals, and remove actions',
635 'Hide button on empty cart or specific devices',
636 'Custom checkout label and quick actions',
637 ]
638 );
639 }
640 }
641
642 /**
643 * Get WooCommerce cart instance when available.
644 *
645 * @return \WC_Cart|null
646 */
647 protected function get_cart(): ?\WC_Cart
648 {
649 if (!function_exists('WC')) {
650 return null;
651 }
652
653 $wc = WC();
654 if (!is_object($wc) || !method_exists($wc, 'cart')) {
655 return null;
656 }
657
658 return $wc->cart ?: null;
659 }
660 }
661
662
663
664
665