feat: create new order

This commit is contained in:
Nikita Kiselev
2025-07-31 23:48:11 +03:00
parent eb1f1dc9c1
commit c057f4be76
24 changed files with 891 additions and 319 deletions

View File

@@ -2,6 +2,7 @@
use App\Adapters\OcModelCatalogProductAdapter;
use App\ApplicationFactory;
use App\Decorators\OcRegistryDecorator;
use Cart\Cart;
use Cart\Currency;
use Cart\Tax;
@@ -25,8 +26,9 @@ class Controllerextensiontgshophandle extends Controller
$app = ApplicationFactory::create([
'oc_config_tax' => $this->config->get('config_tax'),
'oc_default_currency' => $this->config->get('config_currency'),
'oc_customer_group_id' => $this->config->get('config_customer_group_id'),
'timezone' => $this->config->get('config_timezone', 'UTC'),
'language_id' => (int)$this->config->get('config_language_id'),
'language_id' => (int) $this->config->get('config_language_id'),
'shop_base_url' => HTTPS_SERVER,
'dir_image' => DIR_IMAGE,
'db' => [
@@ -61,222 +63,18 @@ class Controllerextensiontgshophandle extends Controller
return new ImageTool(DIR_IMAGE, HTTPS_SERVER);
});
$app->bind(\Cart\Cart::class, function () {
$app->bind(Cart::class, function () {
return $this->cart;
});
$app->bind(DB::class, function () {
return $this->db;
$app->bind(OcRegistryDecorator::class, function () {
return new OcRegistryDecorator($this->registry);
});
$this->load->model('checkout/order');
$app->bind('model_checkout_order', function () {
return $this->model_checkout_order;
});
$this->session->data['language'] = $this->config->get('config_language');
$app->bootAndHandleRequest();
}
public function cart() {
$this->load->language('checkout/cart');
if ($this->cart->hasProducts()) {
if (!$this->cart->hasStock() && (!$this->config->get('config_stock_checkout') || $this->config->get('config_stock_warning'))) {
$data['error_warning'] = $this->language->get('error_stock');
} elseif (isset($this->session->data['error'])) {
$data['error_warning'] = $this->session->data['error'];
unset($this->session->data['error']);
} else {
$data['error_warning'] = '';
}
if ($this->config->get('config_customer_price') && !$this->customer->isLogged()) {
$data['attention'] = sprintf($this->language->get('text_login'), $this->url->link('account/login'), $this->url->link('account/register'));
} else {
$data['attention'] = '';
}
if (isset($this->session->data['success'])) {
$data['success'] = $this->session->data['success'];
unset($this->session->data['success']);
} else {
$data['success'] = '';
}
if ($this->config->get('config_cart_weight')) {
$data['weight'] = $this->weight->format($this->cart->getWeight(), $this->config->get('config_weight_class_id'), $this->language->get('decimal_point'), $this->language->get('thousand_point'));
} else {
$data['weight'] = '';
}
$this->load->model('tool/image');
$this->load->model('tool/upload');
$data['products'] = array();
$products = $this->cart->getProducts();
foreach ($products as $product) {
$product_total = 0;
foreach ($products as $product_2) {
if ($product_2['product_id'] == $product['product_id']) {
$product_total += $product_2['quantity'];
}
}
if ($product['minimum'] > $product_total) {
$data['error_warning'] = sprintf($this->language->get('error_minimum'), $product['name'], $product['minimum']);
}
if ($product['image']) {
$image = $this->model_tool_image->resize($product['image'], $this->config->get('theme_' . $this->config->get('config_theme') . '_image_cart_width'), $this->config->get('theme_' . $this->config->get('config_theme') . '_image_cart_height'));
} else {
$image = '';
}
$option_data = array();
foreach ($product['option'] as $option) {
if ($option['type'] != 'file') {
$value = $option['value'];
} else {
$upload_info = $this->model_tool_upload->getUploadByCode($option['value']);
if ($upload_info) {
$value = $upload_info['name'];
} else {
$value = '';
}
}
$option_data[] = array(
'name' => $option['name'],
'value' => (utf8_strlen($value) > 20 ? utf8_substr($value, 0, 20) . '..' : $value)
);
}
// Display prices
if ($this->customer->isLogged() || !$this->config->get('config_customer_price')) {
$unit_price = $this->tax->calculate($product['price'], $product['tax_class_id'], $this->config->get('config_tax'));
$price = $this->currency->format($unit_price, $this->session->data['currency']);
$total = $this->currency->format($unit_price * $product['quantity'], $this->session->data['currency']);
} else {
$price = false;
$total = false;
}
$recurring = '';
if ($product['recurring']) {
$frequencies = array(
'day' => $this->language->get('text_day'),
'week' => $this->language->get('text_week'),
'semi_month' => $this->language->get('text_semi_month'),
'month' => $this->language->get('text_month'),
'year' => $this->language->get('text_year')
);
if ($product['recurring']['trial']) {
$recurring = sprintf($this->language->get('text_trial_description'), $this->currency->format($this->tax->calculate($product['recurring']['trial_price'] * $product['quantity'], $product['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']), $product['recurring']['trial_cycle'], $frequencies[$product['recurring']['trial_frequency']], $product['recurring']['trial_duration']) . ' ';
}
if ($product['recurring']['duration']) {
$recurring .= sprintf($this->language->get('text_payment_description'), $this->currency->format($this->tax->calculate($product['recurring']['price'] * $product['quantity'], $product['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']), $product['recurring']['cycle'], $frequencies[$product['recurring']['frequency']], $product['recurring']['duration']);
} else {
$recurring .= sprintf($this->language->get('text_payment_cancel'), $this->currency->format($this->tax->calculate($product['recurring']['price'] * $product['quantity'], $product['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']), $product['recurring']['cycle'], $frequencies[$product['recurring']['frequency']], $product['recurring']['duration']);
}
}
$data['products'][] = array(
'cart_id' => (int)$product['cart_id'],
'thumb' => $image,
'name' => $product['name'],
'model' => $product['model'],
'option' => $option_data,
'recurring' => $recurring,
'quantity' => (int)$product['quantity'],
'stock' => $product['stock'] ? true : !(!$this->config->get('config_stock_checkout') || $this->config->get('config_stock_warning')),
'reward' => ($product['reward'] ? sprintf($this->language->get('text_points'), $product['reward']) : ''),
'price' => $price,
'total' => $total,
'href' => $this->url->link('product/product', 'product_id=' . $product['product_id'])
);
}
// Totals
$this->load->model('setting/extension');
$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
);
$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);
$data['totals'] = array();
foreach ($totals as $total) {
$data['totals'][] = array(
'title' => $total['title'],
'text' => $this->currency->format($total['value'], $this->session->data['currency'])
);
}
$data['total_products_count'] = $this->cart->countProducts();
} else {
$data['text_error'] = $this->language->get('text_empty');
$data['totals'] = [];
$data['total'] = 0;
$data['products'] = [];
$data['total_products_count'] = 0;
unset($this->session->data['success']);
}
http_response_code(200);
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
header('Access-Control-Allow-Credentials: true');
echo json_encode($data);
die();
}
}

View File

@@ -20,7 +20,8 @@
"ext-pdo": "*",
"psr/container": "^2.0",
"ext-json": "*",
"intervention/image": "^2.7"
"intervention/image": "^2.7",
"rakit/validation": "^1.4"
},
"require-dev": {
"roave/security-advisories": "dev-latest"

View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "4c731e75f55435f8b300c557fdfabfed",
"content-hash": "0862025c427a0e17dfde4fb54820c5c0",
"packages": [
{
"name": "guzzlehttp/psr7",
@@ -367,6 +367,52 @@
},
"time": "2023-04-04T09:54:51+00:00"
},
{
"name": "rakit/validation",
"version": "v1.4.0",
"source": {
"type": "git",
"url": "https://github.com/rakit/validation.git",
"reference": "ff003a35cdf5030a5f2482299f4c93f344a35b29"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/rakit/validation/zipball/ff003a35cdf5030a5f2482299f4c93f344a35b29",
"reference": "ff003a35cdf5030a5f2482299f4c93f344a35b29",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"php": ">=7.0"
},
"require-dev": {
"php-coveralls/php-coveralls": "^2.2",
"phpunit/phpunit": "^6.5",
"squizlabs/php_codesniffer": "^3"
},
"type": "library",
"autoload": {
"psr-4": {
"Rakit\\Validation\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Muhammad Syifa",
"email": "emsifa@gmail.com"
}
],
"description": "PHP Laravel like standalone validation library",
"support": {
"issues": "https://github.com/rakit/validation/issues",
"source": "https://github.com/rakit/validation/tree/v1.4.0"
},
"time": "2020-08-27T05:07:01+00:00"
},
{
"name": "ralouphie/getallheaders",
"version": "3.0.3",

View File

@@ -15,13 +15,14 @@ class Request
private $content;
public function __construct(
array $query,
array $request,
array $cookies,
array $files,
array $server,
array $query,
array $request,
array $cookies,
array $files,
array $server,
string $content = null
) {
)
{
$this->query = $query;
$this->request = $request;
$this->cookies = $cookies;
@@ -69,4 +70,9 @@ class Request
return $this->query[$key] ?? $default;
}
public function getClientIp(): ?string
{
return $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? null;
}
}

View File

@@ -31,4 +31,10 @@ interface ConnectionInterface
public function lastInsertId($name = null): int;
public function getVersion(): string;
public function insert(string $table, array $data): bool;
public function transaction(callable $callback): void;
public function getLastError(): ?array;
}

View File

@@ -9,6 +9,7 @@ use RuntimeException;
class MySqlConnection implements ConnectionInterface
{
private $pdo;
private ?array $lastError = null;
public function __construct(PDO $pdo)
{
@@ -37,7 +38,7 @@ class MySqlConnection implements ConnectionInterface
return 'null';
case is_int($value) || is_float($value):
return (string)$value;
return (string) $value;
case is_bool($value):
return $value ? '1' : '0';
@@ -87,7 +88,21 @@ class MySqlConnection implements ConnectionInterface
public function statement(string $sql, array $bindings = []): bool
{
return $this->pdo->prepare($sql)->execute($bindings);
$statement = $this->pdo->prepare($sql);
if (! $statement) {
$this->lastError = $this->pdo->errorInfo();
return false;
}
$success = $statement->execute($bindings);
if (! $success) {
$this->lastError = $statement->errorInfo();
return false;
}
return $success;
}
public function beginTransaction(): bool
@@ -128,4 +143,30 @@ class MySqlConnection implements ConnectionInterface
->query('SELECT VERSION()')
->fetch(PDO::FETCH_COLUMN);
}
public function insert(string $table, array $data): bool
{
$placeholders = implode(',', array_fill(0, count($data), '?'));
$columns = implode(',', array_map(static fn ($key) => "`${key}`", array_keys($data)));
$sql = sprintf('INSERT INTO `%s` (%s) VALUES (%s)', $table, $columns, $placeholders);
return $this->statement($sql, array_values($data));
}
public function transaction(callable $callback): void
{
try {
$this->beginTransaction();
$callback();
$this->commitTransaction();
} catch (\Exception $exception) {
$this->rollBackTransaction();
throw $exception;
}
}
public function getLastError(): ?array
{
return $this->lastError;
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace App\Decorators;
use Cart\Cart;
use Loader;
use Registry;
/**
* @property Loader $load
* @property Cart $cart
*/
class OcRegistryDecorator
{
private Registry $registry;
public function __construct(Registry $registry)
{
$this->registry = $registry;
}
public function __get($key)
{
return $this->registry->get($key);
}
public function __set($key, $value)
{
$this->registry->set($key, $value);
}
public function __isset($key)
{
return $this->registry->has($key);
}
}

View File

@@ -2,6 +2,7 @@
namespace App\Handlers;
use App\Services\CartService;
use Cart\Cart;
use Openguru\OpenCartFramework\Http\JsonResponse;
use Openguru\OpenCartFramework\Http\Request;
@@ -11,12 +12,22 @@ class CartHandler
{
private Cart $cart;
private ImageToolInterface $imageTool;
private CartService $cartService;
public function __construct(Cart $cart, \DB $database, ImageToolInterface $imageTool)
public function __construct(Cart $cart, ImageToolInterface $imageTool, CartService $cartService)
{
$this->cart = $cart;
$this->database = $database;
$this->imageTool = $imageTool;
$this->cartService = $cartService;
}
public function index(): JsonResponse
{
$items = $this->cartService->getCart();
return new JsonResponse([
'data' => $items,
]);
}
public function checkout(Request $request): JsonResponse
@@ -43,15 +54,4 @@ class CartHandler
'data' => $items,
]);
}
private function getProducts(): array
{
$products = $this->cart->getProducts();
foreach ($products as &$product) {
$product['thumb'] = $this->imageTool->resize($product['image'], 100, 100, 'placeholder.png');
}
return $products;
}
}

View File

@@ -1,60 +0,0 @@
<?php
namespace App\Handlers;
use Openguru\OpenCartFramework\Http\JsonResponse;
use Openguru\OpenCartFramework\Http\Request;
use Openguru\OpenCartFramework\QueryBuilder\Connections\ConnectionInterface;
class OrderCreateHandler
{
private ConnectionInterface $database;
public function __construct(ConnectionInterface $database)
{
$this->database = $database;
}
public function handle(Request $request): JsonResponse
{
$now = date('Y-m-d H:i:s');
$storeId = 0;
$storeName = 'Ваш магазин';
$sql = <<<SQL
INSERT INTO oc_order
(
store_id,
store_name,
firstname,
lastname,
shipping_code,
total,
order_status_id,
currency_code,
currency_value,
date_added,
date_modified
)
VALUES
(
$storeId,
'$storeName',
'John',
'Doe',
'flat.flat',
99.9999,
1,
'RUB',
1,
'$now',
'$now'
)
SQL;
$result = $this->database->statement($sql);
return new JsonResponse([]);
}
}

View File

@@ -0,0 +1,159 @@
<?php
namespace App\Handlers;
use App\Decorators\OcRegistryDecorator;
use App\Services\CartService;
use Openguru\OpenCartFramework\Config\Settings;
use Openguru\OpenCartFramework\Http\JsonResponse;
use Openguru\OpenCartFramework\Http\Request;
use Openguru\OpenCartFramework\Http\Response;
use Openguru\OpenCartFramework\QueryBuilder\Connections\ConnectionInterface;
use Rakit\Validation\Validator;
use RuntimeException;
class OrderHandler
{
private ConnectionInterface $database;
private CartService $cartService;
private OcRegistryDecorator $oc;
private Settings $settings;
public function __construct(
ConnectionInterface $database,
CartService $cartService,
OcRegistryDecorator $registry,
Settings $settings
) {
$this->database = $database;
$this->cartService = $cartService;
$this->oc = $registry;
$this->settings = $settings;
}
public function store(Request $request): JsonResponse
{
$validator = new Validator();
$validation = $validator->make($request->json(), [
'firstName' => 'required',
'lastName' => 'required',
'email' => 'required|email',
'phone' => 'required',
'address' => 'required',
'comment' => 'required',
]);
$validation->validate();
if ($validation->fails()) {
$errors = $validation->errors();
return new JsonResponse([
'data' => $errors->firstOfAll(),
], Response::HTTP_UNPROCESSABLE_ENTITY);
}
$now = date('Y-m-d H:i:s');
$storeId = 0;
$storeName = 'Ваш магазин';
$cart = $this->cartService->getCart();
$total = $cart['total'] ?? 0;
$orderStatusId = 1;
$products = $cart['products'] ?? [];
$totals = $cart['totals'] ?? [];
$customerGroupId = $this->settings->get('oc_customer_group_id');
$languageId = $this->oc->config->get('config_language_id');
$currencyId = $this->oc->currency->getId($this->oc->session->data['currency']);
$currencyCode = $this->oc->session->data['currency'];
$currencyValue = $this->oc->currency->getValue($this->oc->session->data['currency']);
$orderData = [
'store_id' => $storeId,
'store_name' => $storeName,
'firstname' => $request->json('firstName'),
'lastname' => $request->json('lastName'),
'email' => $request->json('email'),
'telephone' => $request->json('phone'),
'comment' => $request->json('comment'),
'shipping_address_1' => $request->json('address'),
'total' => $total,
'order_status_id' => $orderStatusId,
'ip' => $request->getClientIp(),
'date_added' => $now,
'date_modified' => $now,
'language_id' => $languageId,
'currency_id' => $currencyId,
'currency_code' => $currencyCode,
'currency_value' => $currencyValue,
'customer_group_id' => $customerGroupId,
];
$this->database->transaction(
function () use ($orderData, $products, $totals, $orderStatusId, $now) {
$success = $this->database->insert(db_table('order'), $orderData);
if (! $success) {
[, $error] = $this->database->getLastError();
throw new RuntimeException("Failed to insert row into order. Error: $error");
}
$orderId = $this->database->lastInsertId();
// Insert products
foreach ($products as $product) {
$success = $this->database->insert(db_table('order_product'), [
'order_id' => $orderId,
'product_id' => $product['product_id'],
'name' => $product['name'],
'model' => $product['model'],
'quantity' => $product['quantity'],
'price' => $product['price_numeric'],
'total' => $product['total_numeric'],
'reward' => $product['reward_numeric'],
]);
if (! $success) {
[, $error] = $this->database->getLastError();
throw new RuntimeException("Failed to insert row into order_product. Error: $error");
}
}
// Insert totals
foreach ($totals as $total) {
$success = $this->database->insert(db_table('order_total'), [
'order_id' => $orderId,
'code' => $total['code'],
'title' => $total['title'],
'value' => $total['value'],
'sort_order' => $total['sort_order'],
]);
if (! $success) {
[, $error] = $this->database->getLastError();
throw new RuntimeException("Failed to insert row into order_total. Error: $error");
}
}
// Insert history
$success = $this->database->insert(db_table('order_history'), [
'order_id' => $orderId,
'order_status_id' => $orderStatusId,
'notify' => 0,
'comment' => 'Заказ оформлен через Telegram Mini App',
'date_added' => $now,
]);
if (! $success) {
[, $error] = $this->database->getLastError();
throw new RuntimeException("Failed to insert row into order_history. Error: $error");
}
}
);
$this->cartService->flush();
return new JsonResponse([]);
}
}

View File

@@ -0,0 +1,300 @@
<?php
namespace App\Services;
use App\Decorators\OcRegistryDecorator;
use Cart\Cart;
class CartService
{
private OcRegistryDecorator $oc;
private Cart $cart;
public function __construct(OcRegistryDecorator $registry, Cart $cart)
{
$this->oc = $registry;
$this->cart = $cart;
}
public function getCart(): array
{
$this->oc->load->language('checkout/cart');
if ($this->oc->cart->hasProducts()) {
if (! $this->oc->cart->hasStock() && (! $this->oc->config->get('config_stock_checkout') || $this->oc->config->get(
'config_stock_warning'
))) {
$data['error_warning'] = $this->oc->language->get('error_stock');
} elseif (isset($this->oc->session->data['error'])) {
$data['error_warning'] = $this->oc->session->data['error'];
unset($this->oc->session->data['error']);
} else {
$data['error_warning'] = '';
}
if ($this->oc->config->get('config_customer_price') && ! $this->oc->customer->isLogged()) {
$data['attention'] = sprintf(
$this->oc->language->get('text_login'),
$this->oc->url->link('account/login'),
$this->oc->url->link('account/register')
);
} else {
$data['attention'] = '';
}
if (isset($this->oc->session->data['success'])) {
$data['success'] = $this->oc->session->data['success'];
unset($this->oc->session->data['success']);
} else {
$data['success'] = '';
}
if ($this->oc->config->get('config_cart_weight')) {
$data['weight'] = $this->oc->weight->format(
$this->oc->cart->getWeight(),
$this->oc->config->get('config_weight_class_id'),
$this->oc->language->get('decimal_point'),
$this->oc->language->get('thousand_point')
);
} else {
$data['weight'] = '';
}
$this->oc->load->model('tool/image');
$this->oc->load->model('tool/upload');
$data['products'] = array();
$products = $this->oc->cart->getProducts();
foreach ($products as $product) {
$product_total = 0;
foreach ($products as $product_2) {
if ($product_2['product_id'] == $product['product_id']) {
$product_total += $product_2['quantity'];
}
}
if ($product['minimum'] > $product_total) {
$data['error_warning'] = sprintf(
$this->oc->language->get('error_minimum'),
$product['name'],
$product['minimum']
);
}
if ($product['image']) {
$image = $this->oc->model_tool_image->resize(
$product['image'],
$this->oc->config->get('theme_' . $this->oc->config->get('config_theme') . '_image_cart_width'),
$this->oc->config->get('theme_' . $this->oc->config->get('config_theme') . '_image_cart_height')
);
} else {
$image = '';
}
$option_data = array();
foreach ($product['option'] as $option) {
if ($option['type'] != 'file') {
$value = $option['value'];
} else {
$upload_info = $this->oc->model_tool_upload->getUploadByCode($option['value']);
if ($upload_info) {
$value = $upload_info['name'];
} else {
$value = '';
}
}
$option_data[] = array(
'name' => $option['name'],
'value' => (utf8_strlen($value) > 20 ? utf8_substr($value, 0, 20) . '..' : $value)
);
}
$priceNumeric = 0;
$totalNumeric = 0;
// Display prices
if ($this->oc->customer->isLogged() || ! $this->oc->config->get('config_customer_price')) {
$unit_price = $this->oc->tax->calculate(
$product['price'],
$product['tax_class_id'],
$this->oc->config->get('config_tax')
);
$priceNumeric = $unit_price;
$totalNumeric = $unit_price * $product['quantity'];
$price = $this->oc->currency->format($unit_price, $this->oc->session->data['currency']);
$total = $this->oc->currency->format($totalNumeric, $this->oc->session->data['currency']);
} else {
$price = false;
$total = false;
}
$recurring = '';
if ($product['recurring']) {
$frequencies = array(
'day' => $this->oc->language->get('text_day'),
'week' => $this->oc->language->get('text_week'),
'semi_month' => $this->oc->language->get('text_semi_month'),
'month' => $this->oc->language->get('text_month'),
'year' => $this->oc->language->get('text_year')
);
if ($product['recurring']['trial']) {
$recurring = sprintf(
$this->oc->language->get('text_trial_description'),
$this->oc->currency->format(
$this->oc->tax->calculate(
$product['recurring']['trial_price'] * $product['quantity'],
$product['tax_class_id'],
$this->oc->config->get('config_tax')
),
$this->oc->session->data['currency']
),
$product['recurring']['trial_cycle'],
$frequencies[$product['recurring']['trial_frequency']],
$product['recurring']['trial_duration']
) . ' ';
}
if ($product['recurring']['duration']) {
$recurring .= sprintf(
$this->oc->language->get('text_payment_description'),
$this->oc->currency->format(
$this->oc->tax->calculate(
$product['recurring']['price'] * $product['quantity'],
$product['tax_class_id'],
$this->oc->config->get('config_tax')
),
$this->oc->session->data['currency']
),
$product['recurring']['cycle'],
$frequencies[$product['recurring']['frequency']],
$product['recurring']['duration']
);
} else {
$recurring .= sprintf(
$this->oc->language->get('text_payment_cancel'),
$this->oc->currency->format(
$this->oc->tax->calculate(
$product['recurring']['price'] * $product['quantity'],
$product['tax_class_id'],
$this->oc->config->get('config_tax')
),
$this->oc->session->data['currency']
),
$product['recurring']['cycle'],
$frequencies[$product['recurring']['frequency']],
$product['recurring']['duration']
);
}
}
$data['products'][] = array(
'product_id' => (int) $product['product_id'],
'cart_id' => (int) $product['cart_id'],
'thumb' => $image,
'name' => $product['name'],
'model' => $product['model'],
'option' => $option_data,
'recurring' => $recurring,
'quantity' => (int) $product['quantity'],
'stock' => $product['stock'] ? true : ! (! $this->oc->config->get(
'config_stock_checkout'
) || $this->oc->config->get('config_stock_warning')),
'reward' => ($product['reward'] ? sprintf(
$this->oc->language->get('text_points'),
$product['reward']
) : ''),
'price' => $price,
'total' => $total,
'href' => $this->oc->url->link('product/product', 'product_id=' . $product['product_id']),
'price_numeric' => $priceNumeric,
'total_numeric' => $totalNumeric,
'reward_numeric' => $product['reward'] ?? 0,
);
}
// Totals
$this->oc->load->model('setting/extension');
$totals = array();
$taxes = $this->oc->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
);
$sort_order = array();
$results = $this->oc->model_setting_extension->getExtensions('total');
foreach ($results as $key => $value) {
$sort_order[$key] = $this->oc->config->get('total_' . $value['code'] . '_sort_order');
}
array_multisort($sort_order, SORT_ASC, $results);
foreach ($results as $result) {
if ($this->oc->config->get('total_' . $result['code'] . '_status')) {
$this->oc->load->model('extension/total/' . $result['code']);
// We have to put the totals in an array so that they pass by reference.
$this->oc->{'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);
$data['totals'] = array();
foreach ($totals as $total) {
$data['totals'][] = [
'code' => $total['code'],
'title' => $total['title'],
'value' => $total['value'],
'sort_order' => $total['sort_order'],
'text' => $this->oc->currency->format($total['value'], $this->oc->session->data['currency']),
];
}
$lastTotal = $totals[count($totals) - 1] ?? false;
$data['total'] = $lastTotal ? $lastTotal['value'] : 0;
$data['total_products_count'] = $this->oc->cart->countProducts();
} else {
$data['text_error'] = $this->oc->language->get('text_empty');
$data['totals'] = [];
$data['total'] = 0;
$data['products'] = [];
$data['total_products_count'] = 0;
unset($this->oc->session->data['success']);
}
return $data;
}
public function flush(): void
{
$this->cart->clear();
}
}

View File

@@ -3,15 +3,16 @@
use App\Handlers\CategoriesHandler;
use App\Handlers\CartHandler;
use App\Handlers\HelloWorldHandler;
use App\Handlers\OrderCreateHandler;
use App\Handlers\OrderHandler;
use App\Handlers\ProductsHandler;
return [
'products' => [ProductsHandler::class, 'handle'],
'product_show' => [ProductsHandler::class, 'show'],
'order_create' => [OrderCreateHandler::class, 'handle'],
'storeOrder' => [OrderHandler::class, 'store'],
'categoriesList' => [CategoriesHandler::class, 'index'],
'checkout' => [CartHandler::class, 'checkout'],
'getCart' => [CartHandler::class, 'index'],
];