PluginProbe
SuperFrete / 2.1.6
SuperFrete v2.1.6
trunk 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 2.0.0 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 3.2.1 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4
superfrete / app / Controllers / ProductShipping.php

ProductShipping.php in SuperFrete 2.1.6, at app/Controllers/ProductShipping.php

490 lines 17.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace SuperFrete_API\Controllers;
4
5 use SuperFrete_API\Http\Request;
6 use WC_Shipping_Zones;
7
8 if (!defined('ABSPATH'))
9 exit; // Segurança
10
11 class ProductShipping {
12
13 public function __construct() {
14
15
16 add_action('woocommerce_after_add_to_cart_form', array(__CLASS__, 'calculator'));
17
18
19 add_shortcode('pi_shipping_calculator', array($this, 'calculator_shortcode'));
20
21 add_action('wc_ajax_pi_load_location_by_ajax', array(__CLASS__, 'loadLocation') );
22 add_action('woocommerce_after_add_to_cart_form', [$this, 'enqueue_scripts']);
23 add_action('wp_ajax_superfrete_calculate', [$this, 'calculate_shipping']);
24 add_action('wp_ajax_nopriv_superfrete_calculate', [$this, 'calculate_shipping']); // Para usuários não logados
25
26 add_action('wp_ajax_superfrete_cal_shipping', array(__CLASS__, 'applyShipping'));
27 add_action('wp_ajax_nopriv_superfrete_cal_shipping', array(__CLASS__, 'applyShipping'));
28 add_action('wc_ajax_superfrete_cal_shipping', array(__CLASS__, 'applyShipping'));
29 }
30
31 static function resultHtml() {
32 echo '<div id="superfrete-alert-container" class="superfrete-alert-container"></div>';
33 }
34
35 function calculator_shortcode() {
36 if ($this->position != 'shortcode') {
37 return '<div class="error">' . __('Short code is disabled in setting', 'superfrete-product-page-shipping-calculator-woocommerce') . '</di>';
38 }
39
40 if (function_exists('is_product') && !is_product()) {
41 return '<div class="error">' . __('This shortcode will only work on product page', 'superfrete-product-page-shipping-calculator-woocommerce') . '</di>';
42 }
43
44 global $product;
45
46 if (!is_object($product) || $product->is_virtual() || !$product->is_in_stock())
47 return;
48
49 ob_start();
50 self::calculator();
51 $html = ob_get_contents();
52 ob_end_clean();
53 return $html;
54 }
55
56 static function calculator() {
57 global $product;
58
59 if (apply_filters('superfrete_hide_calculator_on_single_product_page', false, $product)) {
60 return;
61 }
62
63 if (is_object($product)) {
64 $product_id = $product->get_id();
65 } else {
66 $product = "";
67 }
68
69 $enable_calculator = get_option('superfrete_enable_calculator');
70
71 if ($enable_calculator === 'no')
72 return;
73
74 $button_text = get_option('superfrete_open_drawer_button_text', 'Calcular Entrega');
75 $update_address_btn_text = get_option('superfrete_update_button_text', 'Calcular');
76
77 include plugin_dir_path(__FILE__) . '../../templates/woocommerce/shipping-calculator.php';
78 }
79
80 static function hideCalculator($val, $product) {
81 if (is_object($product) && $product->is_virtual())
82 return true;
83
84 return $val;
85 }
86
87 static function applyShipping() {
88 if (!isset($_POST['superfrete_nonce']) || !wp_verify_nonce($_POST['superfrete_nonce'], 'superfrete_nonce')) {
89 wp_send_json_error(['message' => 'Requisição inválida.'], 403);
90 }
91 if (!class_exists('WC_Shortcode_Cart')) {
92 include_once WC_ABSPATH . 'includes/shortcodes/class-wc-shortcode-cart.php';
93 }
94
95
96 if (self::doingCalculation()) {
97
98
99 if ((isset($_POST['action_auto_load']) && self::disableAutoLoadEstimate()) || empty($_POST['calc_shipping_postcode']) || !isset($_POST['calc_shipping_postcode'])) {
100
101 $return['shipping_methods'] = sprintf('<div class="superfrete-alert">%s</div>', esc_html(get_option('superfrete_no_address_added_yet', 'Informe seu Endereço para calcular')));
102 wp_send_json($return);
103 }
104
105 /*
106 $return = array();
107 WC_Shortcode_Cart::calculate_shipping();
108 WC()->cart->calculate_totals();
109
110
111 $item_key = self::addTestProductForProperShippingCost();
112
113
114 if(WC()->cart->get_cart_contents_count() == 0 ){
115 $blank_package = self::get_shipping_packages();
116 WC()->shipping()->calculate_shipping($blank_package );
117 }
118 $packages = WC()->shipping()->get_packages();
119 $shipping_methods = self::getShippingMethods($packages);
120 $return['error'] = wc_print_notices(true);
121 //error_log(print_r($return,true));
122 //wc_clear_notices();
123 $return['shipping_methods'] = self::messageTemplate($shipping_methods);
124 echo json_encode($return);
125
126 if($item_key){
127 WC()->cart->remove_cart_item($item_key);
128 }
129 */
130
131 $return = array();
132 \WC_Shortcode_Cart::calculate_shipping();
133 WC()->cart->calculate_totals();
134
135
136
137
138 $original_cart = WC()->cart->get_cart();
139 WC()->cart->empty_cart();
140 $item_key = self::addTestProductForProperShippingCost();
141
142 WC()->shipping()->calculate_shipping();
143 WC()->cart->calculate_totals();
144 $packages = WC()->shipping()->get_packages();
145
146
147
148
149
150 $shipping_methods = self::getShippingMethods($packages);
151 $return['error'] = wc_print_notices(true);
152 $return['shipping_methods'] = self::messageTemplate($shipping_methods);
153 echo wp_json_encode($return);
154
155 if (!empty($original_cart)) {
156 WC()->cart->set_cart_contents($original_cart);
157 WC()->cart->calculate_totals();
158 }
159
160 if ($item_key) {
161 WC()->cart->remove_cart_item($item_key);
162 }
163 }
164 wp_die();
165 }
166
167 static function is_product_present_in_cart() {
168 return false;
169 }
170
171 static function noShippingLocationInserted() {
172 $country = WC()->customer->get_shipping_country();
173 if (empty($country) || $country == 'default')
174 return true;
175
176 return false;
177 }
178
179 static function onlyPassErrorNotice($notice_type) {
180 if (self::doingCalculation()) {
181 return array('error');
182 }
183 return $notice_type;
184 }
185
186 static function doingCalculation() {
187
188
189 if (wp_verify_nonce($_POST['superfrete_nonce'], 'superfrete_nonce') && !empty($_POST['calc_shipping']) ) {
190 return true;
191 }
192 return false;
193 }
194
195 static function addTestProductForProperShippingCost() {
196 $product_id = filter_input(INPUT_POST, 'product_id');
197 $quantity = filter_input(INPUT_POST, 'quantity');
198 if (empty($quantity))
199 $quantity = 1;
200
201 if ($product_id) {
202 $variation_id = filter_input(INPUT_POST, 'variation_id');
203 if (!$variation_id) {
204 $variation_id = 0;
205 }
206 $item_key = self::addProductToCart($product_id, $variation_id, $quantity);
207 } else {
208 $item_key = "";
209 }
210 return $item_key;
211 }
212
213 static function addProductToCart($product_id, $variation_id, $quantity = 1) {
214 $consider_product_quantity = apply_filters('superfrete_ppscw_consider_quantity_in_shipping_calculation', get_option('superfrete_consider_quantity_field', 'dont-consider-quantity-field'), $product_id, $variation_id, $quantity);
215
216 if ($consider_product_quantity == 'dont-consider-quantity-field') {
217 if (self::productExistInCart($product_id, $variation_id))
218 return "";
219 $quantity = 1;
220 }
221
222 if (!empty($variation_id)) {
223 $variation = self::getVariationAttributes($variation_id);
224 } else {
225 $variation = array();
226 }
227
228 $item_key = WC()->cart->add_to_cart(
229 $product_id,
230 $quantity,
231 $variation_id,
232 $variation,
233 array(
234 'superfrete_test_product_for_calculation' => '1',
235 )
236 );
237 return $item_key;
238 }
239
240 static function getVariationAttributes($product_id) {
241
242 if (empty($product_id))
243 return array();
244
245 $product = wc_get_product($product_id);
246
247 if (!is_object($product))
248 return array();
249
250 $variation = array();
251 $type = $product->get_type();
252 if ($type == 'variation') {
253 $parent_id = $product->get_parent_id();
254 $parent_obj = wc_get_product($parent_id);
255 $default_attributes = $parent_obj->get_default_attributes();
256 $variation_attributes = $product->get_variation_attributes();
257 // Get all parent attributes, needed to fetch attribute options.
258 $parent_attributes = $parent_obj->get_attributes();
259 $variation = self::getAttributes($variation_attributes, $default_attributes, $parent_attributes);
260 return $variation;
261 }
262 return $variation;
263 }
264
265 static function getAttributes($variation_attributes, $default_attributes, $parent_attributes) {
266 $list = array();
267 foreach ($variation_attributes as $name => $value) {
268 $att_name = str_replace('attribute_', "", $name);
269 if (empty($value)) {
270 $value = isset($default_attributes[$att_name]) ? $default_attributes[$att_name] : "";
271
272 if (empty($value) && isset($parent_attributes[$att_name])) {
273 $attribute_obj = $parent_attributes[$att_name];
274 if ($attribute_obj->get_variation()) {
275 $options = $attribute_obj->get_options();
276 if (!empty($options)) {
277 // If taxonomy based, options are term IDs so convert the first one to slug.
278 if ($attribute_obj->is_taxonomy()) {
279 $term = get_term($options[0]);
280 if (!is_wp_error($term) && $term) {
281 $value = $term->slug;
282 } else {
283 $value = 'x';
284 }
285 } else {
286 // For custom attributes, simply use the first option.
287 $value = $options[0];
288 }
289 } else {
290 $value = 'x'; // Fallback if no options found.
291 }
292 } else {
293 $value = 'x'; // Fallback if attribute is not variation-enabled.
294 }
295 }
296 }
297 $list[$name] = $value;
298 }
299 return $list;
300 }
301
302 static function productExistInCart($product_id, $variation_id) {
303 if (!WC()->cart->is_empty()) {
304 foreach (WC()->cart->get_cart() as $cart_item) {
305 if ($cart_item['product_id'] == $product_id && $cart_item['variation_id'] == $variation_id) {
306 return true;
307 }
308 }
309 }
310 return false;
311 }
312
313 static function get_shipping_packages() {
314 return array(
315 array(
316 'contents' => array(),
317 'contents_cost' => 0,
318 'applied_coupons' => '',
319 'user' => array(
320 'ID' => get_current_user_id(),
321 ),
322 'destination' => array(
323 'country' => self::get_customer()->get_shipping_country(),
324 'state' => self::get_customer()->get_shipping_state(),
325 'postcode' => self::get_customer()->get_shipping_postcode(),
326 'city' => self::get_customer()->get_shipping_city(),
327 ),
328 'cart_subtotal' => 0,
329 ),
330 );
331 }
332
333 static function get_customer() {
334 return WC()->customer;
335 }
336
337 static function getShippingMethods($packages) {
338 $shipping_methods = array();
339 $product_id = filter_input(INPUT_POST, 'product_id');
340 $variation_id = filter_input(INPUT_POST, 'variation_id');
341 foreach ($packages as $package) {
342 if (empty($package['rates']) || !is_array($package['rates']))
343 break;
344
345 foreach ($package['rates'] as $id => $rate) {
346 $title = wc_cart_totals_shipping_method_label($rate);
347 $title = self::modifiedTitle($title, $rate);
348 $shipping_methods[$id] = apply_filters('superfrete_ppscw_shipping_method_name', $title, $rate, $product_id, $variation_id);
349 }
350 }
351 return $shipping_methods;
352 }
353
354 static function noMethodAvailableMsg() {
355
356 if (self::noShippingLocationInserted()) {
357 return wp_kses_post(get_option('superfrete_no_address_added_yet', 'Informe seu Endereço para calcular'));
358 } else {
359 return wp_kses_post(get_option('superfrete_no_shipping_methods_msg', 'Nenhum método de envio encontrado'));
360 }
361 }
362
363 static function disableAutoLoadEstimate() {
364 $auto_loading = get_option('superfrete_auto_calculation', 'enabled');
365
366 if ($auto_loading == 'enabled')
367 return false;
368
369 return true;
370 }
371
372 static function messageTemplate($shipping_methods) {
373
374
375
376 $message_above = get_option('superfrete_above_shipping_methods', 'Metódos de Envio Disponíveis');
377
378 $message_above = self::shortCode($message_above);
379
380 if (is_array($shipping_methods) && !empty($shipping_methods)) {
381 $html = '';
382 foreach ($shipping_methods as $id => $method) {
383 $html .= sprintf('<li id="%s">%s</li>', esc_attr($id), $method);
384 }
385 if (!empty($html)) {
386 $shipping_methods_msg = '<ul class="superfrete-methods">' . $html . '</ul>';
387 } else {
388 $shipping_methods_msg = "";
389 }
390 } else {
391 $shipping_methods_msg = "";
392 }
393
394 $when_shipping_msg = wp_kses_post($message_above) . '<br>' . $shipping_methods_msg;
395
396 $msg = is_array($shipping_methods) && !empty($shipping_methods) ? $when_shipping_msg : self::noMethodAvailableMsg();
397
398 return sprintf('<div class="superfrete-alert">%s</div>', $msg);
399 }
400
401 static function shortCode($message) {
402
403 $country = __('Country', 'superfrete-product-page-shipping-calculator-woocommerce');
404
405 if (isset(WC()->customer)) {
406 $country_code = self::get_customer()->get_shipping_country();
407 if (!empty($country_code) && isset(WC()->countries) && $country_code !== 'default') {
408 $country = WC()->countries->countries[$country_code];
409 }
410 }
411
412 $find_replace = array(
413 '[country]' => $country
414 );
415
416 $message = str_replace(array_keys($find_replace), array_values($find_replace), $message);
417
418 return $message;
419 }
420
421 function enableShippingCalculationWithoutAddress($val) {
422 if (wp_verify_nonce($_POST['superfrete_nonce'], 'superfrete_nonce') && ((isset($_POST['action']) && $_POST['action'] === 'superfrete_cal_shipping') || (isset($_POST['action']) && $_POST['action'] === 'superfrete_save_address_form'))) {
423 return null;
424 }
425 return $val;
426 }
427
428 static function modifiedTitle($title, $rate) {
429
430 if (isset($rate->cost) && $rate->cost == 0) {
431 $free_display_type = get_option('superfrete_free_shipping_price', 'nothing');
432
433 if ($free_display_type == 'nothing')
434 return $title;
435
436 if ($free_display_type == 'zero') {
437 $label = $rate->get_label();
438 $title = $label . ': ' . wc_price($rate->cost);
439 }
440 }
441
442 return $title;
443 }
444
445 static function loadLocation() {
446 $location = ['calc_shipping_country' => '', 'calc_shipping_state' => '', 'calc_shipping_city' => '', 'calc_shipping_postcode' => ''];
447
448 if (function_exists('WC') && isset(WC()->customer) && is_object(WC()->customer)) {
449 $location['calc_shipping_country'] = WC()->customer->get_shipping_country();
450 $location['calc_shipping_state'] = WC()->customer->get_shipping_state();
451 $location['calc_shipping_city'] = WC()->customer->get_shipping_city();
452 $location['calc_shipping_postcode'] = WC()->customer->get_shipping_postcode();
453 }
454
455 wp_send_json($location);
456 }
457
458 /**
459 * Exibe o formulário de cálculo de frete na página do produto.
460 */
461 public function display_calculator_form() {
462 include plugin_dir_path(__FILE__) . '../../templates/woocommerce/shipping-calculator.php';
463 }
464 /**
465 * Adiciona os scripts necessários
466 */
467 public function enqueue_scripts() {
468 $plugin_file = plugin_dir_path(__FILE__) . '../../superfrete.php';
469
470 // Inclui função get_plugin_data se ainda não estiver disponível
471 if ( ! function_exists( 'get_plugin_data' ) ) {
472 require_once ABSPATH . 'wp-admin/includes/plugin.php';
473 }
474 $plugin_data = get_plugin_data( $plugin_file );
475 $plugin_version = $plugin_data['Version'];
476 wp_enqueue_script(
477 'superfrete-calculator',
478 plugin_dir_url(__FILE__) . '../../assets/scripts/superfrete-calculator.js',
479 ['jquery'],
480 $plugin_version, // Versão do script
481 null,
482 true
483 );
484
485 wp_localize_script('superfrete-calculator', 'superfrete_ajax', [
486 'ajax_url' => admin_url('admin-ajax.php'),
487 ]);
488 }
489 }
490