Add .gitignore and .htaccess for security
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
14
.gitignore
vendored
Normal file
14
.gitignore
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# IDE
|
||||
.idea/
|
||||
.vscode/
|
||||
*.sublime-*
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Node (if any build tools)
|
||||
node_modules/
|
||||
|
||||
# Composer dev dependencies (if installed locally)
|
||||
vendor/
|
||||
10
.htaccess
Normal file
10
.htaccess
Normal file
@@ -0,0 +1,10 @@
|
||||
# Apache 2.2
|
||||
<IfModule !mod_authz_core.c>
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
</IfModule>
|
||||
|
||||
# Apache 2.4
|
||||
<IfModule mod_authz_core.c>
|
||||
Require all denied
|
||||
</IfModule>
|
||||
27
composer.json
Normal file
27
composer.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "myprestarocks/prestashop-session",
|
||||
"description": "Shared session tracking for PrestaShop modules - bot detection, browser/device/OS detection, session hash generation, shared mpr_sessions table",
|
||||
"keywords": ["prestashop", "session", "tracking", "bot-detection", "analytics"],
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "mypresta.rocks",
|
||||
"email": "info@mypresta.rocks"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"MyPrestaRocks\\Session\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"minimum-stability": "stable"
|
||||
}
|
||||
262
src/CartActionsTable.php
Normal file
262
src/CartActionsTable.php
Normal file
@@ -0,0 +1,262 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Cart Actions Table - Cart action tracking
|
||||
*
|
||||
* Handles installation and management of the mpr_cart_actions table.
|
||||
* Tracks add/remove/update/voucher actions for cart analysis.
|
||||
*
|
||||
* Usage:
|
||||
* use MyPrestaRocks\Session\CartActionsTable;
|
||||
*
|
||||
* // In module install():
|
||||
* CartActionsTable::install();
|
||||
*
|
||||
* // In module uninstall():
|
||||
* CartActionsTable::uninstall('yourmodulename');
|
||||
*
|
||||
* @author mypresta.rocks <info@mypresta.rocks>
|
||||
* @copyright Copyright (c) mypresta.rocks
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace MyPrestaRocks\Session;
|
||||
|
||||
if (!defined('_PS_VERSION_')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class CartActionsTable
|
||||
{
|
||||
/**
|
||||
* Table name without prefix
|
||||
*/
|
||||
private const TABLE_NAME = 'mpr_cart_actions';
|
||||
|
||||
/**
|
||||
* Get full table name with prefix
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getTableName()
|
||||
{
|
||||
return _DB_PREFIX_ . self::TABLE_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the table exists
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function tableExists()
|
||||
{
|
||||
$sql = "SHOW TABLES LIKE '" . self::getTableName() . "'";
|
||||
return (bool) \Db::getInstance()->getValue($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Install the cart actions table
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function install()
|
||||
{
|
||||
$engine = _MYSQL_ENGINE_;
|
||||
$charset = 'utf8mb4';
|
||||
$table = self::getTableName();
|
||||
|
||||
$sql = "CREATE TABLE IF NOT EXISTS `{$table}` (
|
||||
`id_cart_action` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`id_session` INT(10) UNSIGNED NOT NULL,
|
||||
`id_cart` INT(10) UNSIGNED NOT NULL,
|
||||
`id_product` INT(10) UNSIGNED NOT NULL,
|
||||
`id_product_attribute` INT(10) UNSIGNED DEFAULT 0,
|
||||
`action_type` ENUM('add', 'remove', 'update', 'voucher_add', 'voucher_remove') NOT NULL,
|
||||
`quantity` INT(10) UNSIGNED NOT NULL DEFAULT 1,
|
||||
`quantity_before` INT(10) UNSIGNED DEFAULT NULL,
|
||||
`product_name` VARCHAR(255) DEFAULT NULL,
|
||||
`product_price` DECIMAL(20,6) DEFAULT NULL,
|
||||
`date_add` DATETIME NOT NULL,
|
||||
PRIMARY KEY (`id_cart_action`),
|
||||
KEY `idx_session` (`id_session`),
|
||||
KEY `idx_cart` (`id_cart`),
|
||||
KEY `idx_product` (`id_product`),
|
||||
KEY `idx_action_type` (`action_type`),
|
||||
KEY `idx_date_add` (`date_add`),
|
||||
KEY `idx_session_date` (`id_session`, `date_add`)
|
||||
) ENGINE={$engine} DEFAULT CHARSET={$charset};";
|
||||
|
||||
return \Db::getInstance()->execute($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall the cart actions table
|
||||
*
|
||||
* @param string $currentModule The module being uninstalled
|
||||
* @return bool
|
||||
*/
|
||||
public static function uninstall($currentModule)
|
||||
{
|
||||
foreach (SessionTable::getModulesUsingSession() as $moduleName) {
|
||||
if ($moduleName === $currentModule) {
|
||||
continue;
|
||||
}
|
||||
if (\Module::isInstalled($moduleName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return \Db::getInstance()->execute("DROP TABLE IF EXISTS `" . self::getTableName() . "`");
|
||||
}
|
||||
|
||||
/**
|
||||
* Track a cart action
|
||||
*
|
||||
* @param int $idSession Session ID
|
||||
* @param int $idCart Cart ID
|
||||
* @param int $idProduct Product ID
|
||||
* @param int $idProductAttribute Product attribute ID (0 if none)
|
||||
* @param string $actionType 'add', 'remove', 'update', 'voucher_add', or 'voucher_remove'
|
||||
* @param int $quantity Current/new quantity
|
||||
* @param int|null $quantityBefore Previous quantity (for update actions)
|
||||
* @param string|null $productName Product name or voucher name
|
||||
* @param float|null $productPrice Product price or voucher value
|
||||
* @return bool
|
||||
*/
|
||||
public static function trackCartAction(
|
||||
$idSession,
|
||||
$idCart,
|
||||
$idProduct,
|
||||
$idProductAttribute,
|
||||
$actionType,
|
||||
$quantity,
|
||||
$quantityBefore = null,
|
||||
$productName = null,
|
||||
$productPrice = null
|
||||
) {
|
||||
if (!$idSession || !$idCart) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$validActions = ['add', 'remove', 'update', 'voucher_add', 'voucher_remove'];
|
||||
if (!in_array($actionType, $validActions)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$isVoucherAction = strpos($actionType, 'voucher_') === 0;
|
||||
if (!$isVoucherAction && !$idProduct) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Look up product name if not provided (only for product actions)
|
||||
if ($productName === null && !$isVoucherAction && $idProduct) {
|
||||
$idLang = (int) \Context::getContext()->language->id;
|
||||
$productName = \Db::getInstance()->getValue(
|
||||
'SELECT name FROM ' . _DB_PREFIX_ . 'product_lang
|
||||
WHERE id_product = ' . (int) $idProduct . '
|
||||
AND id_lang = ' . $idLang
|
||||
);
|
||||
}
|
||||
|
||||
// Look up price if not provided
|
||||
if ($productPrice === null && $idProduct) {
|
||||
$productPrice = \Product::getPriceStatic(
|
||||
(int) $idProduct,
|
||||
true,
|
||||
(int) $idProductAttribute ?: null,
|
||||
6
|
||||
);
|
||||
}
|
||||
|
||||
$table = self::getTableName();
|
||||
|
||||
$sql = "INSERT INTO `{$table}`
|
||||
(id_session, id_cart, id_product, id_product_attribute, action_type,
|
||||
quantity, quantity_before, product_name, product_price, date_add)
|
||||
VALUES (
|
||||
" . (int) $idSession . ",
|
||||
" . (int) $idCart . ",
|
||||
" . (int) $idProduct . ",
|
||||
" . (int) $idProductAttribute . ",
|
||||
'" . pSQL($actionType) . "',
|
||||
" . (int) $quantity . ",
|
||||
" . ($quantityBefore !== null ? (int) $quantityBefore : 'NULL') . ",
|
||||
" . ($productName ? "'" . pSQL(substr($productName, 0, 255)) . "'" : 'NULL') . ",
|
||||
" . ($productPrice !== null ? (float) $productPrice : 'NULL') . ",
|
||||
NOW()
|
||||
)";
|
||||
|
||||
return \Db::getInstance()->execute($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cart actions for a session
|
||||
*
|
||||
* @param int $idSession Session ID
|
||||
* @param int $limit Max records
|
||||
* @return array
|
||||
*/
|
||||
public static function getCartActionsForSession($idSession, $limit = 100)
|
||||
{
|
||||
$table = self::getTableName();
|
||||
|
||||
return \Db::getInstance()->executeS(
|
||||
"SELECT * FROM `{$table}`
|
||||
WHERE id_session = " . (int) $idSession . "
|
||||
ORDER BY date_add ASC
|
||||
LIMIT " . (int) $limit
|
||||
) ?: [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cart actions for multiple sessions (batch lookup)
|
||||
*
|
||||
* @param array $sessionIds Array of session IDs
|
||||
* @param int $limit Max records per session
|
||||
* @return array Grouped by session ID
|
||||
*/
|
||||
public static function getCartActionsForSessions(array $sessionIds, $limit = 100)
|
||||
{
|
||||
if (empty($sessionIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$table = self::getTableName();
|
||||
$ids = array_map('intval', $sessionIds);
|
||||
|
||||
$actions = \Db::getInstance()->executeS(
|
||||
"SELECT * FROM `{$table}`
|
||||
WHERE id_session IN (" . implode(',', $ids) . ")
|
||||
ORDER BY id_session, date_add ASC"
|
||||
) ?: [];
|
||||
|
||||
$grouped = [];
|
||||
foreach ($actions as $action) {
|
||||
$sessId = $action['id_session'];
|
||||
if (!isset($grouped[$sessId])) {
|
||||
$grouped[$sessId] = [];
|
||||
}
|
||||
if (count($grouped[$sessId]) < $limit) {
|
||||
$grouped[$sessId][] = $action;
|
||||
}
|
||||
}
|
||||
|
||||
return $grouped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean old cart action records
|
||||
*
|
||||
* @param int $hours Hours to keep
|
||||
* @return bool
|
||||
*/
|
||||
public static function cleanOldCartActions($hours = 168)
|
||||
{
|
||||
$table = self::getTableName();
|
||||
|
||||
return \Db::getInstance()->execute(
|
||||
"DELETE FROM `{$table}`
|
||||
WHERE date_add < DATE_SUB(NOW(), INTERVAL " . (int) $hours . " HOUR)"
|
||||
);
|
||||
}
|
||||
}
|
||||
189
src/PageViewsTable.php
Normal file
189
src/PageViewsTable.php
Normal file
@@ -0,0 +1,189 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Page Views Table - Detailed page view tracking
|
||||
*
|
||||
* Handles installation and management of the mpr_page_views table.
|
||||
* This is an optional table for detailed funnel analysis.
|
||||
*
|
||||
* Usage:
|
||||
* use MyPrestaRocks\Session\PageViewsTable;
|
||||
*
|
||||
* // In module install():
|
||||
* PageViewsTable::install();
|
||||
*
|
||||
* // In module uninstall():
|
||||
* PageViewsTable::uninstall('yourmodulename');
|
||||
*
|
||||
* @author mypresta.rocks <info@mypresta.rocks>
|
||||
* @copyright Copyright (c) mypresta.rocks
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace MyPrestaRocks\Session;
|
||||
|
||||
if (!defined('_PS_VERSION_')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class PageViewsTable
|
||||
{
|
||||
/**
|
||||
* Table name without prefix
|
||||
*/
|
||||
private const TABLE_NAME = 'mpr_page_views';
|
||||
|
||||
/**
|
||||
* Get full table name with prefix
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getTableName()
|
||||
{
|
||||
return _DB_PREFIX_ . self::TABLE_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the table exists
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function tableExists()
|
||||
{
|
||||
$sql = "SHOW TABLES LIKE '" . self::getTableName() . "'";
|
||||
return (bool) \Db::getInstance()->getValue($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Install the page views table
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function install()
|
||||
{
|
||||
$engine = _MYSQL_ENGINE_;
|
||||
$charset = 'utf8mb4';
|
||||
$table = self::getTableName();
|
||||
|
||||
$sql = "CREATE TABLE IF NOT EXISTS `{$table}` (
|
||||
`id_page_view` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`id_session` INT(10) UNSIGNED NOT NULL,
|
||||
`page_type` TINYINT(2) UNSIGNED NOT NULL,
|
||||
`page_id` INT(10) UNSIGNED DEFAULT NULL,
|
||||
`controller` VARCHAR(64) DEFAULT NULL,
|
||||
`date_add` DATETIME NOT NULL,
|
||||
PRIMARY KEY (`id_page_view`),
|
||||
KEY `id_session` (`id_session`),
|
||||
KEY `page_type` (`page_type`),
|
||||
KEY `date_add` (`date_add`),
|
||||
KEY `session_date` (`id_session`, `date_add`)
|
||||
) ENGINE={$engine} DEFAULT CHARSET={$charset};";
|
||||
|
||||
return \Db::getInstance()->execute($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall the page views table
|
||||
*
|
||||
* @param string $currentModule The module being uninstalled
|
||||
* @return bool
|
||||
*/
|
||||
public static function uninstall($currentModule)
|
||||
{
|
||||
foreach (SessionTable::getModulesUsingSession() as $moduleName) {
|
||||
if ($moduleName === $currentModule) {
|
||||
continue;
|
||||
}
|
||||
if (\Module::isInstalled($moduleName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return \Db::getInstance()->execute("DROP TABLE IF EXISTS `" . self::getTableName() . "`");
|
||||
}
|
||||
|
||||
/**
|
||||
* Track detailed page view
|
||||
*
|
||||
* @param int $idSession Session ID
|
||||
* @param int $pageType Page type constant
|
||||
* @param int|null $pageId Page ID
|
||||
* @param string|null $controller Controller name
|
||||
* @return bool
|
||||
*/
|
||||
public static function trackPageView($idSession, $pageType, $pageId = null, $controller = null)
|
||||
{
|
||||
if (!$idSession) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$table = self::getTableName();
|
||||
|
||||
$sql = "INSERT INTO `{$table}` (id_session, page_type, page_id, controller, date_add)
|
||||
VALUES (" . (int) $idSession . ", " . (int) $pageType . ", " .
|
||||
($pageId !== null ? (int) $pageId : 'NULL') . ", " .
|
||||
($controller ? "'" . pSQL(substr($controller, 0, 64)) . "'" : 'NULL') . ", NOW())";
|
||||
|
||||
return \Db::getInstance()->execute($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get page views for a session
|
||||
*
|
||||
* @param int $idSession Session ID
|
||||
* @param int $limit Max records to return
|
||||
* @return array
|
||||
*/
|
||||
public static function getPageViewsForSession($idSession, $limit = 100)
|
||||
{
|
||||
$table = self::getTableName();
|
||||
|
||||
$sql = "SELECT * FROM `{$table}`
|
||||
WHERE id_session = " . (int) $idSession . "
|
||||
ORDER BY date_add ASC
|
||||
LIMIT " . (int) $limit;
|
||||
|
||||
return \Db::getInstance()->executeS($sql) ?: [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get page view statistics for a session
|
||||
*
|
||||
* @param int $idSession Session ID
|
||||
* @return array
|
||||
*/
|
||||
public static function getPageViewStats($idSession)
|
||||
{
|
||||
$table = self::getTableName();
|
||||
|
||||
$sql = "SELECT page_type, COUNT(*) as count
|
||||
FROM `{$table}`
|
||||
WHERE id_session = " . (int) $idSession . "
|
||||
GROUP BY page_type";
|
||||
|
||||
$byType = \Db::getInstance()->executeS($sql) ?: [];
|
||||
|
||||
$stats = ['by_type' => []];
|
||||
foreach ($byType as $row) {
|
||||
$stats['by_type'][$row['page_type']] = (int) $row['count'];
|
||||
}
|
||||
|
||||
return $stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean old page view records
|
||||
*
|
||||
* @param int $hours Hours to keep
|
||||
* @return bool
|
||||
*/
|
||||
public static function cleanOldPageViews($hours = 24)
|
||||
{
|
||||
$table = self::getTableName();
|
||||
|
||||
return \Db::getInstance()->execute(
|
||||
"DELETE FROM `{$table}`
|
||||
WHERE date_add < DATE_SUB(NOW(), INTERVAL " . (int) $hours . " HOUR)"
|
||||
);
|
||||
}
|
||||
}
|
||||
77
src/SessionInstaller.php
Normal file
77
src/SessionInstaller.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Session Installer - Convenience class for installing all session tables
|
||||
*
|
||||
* Provides a single entry point for installing and uninstalling
|
||||
* all shared session tables (mpr_sessions, mpr_page_views, mpr_cart_actions).
|
||||
*
|
||||
* Usage:
|
||||
* use MyPrestaRocks\Session\SessionInstaller;
|
||||
*
|
||||
* // In module install():
|
||||
* SessionInstaller::installAll();
|
||||
*
|
||||
* // In module uninstall():
|
||||
* SessionInstaller::uninstallAll('yourmodulename');
|
||||
*
|
||||
* @author mypresta.rocks <info@mypresta.rocks>
|
||||
* @copyright Copyright (c) mypresta.rocks
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace MyPrestaRocks\Session;
|
||||
|
||||
if (!defined('_PS_VERSION_')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SessionInstaller
|
||||
{
|
||||
/**
|
||||
* Install all shared session tables
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function installAll()
|
||||
{
|
||||
$result = true;
|
||||
$result = $result && SessionTable::install();
|
||||
$result = $result && PageViewsTable::install();
|
||||
$result = $result && CartActionsTable::install();
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall all shared session tables
|
||||
* Only drops tables if no other module using them is installed
|
||||
*
|
||||
* @param string $currentModule The module being uninstalled
|
||||
* @return bool
|
||||
*/
|
||||
public static function uninstallAll($currentModule)
|
||||
{
|
||||
$result = true;
|
||||
$result = $result && CartActionsTable::uninstall($currentModule);
|
||||
$result = $result && PageViewsTable::uninstall($currentModule);
|
||||
$result = $result && SessionTable::uninstall($currentModule);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up old data from all session tables
|
||||
*
|
||||
* @param int $sessionHours Hours to keep sessions (default 24)
|
||||
* @param int $pageViewsHours Hours to keep page views (default 24)
|
||||
* @param int $cartActionsHours Hours to keep cart actions (default 168 / 7 days)
|
||||
* @return bool
|
||||
*/
|
||||
public static function cleanAll($sessionHours = 24, $pageViewsHours = 24, $cartActionsHours = 168)
|
||||
{
|
||||
$result = true;
|
||||
$result = $result && SessionTable::cleanOldSessions($sessionHours);
|
||||
$result = $result && PageViewsTable::cleanOldPageViews($pageViewsHours);
|
||||
$result = $result && CartActionsTable::cleanOldCartActions($cartActionsHours);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
395
src/SessionTable.php
Normal file
395
src/SessionTable.php
Normal file
@@ -0,0 +1,395 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Session Table - Shared mpr_sessions table management
|
||||
*
|
||||
* Handles installation and uninstallation of the shared mpr_sessions table.
|
||||
* Multiple modules can use this table, and it's only dropped when the last
|
||||
* module using it is uninstalled.
|
||||
*
|
||||
* Usage:
|
||||
* use MyPrestaRocks\Session\SessionTable;
|
||||
*
|
||||
* // In module install():
|
||||
* SessionTable::install();
|
||||
*
|
||||
* // In module uninstall():
|
||||
* SessionTable::uninstall('yourmodulename');
|
||||
*
|
||||
* @author mypresta.rocks <info@mypresta.rocks>
|
||||
* @copyright Copyright (c) mypresta.rocks
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace MyPrestaRocks\Session;
|
||||
|
||||
if (!defined('_PS_VERSION_')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class SessionTable
|
||||
{
|
||||
/**
|
||||
* List of modules that use the shared mpr_sessions table.
|
||||
* Add your module name here when integrating.
|
||||
*/
|
||||
private const MODULES_USING_SESSION = [
|
||||
'mprexpresscheckout',
|
||||
'mprtotaldefender',
|
||||
'mprtradeaccount',
|
||||
];
|
||||
|
||||
/**
|
||||
* Table name without prefix
|
||||
*/
|
||||
private const TABLE_NAME = 'mpr_sessions';
|
||||
|
||||
/**
|
||||
* Get full table name with prefix
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getTableName()
|
||||
{
|
||||
return _DB_PREFIX_ . self::TABLE_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the session table exists
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function tableExists()
|
||||
{
|
||||
$sql = "SHOW TABLES LIKE '" . self::getTableName() . "'";
|
||||
return (bool) \Db::getInstance()->getValue($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Install the shared session table
|
||||
* Uses IF NOT EXISTS so any module can safely call this
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function install()
|
||||
{
|
||||
$engine = _MYSQL_ENGINE_;
|
||||
$charset = 'utf8mb4';
|
||||
$table = self::getTableName();
|
||||
|
||||
$sql = "CREATE TABLE IF NOT EXISTS `{$table}` (
|
||||
`id_session` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`id_customer` INT(10) UNSIGNED DEFAULT NULL,
|
||||
`id_guest` INT(10) UNSIGNED NOT NULL,
|
||||
`session_hash` VARCHAR(32) NOT NULL,
|
||||
|
||||
-- Core tracking (all modules)
|
||||
`ip_address` VARCHAR(45) DEFAULT NULL,
|
||||
`user_agent` VARCHAR(512) DEFAULT NULL,
|
||||
`browser` VARCHAR(32) DEFAULT NULL,
|
||||
`device_type` VARCHAR(16) DEFAULT NULL,
|
||||
`os` VARCHAR(32) DEFAULT NULL,
|
||||
`is_bot` TINYINT(1) UNSIGNED NOT NULL DEFAULT 0,
|
||||
|
||||
-- Attribution tracking (mprexpresscheckout)
|
||||
`source_type` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`source_detail` VARCHAR(500) DEFAULT NULL,
|
||||
`utm_source` VARCHAR(128) DEFAULT NULL,
|
||||
`utm_medium` VARCHAR(128) DEFAULT NULL,
|
||||
`utm_campaign` VARCHAR(128) DEFAULT NULL,
|
||||
`utm_term` VARCHAR(255) DEFAULT NULL,
|
||||
`utm_content` VARCHAR(255) DEFAULT NULL,
|
||||
`gclid` VARCHAR(255) DEFAULT NULL,
|
||||
`fbclid` VARCHAR(255) DEFAULT NULL,
|
||||
`msclkid` VARCHAR(255) DEFAULT NULL,
|
||||
`ttclid` VARCHAR(255) DEFAULT NULL,
|
||||
|
||||
-- Landing page tracking (mprexpresscheckout)
|
||||
`landing_page_type` TINYINT(2) UNSIGNED DEFAULT NULL,
|
||||
`landing_page_id` INT(10) UNSIGNED DEFAULT NULL,
|
||||
`landing_url` VARCHAR(500) DEFAULT NULL,
|
||||
|
||||
-- Context
|
||||
`id_lang` INT(10) UNSIGNED DEFAULT NULL,
|
||||
`id_currency` INT(10) UNSIGNED DEFAULT NULL,
|
||||
`is_first_visit` TINYINT(1) UNSIGNED NOT NULL DEFAULT 0,
|
||||
|
||||
-- Page tracking (lightweight counters)
|
||||
`pages_viewed` INT(10) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`last_page_type` TINYINT(2) UNSIGNED DEFAULT NULL,
|
||||
`last_page_id` INT(10) UNSIGNED DEFAULT NULL,
|
||||
|
||||
-- Timestamps
|
||||
`date_add` DATETIME NOT NULL,
|
||||
`date_last_activity` DATETIME NOT NULL,
|
||||
|
||||
PRIMARY KEY (`id_session`),
|
||||
UNIQUE KEY `session_hash` (`session_hash`),
|
||||
KEY `id_customer` (`id_customer`),
|
||||
KEY `id_guest` (`id_guest`),
|
||||
KEY `ip_address` (`ip_address`),
|
||||
KEY `source_type` (`source_type`),
|
||||
KEY `is_bot` (`is_bot`),
|
||||
KEY `date_add` (`date_add`),
|
||||
KEY `date_last_activity` (`date_last_activity`),
|
||||
KEY `customer_sessions` (`id_customer`, `date_add`),
|
||||
KEY `guest_sessions` (`id_guest`, `date_add`)
|
||||
) ENGINE={$engine} DEFAULT CHARSET={$charset};";
|
||||
|
||||
return \Db::getInstance()->execute($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall the shared session table
|
||||
* Only drops the table if no other module using it is still installed
|
||||
*
|
||||
* @param string $currentModule The module being uninstalled
|
||||
* @return bool
|
||||
*/
|
||||
public static function uninstall($currentModule)
|
||||
{
|
||||
// Check if any other module using sessions is still installed
|
||||
foreach (self::MODULES_USING_SESSION as $moduleName) {
|
||||
if ($moduleName === $currentModule) {
|
||||
continue;
|
||||
}
|
||||
if (\Module::isInstalled($moduleName)) {
|
||||
// Another module still needs the table
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// No other module needs it - drop the table
|
||||
return \Db::getInstance()->execute("DROP TABLE IF EXISTS `" . self::getTableName() . "`");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of modules that use the session table
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getModulesUsingSession()
|
||||
{
|
||||
return self::MODULES_USING_SESSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if another module using the session table is installed
|
||||
*
|
||||
* @param string $excludeModule Module to exclude from check
|
||||
* @return bool
|
||||
*/
|
||||
public static function isAnotherModuleInstalled($excludeModule)
|
||||
{
|
||||
foreach (self::MODULES_USING_SESSION as $moduleName) {
|
||||
if ($moduleName === $excludeModule) {
|
||||
continue;
|
||||
}
|
||||
if (\Module::isInstalled($moduleName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update session last activity (with 1-minute throttling)
|
||||
*
|
||||
* @param int $idSession Session ID
|
||||
* @return bool
|
||||
*/
|
||||
public static function updateSessionActivity($idSession)
|
||||
{
|
||||
$table = self::getTableName();
|
||||
|
||||
// Check if recently updated (within 1 minute)
|
||||
$sql = "SELECT 1 FROM `{$table}`
|
||||
WHERE id_session = " . (int) $idSession . "
|
||||
AND date_last_activity > DATE_SUB(NOW(), INTERVAL 1 MINUTE)";
|
||||
|
||||
if (\Db::getInstance()->getValue($sql)) {
|
||||
return true; // Skip update - already recent
|
||||
}
|
||||
|
||||
return \Db::getInstance()->execute(
|
||||
"UPDATE `{$table}`
|
||||
SET date_last_activity = NOW()
|
||||
WHERE id_session = " . (int) $idSession
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get active session by hash
|
||||
*
|
||||
* @param string $sessionHash
|
||||
* @param int $timeoutMinutes
|
||||
* @return int|null Session ID or null
|
||||
*/
|
||||
public static function getActiveSessionId($sessionHash, $timeoutMinutes = 60)
|
||||
{
|
||||
$table = self::getTableName();
|
||||
|
||||
$sql = "SELECT id_session FROM `{$table}`
|
||||
WHERE session_hash = '" . pSQL($sessionHash) . "'
|
||||
AND date_last_activity > DATE_SUB(NOW(), INTERVAL " . (int) $timeoutMinutes . " MINUTE)";
|
||||
|
||||
$result = \Db::getInstance()->getValue($sql);
|
||||
return $result ? (int) $result : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Link guest sessions to customer (on login/registration)
|
||||
*
|
||||
* @param int $idGuest
|
||||
* @param int $idCustomer
|
||||
* @return bool
|
||||
*/
|
||||
public static function linkGuestToCustomer($idGuest, $idCustomer)
|
||||
{
|
||||
if (!$idGuest || !$idCustomer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return \Db::getInstance()->update(
|
||||
self::TABLE_NAME,
|
||||
['id_customer' => (int) $idCustomer],
|
||||
'id_guest = ' . (int) $idGuest . ' AND id_customer IS NULL'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean old sessions
|
||||
*
|
||||
* @param int $hours Hours to keep (default 24)
|
||||
* @return bool
|
||||
*/
|
||||
public static function cleanOldSessions($hours = 24)
|
||||
{
|
||||
$table = self::getTableName();
|
||||
|
||||
return \Db::getInstance()->execute(
|
||||
"DELETE FROM `{$table}`
|
||||
WHERE date_last_activity < DATE_SUB(NOW(), INTERVAL " . (int) $hours . " HOUR)"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get active session count
|
||||
*
|
||||
* @param int $timeoutMinutes
|
||||
* @param bool $excludeBots
|
||||
* @return int
|
||||
*/
|
||||
public static function getActiveSessionCount($timeoutMinutes = 60, $excludeBots = true)
|
||||
{
|
||||
$table = self::getTableName();
|
||||
|
||||
$sql = "SELECT COUNT(*) FROM `{$table}`
|
||||
WHERE date_last_activity > DATE_SUB(NOW(), INTERVAL " . (int) $timeoutMinutes . " MINUTE)";
|
||||
|
||||
if ($excludeBots) {
|
||||
$sql .= " AND is_bot = 0";
|
||||
}
|
||||
|
||||
return (int) \Db::getInstance()->getValue($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sessions for an IP address
|
||||
*
|
||||
* @param string $ipAddress
|
||||
* @param int $hours Time window (0 for all)
|
||||
* @return array
|
||||
*/
|
||||
public static function getSessionsForIP($ipAddress, $hours = 24)
|
||||
{
|
||||
$table = self::getTableName();
|
||||
|
||||
$sql = "SELECT * FROM `{$table}` WHERE ip_address = '" . pSQL($ipAddress) . "'";
|
||||
|
||||
if ($hours > 0) {
|
||||
$sql .= " AND date_add >= DATE_SUB(NOW(), INTERVAL " . (int) $hours . " HOUR)";
|
||||
}
|
||||
|
||||
$sql .= " ORDER BY date_add DESC";
|
||||
|
||||
return \Db::getInstance()->executeS($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count sessions for an IP address
|
||||
*
|
||||
* @param string $ipAddress
|
||||
* @param int $hours Time window
|
||||
* @param bool $excludeBots Exclude bot sessions
|
||||
* @return int
|
||||
*/
|
||||
public static function countSessionsForIP($ipAddress, $hours = 24, $excludeBots = true)
|
||||
{
|
||||
$table = self::getTableName();
|
||||
|
||||
$sql = "SELECT COUNT(*) FROM `{$table}` WHERE ip_address = '" . pSQL($ipAddress) . "'";
|
||||
|
||||
if ($excludeBots) {
|
||||
$sql .= " AND is_bot = 0";
|
||||
}
|
||||
|
||||
if ($hours > 0) {
|
||||
$sql .= " AND date_add >= DATE_SUB(NOW(), INTERVAL " . (int) $hours . " HOUR)";
|
||||
}
|
||||
|
||||
return (int) \Db::getInstance()->getValue($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Track page view for a session (lightweight - just increment counter)
|
||||
*
|
||||
* @param int $idSession Session ID
|
||||
* @param int|null $pageType Page type constant
|
||||
* @param int|null $pageId Page ID (product, category, etc.)
|
||||
* @return bool
|
||||
*/
|
||||
public static function trackPageView($idSession, $pageType = null, $pageId = null)
|
||||
{
|
||||
if (!$idSession) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$table = self::getTableName();
|
||||
|
||||
$sql = "UPDATE `{$table}` SET
|
||||
pages_viewed = pages_viewed + 1,
|
||||
last_page_type = " . ($pageType !== null ? (int) $pageType : 'NULL') . ",
|
||||
last_page_id = " . ($pageId !== null ? (int) $pageId : 'NULL') . ",
|
||||
date_last_activity = NOW()
|
||||
WHERE id_session = " . (int) $idSession;
|
||||
|
||||
return \Db::getInstance()->execute($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Track page view by session hash (optimized - single query when session exists)
|
||||
*
|
||||
* @param string $sessionHash Session hash
|
||||
* @param int|null $pageType Page type constant
|
||||
* @param int|null $pageId Page ID
|
||||
* @param int $timeoutMinutes Session timeout
|
||||
* @return bool True if page was tracked, false if session not found
|
||||
*/
|
||||
public static function trackPageViewByHash($sessionHash, $pageType = null, $pageId = null, $timeoutMinutes = 60)
|
||||
{
|
||||
$table = self::getTableName();
|
||||
|
||||
$sql = "UPDATE `{$table}` SET
|
||||
pages_viewed = pages_viewed + 1,
|
||||
last_page_type = " . ($pageType !== null ? (int) $pageType : 'NULL') . ",
|
||||
last_page_id = " . ($pageId !== null ? (int) $pageId : 'NULL') . ",
|
||||
date_last_activity = NOW()
|
||||
WHERE session_hash = '" . pSQL($sessionHash) . "'
|
||||
AND date_last_activity > DATE_SUB(NOW(), INTERVAL " . (int) $timeoutMinutes . " MINUTE)";
|
||||
|
||||
\Db::getInstance()->execute($sql);
|
||||
|
||||
return \Db::getInstance()->Affected_Rows() > 0;
|
||||
}
|
||||
}
|
||||
364
src/SessionTrait.php
Normal file
364
src/SessionTrait.php
Normal file
@@ -0,0 +1,364 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Session Trait - Shared session detection and tracking for PrestaShop modules
|
||||
*
|
||||
* Provides common session functionality used by multiple MPR modules:
|
||||
* - Bot detection
|
||||
* - Browser detection
|
||||
* - Device type detection
|
||||
* - OS detection
|
||||
* - Session hash generation
|
||||
* - IP address handling
|
||||
* - User agent handling
|
||||
*
|
||||
* Usage:
|
||||
* use MyPrestaRocks\Session\SessionTrait;
|
||||
*
|
||||
* class YourSessionClass extends ObjectModel {
|
||||
* use SessionTrait;
|
||||
* }
|
||||
*
|
||||
* @author mypresta.rocks <info@mypresta.rocks>
|
||||
* @copyright Copyright (c) mypresta.rocks
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace MyPrestaRocks\Session;
|
||||
|
||||
if (!defined('_PS_VERSION_')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
trait SessionTrait
|
||||
{
|
||||
/**
|
||||
* Page type values for last_page_type column
|
||||
* Note: Using static array instead of constants for PHP 7.4 compatibility
|
||||
* (traits cannot have constants in PHP < 8.2)
|
||||
*/
|
||||
protected static $PAGE_TYPES = [
|
||||
'HOME' => 1,
|
||||
'CATEGORY' => 2,
|
||||
'PRODUCT' => 3,
|
||||
'CMS' => 4,
|
||||
'CART' => 5,
|
||||
'CHECKOUT' => 6,
|
||||
'ORDER_CONFIRMATION' => 7,
|
||||
'MY_ACCOUNT' => 8,
|
||||
'SEARCH' => 9,
|
||||
'MANUFACTURER' => 10,
|
||||
'SUPPLIER' => 11,
|
||||
'CONTACT' => 12,
|
||||
'OTHER' => 99,
|
||||
];
|
||||
|
||||
/**
|
||||
* Detect if request is from a bot
|
||||
*
|
||||
* @param string|null $userAgent Optional user agent (uses $_SERVER if not provided)
|
||||
* @return bool
|
||||
*/
|
||||
protected static function mprIsBot($userAgent = null)
|
||||
{
|
||||
if ($userAgent === null) {
|
||||
if (!isset($_SERVER['HTTP_USER_AGENT'])) {
|
||||
return true;
|
||||
}
|
||||
$userAgent = $_SERVER['HTTP_USER_AGENT'];
|
||||
}
|
||||
|
||||
$userAgent = strtolower($userAgent);
|
||||
|
||||
$botPatterns = [
|
||||
// Search engine crawlers
|
||||
'googlebot', 'bingbot', 'slurp', 'duckduckbot', 'baiduspider',
|
||||
'yandexbot', 'sogou', 'exabot',
|
||||
// Social media bots
|
||||
'facebot', 'facebookexternalhit', 'twitterbot', 'linkedinbot',
|
||||
'whatsapp', 'telegrambot', 'slackbot', 'discordbot', 'pinterestbot',
|
||||
// SEO tools
|
||||
'applebot', 'semrushbot', 'ahrefsbot', 'mj12bot', 'dotbot',
|
||||
'rogerbot', 'petalbot', 'screaming frog',
|
||||
// Archive bots
|
||||
'ia_archiver', 'archive.org_bot',
|
||||
// Generic patterns
|
||||
'crawler', 'spider', 'bot.htm', 'bot.php', 'crawl',
|
||||
// HTTP clients
|
||||
'wget', 'curl', 'python-requests', 'python/', 'scrapy',
|
||||
'php/', 'java/', 'go-http-client', 'httpclient', 'apache-httpclient',
|
||||
'libwww', 'lwp-', 'mechanize',
|
||||
// Headless browsers
|
||||
'headlesschrome', 'phantomjs', 'selenium', 'webdriver', 'puppeteer',
|
||||
// API testing tools
|
||||
'postman', 'insomnia',
|
||||
// Monitoring
|
||||
'pingdom', 'uptimerobot', 'monitoring', 'check_http',
|
||||
// Generic http pattern (often bots)
|
||||
'http',
|
||||
'httrack',
|
||||
'mediapartners',
|
||||
];
|
||||
|
||||
foreach ($botPatterns as $pattern) {
|
||||
if (strpos($userAgent, $pattern) !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect browser from user agent
|
||||
*
|
||||
* @param string|null $userAgent Optional user agent
|
||||
* @return string Browser name (chrome, firefox, safari, edge, opera, ie, other)
|
||||
*/
|
||||
protected static function mprDetectBrowser($userAgent = null)
|
||||
{
|
||||
if ($userAgent === null) {
|
||||
if (!isset($_SERVER['HTTP_USER_AGENT'])) {
|
||||
return 'other';
|
||||
}
|
||||
$userAgent = $_SERVER['HTTP_USER_AGENT'];
|
||||
}
|
||||
|
||||
// Edge must be checked before Chrome (Edge contains "Chrome" in UA)
|
||||
if (strpos($userAgent, 'Edg') !== false || strpos($userAgent, 'Edge') !== false) {
|
||||
return 'edge';
|
||||
}
|
||||
// Chrome must be checked before Safari (Chrome contains "Safari" in UA)
|
||||
if (strpos($userAgent, 'Chrome') !== false && strpos($userAgent, 'Chromium') === false) {
|
||||
return 'chrome';
|
||||
}
|
||||
if (strpos($userAgent, 'Firefox') !== false) {
|
||||
return 'firefox';
|
||||
}
|
||||
if (strpos($userAgent, 'Safari') !== false && strpos($userAgent, 'Chrome') === false) {
|
||||
return 'safari';
|
||||
}
|
||||
if (strpos($userAgent, 'OPR') !== false || strpos($userAgent, 'Opera') !== false) {
|
||||
return 'opera';
|
||||
}
|
||||
if (strpos($userAgent, 'MSIE') !== false || strpos($userAgent, 'Trident') !== false) {
|
||||
return 'ie';
|
||||
}
|
||||
|
||||
return 'other';
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect device type from user agent
|
||||
*
|
||||
* @param string|null $userAgent Optional user agent
|
||||
* @return string Device type (mobile, tablet, desktop)
|
||||
*/
|
||||
protected static function mprDetectDeviceType($userAgent = null)
|
||||
{
|
||||
if ($userAgent === null) {
|
||||
if (!isset($_SERVER['HTTP_USER_AGENT'])) {
|
||||
return 'desktop';
|
||||
}
|
||||
$userAgent = $_SERVER['HTTP_USER_AGENT'];
|
||||
}
|
||||
|
||||
$userAgentLower = strtolower($userAgent);
|
||||
|
||||
// Check mobile first (phones)
|
||||
if (preg_match('/mobile|android.*mobile|iphone|ipod|phone|blackberry|iemobile|opera mini|opera mobi/i', $userAgentLower)) {
|
||||
return 'mobile';
|
||||
}
|
||||
|
||||
// Check tablet
|
||||
if (preg_match('/tablet|ipad|android(?!.*mobile)|kindle|silk/i', $userAgentLower)) {
|
||||
return 'tablet';
|
||||
}
|
||||
|
||||
return 'desktop';
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect operating system from user agent
|
||||
*
|
||||
* @param string|null $userAgent Optional user agent
|
||||
* @return string OS name (windows, macos, android, ios, linux, other)
|
||||
*/
|
||||
protected static function mprDetectOS($userAgent = null)
|
||||
{
|
||||
if ($userAgent === null) {
|
||||
if (!isset($_SERVER['HTTP_USER_AGENT'])) {
|
||||
return 'other';
|
||||
}
|
||||
$userAgent = $_SERVER['HTTP_USER_AGENT'];
|
||||
}
|
||||
|
||||
if (strpos($userAgent, 'Windows') !== false) {
|
||||
return 'windows';
|
||||
}
|
||||
if (strpos($userAgent, 'Mac OS X') !== false) {
|
||||
return 'macos';
|
||||
}
|
||||
if (strpos($userAgent, 'Android') !== false) {
|
||||
return 'android';
|
||||
}
|
||||
if (strpos($userAgent, 'iPhone') !== false || strpos($userAgent, 'iPad') !== false) {
|
||||
return 'ios';
|
||||
}
|
||||
if (strpos($userAgent, 'Linux') !== false) {
|
||||
return 'linux';
|
||||
}
|
||||
|
||||
return 'other';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate session hash
|
||||
*
|
||||
* @param int $idGuest Guest ID
|
||||
* @param string|null $extra Additional data to include in hash (e.g., campaign params)
|
||||
* @param int $timeBucket Time bucket in seconds (default 30 minutes)
|
||||
* @return string MD5 hash
|
||||
*/
|
||||
protected static function mprGenerateSessionHash($idGuest, $extra = null, $timeBucket = 1800)
|
||||
{
|
||||
$timestamp = floor(time() / $timeBucket);
|
||||
$hashData = $idGuest . '_' . $timestamp;
|
||||
|
||||
if ($extra) {
|
||||
$hashData .= '_' . $extra;
|
||||
}
|
||||
|
||||
return md5($hashData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current IP address
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function mprGetIPAddress()
|
||||
{
|
||||
return \Tools::getRemoteAddr();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current user agent
|
||||
*
|
||||
* @param int $maxLength Maximum length to return
|
||||
* @return string|null
|
||||
*/
|
||||
protected static function mprGetUserAgent($maxLength = 512)
|
||||
{
|
||||
if (!isset($_SERVER['HTTP_USER_AGENT'])) {
|
||||
return null;
|
||||
}
|
||||
return substr($_SERVER['HTTP_USER_AGENT'], 0, $maxLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect current page type from controller
|
||||
*
|
||||
* @return array [page_type, page_id]
|
||||
*/
|
||||
protected static function mprDetectPageType()
|
||||
{
|
||||
$controller = \Tools::getValue('controller', '');
|
||||
|
||||
switch ($controller) {
|
||||
case 'index':
|
||||
return [self::$PAGE_TYPES['HOME'], null];
|
||||
|
||||
case 'category':
|
||||
$pageId = (int) \Tools::getValue('id_category');
|
||||
return [self::$PAGE_TYPES['CATEGORY'], $pageId ?: null];
|
||||
|
||||
case 'product':
|
||||
$pageId = (int) \Tools::getValue('id_product');
|
||||
return [self::$PAGE_TYPES['PRODUCT'], $pageId ?: null];
|
||||
|
||||
case 'cms':
|
||||
$pageId = (int) \Tools::getValue('id_cms');
|
||||
return [self::$PAGE_TYPES['CMS'], $pageId ?: null];
|
||||
|
||||
case 'cart':
|
||||
return [self::$PAGE_TYPES['CART'], null];
|
||||
|
||||
case 'order':
|
||||
case 'orderopc':
|
||||
case 'checkout':
|
||||
case 'mprexpresscheckoutcheckout':
|
||||
return [self::$PAGE_TYPES['CHECKOUT'], null];
|
||||
|
||||
case 'orderconfirmation':
|
||||
case 'order-confirmation':
|
||||
$pageId = (int) \Tools::getValue('id_order');
|
||||
return [self::$PAGE_TYPES['ORDER_CONFIRMATION'], $pageId ?: null];
|
||||
|
||||
case 'my-account':
|
||||
case 'identity':
|
||||
case 'addresses':
|
||||
case 'address':
|
||||
case 'history':
|
||||
case 'order-detail':
|
||||
case 'order-follow':
|
||||
case 'order-slip':
|
||||
return [self::$PAGE_TYPES['MY_ACCOUNT'], null];
|
||||
|
||||
case 'search':
|
||||
return [self::$PAGE_TYPES['SEARCH'], null];
|
||||
|
||||
case 'manufacturer':
|
||||
$pageId = (int) \Tools::getValue('id_manufacturer');
|
||||
return [self::$PAGE_TYPES['MANUFACTURER'], $pageId ?: null];
|
||||
|
||||
case 'supplier':
|
||||
$pageId = (int) \Tools::getValue('id_supplier');
|
||||
return [self::$PAGE_TYPES['SUPPLIER'], $pageId ?: null];
|
||||
|
||||
case 'contact':
|
||||
case 'contact-us':
|
||||
return [self::$PAGE_TYPES['CONTACT'], null];
|
||||
|
||||
default:
|
||||
return [self::$PAGE_TYPES['OTHER'], null];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get page type name for display
|
||||
*
|
||||
* @param int $pageType Page type constant
|
||||
* @return string
|
||||
*/
|
||||
public static function getPageTypeName($pageType)
|
||||
{
|
||||
$names = [
|
||||
self::$PAGE_TYPES['HOME'] => 'Home',
|
||||
self::$PAGE_TYPES['CATEGORY'] => 'Category',
|
||||
self::$PAGE_TYPES['PRODUCT'] => 'Product',
|
||||
self::$PAGE_TYPES['CMS'] => 'CMS',
|
||||
self::$PAGE_TYPES['CART'] => 'Cart',
|
||||
self::$PAGE_TYPES['CHECKOUT'] => 'Checkout',
|
||||
self::$PAGE_TYPES['ORDER_CONFIRMATION'] => 'Order Confirmation',
|
||||
self::$PAGE_TYPES['MY_ACCOUNT'] => 'My Account',
|
||||
self::$PAGE_TYPES['SEARCH'] => 'Search',
|
||||
self::$PAGE_TYPES['MANUFACTURER'] => 'Manufacturer',
|
||||
self::$PAGE_TYPES['SUPPLIER'] => 'Supplier',
|
||||
self::$PAGE_TYPES['CONTACT'] => 'Contact',
|
||||
self::$PAGE_TYPES['OTHER'] => 'Other',
|
||||
];
|
||||
|
||||
return $names[$pageType] ?? 'Unknown';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get page types array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getPageTypes()
|
||||
{
|
||||
return self::$PAGE_TYPES;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user