HEX
Server: nginx/1.28.1
System: Linux 10-41-63-61 6.8.0-31-generic #31-Ubuntu SMP PREEMPT_DYNAMIC Sat Apr 20 00:40:06 UTC 2024 x86_64
User: www (1001)
PHP: 7.4.33
Disabled: passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv
Upload Files
File: /www/wwwroot/shop.glgz.tw/catalog/model/checkout/checkout.php
<?php

/**
 * Checkout.php
 *
 * @copyright  2017 opencart.cn - All Rights Reserved
 * @link       http://www.guangdawangluo.com
 * @author     Sam Chen <samchen@opencart.cn>
 * @created    2017-07-31 15:37
 * @modified         2017-08-14 19:09:49
 */

class ModelCheckoutCheckout extends Model {
	private $logger;

	public function __construct($registry) {
		parent::__construct($registry);
		$this->load->model('tool/image');
		$this->load->model('tool/upload');
		$this->load->model('checkout/order');
		$this->load->model('localisation/country');
		$this->load->model('localisation/zone');
		$this->load->model('localisation/city');
		$this->load->model('account/order');

		$this->logger = new Log("checkout.log");
	}

	public function createOrder() {
		$this->log(__FUNCTION__);

		// Default order data
		$order_data = array(
			'invoice_prefix'            => $this->config->get('config_invoice_prefix'),
			'store_id'                  => $this->config->get('config_store_id'),
			'store_name'                => $this->config->get('config_name'),
			'store_url'                 => $this->config->get('config_store_id') ? $this->config->get('config_url') : HTTP_SERVER,
			'customer_id'               => $this->customer->isLogged() ? $this->customer->getId() : 0,
			'customer_group_id'         => $this->customer->isLogged() ? $this->customer->getGroupId() : $this->config->get('config_customer_group_id'),
			'firstname'                 => $this->customer->isLogged() ? $this->customer->getFirstName() : '',
            'lastname'                  => $this->customer->isLogged() ? $this->customer->getLastName() : '',
			'email'                     => $this->customer->isLogged() ? $this->customer->getEmail() : '',
			'calling_code'              => $this->customer->isLogged() ? $this->customer->getCallingCode() : '',
			'telephone'                 => $this->customer->isLogged() ? $this->customer->getTelephone() : '',
			'fax'                       => '',
			'custom_field'              => array(),

			// Payment address
			'payment_firstname'         => '',
            'payment_lastname'         => '',
			'payment_calling_code'      => '',
			'payment_telephone'         => '',
			'payment_company'           => '',
			'payment_address_1'         => '',
			'payment_address_2'         => '',
			'payment_city'              => '',
			'payment_postcode'          => '',
			'payment_country'           => '',
			'payment_country_id'        => '',
			'payment_tax_id'            => '',
			'payment_zone'              => '',
			'payment_zone_id'           => '',
			'payment_city'              => '',
			'payment_city_id'           => '',
			'payment_county'            => '',
			'payment_county_id'         => '',
			'payment_address_format'    => '',
			'payment_custom_field'      => array(),
			'payment_method'            => '',
			'payment_code'              => '',

			// Shipping address
			'shipping_firstname'         => '',
            'shipping_lastname'         => '',
			'shipping_telephone'        => '',
			'shipping_calling_code'     => '',
			'shipping_company'          => '',
			'shipping_address_1'        => '',
			'shipping_address_2'        => '',
			'shipping_city'             => '',
			'shipping_postcode'         => '',
			'shipping_country'          => '',
			'shipping_country_id'       => '',
			'shipping_zone'             => '',
			'shipping_zone_id'          => '',
			'shipping_city'             => '',
			'shipping_city_id'          => '',
			'shipping_county'           => '',
			'shipping_county_id'        => '',
			'shipping_address_format'   => '',
			'shipping_custom_field'     => array(),
			'shipping_method'           => '',
			'shipping_code'             => '',

			'comment'                   => '',
			'total'                     => '',
			'order_status_id'           => 0,
			'affiliate_id'              => '',
			'commission'                => '',
			'marketing_id'              => '',
			'tracking'                  => '',
			'language_id'								=> $this->config->get('config_language_id'),
			'currency_id'               => $this->currency->getId($this->session->data['currency']),
			'currency_code'             => $this->session->data['currency'],
			'currency_value'            => $this->currency->getValue($this->session->data['currency']),
			'ip'                        => $this->request->server['REMOTE_ADDR'],
			'forwarded_ip'              => array_get($this->request->server, 'HTTP_X_FORWARDED_FOR'),
			'user_agent'                => array_get($this->request->server, 'HTTP_USER_AGENT'),
			'accept_language'           => array_get($this->request->server, 'HTTP_ACCEPT_LANGUAGE')
		);

		// Update order data
		if (!$this->customer->isLogged()) {
			$order_data['firstname'] = array_get($this->session->data, 'guest.firstname', '');
            $order_data['lastname'] = array_get($this->session->data, 'guest.lastname', '');
			$order_data['email'] = array_get($this->session->data, 'guest.email', '');
			$order_data['calling_code'] = array_get($this->session->data, 'guest.calling_code', '');
			$order_data['telephone'] = array_get($this->session->data, 'guest.telephone', '');
			$order_data['fax'] = array_get($this->session->data, 'guest.fax', '');
		}

		if (array_get($this->session->data, 'payment_method.code')) {
			$order_data['payment_code'] = $this->session->data['payment_method']['code'];
			$order_data['payment_method'] = $this->session->data['payment_method']['title'];
		}

		if (array_get($this->session->data, 'shipping_method.code')) {
			if ($this->cart->hasshipping()) {
				$order_data['shipping_code'] = $this->session->data['shipping_method']['code'];
				$order_data['shipping_method'] = $this->session->data['shipping_method']['title'];
			} else {
				unset($this->session->data['shipping_address']);
				unset($this->session->data['shipping_methods']);
				unset($this->session->data['shipping_method']);
			}
		}

		$order_data['comment'] = array_get($this->session->data, 'comment', '');

		// Map session addresses to order data
		// Example. $this->session->data['payment_address']['firstname'] -> $this->session->data['payment_firstname']
		foreach (['payment', 'shipping'] as $type) {
			if (!empty($this->session->data[$type . '_address'])) {
				foreach ($this->session->data[$type . '_address'] as $key => $value) {
					$order_data["{$type}_{$key}"] = $value;
				}
			}

			// Format custom_field
			if (empty($order_data["{$type}_custom_field"])) {
				unset($order_data["{$type}_custom_field"]);
			}

			// Get country name
			if (!empty($this->session->data[$type . '_address']['country_id'])) {
				$country_info = $this->model_localisation_country->getCountry($this->session->data[$type . '_address']['country_id']);
				if ($country_info) {
					$order_data["{$type}_country"] = $country_info['name'];
					$order_data["{$type}_address_format"] = $country_info['address_format'];
				}
			}

			// Get zone name
			if (!empty($this->session->data[$type . '_address']['zone_id'])) {
				$zone_info = $this->model_localisation_zone->getZone($this->session->data[$type . '_address']['zone_id']);
				if ($zone_info) {
					$order_data["{$type}_zone"] = $zone_info['name'];
				}
			}

			// Get city name
			if (!empty($this->session->data[$type . '_address']['city_id'])) {
				$city_info = $this->model_localisation_city->getCity($this->session->data[$type . '_address']['city_id']);
				if ($city_info) {
					$order_data["{$type}_city"] = $city_info['name'];
				}
			}

			// Get county name
			if (!empty($this->session->data[$type . '_address']['county_id'])) {
				$county_info = $this->model_localisation_city->getCity($this->session->data[$type . '_address']['county_id']);
				if ($county_info) {
					$order_data["{$type}_county"] = $county_info['name'];
				}
			}
		}

		$order_data['products'] = $this->getProducts();
		$order_data['vouchers'] = $this->getVouchers();
		$order_data['totals'] = $this->getTotals();
		$order_data['total'] = $this->getTotal();

        if (isset($this->request->cookie['tracking'])) {
            $order_data['tracking'] = $this->request->cookie['tracking'];

            $subtotal = $this->cart->getSubTotal();

            // Affiliate
            $this->load->model('account/affiliate');
            $affiliate_info = $this->model_account_affiliate->getAffiliateByTracking($this->request->cookie['tracking']);

            if ($affiliate_info) {
                $commission_total = 0;
                $product_commission = 0;
                $products = $order_data['products'];
                foreach ($products as $product) {
                    $commission = (float)$product['commission'];
                    if ($commission) {
                        $commission_total += $product['total'];
                        $product_commission += ($product['total'] / 100) * $commission;
                    }
                }
                $order_data['affiliate_id'] = $affiliate_info['customer_id'];
                $order_data['commission'] = $product_commission + (($subtotal - $commission_total) / 100) * $affiliate_info['commission'];
            } else {
                $order_data['affiliate_id'] = 0;
                $order_data['commission'] = 0;
            }

            // Marketing
            $this->load->model('marketing/marketing');
            $marketing_info = $this->model_marketing_marketing->getMarketingByCode($this->request->cookie['tracking']);
            if ($marketing_info) {
                $order_data['marketing_id'] = $marketing_info['marketing_id'];
            } else {
                $order_data['marketing_id'] = 0;
            }
        } else {
            $order_data['affiliate_id'] = 0;
            $order_data['commission'] = 0;
            $order_data['marketing_id'] = 0;
            $order_data['tracking'] = '';
        }

		$this->log($order_data);
		// Create new order
		$order_id = $this->model_checkout_order->addOrder($order_data);
		$this->session->data['order_id'] = $order_id;
		return $order_id;
	}

	// Private
	private function getProducts() {
		$products = array();

		foreach ($this->cart->getProducts() as $product) {
			$option_data = array();

			foreach ($product['option'] as $option) {
				$option_data[] = array(
					'product_option_id'       => $option['product_option_id'],
					'product_option_value_id' => $option['product_option_value_id'],
					'option_id'               => $option['option_id'],
					'option_value_id'         => $option['option_value_id'],
					'name'                    => $option['name'],
					'value'                   => $option['value'],
					'type'                    => $option['type']
				);
			}

			$products[] = array(
				'product_id' => $product['product_id'],
				'name'       => $product['name'],
				'model'      => $product['model'],
				'option'     => $option_data,
				'download'   => $product['download'],
				'quantity'   => $product['quantity'],
				'subtract'   => $product['subtract'],
				'price'      => $product['price'],
				'total'      => $product['total'],
				'tax'        => $this->tax->getTax($product['price'], $product['tax_class_id']),
				'reward'     => $product['reward']
			);
		}

		return $products;
	}

	private function getVouchers() {
		// Gift Voucher
		$vouchers = array();

		if (empty($this->session->data['vouchers'])) {
			return $vouchers;
		}

		foreach ($this->session->data['vouchers'] as $voucher) {
			$vouchers[] = array(
				'description'      => $voucher['description'],
				'code'             => token(10),
				'to_name'          => $voucher['to_name'],
				'to_email'         => $voucher['to_email'],
				'from_name'        => $voucher['from_name'],
				'from_email'       => $voucher['from_email'],
				'voucher_theme_id' => $voucher['voucher_theme_id'],
				'message'          => $voucher['message'],
				'amount'           => $voucher['amount']
			);
		}

		return $vouchers;
	}

	// Public
	public function getDefaultCountryId() {
		return $this->config->get('config_country_id');
	}

	public function getDefaultZoneId() {
		return $this->config->get('config_zone_id');
	}

	/*
	 * $code = 'pp_express'
	 */
	public function setPaymentMethod($code = '') {
		$methods = $this->getPaymentMethods();

		if (!$methods) {
			unset($this->session->data['payment_methods']);
			unset($this->session->data['payment_method']);
			return false;
		}

		// Use first method in payment methods session when code is empty
		if (empty($code)) {
			$this->session->data['payment_method'] = reset($methods);
			return true;
		}

		// Check if selected payment code still available
		if (!isset($methods[$code])) {
			unset($this->session->data['payment_method']);
			return false;
		} else {
			$this->session->data['payment_method'] = $methods[$code];
			return true;
		}
	}

	public function getPaymentMethods() {
		$payment_methods = array();

		$this->load->model('setting/extension');
		$results = $this->model_setting_extension->getExtensions('payment');
		$total = $this->getTotal();

		foreach ($results as $result) {
			if (!$this->config->get('payment_' . $result['code'] . '_status')) {
				continue;
			}

			$this->load->model('extension/payment/' . $result['code']);
			$method = $this->{'model_extension_payment_' . $result['code']}->getMethod($this->session->data['payment_address'], $total);

			if (!$method) {
				continue;
			}

			$payment_methods[$result['code']] = $method;
		}

		$sort_order = array();
		foreach ($payment_methods as $key => $value) {
			$sort_order[$key] = $value['sort_order'];
		}
		array_multisort($sort_order, SORT_ASC, $payment_methods);
		$this->session->data['payment_methods'] = $payment_methods;

		return $payment_methods;
	}

	/*
	 * $code = 'flat.flat'
	 */
	public function setShippingMethod($code = '') {
		$methods = $this->getShippingMethods();

		if (!$methods) {
			unset($this->session->data['shipping_methods']);
			unset($this->session->data['shipping_method']);
			return false;
		}

		// Use first method in payment methods session when code is empty
		if (empty($code)) {
			$first = reset($methods);
			$this->session->data['shipping_method'] = current($first['quote']);
			return true;
		}

		// Check if selected shipping code still available
		$shipping = explode('.', $code);
		if (!isset($shipping[0]) || !isset($shipping[1]) || !isset($methods[$shipping[0]]['quote'][$shipping[1]])) {
			unset($this->session->data['shipping_method']);
			return false;
		} else {
			$this->session->data['shipping_method'] = $methods[$shipping[0]]['quote'][$shipping[1]];
			return true;
		}
	}

	public function getShippingMethods() {
		$method_data = array();

		if (!$this->cart->hasShipping() && !isset($this->session->data['shipping_address'])) {
			return $method_data;
		}

		$this->load->model('setting/extension');
		$results = $this->model_setting_extension->getExtensions('shipping');
		foreach ($results as $result) {
			if (!$this->config->get('shipping_' . $result['code'] . '_status')) {
				continue;
			}

			$this->load->model('extension/shipping/' . $result['code']);
			$quote = $this->{'model_extension_shipping_' . $result['code']}->getQuote($this->session->data['shipping_address']);
			if ($quote) {
				$method_data[$result['code']] = array(
					'title' => $quote['title'],
					'quote' => $quote['quote'],
					'sort_order' => $quote['sort_order'],
					'error' => $quote['error']
				);
			}
		}

		$sort_order = array();
		foreach ($method_data as $key => $value) {
			$sort_order[$key] = $value['sort_order'];
		}
		array_multisort($sort_order, SORT_ASC, $method_data);

		$this->session->data['shipping_methods'] = $method_data;
		return $method_data;
	}

	public function getTotal() {
		$totals = array();
		$taxes = $this->cart->getTaxes();
		$total = 0;

		// Because __call can not keep var references so we put them into an array.
		$total_data = array(
			'totals' => &$totals,
			'taxes'  => &$taxes,
			'total'  => &$total
		);

		$this->load->model('setting/extension');
		$sort_order = array();
		$results = $this->model_setting_extension->getExtensions('total');
		foreach ($results as $key => $value) {
			$sort_order[$key] = $this->config->get('total_' . $value['code'] . '_sort_order');
		}

		array_multisort($sort_order, SORT_ASC, $results);
		foreach ($results as $result) {
			if (!$this->config->get('total_' . $result['code'] . '_status')) {
				continue;
			}

			$this->load->model('extension/total/' . $result['code']);
			// We have to put the totals in an array so that they pass by reference.
			$this->{'model_extension_total_' . $result['code']}->getTotal($total_data);
		}

		return $total;
	}

	public function getTotals() {
		$totals = array();
		$taxes = $this->cart->getTaxes();
		$total = 0;

		// Because __call can not keep var references so we put them into an array.
		$total_data = array(
			'totals' => &$totals,
			'taxes'  => &$taxes,
			'total'  => &$total
		);

		$this->load->model('setting/extension');
		$sort_order = array();
		$results = $this->model_setting_extension->getExtensions('total');
		foreach ($results as $key => $value) {
			$sort_order[$key] = $this->config->get('total_' . $value['code'] . '_sort_order');
		}

		array_multisort($sort_order, SORT_ASC, $results);
		foreach ($results as $result) {
			if ($this->config->get('total_' . $result['code'] . '_status')) {
				$this->load->model('extension/total/' . $result['code']);
				// We have to put the totals in an array so that they pass by reference.
				$this->{'model_extension_total_' . $result['code']}->getTotal($total_data);
			}
		}

		$sort_order = array();
		foreach ($totals as $key => $value) {
			$sort_order[$key] = $value['sort_order'];
		}
		array_multisort($sort_order, SORT_ASC, $totals);

		return $totals;
	}

	public function bindOrderCustomerId($order_id, $customer_id, $customer_group_id) {
		$this->db->query("UPDATE `" . DB_PREFIX . "order` SET customer_id = '" . (int)$customer_id . "', customer_group_id = '" . (int)$customer_group_id . "' WHERE order_id = '" . (int)$order_id . "'");
	}

	public function syncCustomerIdInCartTableAfterRegistered() {
		$this->db->query("UPDATE " . DB_PREFIX . "cart SET customer_id = '" . (int)$this->customer->getId() . "' WHERE customer_id = '0' AND session_id = '" . $this->db->escape($this->session->getId()) . "'");
	}

	public function log($data = null) {
		if (!$data) {
			return;
		}

		if (!defined('DEBUG') || DEBUG == false) {
			return;
		}

		if (is_array($data)) {
			$this->logger->write(json_encode($data));
		} else {
			$this->logger->write($data);
		}
	}
}