From 3b1df045057b9063c2060830dc975a735ad7cca3 Mon Sep 17 00:00:00 2001 From: Audrius Date: Sun, 6 Sep 2026 08:41:34 +0200 Subject: [PATCH] Count the online visitors in SQL instead of in PHP The Online Visitors tile only ever used the NUMBER of rows the query returned: it ran executeS() and then read NumRows(). So every online visitor was carried into PHP with five columns each and thrown away, and the database was asked to sort them by date for an order nothing reads. Both branches now count in SQL. The two joins to page and page_type only produced the page name the hook discards and both join on a primary key, so removing them cannot change the count; connections_page is the one table that can match a connection more than once, which is what the GROUP BY collapsed and COUNT(DISTINCT) still does. Reading the value with getValue() also replaces a pair of Db::getInstance() lookups that asked two different instances for the query and for its row count. --- dashactivity.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/dashactivity.php b/dashactivity.php index 9e725fc..60fe45c 100755 --- a/dashactivity.php +++ b/dashactivity.php @@ -159,32 +159,32 @@ static function ($item) { ) ); } + // WHY: only the NUMBER of visitors is used, so the counting belongs in SQL. Selecting the + // rows and calling NumRows() carried every online visitor into PHP and made the database + // sort them for an order nothing reads. The two `page` joins existed only to produce the + // page name this hook discards, and both join on a primary key, so removing them cannot + // change the count; `connections_page` is the one table that can match a connection more + // than once, which is exactly what the GROUP BY collapsed and COUNT(DISTINCT) still does. if (Configuration::get('PS_STATSDATA_CUSTOMER_PAGESVIEWS')) { - $sql = 'SELECT c.id_guest, c.ip_address, c.date_add, c.http_referer, pt.name as page + $sql = 'SELECT COUNT(DISTINCT c.id_connections) FROM `' . _DB_PREFIX_ . 'connections` c LEFT JOIN `' . _DB_PREFIX_ . 'connections_page` cp ON c.id_connections = cp.id_connections - LEFT JOIN `' . _DB_PREFIX_ . 'page` p ON p.id_page = cp.id_page - LEFT JOIN `' . _DB_PREFIX_ . 'page_type` pt ON p.id_page_type = pt.id_page_type INNER JOIN `' . _DB_PREFIX_ . 'guest` g ON c.id_guest = g.id_guest WHERE (g.id_customer IS NULL OR g.id_customer = 0) ' . Shop::addSqlRestriction(false, 'c') . ' AND cp.`time_end` IS NULL AND (\'' . pSQL(date('Y-m-d H:i:00', time() - 60 * (int) Configuration::get('DASHACTIVITY_VISITOR_ONLINE'))) . '\' < cp.`time_start`) - ' . ($maintenance_ips ? 'AND c.ip_address NOT IN (' . preg_replace('/[^,0-9]/', '', $maintenance_ips) . ')' : '') . ' - GROUP BY c.id_connections - ORDER BY c.date_add DESC'; + ' . ($maintenance_ips ? 'AND c.ip_address NOT IN (' . preg_replace('/[^,0-9]/', '', $maintenance_ips) . ')' : '') . ''; } else { - $sql = 'SELECT c.id_guest, c.ip_address, c.date_add, c.http_referer, "-" as page + $sql = 'SELECT COUNT(*) FROM `' . _DB_PREFIX_ . 'connections` c INNER JOIN `' . _DB_PREFIX_ . 'guest` g ON c.id_guest = g.id_guest WHERE (g.id_customer IS NULL OR g.id_customer = 0) ' . Shop::addSqlRestriction(false, 'c') . ' AND (\'' . pSQL(date('Y-m-d H:i:00', time() - 60 * (int) Configuration::get('DASHACTIVITY_VISITOR_ONLINE'))) . '\' < c.`date_add`) - ' . ($maintenance_ips ? 'AND c.ip_address NOT IN (' . preg_replace('/[^,0-9]/', '', $maintenance_ips) . ')' : '') . ' - ORDER BY c.date_add DESC'; + ' . ($maintenance_ips ? 'AND c.ip_address NOT IN (' . preg_replace('/[^,0-9]/', '', $maintenance_ips) . ')' : '') . ''; } - Db::getInstance((bool) _PS_USE_SQL_SLAVE_)->executeS($sql); - $online_visitor = Db::getInstance()->NumRows(); + $online_visitor = (int) Db::getInstance((bool) _PS_USE_SQL_SLAVE_)->getValue($sql); $pending_orders = Db::getInstance((bool) _PS_USE_SQL_SLAVE_)->getValue(' SELECT COUNT(*)