Skip to content

Instantly share code, notes, and snippets.

@0test
Last active March 15, 2024 10:38
Show Gist options
  • Save 0test/e50af9872977abcf3f7589986b0d5cdc to your computer and use it in GitHub Desktop.
Save 0test/e50af9872977abcf3f7589986b0d5cdc to your computer and use it in GitHub Desktop.
<?php
//plugin
use Illuminate\Support\Facades\Event;
use Commerce\Carts\ProductsCart;
use Commerce\Carts\SessionCartStore;
use Commerce\Currency;
use EvolutionCMS\Facades\AuthServices as Auth;
use EvolutionCMS\Main\Controllers\Shop\DbCartClass;
Event::listen(['evolution.OnInitializeCommerce'], function ($params) {
ci()->commerce->currency = new Currency(evo());
$carts = ci()->carts;
$carts->registerStore('session', SessionCartStore::class);
$carts->registerStore('custom_db', DbCartClass::class);
$cartSession = new ProductsCart(evo(),'session_products_instance','session');
$cartDb = new ProductsCart(evo(), 'db_products_instance', 'custom_db');
$carts->addCart('session_products_instance', $cartSession);
$carts->addCart('db_products_instance', $cartDb);
});
Event::listen(['evolution.OnUserLogout'], function ($params) {
});
<?php
namespace EvolutionCMS\Main\Controllers\Shop;
use EvolutionCMS\Facades\AuthServices as Auth;
use Commerce\Interfaces\CartStore;
/**
* store cart to db
*/
class DbCartClass implements CartStore
{
protected $modx;
protected $instance = '';
protected $id = 0;
protected $cartKey = '';
protected $items = [];
protected $uid;
public function __construct()
{
$this->modx = ci()->modx;
$this->uid = (int) $this->modx->getLoginUserID('web') ? (int) $this->modx->getLoginUserID('web') : null;
}
public function load($instance = 'cart')
{
$this->instance = $instance;
return $this->loadCart();
}
public function save(array $items)
{
if (!$this->id && !empty($items)) {
$this->createCart();
};
$old = array_keys($this->items);
$new = array_keys($items);
$delete = array_diff($old, $new);
if (!empty($delete)) {
$rows = \APIhelpers::sanitarIn($delete);
$this->modx->db->query("DELETE FROM {$this->modx->getFullTableName('commerce_db_cart_products')} WHERE `cart_id` = {$this->id} AND `row` IN ({$rows})");
}
$insert = array_diff($new, $old);
$update = array_intersect($new, $old);
foreach ($update as $row) {
if ($items[$row] != $this->items[$row]) {
$insert[] = $row;
}
}
foreach ($insert as $row) {
$item = $items[$row];
$data = [
'cart_id' => $this->id,
'product_id' => (int) $item['id'],
'hash' => $item['hash'],
'row' => $row,
'title' => $this->modx->db->escape(trim(isset($item['title']) ? $item['title'] : $item['name'])),
'price' => $this->normalizeFloat($item['price']),
'count' => $this->normalizeFloat($item['count']),
'options' => json_encode(isset($item['options']) && is_array($item['options']) ? $item['options'] : [], JSON_UNESCAPED_UNICODE),
'meta' => json_encode(isset($item['meta']) && is_array($item['meta']) ? $item['meta'] : [], JSON_UNESCAPED_UNICODE),
];
$fields = '`' . implode('`,`', array_keys($data)) . '`';
$values = \APIhelpers::sanitarIn(array_values($data));
$this->modx->db->query("INSERT IGNORE INTO {$this->modx->getFullTableName('commerce_db_cart_products')} ({$fields}) VALUES ({$values}) ON DUPLICATE KEY UPDATE `product_id` = {$data['product_id']}, `count` = '{$data['count']}', `title` = '{$data['title']}', `price` = '{$data['price']}', `options` = '{$data['options']}', `meta` = '{$data['meta']}'");
}
$this->items = $items;
if (!empty($delete) || !empty($insert)) {
$this->updateCart();
}
}
/**
* @params id, hash
*/
protected function loadCart()
{
$items = [];
$instance = $this->modx->db->escape($this->instance);
if(!$this->uid){
return false;
}
$q = $this->modx->db->query("SELECT `id` FROM {$this->modx->getFullTableName('commerce_db_carts')} WHERE `customer_id`= {$this->uid} AND `instance` = '{$instance}'");
if ($id = $this->modx->db->getValue($q)) {
$this->id = $id;
$q = $this->modx->db->query("SELECT * FROM {$this->modx->getFullTableName('commerce_db_cart_products')} WHERE `cart_id` = {$id} ORDER BY `id` ASC");
while ($row = $this->modx->db->getRow($q)) {
$items[$row['row']] = [
'id' => $row['product_id'],
'name' => $row['title'],
'price' => $row['price'],
'count' => $row['count'],
'hash' => $row['hash'],
'row' => $row['row'],
'options' => \jsonHelper::jsonDecode($row['options'], ['assoc' => true], true),
'meta' => \jsonHelper::jsonDecode($row['meta'], ['assoc' => true], true),
];
}
} else {
$this->id = 0;
//?
//$this->createCart();
}
$this->items = $items;
return $items;
}
protected function createCart( )
{
$hash = ci()->commerce->generateRandomString(32);
$instance = $this->modx->db->escape($this->instance);
$updated_at = date('Y-m-d H:i:s', time() + $this->modx->getConfig('server_offset_time'));
$q = $this->modx->db->query("INSERT INTO {$this->modx->getFullTableName('commerce_db_carts')} (`instance`, `hash`, `customer_id`, `updated_at`) VALUES ('{$instance}', '{$hash}', {$this->uid}, '{$updated_at}')");
$this->id = $this->modx->db->getInsertId();
}
protected function updateCart()
{
$id = $this->id;
$updated_at = date('Y-m-d H:i:s', time() + $this->modx->getConfig('server_offset_time'));
$update = [];
$update[] = "`updated_at` = '{$updated_at}'";
$update[] = "`updated_at` = '{$this->uid}'";
$update = implode(',', $update);
$this->modx->db->query("UPDATE {$this->modx->getFullTableName('commerce_db_carts')} SET {$update} WHERE `id` = {$id}");
}
protected function normalizeFloat($value)
{
$value = str_replace(',', '.', $value);
return number_format((float) $value, 6, '.', '');
}
}
<?php
use Illuminate\Support\Facades\Event;
Event::listen(['evolution.OnUserLogin'], function ($params) {
if(evo()->isBackend()) return;
if(!function_exists('ci')){evo()->invokeEvent('OnWebPageInit');}
$carts = ci()->carts;
$sessionCart = ci()->carts->getCart('session_products_instance'); // корзина анонима
$sessionItems = $sessionCart->getItems(); // товары анонима
$dbCart = ci()->carts->getCart('db_products_instance'); // корзина юзера в БД
$dbItems = $dbCart->getItems(); // товары юзера
if( count($sessionItems) === 0){
// корзина анонима пуста, берём товар из корзины в БД
// В плагине DbCart мы сменим инстанс, товары
// будут из корзины БД. И делать ничего не надо
}else{
// корзина анонима не пуста, нужно объединить её и корзину в БД
if(count($dbItems) === 0){
// в корзине БД пусто, в сессии не пусто
// надо удалить из сессии и добавить в БД корзину
foreach ($sessionItems as $key => $item) {
$dbCart->add($item, false);
}
}
else{
// в обоих корзинах что-то есть
// нужно сливать товары
foreach ($sessionItems as $key => $sessionItem) {
foreach ($dbItems as $k => $dbItem) {
if($dbItem['id'] != $sessionItem['id'] && $dbItem['hash'] != $sessionItem['hash']){
$dbCart->add($sessionItem, false);
}
}
}
}
// почистить корзину сессии
// она нам больше не нужна, товары на месте
$sessionCart->clean();
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment