diff --git a/.vscode/ftp-kr.sync.cache.json b/.vscode/ftp-kr.sync.cache.json index 49b9e57f..e3a6edaf 100644 --- a/.vscode/ftp-kr.sync.cache.json +++ b/.vscode/ftp-kr.sync.cache.json @@ -99,7 +99,7 @@ "parameters.php": { "type": "-", "size": 959, - "lmtime": 1772190614158, + "lmtime": 1772655199577, "modified": false }, "parameters.yml": { @@ -188,14 +188,109 @@ "modified": false }, "classes": {}, - ".claude": {}, + ".claude": { + "settings.local.json": { + "type": "-", + "size": 96, + "lmtime": 1772461611751, + "modified": false + } + }, "composer.lock": { "type": "-", "size": 429111, "lmtime": 0, "modified": false }, - "config": {}, + "config": { + "alias.php": { + "type": "-", + "size": 2057, + "lmtime": 0, + "modified": false + }, + "autoload.php": { + "type": "-", + "size": 1340, + "lmtime": 0, + "modified": false + }, + "bootstrap.php": { + "type": "-", + "size": 6171, + "lmtime": 0, + "modified": false + }, + "config.inc.php": { + "type": "-", + "size": 11693, + "lmtime": 0, + "modified": false + }, + "db_slave_server.inc.php": { + "type": "-", + "size": 1337, + "lmtime": 0, + "modified": false + }, + "defines.inc.php": { + "type": "-", + "size": 8109, + "lmtime": 1772655759173, + "modified": false + }, + "defines_uri.inc.php": { + "type": "-", + "size": 3237, + "lmtime": 0, + "modified": false + }, + ".htaccess": { + "type": "-", + "size": 170, + "lmtime": 0, + "modified": false + }, + "index.php": { + "type": "-", + "size": 1369, + "lmtime": 0, + "modified": false + }, + "services": {}, + "settings.inc.php": { + "type": "-", + "size": 24, + "lmtime": 0, + "modified": false + }, + "smartyadmin.config.inc.php": { + "type": "-", + "size": 5934, + "lmtime": 0, + "modified": false + }, + "smarty.config.inc.php": { + "type": "-", + "size": 6750, + "lmtime": 0, + "modified": false + }, + "smartyfront.config.inc.php": { + "type": "-", + "size": 8867, + "lmtime": 0, + "modified": false + }, + "smartyfront.config.inc.php.before_pagecache_widget_block": { + "type": "-", + "size": 8488, + "lmtime": 0, + "modified": false + }, + "themes": {}, + "xml": {} + }, "controllers": {}, "cron-estella.php": { "type": "-", @@ -209,6 +304,18 @@ "lmtime": 0, "modified": false }, + "diag_fix_tmp.php": { + "type": "-", + "size": 14, + "lmtime": 1772659558751, + "modified": false + }, + "diag_upload_tmp.php": { + "type": "-", + "size": 4362, + "lmtime": 1772663092528, + "modified": false + }, "docs": {}, "download": {}, "error500.html": { @@ -279,9 +386,9 @@ }, ".htaccess": { "type": "-", - "size": 18466, - "lmtime": 0, - "modified": true + "size": 18985, + "lmtime": 1772451998229, + "modified": false }, ".htaccess.2025-01-27-1738009656": { "type": "-", @@ -436,6 +543,12 @@ "modified": false }, "config": {}, + "config_pl.xml": { + "type": "-", + "size": 648, + "lmtime": 0, + "modified": false + }, "config.xml": { "type": "-", "size": 430, @@ -463,8 +576,8 @@ }, "omnibuseufree.php": { "type": "-", - "size": 37153, - "lmtime": 1768471196653, + "size": 40041, + "lmtime": 1772663159729, "modified": false }, "Readme.md": { diff --git a/config/defines.inc.php b/config/defines.inc.php index 0ca8c162..156df347 100644 --- a/config/defines.inc.php +++ b/config/defines.inc.php @@ -26,7 +26,7 @@ /* Debug only */ if (!defined('_PS_MODE_DEV_')) { - if ( $_SERVER['REMOTE_ADDR'] == '91.189.216.43' ) + if ( $_SERVER['REMOTE_ADDR'] == '79.191.197.145' ) define('_PS_MODE_DEV_', false); else define('_PS_MODE_DEV_', false ); diff --git a/diag_20792_tmp.php b/diag_20792_tmp.php new file mode 100644 index 00000000..2626b5a8 --- /dev/null +++ b/diag_20792_tmp.php @@ -0,0 +1,66 @@ +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + +$prefix = $p['database_prefix']; +$id = 20792; + +echo "
\n";
+
+// Ile wierszy omnibus dla tego produktu
+echo "=== omnibus_eu_free dla produktu $id ===\n";
+$cnt = $pdo->query("SELECT COUNT(*) FROM {$prefix}omnibus_eu_free WHERE id_product = $id")->fetchColumn();
+echo "Laczna liczba wierszy: $cnt\n";
+
+$cnt_all = $pdo->query("SELECT COUNT(*) FROM {$prefix}omnibus_eu_free")->fetchColumn();
+echo "Cala tabela: $cnt_all wierszy\n\n";
+
+echo "=== Wierszy na kombinacje (top 10) ===\n";
+$stmt = $pdo->query("SELECT id_product_attribute, COUNT(*) AS ile FROM {$prefix}omnibus_eu_free WHERE id_product = $id GROUP BY id_product_attribute ORDER BY ile DESC LIMIT 10");
+foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) echo json_encode($row) . "\n";
+
+// Czas zapytania SELECT * dla tego produktu
+echo "\n=== Czas SELECT * omnibus dla produktu (ms) ===\n";
+$start = microtime(true);
+$rows = $pdo->query("SELECT * FROM {$prefix}omnibus_eu_free WHERE id_product = $id ORDER BY id_omnibuseufree DESC")->fetchAll();
+echo round((microtime(true) - $start) * 1000, 2) . " ms, pobranych: " . count($rows) . " wierszy\n";
+
+// Duplikaty hookow
+echo "\n=== Duplikaty hook registracji ===\n";
+$stmt = $pdo->query("SELECT m.name, COUNT(*) AS rejestracji
+ FROM {$prefix}module m
+ JOIN {$prefix}hook_module hm ON m.id_module = hm.id_module
+ JOIN {$prefix}hook h ON hm.id_hook = h.id_hook
+ WHERE h.name = 'displayAdminProductsExtra'
+ GROUP BY m.name
+ HAVING rejestracji > 1");
+$dups = $stmt->fetchAll(PDO::FETCH_ASSOC);
+if (empty($dups)) {
+ echo "Brak duplikatow\n";
+} else {
+ foreach ($dups as $row) echo json_encode($row) . "\n";
+}
+
+// PHP config
+echo "\n=== PHP limits ===\n";
+echo "max_execution_time: " . ini_get('max_execution_time') . "s\n";
+echo "memory_limit: " . ini_get('memory_limit') . "\n";
+
+// gm_omniprice_history dla tego produktu
+echo "\n=== gm_omniprice_history dla produktu $id ===\n";
+$cnt2 = $pdo->query("SELECT COUNT(*) FROM {$prefix}gm_omniprice_history WHERE id_product = $id")->fetchColumn();
+echo "Wierszy: $cnt2\n";
+
+echo "";
+echo "PAMIETAJ: usun ten plik po diagnostyce!
"; diff --git a/diag_fix_tmp.php b/diag_fix_tmp.php new file mode 100644 index 00000000..36bfa89d --- /dev/null +++ b/diag_fix_tmp.php @@ -0,0 +1 @@ +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + +$prefix = $p['database_prefix']; +$id = 20792; + +echo "\n";
+
+// Product rows
+$cnt = $pdo->query("SELECT COUNT(*) FROM {$prefix}omnibus_eu_free WHERE id_product = $id")->fetchColumn();
+echo "=== Produkt $id: $cnt wierszy ===\n";
+
+// Table structure
+echo "\n=== Kolumny tabeli ===\n";
+$stmt = $pdo->query("DESCRIBE {$prefix}omnibus_eu_free");
+foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
+ echo "{$row['Field']} ({$row['Type']})\n";
+}
+
+// Combinations
+$combCount = $pdo->query("SELECT COUNT(*) FROM {$prefix}product_attribute WHERE id_product = $id")->fetchColumn();
+echo "\n=== Kombinacje: $combCount ===\n";
+
+// SELECT speed
+$start = microtime(true);
+$pdo->query("SELECT * FROM {$prefix}omnibus_eu_free WHERE id_product = $id AND is_last = 1")->fetchAll();
+echo "SELECT is_last=1: " . round((microtime(true) - $start) * 1000, 1) . " ms\n";
+
+// All action hooks with modules
+echo "\n=== actionProductAttributeUpdate ===\n";
+$stmt = $pdo->query("
+ SELECT m.name, hm.position
+ FROM {$prefix}hook h
+ JOIN {$prefix}hook_module hm ON h.id_hook = hm.id_hook
+ JOIN {$prefix}module m ON hm.id_module = m.id_module AND m.active = 1
+ WHERE h.name = 'actionProductAttributeUpdate'
+ ORDER BY hm.position
+");
+foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
+ echo " {$row['name']} (pos {$row['position']})\n";
+}
+
+echo "\n=== actionProductUpdate ===\n";
+$stmt = $pdo->query("
+ SELECT m.name, hm.position
+ FROM {$prefix}hook h
+ JOIN {$prefix}hook_module hm ON h.id_hook = hm.id_hook
+ JOIN {$prefix}module m ON hm.id_module = m.id_module AND m.active = 1
+ WHERE h.name = 'actionProductUpdate'
+ ORDER BY hm.position
+");
+foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
+ echo " {$row['name']} (pos {$row['position']})\n";
+}
+
+echo "\n=== actionProductSave ===\n";
+$stmt = $pdo->query("
+ SELECT m.name, hm.position
+ FROM {$prefix}hook h
+ JOIN {$prefix}hook_module hm ON h.id_hook = hm.id_hook
+ JOIN {$prefix}module m ON hm.id_module = m.id_module AND m.active = 1
+ WHERE h.name = 'actionProductSave'
+ ORDER BY hm.position
+");
+foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
+ echo " {$row['name']} (pos {$row['position']})\n";
+}
+
+echo "\n=== actionObjectProductUpdateAfter ===\n";
+$stmt = $pdo->query("
+ SELECT m.name, hm.position
+ FROM {$prefix}hook h
+ JOIN {$prefix}hook_module hm ON h.id_hook = hm.id_hook
+ JOIN {$prefix}module m ON hm.id_module = m.id_module AND m.active = 1
+ WHERE h.name = 'actionObjectProductUpdateAfter'
+ ORDER BY hm.position
+");
+foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
+ echo " {$row['name']} (pos {$row['position']})\n";
+}
+
+// How many times does actionProductAttributeUpdate fire?
+echo "\n=== Ile razy odpala sie actionProductAttributeUpdate ===\n";
+echo "Raz na kazda kombinacje = $combCount razy!\n";
+echo "Kazdy modul na tym hooku odpala sie $combCount razy.\n";
+
+// Check gm_omniprice module
+echo "\n=== gm_omniprice hooki ===\n";
+$stmt = $pdo->query("
+ SELECT h.name, hm.position
+ FROM {$prefix}hook h
+ JOIN {$prefix}hook_module hm ON h.id_hook = hm.id_hook
+ JOIN {$prefix}module m ON hm.id_module = m.id_module
+ WHERE m.name = 'gm_omniprice'
+ ORDER BY h.name
+");
+foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
+ echo " {$row['name']} (pos {$row['position']})\n";
+}
+
+// Check creativeelements module hooks
+echo "\n=== creativeelements hooki actionProduct* ===\n";
+$stmt = $pdo->query("
+ SELECT h.name, hm.position
+ FROM {$prefix}hook h
+ JOIN {$prefix}hook_module hm ON h.id_hook = hm.id_hook
+ JOIN {$prefix}module m ON hm.id_module = m.id_module
+ WHERE m.name = 'creativeelements' AND h.name LIKE 'action%'
+ ORDER BY h.name
+");
+foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
+ echo " {$row['name']} (pos {$row['position']})\n";
+}
+
+echo "\n";
diff --git a/modules/omnibuseufree/omnibuseufree.php b/modules/omnibuseufree/omnibuseufree.php
index 3bb07ed3..53f03b71 100644
--- a/modules/omnibuseufree/omnibuseufree.php
+++ b/modules/omnibuseufree/omnibuseufree.php
@@ -48,6 +48,7 @@ class OmnibusEuFree extends Module
Configuration::updateValue('OMNIBUSEUFREE_DISPLAY_PRODUCT_PRICE_BLOCK', 1);
Configuration::updateValue('OMNIBUSEUFREE_CRON_STATUS', 2);
Configuration::updateValue('OMNIBUSEUFREE_DAYS', 30);
+ Configuration::updateValue('OMNIBUSEUFREE_HISTORY_DAYS', 60);
include(dirname(__FILE__) . '/sql/install.php');
@@ -68,6 +69,7 @@ class OmnibusEuFree extends Module
Configuration::deleteByName('OMNIBUSEUFREE_DISPLAY_PRODUCT_PRICE_BLOCK');
Configuration::deleteByName('OMNIBUSEUFREE_CRON_STATUS');
Configuration::deleteByName('OMNIBUSEUFREE_DAYS');
+ Configuration::deleteByName('OMNIBUSEUFREE_HISTORY_DAYS');
include(dirname(__FILE__) . '/sql/uninstall.php');
@@ -287,6 +289,9 @@ class OmnibusEuFree extends Module
public function hookDisplayAdminProductsExtra($params)
{
$OmnibusData = array();
+ $product = new Product((int) $params['id_product']);
+ $hasCombinations = $product->hasCombinations();
+ $nameCache = array();
foreach ($this->getOmnibusData($params['id_product']) as $rowId => $rowValue) {
$OmnibusData[$rowId]['price_locale'] = '';
@@ -301,9 +306,14 @@ class OmnibusEuFree extends Module
$OmnibusData[$rowId]['currency_iso_code'] = $currency->iso_code;
}
elseif ($key == 'id_product_attribute') {
- $product = new Product($params['id_product']);
- $OmnibusData[$rowId]['name'] = $product->getProductName($params['id_product'], $value);
- ($product->hasCombinations() && $value == 0) ? $OmnibusData[$rowId]['name'] .= ' ' . $this->l('(default combination)') : '';
+ $attrId = (int) $value;
+ if (!isset($nameCache[$attrId])) {
+ $nameCache[$attrId] = $product->getProductName((int) $params['id_product'], $attrId);
+ if ($hasCombinations && $attrId === 0) {
+ $nameCache[$attrId] .= ' ' . $this->l('(default combination)');
+ }
+ }
+ $OmnibusData[$rowId]['name'] = $nameCache[$attrId];
}
elseif ($key == 'is_last' && $value == 1) {
$OmnibusData[$rowId]['is_last_icon'] = '';
@@ -334,10 +344,18 @@ class OmnibusEuFree extends Module
public function hookActionProductSave($hook_params)
{
if (Module::isEnabled('omnibuseufree')) {
- Product::flushPriceCache();
+ $id_product = (int) $hook_params['id_product'];
- $this->addProductPriceWithCombinations($hook_params['id_product']);
- $this->addProductPrice($hook_params['id_product']);
+ $combinationCount = (int) Db::getInstance()->getValue(
+ 'SELECT COUNT(*) FROM `' . _DB_PREFIX_ . 'product_attribute` WHERE `id_product` = ' . $id_product
+ );
+
+ Product::flushPriceCache();
+ $this->addProductPrice($id_product);
+
+ if ($combinationCount <= 30) {
+ $this->addProductPriceWithCombinations($id_product);
+ }
}
}
@@ -345,10 +363,21 @@ class OmnibusEuFree extends Module
{
if (Module::isEnabled('omnibuseufree')) {
$id_product = (int) Tools::getValue('id_product');
- Product::flushPriceCache();
- $this->addProductPriceWithCombinations($id_product);
+ $combinationCount = (int) Db::getInstance()->getValue(
+ 'SELECT COUNT(*) FROM `' . _DB_PREFIX_ . 'product_attribute` WHERE `id_product` = ' . $id_product
+ );
+
+ // Skip entirely for products with many combinations.
+ // hookActionProductSave already handles base price recording.
+ // This hook fires once PER combination (168x), so running here is wasteful.
+ if ($combinationCount > 30) {
+ return;
+ }
+
+ Product::flushPriceCache();
$this->addProductPrice($id_product);
+ $this->addProductPriceWithCombinations($id_product);
}
}
@@ -473,11 +502,21 @@ class OmnibusEuFree extends Module
array(
'type' => 'text',
'label' => $this->l('Number of days'),
+ 'desc' => $this->l('Number of days for front-end lowest price display (Omnibus Directive).'),
'name' => 'OMNIBUSEUFREE_DAYS',
'class' => 'omnibus-input-days',
'maxlength' => '3',
'required' => true
),
+ array(
+ 'type' => 'text',
+ 'label' => $this->l('History retention (days)'),
+ 'desc' => $this->l('How many days of price history to keep and display in admin. Older entries (except current price) will be deleted by CRON.'),
+ 'name' => 'OMNIBUSEUFREE_HISTORY_DAYS',
+ 'class' => 'omnibus-input-days',
+ 'maxlength' => '4',
+ 'required' => true
+ ),
array(
'type' => 'switch',
'label' => $this->l('Display on product page'),
@@ -539,7 +578,8 @@ class OmnibusEuFree extends Module
'OMNIBUSEUFREE_INFORMATION_VERSION' => Configuration::get('OMNIBUSEUFREE_INFORMATION_VERSION', null, null, null, 2),
'OMNIBUSEUFREE_DISPLAY_PRODUCT_PRICE_BLOCK' => Configuration::get('OMNIBUSEUFREE_DISPLAY_PRODUCT_PRICE_BLOCK', null, null, null, 1),
'OMNIBUSEUFREE_CRON_STATUS' => Configuration::get('OMNIBUSEUFREE_CRON_STATUS', null, null, null, 2),
- 'OMNIBUSEUFREE_DAYS' => Configuration::get('OMNIBUSEUFREE_DAYS', null, null, null, 30)
+ 'OMNIBUSEUFREE_DAYS' => Configuration::get('OMNIBUSEUFREE_DAYS', null, null, null, 30),
+ 'OMNIBUSEUFREE_HISTORY_DAYS' => Configuration::get('OMNIBUSEUFREE_HISTORY_DAYS', null, null, null, 60)
);
}
@@ -556,6 +596,7 @@ class OmnibusEuFree extends Module
Configuration::updateValue('OMNIBUSEUFREE_DISPLAY_PRODUCT_PRICE_BLOCK', (int) Tools::getValue('OMNIBUSEUFREE_DISPLAY_PRODUCT_PRICE_BLOCK'));
Configuration::updateValue('OMNIBUSEUFREE_CRON_STATUS', (int) Tools::getValue('OMNIBUSEUFREE_CRON_STATUS'));
Configuration::updateValue('OMNIBUSEUFREE_DAYS', (int) Tools::getValue('OMNIBUSEUFREE_DAYS'));
+ Configuration::updateValue('OMNIBUSEUFREE_HISTORY_DAYS', max(1, (int) Tools::getValue('OMNIBUSEUFREE_HISTORY_DAYS')));
$confirmation = $this->l('The settings have been updated.');
@@ -886,10 +927,13 @@ class OmnibusEuFree extends Module
throw new Exception('Missing parameter: $id_product');
}
+ $historyDays = (int) Configuration::get('OMNIBUSEUFREE_HISTORY_DAYS', null, null, null, 60);
+
$sql = new DbQuery();
$sql->select('*');
$sql->from('omnibus_eu_free');
$sql->where('id_product = ' . (int) $id_product);
+ $sql->where('(`is_last` = 1 OR `date_add` >= DATE_SUB(NOW(), INTERVAL ' . $historyDays . ' DAY))');
$sql->orderBy('is_default_currency DESC');
$sql->orderBy('id_currency ASC');
$sql->orderBy('id_product_attribute ASC');
@@ -923,30 +967,14 @@ class OmnibusEuFree extends Module
public function removeOldDataFromOmnibusTable()
{
- $NumberOfDays = (int) Configuration::get('OMNIBUSEUFREE_DAYS', null, null, null, 30);
- $NumberOfDays = 90;
+ $numberOfDays = (int) Configuration::get('OMNIBUSEUFREE_HISTORY_DAYS', null, null, null, 60);
- $date = new DateTime();
- $date->modify('-' . $NumberOfDays . ' days');
- $CutOffDate = $date->format('U');
- $counter = 0;
+ Db::getInstance()->execute(
+ 'DELETE FROM `' . _DB_PREFIX_ . 'omnibus_eu_free`
+ WHERE `is_last` = 0
+ AND `date_add` < DATE_SUB(NOW(), INTERVAL ' . $numberOfDays . ' DAY)'
+ );
- $sql = new DbQuery();
- $sql->select('id_omnibuseufree, date_add');
- $sql->from('omnibus_eu_free');
- $sql->where('is_last = 0');
- $result = Db::getInstance()->executeS($sql);
-
- foreach ($result as $row) {
- $date = new DateTime($row['date_add']);
- $DatabaseDate = $date->format('U');
-
- if ($DatabaseDate < $CutOffDate) {
- Db::getInstance()->delete('omnibus_eu_free', '`id_omnibuseufree` = ' . (int) $row['id_omnibuseufree']);
- $counter++;
- }
- }
-
- return $counter;
+ return (int) Db::getInstance()->Affected_Rows();
}
}