Passed
Pull Request — master (#45)
by pablo
02:40
created

WcPagantisGateway::pagantisNotification()   A

Complexity

Conditions 5
Paths 48

Size

Total Lines 30
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 21
c 0
b 0
f 0
nc 48
nop 0
dl 0
loc 30
rs 9.2728
1
<?php
2
3
//namespace empty
4
use Pagantis\ModuleUtils\Exception\OrderNotFoundException;
5
use Pagantis\OrdersApiClient\Model\Order\User\Address;
6
use Pagantis\OrdersApiClient\Model\Order\User;
7
use Pagantis\OrdersApiClient\Model\Order\User\OrderHistory;
8
use Pagantis\OrdersApiClient\Model\Order\ShoppingCart\Details;
9
use Pagantis\OrdersApiClient\Model\Order\ShoppingCart;
10
use Pagantis\OrdersApiClient\Model\Order\ShoppingCart\Details\Product;
11
use Pagantis\OrdersApiClient\Model\Order\Metadata;
12
use Pagantis\OrdersApiClient\Model\Order\Configuration\Urls;
13
use Pagantis\OrdersApiClient\Model\Order\Configuration\Channel;
14
use Pagantis\OrdersApiClient\Model\Order\Configuration;
15
use Pagantis\OrdersApiClient\Client;
16
use Pagantis\OrdersApiClient\Model\Order;
17
use Pagantis\ModuleUtils\Model\Log\LogEntry;
18
19
if (!defined('ABSPATH')) {
20
    exit;
21
}
22
23
define('__ROOT__', dirname(dirname(__FILE__)));
24
25
26
class WcPagantisGateway extends WC_Payment_Gateway
27
{
28
    const METHOD_ID = "pagantis";
29
30
    /** Orders tablename */
31
    const ORDERS_TABLE = 'cart_process';
32
33
    /** Concurrency tablename */
34
    const LOGS_TABLE = 'pagantis_logs';
35
36
    const NOT_CONFIRMED = 'No se ha podido confirmar el pago';
37
38
    const CONFIG_TABLE = 'pagantis_config';
39
40
    /** @var Array $extraConfig */
41
    public $extraConfig;
42
43
    /** @var string $language */
44
    public $language;
45
46
    /**
47
     * WcPagantisGateway constructor.
48
     */
49
    public function __construct()
50
    {
51
        //Mandatory vars for plugin
52
        $this->id = WcPagantisGateway::METHOD_ID;
53
        $this->has_fields = true;
54
        $this->method_title = ucfirst($this->id);
55
56
        //Useful vars
57
        $this->template_path = plugin_dir_path(__FILE__) . '../templates/';
58
        $this->allowed_currencies = array("EUR");
59
        $this->mainFileLocation = dirname(plugin_dir_path(__FILE__)) . '/WC_Pagantis.php';
60
        $this->plugin_info = get_file_data($this->mainFileLocation, array('Version' => 'Version'), false);
61
        $this->language = strstr(get_locale(), '_', true);
62
        if ($this->language=='') {
63
            $this->language = 'ES';
64
        }
65
        $this->icon = 'https://cdn.digitalorigin.com/assets/master/logos/pg-130x30.svg';
66
67
        //Panel form fields
68
        $this->form_fields = include(plugin_dir_path(__FILE__).'../includes/settings-pagantis.php');//Panel options
69
        $this->init_settings();
70
71
        $this->extraConfig = $this->getExtraConfig();
72
        $this->title = __($this->extraConfig['PAGANTIS_TITLE'], 'pagantis');
73
        $this->method_description = "Financial Payment Gateway. Enable the possibility for your customers to pay their order in confortable installments with Pagantis.";
74
75
        $this->settings['ok_url'] = ($this->extraConfig['PAGANTIS_URL_OK']!='')?$this->extraConfig['PAGANTIS_URL_OK']:$this->generateOkUrl();
76
        $this->settings['ko_url'] = ($this->extraConfig['PAGANTIS_URL_KO']!='')?$this->extraConfig['PAGANTIS_URL_KO']:$this->generateKoUrl();
77
        foreach ($this->settings as $setting_key => $setting_value) {
78
            $this->$setting_key = $setting_value;
79
        }
80
81
        //Hooks
82
        add_action('woocommerce_update_options_payment_gateways_'.$this->id, array($this,'process_admin_options')); //Save plugin options
83
        add_action('admin_notices', array($this, 'pagantisCheckFields'));                          //Check config fields
84
        add_action('woocommerce_receipt_'.$this->id, array($this, 'pagantisReceiptPage'));          //Pagantis form
85
        add_action('woocommerce_api_wcpagantisgateway', array($this, 'pagantisNotification'));      //Json Notification
86
        add_filter('woocommerce_payment_complete_order_status', array($this,'pagantisCompleteStatus'), 10, 3);
87
        add_filter('load_textdomain_mofile', array($this, 'loadPagantisTranslation'), 10, 2);
88
    }
89
90
    /**
91
     * @param $mofile
92
     * @param $domain
93
     *
94
     * @return string
95
     */
96
    public function loadPagantisTranslation($mofile, $domain)
97
    {
98
        if ('pagantis' === $domain) {
99
            $mofile = WP_LANG_DIR . '/../plugins/pagantis/languages/pagantis-' . get_locale() . '.mo';
100
        }
101
        return $mofile;
102
    }
103
104
    /***********
105
     *
106
     * HOOKS
107
     *
108
     ***********/
109
110
    /**
111
     * PANEL - Display admin panel -> Hook: woocommerce_update_options_payment_gateways_pagantis
112
     */
113
    public function admin_options()
114
    {
115
        $template_fields = array(
116
            'panel_description' => $this->method_description,
117
            'button1_label' => __('Login to your panel', 'pagantis'),
118
            'button2_label' => __('Documentation', 'pagantis'),
119
            'logo' => $this->icon,
120
            'settings' => $this->generate_settings_html($this->form_fields, false)
121
        );
122
        wc_get_template('admin_header.php', $template_fields, '', $this->template_path);
123
    }
124
125
    /**
126
     * PANEL - Check admin panel fields -> Hook: admin_notices
127
     */
128
    public function pagantisCheckFields()
129
    {
130
        $error_string = '';
131
        if ($this->settings['enabled'] !== 'yes') {
132
            return;
133
        } elseif (!version_compare(phpversion(), '5.3.0', '>=')) {
134
            $error_string =  __(' is not compatible with your php and/or curl version', 'pagantis');
135
            $this->settings['enabled'] = 'no';
136
        } elseif ($this->settings['pagantis_public_key']=="" || $this->settings['pagantis_private_key']=="") {
137
            $error_string = __(' is not configured correctly, the fields Public Key and Secret Key are mandatory for use this plugin', 'pagantis');
138
            $this->settings['enabled'] = 'no';
139
        } elseif (!in_array(get_woocommerce_currency(), $this->allowed_currencies)) {
140
            $error_string =  __(' only can be used in Euros', 'pagantis');
141
            $this->settings['enabled'] = 'no';
142
        } elseif ($this->extraConfig['PAGANTIS_SIMULATOR_MAX_INSTALLMENTS']<'2'
143
                  || $this->extraConfig['PAGANTIS_SIMULATOR_MAX_INSTALLMENTS']>'12') {
144
            $error_string = __(' only can be payed from 2 to 12 installments', 'pagantis');
145
        } elseif ($this->extraConfig['PAGANTIS_SIMULATOR_START_INSTALLMENTS']<'2'
146
                  || $this->extraConfig['PAGANTIS_SIMULATOR_START_INSTALLMENTS']>'12') {
147
            $error_string = __(' only can be payed from 2 to 12 installments', 'pagantis');
148
        } elseif ($this->extraConfig['PAGANTIS_DISPLAY_MIN_AMOUNT']<0) {
149
            $error_string = __(' can not have a minimum amount less than 0', 'pagantis');
150
        }
151
152
        if ($error_string!='') {
153
            $template_fields = array(
154
                'error_msg' => ucfirst(WcPagantisGateway::METHOD_ID).' '.$error_string,
155
            );
156
            wc_get_template('error_msg.php', $template_fields, '', $this->template_path);
157
        }
158
    }
159
160
161
    /**
162
     * CHECKOUT - Generate the pagantis form. "Return" iframe or redirect. - Hook: woocommerce_receipt_pagantis
163
     * @param $order_id
164
     *
165
     * @throws Exception
166
     */
167
    public function pagantisReceiptPage($order_id)
168
    {
169
        try {
170
            require_once(__ROOT__.'/vendor/autoload.php');
171
            global $woocommerce;
172
            $order = new WC_Order($order_id);
173
            $order->set_payment_method(ucfirst($this->id));
174
            $order->save();
175
176
            if (!isset($order)) {
177
                throw new Exception(_("Order not found"));
178
            }
179
180
            $shippingAddress = $order->get_address('shipping');
181
            $billingAddress = $order->get_address('billing');
182
            if ($shippingAddress['address_1'] == '') {
183
                $shippingAddress = $billingAddress;
184
            }
185
186
            $national_id = $this->getNationalId($order);
187
            $tax_id = $this->getTaxId($order);
188
189
            $userAddress = new Address();
190
            $userAddress
191
                ->setZipCode($shippingAddress['postcode'])
192
                ->setFullName($shippingAddress['first_name']." ".$shippingAddress['last_name'])
193
                ->setCountryCode($shippingAddress['country']!='' ? $shippingAddress['country'] : $this->language)
194
                ->setCity($shippingAddress['city'])
195
                ->setAddress($shippingAddress['address_1']." ".$shippingAddress['address_2'])
196
            ;
197
            $orderShippingAddress = new Address();
198
            $orderShippingAddress
199
                ->setZipCode($shippingAddress['postcode'])
200
                ->setFullName($shippingAddress['first_name']." ".$shippingAddress['last_name'])
201
                ->setCountryCode($shippingAddress['country']!='') ? $shippingAddress['country'] : $this->language)
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected ')' on line 201 at column 113
Loading history...
202
                ->setCity($shippingAddress['city'])
203
                ->setAddress($shippingAddress['address_1']." ".$shippingAddress['address_2'])
204
                ->setFixPhone($shippingAddress['phone'])
205
                ->setMobilePhone($shippingAddress['phone'])
206
                ->setNationalId($national_id)
207
                ->setTaxId($tax_id)
208
            ;
209
            $orderBillingAddress =  new Address();
210
            $orderBillingAddress
211
                ->setZipCode($billingAddress['postcode'])
212
                ->setFullName($billingAddress['first_name']." ".$billingAddress['last_name'])
213
                ->setCountryCode($billingAddress['country']!='' ? $billingAddress['country'] : $this->language)
214
                ->setCity($billingAddress['city'])
215
                ->setAddress($billingAddress['address_1']." ".$billingAddress['address_2'])
216
                ->setFixPhone($billingAddress['phone'])
217
                ->setMobilePhone($billingAddress['phone'])
218
                ->setNationalId($national_id)
219
                ->setTaxId($tax_id)
220
            ;
221
            $orderUser = new User();
222
            $orderUser
223
                ->setAddress($userAddress)
224
                ->setFullName($billingAddress['first_name']." ".$billingAddress['last_name'])
225
                ->setBillingAddress($orderBillingAddress)
226
                ->setEmail($billingAddress['email'])
227
                ->setFixPhone($billingAddress['phone'])
228
                ->setMobilePhone($billingAddress['phone'])
229
                ->setShippingAddress($orderShippingAddress)
230
                ->setNationalId($national_id)
231
                ->setTaxId($tax_id)
232
            ;
233
234
            $previousOrders = $this->getOrders($order->get_user(), $billingAddress['email']);
235
            foreach ($previousOrders as $previousOrder) {
236
                $orderHistory = new OrderHistory();
237
                $orderElement = wc_get_order($previousOrder);
238
                $orderCreated = $orderElement->get_date_created();
239
                $orderHistory
240
                    ->setAmount(intval(100 * $orderElement->get_total()))
241
                    ->setDate(new \DateTime($orderCreated->date('Y-m-d H:i:s')))
242
                ;
243
                $orderUser->addOrderHistory($orderHistory);
244
            }
245
246
            $metadataOrder = new Metadata();
247
            $metadata = array(
248
                'woocommerce' => WC()->version,
249
                'pagantis'         => $this->plugin_info['Version'],
250
                'php'         => phpversion()
251
            );
252
            foreach ($metadata as $key => $metadatum) {
253
                $metadataOrder->addMetadata($key, $metadatum);
254
            }
255
256
            $details = new Details();
257
            $shippingCost = $order->shipping_total;
258
            $details->setShippingCost(intval(strval(100 * $shippingCost)));
259
            $items = $order->get_items();
260
            $promotedAmount = 0;
261
            foreach ($items as $key => $item) {
262
                $wcProduct = $item->get_product();
263
                $product = new Product();
264
                $productDescription = sprintf(
265
                    '%s %s %s',
266
                    $wcProduct->get_name(),
267
                    $wcProduct->get_description(),
268
                    $wcProduct->get_short_description()
269
                );
270
                $productDescription = substr($productDescription, 0, 9999);
271
272
                $product
273
                    ->setAmount(intval(100 * ($item->get_total() + $item->get_total_tax())))
274
                    ->setQuantity($item->get_quantity())
275
                    ->setDescription($productDescription)
276
                ;
277
                $details->addProduct($product);
278
279
                $promotedProduct = $this->isPromoted($item->get_product_id());
280
                if ($promotedProduct == 'true') {
281
                    $promotedAmount+=$product->getAmount();
282
                    $promotedMessage = 'Promoted Item: ' . $wcProduct->get_name() .
283
                                       ' - Price: ' . $item->get_total() .
284
                                       ' - Qty: ' . $product->getQuantity() .
285
                                       ' - Item ID: ' . $item['id_product'];
286
                    $promotedMessage = substr($promotedMessage, 0, 999);
287
                    $metadataOrder->addMetadata('promotedProduct', $promotedMessage);
288
                }
289
            }
290
291
            $orderShoppingCart = new ShoppingCart();
292
            $orderShoppingCart
293
                ->setDetails($details)
294
                ->setOrderReference($order->get_id())
295
                ->setPromotedAmount($promotedAmount)
296
                ->setTotalAmount(intval(strval(100 * $order->total)))
297
            ;
298
            $orderConfigurationUrls = new Urls();
299
            $cancelUrl = $this->getKoUrl($order);
300
            $callback_arg = array('wc-api'=>'wcpagantisgateway',
301
                'key'=>$order->get_order_key(),
302
                'order-received'=>$order->get_id(),
303
                'origin' => ''
304
            );
305
306
            $callback_arg_user = $callback_arg;
307
            $callback_arg_user['origin'] = 'redirect';
308
            $callback_url_user = add_query_arg($callback_arg_user, home_url('/'));
309
310
            $callback_arg_notif = $callback_arg;
311
            $callback_arg_notif['origin'] = 'notification';
312
            $callback_url_notif = add_query_arg($callback_arg_notif, home_url('/'));
313
314
            $orderConfigurationUrls
315
                ->setCancel($cancelUrl)
316
                ->setKo($callback_url_user)
317
                ->setAuthorizedNotificationCallback($callback_url_notif)
318
                ->setRejectedNotificationCallback(null)
319
                ->setOk($callback_url_user)
320
            ;
321
            $orderChannel = new Channel();
322
            $orderChannel
323
                ->setAssistedSale(false)
324
                ->setType(Channel::ONLINE)
325
            ;
326
327
            $allowedCountries = unserialize($this->extraConfig['PAGANTIS_ALLOWED_COUNTRIES']);
328
            $purchaseCountry =
329
                in_array(strtolower($this->language), $allowedCountries) ? $this->language :
330
                in_array(strtolower($shippingAddress['country']), $allowedCountries) ? $shippingAddress['country'] :
331
                in_array(strtolower($billingAddress['country']), $allowedCountries) ? $billingAddress['country'] : null;
332
333
            $orderConfiguration = new Configuration();
334
            $orderConfiguration
335
                ->setChannel($orderChannel)
336
                ->setUrls($orderConfigurationUrls)
337
                ->setPurchaseCountry($purchaseCountry)
338
            ;
339
340
            $orderApiClient = new Order();
341
            $orderApiClient
342
                ->setConfiguration($orderConfiguration)
343
                ->setMetadata($metadataOrder)
344
                ->setShoppingCart($orderShoppingCart)
345
                ->setUser($orderUser)
346
            ;
347
348
            if ($this->pagantis_public_key=='' || $this->pagantis_private_key=='') {
349
                throw new \Exception('Public and Secret Key not found');
350
            }
351
            $orderClient = new Client($this->pagantis_public_key, $this->pagantis_private_key);
352
            $pagantisOrder = $orderClient->createOrder($orderApiClient);
353
            if ($pagantisOrder instanceof \Pagantis\OrdersApiClient\Model\Order) {
354
                $url = $pagantisOrder->getActionUrls()->getForm();
355
                $this->insertRow($order->get_id(), $pagantisOrder->getId());
356
            } else {
357
                throw new OrderNotFoundException();
358
            }
359
360
            if ($url=="") {
361
                throw new Exception(_("No ha sido posible obtener una respuesta de Pagantis"));
362
            } elseif ($this->extraConfig['PAGANTIS_FORM_DISPLAY_TYPE']=='0') {
363
                wp_redirect($url);
364
                exit;
365
            } else {
366
                $template_fields = array(
367
                    'url' => $url,
368
                    'checkoutUrl'   => $cancelUrl
369
                );
370
                wc_get_template('iframe.php', $template_fields, '', $this->template_path);
371
            }
372
        } catch (\Exception $exception) {
373
            wc_add_notice(__('Payment error ', 'pagantis') . $exception->getMessage(), 'error');
374
            $this->insertLog($exception);
375
            $checkout_url = get_permalink(wc_get_page_id('checkout'));
376
            wp_redirect($checkout_url);
377
            exit;
378
        }
379
    }
380
381
    /**
382
     * NOTIFICATION - Endpoint for Json notification - Hook: woocommerce_api_wcpagantisgateway
383
     */
384
    public function pagantisNotification()
385
    {
386
        try {
387
            $origin = ($_SERVER['REQUEST_METHOD'] == 'POST') ? 'Notify' : 'Order';
388
389
            include_once('notifyController.php');
390
            $notify = new WcPagantisNotify();
391
            $notify->setOrigin($origin);
392
            /** @var \Pagantis\ModuleUtils\Model\Response\AbstractJsonResponse $result */
393
            $result = $notify->processInformation();
394
        } catch (Exception $exception) {
395
            $result['notification_message'] = $exception->getMessage();
396
            $result['notification_error'] = true;
397
        }
398
399
        $paymentOrder = new WC_Order($result->getMerchantOrderId());
400
        if ($paymentOrder instanceof WC_Order) {
401
            $orderStatus = strtolower($paymentOrder->get_status());
402
        } else {
403
            $orderStatus = 'cancelled';
404
        }
405
        $acceptedStatus = array('processing', 'completed');
406
        if (in_array($orderStatus, $acceptedStatus)) {
407
            $returnUrl = $this->getOkUrl($paymentOrder);
408
        } else {
409
            $returnUrl = $this->getKoUrl($paymentOrder);
410
        }
411
412
        wp_redirect($returnUrl);
413
        exit;
414
    }
415
416
    /**
417
     * After failed status, set to processing not complete -> Hook: woocommerce_payment_complete_order_status
418
     * @param $status
419
     * @param $order_id
420
     * @param $order
421
     *
422
     * @return string
423
     */
424
    public function pagantisCompleteStatus($status, $order_id, $order)
425
    {
426
        if ($order->get_payment_method() == WcPagantisGateway::METHOD_ID) {
427
            if ($order->get_status() == 'failed') {
428
                $status = 'processing';
429
            } elseif ($order->get_status() == 'pending' && $status=='completed') {
430
                $status = 'processing';
431
            }
432
        }
433
434
        return $status;
435
    }
436
437
    /***********
438
     *
439
     * REDEFINED FUNCTIONS
440
     *
441
     ***********/
442
443
    /**
444
     * CHECKOUT - Check if payment method is available (called by woocommerce, can't apply cammel caps)
445
     * @return bool
446
     */
447
    public function is_available()
448
    {
449
        $locale = strtolower(strstr(get_locale(), '_', true));
450
        $allowedCountries = unserialize($this->extraConfig['PAGANTIS_ALLOWED_COUNTRIES']);
451
        $allowedCountry = (in_array(strtolower($locale), $allowedCountries));
452
        $minAmount = $this->extraConfig['PAGANTIS_DISPLAY_MIN_AMOUNT'];
453
        $maxAmount = $this->extraConfig['PAGANTIS_DISPLAY_MAX_AMOUNT'];
454
        $totalPrice = (int)$this->get_order_total();
455
        $validAmount = ($totalPrice>=$minAmount && ($totalPrice<=$maxAmount || $maxAmount=='0'));
456
        if ($this->enabled==='yes' && $this->pagantis_public_key!='' && $this->pagantis_private_key!='' &&
457
            $validAmount && $allowedCountry) {
458
            return true;
459
        }
460
461
        return false;
462
    }
463
464
    /**
465
     * CHECKOUT - Checkout + admin panel title(method_title - get_title) (called by woocommerce,can't apply cammel caps)
466
     * @return string
467
     */
468
    public function get_title()
469
    {
470
        return __($this->extraConfig['PAGANTIS_TITLE'], 'pagantis');
471
    }
472
473
    /**
474
     * CHECKOUT - Called after push pagantis button on checkout(called by woocommerce, can't apply cammel caps
475
     * @param $order_id
476
     * @return array
477
     */
478
    public function process_payment($order_id)
479
    {
480
        try {
481
            $order = new WC_Order($order_id);
482
483
            $redirectUrl = $order->get_checkout_payment_url(true); //pagantisReceiptPage function
484
            if (strpos($redirectUrl, 'order-pay=')===false) {
485
                $redirectUrl.="&order-pay=".$order_id;
486
            }
487
488
            return array(
489
                'result'   => 'success',
490
                'redirect' => $redirectUrl
491
            );
492
493
        } catch (Exception $e) {
494
            wc_add_notice(__('Payment error ', 'pagantis') . $e->getMessage(), 'error');
495
            return array();
496
        }
497
    }
498
499
    /**
500
     * CHECKOUT - simulator (called by woocommerce, can't apply cammel caps)
501
     */
502
    public function payment_fields()
503
    {
504
        $locale = strtolower(strstr(get_locale(), '_', true));
505
        $allowedCountries = unserialize($this->extraConfig['PAGANTIS_ALLOWED_COUNTRIES']);
506
        $allowedCountry = (in_array(strtolower($locale), $allowedCountries));
507
        $promotedAmount = $this->getPromotedAmount();
508
509
        $template_fields = array(
510
            'public_key' => $this->pagantis_public_key,
511
            'total' => WC()->session->cart_totals['total'],
512
            'enabled' =>  $this->settings['enabled'],
513
            'min_installments' => $this->extraConfig['PAGANTIS_DISPLAY_MIN_AMOUNT'],
514
            'max_installments' => $this->extraConfig['PAGANTIS_DISPLAY_MAX_AMOUNT'],
515
            'simulator_enabled' => $this->settings['simulator'],
516
            'locale' => $locale,
517
            'country' => $locale,
518
            'allowed_country' => $allowedCountry,
519
            'simulator_type' => $this->extraConfig['PAGANTIS_SIMULATOR_DISPLAY_TYPE_CHECKOUT'],
520
            'promoted_amount' => $promotedAmount,
521
            'thousandSeparator' => $this->extraConfig['PAGANTIS_SIMULATOR_THOUSANDS_SEPARATOR'],
522
            'decimalSeparator' => $this->extraConfig['PAGANTIS_SIMULATOR_DECIMAL_SEPARATOR'],
523
            'pagantisSimulatorSkin' => $this->extraConfig['PAGANTIS_SIMULATOR_DISPLAY_SKIN']
524
        );
525
        wc_get_template('checkout_description.php', $template_fields, '', $this->template_path);
526
    }
527
528
    /***********
529
     *
530
     * UTILS FUNCTIONS
531
     *
532
     ***********/
533
534
    /**
535
     * PANEL KO_URL FIELD
536
     * CHECKOUT PAGE => ?page_id=91 // ORDER-CONFIRMATION PAGE => ?page_id=91&order-pay=<order_id>&key=<order_key>
537
     */
538
    private function generateOkUrl()
539
    {
540
        return $this->generateUrl($this->get_return_url());
541
    }
542
543
    /**
544
     * PANEL OK_URL FIELD
545
     */
546
    private function generateKoUrl()
547
    {
548
        return $this->generateUrl(get_permalink(wc_get_page_id('checkout')));
549
    }
550
551
    /**
552
     * Replace empty space by {{var}}
553
     * @param $url
554
     *
555
     * @return string
556
     */
557
    private function generateUrl($url)
558
    {
559
        $parsed_url = parse_url($url);
560
        if ($parsed_url !== false) {
561
            $parsed_url['query'] = !isset($parsed_url['query']) ? '' : $parsed_url['query'];
562
            parse_str($parsed_url['query'], $arrayParams);
563
            foreach ($arrayParams as $keyParam => $valueParam) {
564
                if ($valueParam=='') {
565
                    $arrayParams[$keyParam] = '{{'.$keyParam.'}}';
566
                }
567
            }
568
            $parsed_url['query'] = http_build_query($arrayParams);
569
            $return_url = $this->unparseUrl($parsed_url);
570
            return urldecode($return_url);
571
        } else {
572
            return $url;
573
        }
574
    }
575
576
    /**
577
     * Replace {{}} by vars values inside ok_url
578
     * @param $order
579
     *
580
     * @return string
581
     */
582
    private function getOkUrl($order)
583
    {
584
        return $this->getKeysUrl($order, $this->ok_url);
585
    }
586
587
    /**
588
     * Replace {{}} by vars values inside ko_url
589
     * @param $order
590
     *
591
     * @return string
592
     */
593
    private function getKoUrl($order)
594
    {
595
        return $this->getKeysUrl($order, $this->ko_url);
596
    }
597
598
    /**
599
     * Replace {{}} by vars values
600
     * @param $order
601
     * @param $url
602
     *
603
     * @return string
604
     */
605
    private function getKeysUrl($order, $url)
606
    {
607
        $defaultFields = (get_class($order)=='WC_Order') ?
608
            array('order-received'=>$order->get_id(), 'key'=>$order->get_order_key()) :
609
            array();
610
611
        $parsedUrl = parse_url($url);
612
        if ($parsedUrl !== false) {
613
            //Replace parameters from url
614
            $parsedUrl['query'] = $this->getKeysParametersUrl($parsedUrl['query'], $defaultFields);
615
616
            //Replace path from url
617
            $parsedUrl['path'] = $this->getKeysPathUrl($parsedUrl['path'], $defaultFields);
618
619
            $returnUrl = $this->unparseUrl($parsedUrl);
620
            return $returnUrl;
621
        }
622
        return $url;
623
    }
624
625
    /**
626
     * Replace {{}} by vars values inside parameters
627
     * @param $queryString
628
     * @param $defaultFields
629
     *
630
     * @return string
631
     */
632
    private function getKeysParametersUrl($queryString, $defaultFields)
633
    {
634
        parse_str(html_entity_decode($queryString), $arrayParams);
635
        $commonKeys = array_intersect_key($arrayParams, $defaultFields);
636
        if (count($commonKeys)) {
637
            $arrayResult = array_merge($arrayParams, $defaultFields);
638
        } else {
639
            $arrayResult = $arrayParams;
640
        }
641
        return urldecode(http_build_query($arrayResult));
642
    }
643
644
    /**
645
     * Replace {{}} by vars values inside path
646
     * @param $pathString
647
     * @param $defaultFields
648
     *
649
     * @return string
650
     */
651
    private function getKeysPathUrl($pathString, $defaultFields)
652
    {
653
        $arrayParams = explode("/", $pathString);
654
        foreach ($arrayParams as $keyParam => $valueParam) {
655
            preg_match('#\{{.*?}\}#', $valueParam, $match);
656
            if (count($match)) {
657
                $key = str_replace(array('{{','}}'), array('',''), $match[0]);
658
                $arrayParams[$keyParam] = $defaultFields[$key];
659
            }
660
        }
661
        return implode('/', $arrayParams);
662
    }
663
664
    /**
665
     * Replace {{var}} by empty space
666
     * @param $parsed_url
667
     *
668
     * @return string
669
     */
670
    private function unparseUrl($parsed_url)
671
    {
672
        $scheme   = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
673
        $host     = isset($parsed_url['host']) ? $parsed_url['host'] : '';
674
        $port     = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
675
        $query    = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
676
        $fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
677
        $path     = $parsed_url['path'];
678
        return $scheme . $host . $port . $path . $query . $fragment;
679
    }
680
681
    /**
682
     * Get the orders of a customer
683
     * @param $current_user
684
     * @param $billingEmail
685
     *
686
     * @return mixed
687
     */
688
    private function getOrders($current_user, $billingEmail)
689
    {
690
        $sign_up = '';
691
        $total_orders = 0;
692
        $total_amt = 0;
693
        $refund_amt = 0;
694
        $total_refunds = 0;
695
        $partial_refunds = 0;
696
        if ($current_user->user_login) {
697
            $is_guest = "false";
698
            $sign_up = substr($current_user->user_registered, 0, 10);
699
            $customer_orders = get_posts(array(
700
                'numberposts' => - 1,
701
                'meta_key'    => '_customer_user',
702
                'meta_value'  => $current_user->ID,
703
                'post_type'   => array( 'shop_order' ),
704
                'post_status' => array( 'wc-completed', 'wc-processing', 'wc-refunded' ),
705
            ));
706
        } else {
707
            $is_guest = "true";
708
            $customer_orders = get_posts(array(
709
                'numberposts' => - 1,
710
                'meta_key'    => '_billing_email',
711
                'meta_value'  => $billingEmail,
712
                'post_type'   => array( 'shop_order' ),
713
                'post_status' => array( 'wc-completed', 'wc-processing', 'wc-refunded'),
714
            ));
715
            foreach ($customer_orders as $customer_order) {
716
                if (trim($sign_up)=='' ||
717
                    strtotime(substr($customer_order->post_date, 0, 10)) <= strtotime($sign_up)) {
718
                    $sign_up = substr($customer_order->post_date, 0, 10);
719
                }
720
            }
721
        }
722
723
        return $customer_orders;
724
    }
725
726
727
    /**
728
     * @param $orderId
729
     * @param $pagantisOrderId
730
     *
731
     * @throws Exception
732
     */
733
    private function insertRow($orderId, $pagantisOrderId)
734
    {
735
        global $wpdb;
736
        $this->checkDbTable();
737
        $tableName = $wpdb->prefix.self::ORDERS_TABLE;
738
739
        //Check if id exists
740
        $resultsSelect = $wpdb->get_results("select * from $tableName where id='$orderId'");
741
        $countResults = count($resultsSelect);
742
        if ($countResults == 0) {
743
            $wpdb->insert(
744
                $tableName,
745
                array('id' => $orderId, 'order_id' => $pagantisOrderId),
746
                array('%d', '%s')
747
            );
748
        } else {
749
            $wpdb->update(
750
                $tableName,
751
                array('order_id' => $pagantisOrderId),
752
                array('id' => $orderId),
753
                array('%s'),
754
                array('%d')
755
            );
756
        }
757
    }
758
759
    /**
760
     * Check if orders table exists
761
     */
762
    private function checkDbTable()
763
    {
764
        global $wpdb;
765
        $tableName = $wpdb->prefix.self::ORDERS_TABLE;
766
767
        if ($wpdb->get_var("SHOW TABLES LIKE '$tableName'") != $tableName) {
768
            $charset_collate = $wpdb->get_charset_collate();
769
            $sql             = "CREATE TABLE $tableName ( id int, order_id varchar(50), wc_order_id varchar(50),  
770
                  UNIQUE KEY id (id)) $charset_collate";
771
772
            require_once(ABSPATH.'wp-admin/includes/upgrade.php');
773
            dbDelta($sql);
774
        }
775
    }
776
777
    /**
778
     * @return array
779
     */
780
    private function getExtraConfig()
781
    {
782
        global $wpdb;
783
        $tableName = $wpdb->prefix.self::CONFIG_TABLE;
784
        $response = array();
785
        $dbResult = $wpdb->get_results("select config, value from $tableName", ARRAY_A);
786
        foreach ($dbResult as $value) {
787
            $response[$value['config']] = $value['value'];
788
        }
789
790
        return $response;
791
    }
792
793
    /**
794
     * @param $order
795
     *
796
     * @return null
797
     */
798
    private function getNationalId($order)
799
    {
800
        foreach ((array)$order->get_meta_data() as $mdObject) {
801
            $data = $mdObject->get_data();
802
            if ($data['key'] == 'vat_number') {
803
                return $data['value'];
804
            }
805
        }
806
807
        return null;
808
    }
809
810
    /**
811
     * @param $order
812
     *
813
     * @return mixed
814
     */
815
    private function getTaxId($order)
816
    {
817
        foreach ((array)$order->get_meta_data() as $mdObject) {
818
            $data = $mdObject->get_data();
819
            if ($data['key'] == 'billing_cfpiva') {
820
                return $data['value'];
821
            }
822
        }
823
    }
824
825
    /**
826
     * @param null $exception
827
     * @param null $message
828
     */
829
    private function insertLog($exception = null, $message = null)
830
    {
831
        global $wpdb;
832
        $this->checkDbLogTable();
833
        $logEntry     = new LogEntry();
834
        if ($exception instanceof \Exception) {
835
            $logEntry = $logEntry->error($exception);
836
        } else {
837
            $logEntry = $logEntry->info($message);
838
        }
839
        $tableName = $wpdb->prefix.self::LOGS_TABLE;
840
        $wpdb->insert($tableName, array('log' => $logEntry->toJson()));
841
    }
842
    /**
843
     * Check if logs table exists
844
     */
845
    private function checkDbLogTable()
846
    {
847
        global $wpdb;
848
        $tableName = $wpdb->prefix.self::LOGS_TABLE;
849
        if ($wpdb->get_var("SHOW TABLES LIKE '$tableName'") != $tableName) {
850
            $charset_collate = $wpdb->get_charset_collate();
851
            $sql = "CREATE TABLE $tableName ( id int NOT NULL AUTO_INCREMENT, log text NOT NULL, 
852
                    createdAt timestamp DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY id (id)) $charset_collate";
853
            require_once(ABSPATH.'wp-admin/includes/upgrade.php');
854
            dbDelta($sql);
855
        }
856
        return;
857
    }
858
859
    /**
860
     * @param $product_id
861
     *
862
     * @return string
863
     */
864
    private function isPromoted($product_id)
865
    {
866
        $metaProduct = get_post_meta($product_id);
867
        return (array_key_exists('custom_product_pagantis_promoted', $metaProduct) &&
868
                $metaProduct['custom_product_pagantis_promoted']['0'] === 'yes') ? 'true' : 'false';
869
    }
870
871
    /**
872
     * @return int
873
     */
874
    private function getPromotedAmount()
875
    {
876
        global $woocommerce;
877
        $items = $woocommerce->cart->get_cart();
878
        $promotedAmount = 0;
879
        foreach ($items as $key => $item) {
880
            $promotedProduct = $this->isPromoted($item['product_id']);
881
            if ($promotedProduct == 'true') {
882
                $promotedAmount+=$item['line_total'] + $item['line_tax'];
883
            }
884
        }
885
886
        return $promotedAmount;
887
    }
888
}
889