PluginProbe
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder / 51.1.86
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder v51.1.86
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.86, at includes/widgets/WooCommerce_Floating_Cart_Icon/WooCommerce_Floating_Cart_Icon.php

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