Files
kupshop/class/smarty_plugins/function.get_stats.php
2025-08-02 16:30:27 +02:00

414 lines
15 KiB
PHP

<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: function
* Name: get_stats
* Purpose: returns various statistic numbers
* -------------------------------------------------------------
*/
use KupShop\CatalogBundle\Util\FavoriteProductsUtil;
use KupShop\I18nBundle\Util\PriceConverter;
use KupShop\KupShopBundle\Context\ContextManager;
use KupShop\KupShopBundle\Context\CountryContext;
use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Context\UserContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\KupShopBundle\Util\Price\Price;
use KupShop\KupShopBundle\Util\Price\PriceCalculator;
use KupShop\OrderingBundle\Util\Purchase\PurchaseUtil;
function smarty_function_get_stats($params, &$smarty)
{
$type = null;
$result = null;
extract($params);
if (empty($type)) {
trigger_error("Chybějící parametr 'type'");
}
switch ($type) {
case 'products_count':
$key = join('_', $params);
$result = getCache($key);
if (!$result) {
$from = getTableName('products').' p';
$where = 'figure="Y"';
$data = [];
if (!empty($params['in_store'])) {
$where .= ' AND p.in_store > 0 ';
}
if (!empty($params['category'])) {
$from .= ' LEFT JOIN '.getTableName('products-sections').' ps ON p.id=ps.id_product';
$where .= ' AND ps.id_section = :section ';
$data['section'] = $params['category'];
}
$result = returnSQLResult("SELECT COUNT(*) FROM {$from} WHERE {$where}", $data);
setCache($key, $result);
}
break;
case 'cart_free_delivery':
case 'free_delivery':
$with_empty_purchasestate = $type == 'free_delivery';
if (!$with_empty_purchasestate) {
/** @var Cart $cart */
$cart = ServiceContainer::getService(\KupShop\OrderingBundle\Cart::class);
if ($cart->hasOnlyVirtualProducts() && !($params['alllow_only_virtual_products'] ?? false)) {
return null;
}
}
$purchaseUtil = ServiceContainer::getService(PurchaseUtil::class);
$freeDeliveryFrom = $purchaseUtil->getFreeDeliveryFrom($with_empty_purchasestate);
if (Contexts::get(UserContext::class)->isActive() || ($params['registered'] ?? false)) {
$freeDeliveryFrom = $freeDeliveryFrom['registered'];
} else {
$freeDeliveryFrom = $freeDeliveryFrom['unregistered'];
}
if ($freeDeliveryFrom) {
$converter = ServiceContainer::getService(PriceConverter::class);
$currencyContext = Contexts::get(CurrencyContext::class);
$result = $converter->convert($freeDeliveryFrom->getCurrency(), $currencyContext->getActive(), $freeDeliveryFrom->getValue());
}
break;
case 'user_spending':
if (Contexts::get(UserContext::class)->isActive()) {
$where = 'o.id_user = :user_id';
$data = [
'user_id' => Contexts::get(UserContext::class)->getActiveId(),
];
if (!empty($params['year'])) {
$where .= ' AND YEAR(o.date_created) = :year ';
$data['year'] = $params['year'];
}
if (!empty($params['last_year'])) {
$year = intval($params['last_year']);
$where .= " AND date_created > DATE_SUB( NOW(), INTERVAL {$year} YEAR) ";
}
// Pokud chtějí zobrazovat přesný součet objednávek v dané měně
if (isset($params['currency'])) {
$spendActiveCurrency = sqlQueryBuilder()
->select('SUM(o.total_price) as total')
->from(getTableName('orders'), 'o')
->andWhere(\Query\Operator::equals(['id_user' => $data['user_id'], 'o.currency' => $params['currency']]))
->execute()->fetchOne();
$result = toDecimal($spendActiveCurrency);
} else {
$result = applyCurrency(returnSQLResult('SELECT SUM(o.total_price'.(findModule('currencies') ? '* o.currency_rate' : '').') FROM orders AS o WHERE '.$where, $data));
}
} else {
$result = null;
}
break;
case 'user_orders':
global $ctrl;
$result = sqlQueryBuilder()
->select('COUNT(*) as orders_num')
->from('orders', 'o')
->where('id_user=:id_user')
->setParameter('id_user', $ctrl['id'])
->execute()->fetchColumn();
break;
case 'user_points':
global $ctrl;
if (!$ctrl['id']) {
$result = null;
break;
}
$last_date = sqlQueryBuilder()
->select('date_created')
->from('bonus_points', 'b')
->where('id_user=:id_user')
->andWhere(\Query\Operator::equals(['b.status' => 'active']))
->setParameter('id_user', $ctrl['id'])
->orderBy('date_created', 'DESC')
->setMaxResults(1)
->execute()->fetchColumn();
if (!$last_date) {
$result = null;
break;
}
$insert_date = (new \DateTime())->setTimestamp(strtotime($last_date));
if (!empty($expire_date)) {
$dbcfg = Settings::getDefault();
$result = $insert_date->modify("+ {$dbcfg->bonus_program['remove_time']} day");
} else {
$result = $insert_date;
}
break;
case 'user_unsolved_orders':
global $ctrl;
$result = sqlQueryBuilder()
->select('COUNT(*) as orders_num')
->from('orders', 'o')
->where('id_user=:id_user')
->andWhere('o.status_storno = 0')
->andWhere(\Query\Operator::inIntArray(getStatuses('nothandled'), 'o.status'))
->setParameter('id_user', $ctrl['id'])
->execute()->fetchColumn();
break;
case 'user_favorite_goods':
$userContext = Contexts::get(UserContext::class);
$productList = new ProductList();
$productList->applyDefaultFilterParams();
$productList->andSpec(function (Query\QueryBuilder $qb) use ($userContext) {
if ($userContext->getActiveId()) {
$qb->join('p', 'products_favorites', 'pf', 'pf.id_product = p.id');
$qb->andWhere(\Query\Operator::equals(['pf.id_user' => $userContext->getActiveId()]));
} else {
$qb->andWhere(\Query\Operator::inIntArray(FavoriteProductsUtil::getCookieProducts(), 'p.id'));
}
});
$result = $productList->getProductsCount();
break;
case 'user_watchdog':
$user = User::getCurrentUser();
$result = sqlQueryBuilder()
->select('COUNT(*) as watchdog')
->from('products_watchdog', 'pw')
->where(\Query\Operator::equals(['id_user' => $user->id]))
->execute()->fetchColumn();
break;
case 'user_shopping_list':
$user = User::getCurrentUser();
$result = sqlQueryBuilder()
->select('COUNT(*) as shopping_list')
->from('shopping_list', 'sl')
->where(\Query\Operator::equals(['id_user' => $user->id]))
->execute()->fetchColumn();
break;
case 'user_reclamations':
$user = User::getCurrentUser();
$result = sqlQueryBuilder()
->select('COUNT(*) as reclamations')
->from('reclamations', 'r')
->join('r', 'order_items', 'oi', 'oi.id=r.id_item')
->join('oi', 'orders', 'o', 'oi.id_order=o.id')
->where(\Query\Operator::equals(['o.id_user' => $user->id]))
->execute()->fetchColumn();
break;
case 'elnino_reclamations':
$user = User::getCurrentUser();
$result = sqlQueryBuilder()
->select('COUNT(*) as reclamations_elnino')
->from('reclamations_elnino', 'r')
->join('r', 'reclamation_items_elnino', 'ri', 'r.id=ri.id_reclamation')
->join('ri', 'order_items', 'oi', 'oi.id=ri.id_item')
->join('oi', 'orders', 'o', 'oi.id_order=o.id')
->where(\Query\Operator::equals(['o.id_user' => $user->id]))
->execute()->fetchColumn();
break;
case 'user_returns':
$user = User::getCurrentUser();
$result = sqlQueryBuilder()
->select('COUNT(*) as returns')
->from('returns', 'r')
->join('r', 'return_items', 'ri', 'r.id = ri.id_return')
->join('ri', 'order_items', 'oi', 'oi.id = ri.id_item')
->join('oi', 'orders', 'o', 'oi.id_order=o.id')
->where(\Query\Operator::equals(['o.id_user' => $user->id]))
->execute()->fetchColumn();
break;
case 'product_compare':
/** @var \Symfony\Component\HttpFoundation\Session\SessionInterface $session */
$session = \KupShop\KupShopBundle\Util\Compat\ServiceContainer::getService('session');
$result = count($session->get('productCompare', []));
break;
case 'delivery_dates':
$country = Contexts::get(CountryContext::class);
$cache_key = "delivery_dates_{$country->getActiveId()}";
$result = getCache($cache_key);
if ($result) {
break;
}
$deliveries = Delivery::getAll();
$dateMinInPerson = null;
$dateMinDelivery = null;
$list = [];
foreach ($deliveries as $id => $delivery) {
$date = $delivery->getDeliveryDate();
if (!$date) {
continue;
}
$list[$id] = [
'name' => $delivery->name,
'delivery_date' => $date,
];
if ($delivery->isInPerson()) {
if (is_null($dateMinInPerson) || $dateMinInPerson > $date) {
$dateMinInPerson = $date;
}
} elseif (is_null($dateMinDelivery) || $dateMinDelivery > $date) {
$dateMinDelivery = $date;
}
}
$result = [
'list' => $list,
'min' => [
'in_person' => $dateMinInPerson,
'delivery' => $dateMinDelivery,
],
];
setCache($cache_key, $result, 600);
break;
case 'max_dimensions':
if (empty($cart)) {
trigger_error('Chybí košík v parametru cart!');
}
$result = $cart->getPurchaseState()->getDeliveryRestrictionParams()->getMaxDimensions();
break;
case 'sum_of_dimensions':
if (empty($cart)) {
trigger_error('Chybí košík v parametru cart!');
}
$result = $cart->getPurchaseState()->getDeliveryRestrictionParams()->getMaxSumOfEachDimension();
break;
case 'cheapest_delivery':
$countryContext = Contexts::get(CountryContext::class);
$contextManager = ServiceContainer::getService(ContextManager::class);
$country = $params['country'] ?? $countryContext->getActiveId();
$result = $contextManager->activateContexts([CountryContext::class => $country], function () use ($params, $country) {
/** @var Cart $cart */
$cart = ServiceContainer::getService(\KupShop\OrderingBundle\Cart::class);
if ($cart->hasOnlyVirtualProducts() && !($params['alllow_only_virtual_products'] ?? false)) {
return null;
}
$cacheName = 'cheapestDelivery_'.$country;
if (!empty($params['key'])) {
$cacheName .= $params['key'];
}
if (User::getCurrentUser() || ($params['registered'] ?? false)) {
$cacheName .= '_reg';
}
if (!isset($params['registered'])) {
$params['registered'] = null;
}
$cache = getCache($cacheName, $found);
if (!$found) {
$cache = null;
$types = DeliveryType::getAll();
$currencyContext = ServiceContainer::getService(CurrencyContext::class);
$defaultCurrency = $currencyContext->getDefault();
$min = null;
$vat = getVat();
$deliveries = [];
foreach ($types as $type) {
if ($type->delivery_class == 'OsobniOdber') {
continue;
}
if ($type->accept(new Price(toDecimal(0), $defaultCurrency, 0), false)) {
if ($type->getDelivery()->getPrice()) {
$price = $type->getDelivery()->getPrice();
$vat = $price->getVat();
$price = PriceCalculator::convert($price, $defaultCurrency);
$deliveries[] = $price->getValue();
}
}
}
if (!empty($deliveries)) {
$min = min($deliveries);
}
if ($min !== null) {
$cache = new Price(toDecimal($min), $defaultCurrency, $vat);
}
setCache($cacheName, $cache);
}
if ($cache != false) {
$result = $cache;
} else {
$result = null;
}
return $result;
});
break;
case 'reviews_count':
$result = 0;
if (findModule(\Modules::REVIEWS)) {
$result = sqlQueryBuilder()
->select('COUNT(*) as reviews_count')
->from('reviews', 'r')
->execute()->fetchColumn();
}
break;
case 'average_rating':
$result = 0;
if (findModule(\Modules::REVIEWS)) {
$result = sqlQueryBuilder()
->select('AVG(r.rating) as average_rating')
->from('reviews', 'r')
->execute()->fetchColumn();
}
break;
default:
trigger_error("Neexistující 'type': {$type}");
}
if (!empty($params['assign'])) {
$smarty->assign($params['assign'], $result);
} else {
return $result;
}
}