PluginProbe
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder / 51.1.81
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder v51.1.81
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 / wishlist / Wishlist_WooCommerce.php

Wishlist_WooCommerce.php in King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder 51.1.81, at includes/wishlist/Wishlist_WooCommerce.php

201 lines 5.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace King_Addons\Wishlist;
4
5 use WC_Product;
6 use WC_Order;
7
8 if (!defined('ABSPATH')) {
9 exit;
10 }
11
12 /**
13 * Integrates wishlist UI into WooCommerce templates and tracks conversions.
14 */
15 class Wishlist_WooCommerce
16 {
17 private Wishlist_Service $service;
18 private Wishlist_Renderer $renderer;
19
20 /**
21 * @param Wishlist_Service $service Wishlist service.
22 * @param Wishlist_Renderer $renderer Wishlist renderer.
23 */
24 public function __construct(Wishlist_Service $service, Wishlist_Renderer $renderer)
25 {
26 $this->service = $service;
27 $this->renderer = $renderer;
28 }
29
30 /**
31 * Register WooCommerce hooks.
32 *
33 * @return void
34 */
35 public function hooks(): void
36 {
37 if (!Wishlist_Settings::is_enabled() || !function_exists('wc_get_product')) {
38 return;
39 }
40
41 $position = Wishlist_Settings::get('button_position', 'after_add_to_cart');
42 $hook = $position === 'before_add_to_cart' ? 'woocommerce_before_add_to_cart_button' : 'woocommerce_after_add_to_cart_button';
43 add_action($hook, [$this, 'render_single_button']);
44
45 $atc_hook = $position === 'before_add_to_cart' ? 'king_addons/woo_product_atc/before_buttons' : 'king_addons/woo_product_atc/after_buttons';
46 add_action($atc_hook, [$this, 'render_single_button']);
47
48 if (Wishlist_Settings::get('show_in_archives', true)) {
49 add_action('woocommerce_after_shop_loop_item', [$this, 'render_loop_button'], 12);
50 add_action('king_addons/woo_products_grid/after_add_to_cart', [$this, 'render_grid_button']);
51 }
52
53 // Track conversions when order is completed
54 add_action('woocommerce_order_status_completed', [$this, 'track_conversion'], 10, 1);
55 add_action('woocommerce_order_status_processing', [$this, 'track_conversion'], 10, 1);
56 }
57
58 /**
59 * Track wishlist to purchase conversions.
60 *
61 * @param int $order_id Order ID.
62 * @return void
63 */
64 public function track_conversion(int $order_id): void
65 {
66 $order = wc_get_order($order_id);
67 if (!$order instanceof WC_Order) {
68 return;
69 }
70
71 // Check if already tracked
72 $tracked = $order->get_meta('_ka_wishlist_conversion_tracked');
73 if ($tracked) {
74 return;
75 }
76
77 $user_id = $order->get_customer_id();
78 if ($user_id <= 0) {
79 return;
80 }
81
82 global $wpdb;
83 $items_table = Wishlist_DB::get_items_table();
84 $conversions_table = Wishlist_DB::get_conversions_table();
85
86 // Get user's wishlist product IDs
87 $wishlist_products = $wpdb->get_col(
88 $wpdb->prepare(
89 "SELECT DISTINCT product_id FROM {$items_table} WHERE user_id = %d",
90 $user_id
91 )
92 );
93
94 if (empty($wishlist_products)) {
95 return;
96 }
97
98 // Check each order item against wishlist
99 foreach ($order->get_items() as $item) {
100 $product_id = $item->get_product_id();
101 $variation_id = $item->get_variation_id();
102
103 if (!in_array($product_id, $wishlist_products, false)) {
104 continue;
105 }
106
107 // This product was in wishlist - record conversion
108 $wpdb->replace(
109 $conversions_table,
110 [
111 'user_id' => $user_id,
112 'product_id' => $product_id,
113 'variation_id' => $variation_id ?: 0,
114 'order_id' => $order_id,
115 'order_item_qty' => $item->get_quantity(),
116 'order_item_total' => $item->get_total(),
117 'converted_at' => current_time('mysql', true),
118 ],
119 ['%d', '%d', '%d', '%d', '%d', '%f', '%s']
120 );
121 }
122
123 // Mark order as tracked
124 $order->update_meta_data('_ka_wishlist_conversion_tracked', 1);
125 $order->save();
126 }
127
128 /**
129 * Render wishlist button on single product pages.
130 *
131 * @param mixed $product Optional product from King Addons ATC widget.
132 * @return void
133 */
134 public function render_single_button($passed = null): void
135 {
136 if (!Wishlist_Settings::is_enabled()) {
137 return;
138 }
139
140 $product = $passed instanceof WC_Product ? $passed : $GLOBALS['product'] ?? null;
141 if (!$product instanceof WC_Product) {
142 return;
143 }
144
145 echo Wishlist_Renderer::kses(
146 $this->renderer->render_button([
147 'product_id' => $product->get_id(),
148 'variation_id' => 0,
149 'class' => 'king-addons-wishlist-button--single',
150 ])
151 );
152 }
153
154 /**
155 * Render wishlist button inside product loop cards.
156 *
157 * @return void
158 */
159 public function render_loop_button(): void
160 {
161 if (!Wishlist_Settings::is_enabled()) {
162 return;
163 }
164
165 global $product;
166 if (!$product instanceof WC_Product) {
167 return;
168 }
169
170 echo Wishlist_Renderer::kses(
171 $this->renderer->render_button([
172 'product_id' => $product->get_id(),
173 'class' => 'king-addons-wishlist-button--loop',
174 ])
175 );
176 }
177
178 /**
179 * Render wishlist button on King Addons Products Grid cards.
180 *
181 * @param mixed $product Product from the grid card.
182 * @return void
183 */
184 public function render_grid_button($product): void
185 {
186 if (!Wishlist_Settings::is_enabled() || !$product instanceof WC_Product) {
187 return;
188 }
189
190 echo Wishlist_Renderer::kses(
191 $this->renderer->render_button([
192 'product_id' => $product->get_id(),
193 'class' => 'king-addons-wishlist-button--loop',
194 ])
195 );
196 }
197 }
198
199
200
201