- Banners frontend: front\Views\Banners (new), BannerRepository +2 frontend methods, front\view\Site przepięty, usunięte front\factory\Banners i front\view\Banners - Cache cleanup: eliminacja legacy class.Cache.php (file-based cache), 13 metod front\factory przepiętych z \Cache::fetch/store na CacheHandler - Shared\Cache namespace: CacheHandler i RedisConnection przeniesione do Shared\Cache\, 60 odwołań CacheHandler i 12 odwołań RedisConnection przepiętych, usunięte backward-compat wrappery class.CacheHandler.php i class.RedisConnection.php - Naprawione rozbieżności kluczy cache (random_products, category_name) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
154 lines
4.7 KiB
PHP
154 lines
4.7 KiB
PHP
<?php
|
|
namespace Domain\Dashboard;
|
|
|
|
class DashboardRepository
|
|
{
|
|
private $db;
|
|
|
|
public function __construct( $db )
|
|
{
|
|
$this->db = $db;
|
|
}
|
|
|
|
public function summaryOrders(): int
|
|
{
|
|
try {
|
|
$redis = \Shared\Cache\RedisConnection::getInstance()->getConnection();
|
|
if ( $redis ) {
|
|
$cached = $redis->get( 'summary_ordersd' );
|
|
if ( $cached !== false ) {
|
|
return (int) unserialize( $cached );
|
|
}
|
|
$summary = (int) $this->db->count( 'pp_shop_orders', [ 'status' => 6 ] );
|
|
$redis->setex( 'summary_ordersd', 300, serialize( $summary ) );
|
|
return $summary;
|
|
}
|
|
} catch ( \RedisException $e ) {
|
|
// fallback
|
|
}
|
|
|
|
return (int) $this->db->count( 'pp_shop_orders', [ 'status' => 6 ] );
|
|
}
|
|
|
|
public function summarySales(): float
|
|
{
|
|
try {
|
|
$redis = \Shared\Cache\RedisConnection::getInstance()->getConnection();
|
|
if ( $redis ) {
|
|
$cached = $redis->get( 'summary_salesd' );
|
|
if ( $cached !== false ) {
|
|
return (float) unserialize( $cached );
|
|
}
|
|
$summary = $this->calculateTotalSales();
|
|
$redis->setex( 'summary_salesd', 300, serialize( $summary ) );
|
|
return $summary;
|
|
}
|
|
} catch ( \RedisException $e ) {
|
|
// fallback
|
|
}
|
|
|
|
return $this->calculateTotalSales();
|
|
}
|
|
|
|
private function calculateTotalSales(): float
|
|
{
|
|
return (float) $this->db->sum( 'pp_shop_orders', 'summary', [ 'status' => 6 ] )
|
|
- (float) $this->db->sum( 'pp_shop_orders', 'transport_cost', [ 'status' => 6 ] );
|
|
}
|
|
|
|
public function salesGrid(): array
|
|
{
|
|
$grid = [];
|
|
$rows = $this->db->select( 'pp_shop_orders', [ 'id', 'date_order' ], [ 'status' => 6 ] );
|
|
|
|
if ( is_array( $rows ) ) {
|
|
foreach ( $rows as $row ) {
|
|
$ts = strtotime( $row['date_order'] );
|
|
$dayOfWeek = date( 'N', $ts );
|
|
$hour = date( 'G', $ts );
|
|
if ( !isset( $grid[$dayOfWeek][$hour] ) ) {
|
|
$grid[$dayOfWeek][$hour] = 0;
|
|
}
|
|
$grid[$dayOfWeek][$hour]++;
|
|
}
|
|
}
|
|
|
|
return $grid;
|
|
}
|
|
|
|
public function mostViewedProducts(): array
|
|
{
|
|
$stmt = $this->db->query(
|
|
'SELECT id, SUM(visits) AS visits '
|
|
. 'FROM pp_shop_products '
|
|
. 'GROUP BY id '
|
|
. 'ORDER BY visits DESC '
|
|
. 'LIMIT 10'
|
|
);
|
|
|
|
return $stmt ? $stmt->fetchAll( \PDO::FETCH_ASSOC ) : [];
|
|
}
|
|
|
|
public function bestSalesProducts(): array
|
|
{
|
|
$stmt = $this->db->query(
|
|
'SELECT parent_product_id, SUM(quantity) AS quantity_summary, SUM(price_brutto_promo * quantity) AS sales '
|
|
. 'FROM pp_shop_order_products AS psop '
|
|
. 'INNER JOIN pp_shop_orders AS pso ON pso.id = psop.order_id '
|
|
. 'WHERE pso.status = 6 '
|
|
. 'GROUP BY parent_product_id '
|
|
. 'ORDER BY sales DESC '
|
|
. 'LIMIT 10'
|
|
);
|
|
|
|
return $stmt ? $stmt->fetchAll( \PDO::FETCH_ASSOC ) : [];
|
|
}
|
|
|
|
public function last24MonthsSales(): array
|
|
{
|
|
$sales = [];
|
|
$date = new \DateTime();
|
|
|
|
for ( $i = 0; $i < 24; $i++ ) {
|
|
$dateStart = $date->format( 'Y-m-01' );
|
|
$dateEnd = $date->format( 'Y-m-t' );
|
|
|
|
$where = [
|
|
'AND' => [
|
|
'status' => 6,
|
|
'date_order[>=]' => $dateStart,
|
|
'date_order[<=]' => $dateEnd,
|
|
]
|
|
];
|
|
|
|
$monthSales = (float) $this->db->sum( 'pp_shop_orders', 'summary', $where )
|
|
- (float) $this->db->sum( 'pp_shop_orders', 'transport_cost', $where );
|
|
|
|
$sales[] = [
|
|
'date' => $date->format( 'Y-m' ),
|
|
'sales' => $monthSales,
|
|
];
|
|
|
|
$date->sub( new \DateInterval( 'P1M' ) );
|
|
}
|
|
|
|
return $sales;
|
|
}
|
|
|
|
public function lastOrders( int $limit = 10 ): array
|
|
{
|
|
$stmt = $this->db->query(
|
|
'SELECT id, number, date_order, '
|
|
. 'CONCAT( client_name, \' \', client_surname ) AS client, '
|
|
. 'client_email, '
|
|
. 'CONCAT( client_street, \', \', client_postal_code, \' \', client_city ) AS address, '
|
|
. 'status, client_phone, summary '
|
|
. 'FROM pp_shop_orders '
|
|
. 'ORDER BY date_order DESC '
|
|
. 'LIMIT ' . (int) $limit
|
|
);
|
|
|
|
return $stmt ? $stmt->fetchAll( \PDO::FETCH_ASSOC ) : [];
|
|
}
|
|
}
|