The_Artist Posted June 14 Share Posted June 14 Bonjour, J'ai une base de donnée WebCloud chez OVH pour mon installation Prestashop (version 1.7.4.4). Dans la bdd, les statistiques Prestashop gavent la base de donnée en quelques jours. C'est notamment la table ps_layered_filter_block qui devient énorme en quelques jours et fait dépasser mon quota. J'en ai marre de devoir me connecter à PHPMyAdmin tous les 2 jours et vider manuellement les tables trop massives. J'ai donc essayé de mettre en place un cron pour vider les tables de statistiques automatiquement chaque jour afin de ne pas dépasser mon quota. Seulement ça ne marche pas, je ne vois pas du tout ce que je fais de travers, et je ne sais plus quoi essayer... Voilà mon script actuel que j'ai placé dans mon dossier admin : <?php ini_set('display_errors', 'on'); include dirname(__FILE__) . '/../config/config.inc.php'; $db = Db::getInstance(); $tables = [ 'ps_layered_filter_block', 'ps_connections', 'ps_connections_page', 'ps_guest', 'ps_page_viewed' ]; $logFile = dirname(__FILE__) . '/stats_deletion_log.txt'; $logMessage = date('Y-m-d H:i:s') . ": Tables emptied successfully\n"; foreach ($tables as $table) { $db->execute('TRUNCATE TABLE `' . _DB_PREFIX_ . $table . '`'); } // Log the deletion to the file file_put_contents($logFile, $logMessage, FILE_APPEND); echo 'Tables emptied successfully'; ?> Dans le module cron de Prestashop, j'ai fait pointer la tâche sur le script ci-dessus : https://mondomaine.fr/dossier_admin/delete_stats.php Dans mon panel OVH j'ai fait pointer la tâche vers mon fichier cron.php (un truc que j'ai trouvé sur un forum) : <?php /** * Lancement des scripts cron * Utilise le module prestashop cronjobs * Permet de planifier les tâches via l'administration */ ini_set('display_errors','on'); include dirname(__FILE__) . '/../config/config.inc.php'; $link = new Link(); $shop_url = $link->getBaseLink(); $admin_dir = basename(dirname(__FILE__)); $cron_job_token = Configuration::getGlobalValue('CRONJOBS_EXECUTION_TOKEN'); $cronUrl = $shop_url . $admin_dir . '/index.php?controller=AdminCronJobs&token=' . $cron_job_token; echo Tools::file_get_contents($cronUrl); J'ai aussi essayé de pointer la tâche OVH vers mon script cron directement, mais rien ne marche. Est-ce que j'ai raté quelque chose? Auriez-vous des scripts cron Prestashop qui fonctionnent ? Des conseils sur le setup dans le panel OVH ? Merci d'avance Link to comment Share on other sites More sharing options...
Eolia Posted June 14 Share Posted June 14 Ce "truc" récupéré sur le forum, c'est moi qui l'ai écrit et il fonctionne sur les 1.6 (pas testé sur 1.7). Dans votre tache cron OVH, mettez directement l'url de votre script. Link to comment Share on other sites More sharing options...
The_Artist Posted June 14 Author Share Posted June 14 30 minutes ago, Eolia said: Ce "truc" récupéré sur le forum, c'est moi qui l'ai écrit et il fonctionne sur les 1.6 (pas testé sur 1.7). Dans votre tache cron OVH, mettez directement l'url de votre script. Alors un grand merci pour ton "truc" 😄 J'ai tenté 20 fois de retrouver ton article/post pour voir si je n'avais pas une erreur dans ma procédure, et impossible de le retrouver. Bref, j'ai essayé en mettant l'url directe du script pour vider les tables dans le panel cron d'OVH, ça ne marche pas. Donc j'ai essayé de pointer une tache cron OVH vers ton script : <?php /** * Lancement des scripts cron * Utilise le module prestashop cronjobs * Permet de planifier les tâches via l'administration */ ini_set('display_errors','on'); include dirname(__FILE__) . '/../config/config.inc.php'; $link = new Link(); $shop_url = $link->getBaseLink(); $admin_dir = basename(dirname(__FILE__)); $cron_job_token = Configuration::getGlobalValue('CRONJOBS_EXECUTION_TOKEN'); $cronUrl = $shop_url . $admin_dir . '/index.php?controller=AdminCronJobs&token=' . $cron_job_token; echo Tools::file_get_contents($cronUrl); ?> et en parallèle, dans Prestashop j'ai pointé l'url d'une tache cron vers le script qui vide les tables : <?php ini_set('display_errors', 'on'); include dirname(__FILE__) . '/../config/config.inc.php'; $db = Db::getInstance(); $tables = [ 'ps_layered_filter_block', 'ps_connections', 'ps_connections_page', 'ps_guest', 'ps_page_viewed' ]; $logFile = dirname(__FILE__) . '/stats_deletion_log.txt'; $logMessage = date('Y-m-d H:i:s') . ": Tables emptied successfully\n"; foreach ($tables as $table) { $db->execute('TRUNCATE TABLE `' . _DB_PREFIX_ . $table . '`'); } // Log the deletion to the file file_put_contents($logFile, $logMessage, FILE_APPEND); echo 'Tables emptied successfully'; ?> ça fonctionne pas, je suis perdu ! Link to comment Share on other sites More sharing options...
magicbel Posted June 14 Share Posted June 14 (edited) Bonjour, Pour le module à facette qui tape dans cette table ps_layered_filter_block , sous 1.7, le module intègre directement les instructions pour les tâches Cron afin de vider les tables. [EDIT] : Je viens de passer sur une vieille PS 1.7, l'option n'y est pas par contre🫣, du coup à vérifier de votre côté. Sinon vous pouvez désactiver le cache dans le pire des cas (toujours dispo dans le même module un peu plus bas dans la config) Edited June 14 by magicbel (see edit history) Link to comment Share on other sites More sharing options...
The_Artist Posted June 14 Author Share Posted June 14 15 minutes ago, magicbel said: Bonjour, Pour le module à facette qui tape dans cette table ps_layered_filter_block , sous 1.7, le module intègre directement les instructions pour les tâches Cron afin de vider les tables. Là je ne comprends pas ce que je suis censé faire avec ça. 🙄 Je n'ai pas le même nombre d'URL dans ma version 1.7.4.4, et pas les mêmes schémas d'URL non plus. Link to comment Share on other sites More sharing options...
The_Artist Posted June 14 Author Share Posted June 14 15 minutes ago, magicbel said: Bonjour, Pour le module à facette qui tape dans cette table ps_layered_filter_block , sous 1.7, le module intègre directement les instructions pour les tâches Cron afin de vider les tables. Là je ne comprends pas ce que je suis censé faire avec ça. 🙄 Je n'ai pas le même nombre d'URL dans ma version 1.7.4.4, et pas les mêmes schémas d'URL non plus. Link to comment Share on other sites More sharing options...
Eolia Posted June 14 Share Posted June 14 Si vous appelez directement l'url vers mon script sur votre site, vous avez quoi à l'écran ? Link to comment Share on other sites More sharing options...
The_Artist Posted June 14 Author Share Posted June 14 12 minutes ago, Eolia said: Si vous appelez directement l'url vers mon script sur votre site, vous avez quoi à l'écran ? Rien. Page blanche. Link to comment Share on other sites More sharing options...
Eolia Posted June 14 Share Posted June 14 Et si vous appelez votre script directement ? (Si aussi page blanche il faudra activer le mode debug pour en savoir plus) Link to comment Share on other sites More sharing options...
The_Artist Posted June 14 Author Share Posted June 14 28 minutes ago, Eolia said: Et si vous appelez votre script directement ? (Si aussi page blanche il faudra activer le mode debug pour en savoir plus) En modifiant ton script pour logger toutes les étapes, il semble que ça marche. L'URL est correctement composée avec le domaine, dossier admin + token. Aucune erreur ne remonte. <?php ini_set('display_errors', 'on'); error_reporting(E_ALL); // Function to log messages function logMessage($message) { echo date('Y-m-d H:i:s') . " - " . $message . "\n"; } logMessage("Starting script execution"); try { include dirname(__FILE__) . '/../config/config.inc.php'; logMessage("Included config file successfully"); } catch (Exception $e) { logMessage("Failed to include config file: " . $e->getMessage()); exit(); } try { $link = new Link(); $shop_url = $link->getBaseLink(); logMessage("Retrieved base link: $shop_url"); } catch (Exception $e) { logMessage("Failed to retrieve base link: " . $e->getMessage()); exit(); } try { $admin_dir = basename(dirname(__FILE__)); logMessage("Admin directory: $admin_dir"); } catch (Exception $e) { logMessage("Failed to get admin directory: " . $e->getMessage()); exit(); } try { $cron_job_token = Configuration::getGlobalValue('CRONJOBS_EXECUTION_TOKEN'); if (empty($cron_job_token)) { throw new Exception("CRONJOBS_EXECUTION_TOKEN is empty"); } logMessage("Retrieved cron job token: $cron_job_token"); } catch (Exception $e) { logMessage("Failed to retrieve cron job token: " . $e->getMessage()); exit(); } $cronUrl = $shop_url . $admin_dir . '/index.php?controller=AdminCronJobs&token=' . $cron_job_token; logMessage("Constructed cron URL: $cronUrl"); try { $response = Tools::file_get_contents($cronUrl); logMessage("Fetched cron URL successfully, response: " . $response); echo $response; } catch (Exception $e) { logMessage("Failed to fetch cron URL: " . $e->getMessage()); exit(); } logMessage("Script execution finished"); ?> Par contre dans le backend prestashop, le module cron ne dit pas que les cron ont bien été exécutés. Après moulte tests, ça marche uniquement quand je remplace https par http. Je ne sais pas ce qui peut bugger dans mon SSL, mais j'imagine que ce n'est pas très sécurisé d'exécuter le script sur la version http ? si j'exécute directement mon script delete_stats.php dans le navigateur, je n'ai pas une page blanche, en revanche idem : dans le backend prestashop, le module cron montre que le cron n'a pas été exécuté. Alors bref, j'ai passé l'aprem à sortir un script qui semble fonctionner, mais qui me donne une erreur cURL : cURL error: transfer closed with outstanding read data remaining <?php ini_set('display_errors', 'on'); error_reporting(E_ALL); include dirname(__FILE__) . '/../config/config.inc.php'; $link = new Link(); $shop_url = $link->getBaseLink(); $admin_dir = basename(dirname(__FILE__)); $cron_job_token = Configuration::getGlobalValue('CRONJOBS_EXECUTION_TOKEN'); if (empty($cron_job_token)) { exit("CRONJOBS_EXECUTION_TOKEN is empty"); } $cronUrl = $shop_url . $admin_dir . '/index.php?controller=AdminCronJobs&token=' . $cron_job_token; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $cronUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); // Enable SSL verification curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)'); $response = curl_exec($ch); if (curl_errno($ch)) { echo "cURL error: " . curl_error($ch); } else { echo $response; } curl_close($ch); ?> Avec ça, le cron s'exécute dans le backend prestashop mais cette erreur cURL me taraude... Link to comment Share on other sites More sharing options...
Eolia Posted June 14 Share Posted June 14 Plusieurs pistes ici: https://stackoverflow.com/questions/1759956/curl-error-18-transfer-closed-with-outstanding-read-data-remaining Link to comment Share on other sites More sharing options...
Prestashop Addict Posted June 17 Share Posted June 17 Le 14/06/2024 à 11:11 AM, The_Artist a dit : $tables = [ 'ps_layered_filter_block', 'ps_connections', 'ps_connections_page', 'ps_guest', 'ps_page_viewed' ]; $db->execute('TRUNCATE TABLE `' . _DB_PREFIX_ . $table . '`'); } Votre tableau de tables contient déjà en dur le préfixe ps_ donc _DB_PREFIX_ le rajoute et vous vous retrouvez avec des tables du genre ps_ps_xxxx, ce qui met votre commande SQL en erreur ! Pour le cron chez OVH mutualisé vous ne pouvez pas appeler les url avec des paramètres 😞 Donc je vous recommande d'utiliser un script php qui appelle vos url exemple : <?php error_reporting(E_ALL); set_time_limit ( 1200); function executeScript( $inUrl) { $ch = curl_init($inUrl); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 600); $raw = curl_exec($ch); $curl_info = curl_getinfo($ch); curl_close($ch); if($curl_info['http_code'] !== 200 && $curl_info['http_code'] !== 301){ echo "Une erreur ".$curl_info['http_code']." est survenue lors de l'appel de l'url ".$inUrl." \r\n"; echo "Type d'erreur: ".curl_error($ch); } else { echo "OK - $inUrl\r\n"; } } executeScript( 'https://www.domiane.ext/modules/gmerchantcenter/cron.php?id_shop=1&token=XXXXXXXX'); executeScript( 'https://www.domiane.ext/modules/mondialrelay/cron.php?secure_key=XXXXXXXXXXXXX'); executeScript( 'https://www.domiane.ext/adminXXXX/index.php?controller=AdminSearch&action=searchCron&ajax=1&full=1&token=XXXXXX&id_shop=1'); executeScript( 'https://www.domiane.ext/modules/gsitemap/gsitemap-cron.php?token=XXXXXX&id_shop=1'); Link to comment Share on other sites More sharing options...
The_Artist Posted June 17 Author Share Posted June 17 Effectivement j'ai déjà modifié mon script pour virer les préfixes. J'ai ENFIN réussi à faire marcher tout ça après 2 semaines de galère et de tests inconcluants. Le script pour déclencher le cron chez OVH : <?php ini_set('display_errors', 'on'); error_reporting(E_ALL); include dirname(__FILE__) . '/../config/config.inc.php'; $link = new Link(); $shop_url = $link->getBaseLink(); $admin_dir = basename(dirname(__FILE__)); $cron_job_token = Configuration::getGlobalValue('CRONJOBS_EXECUTION_TOKEN'); if (empty($cron_job_token)) { exit("CRONJOBS_EXECUTION_TOKEN is empty"); } $cronUrl = $shop_url . $admin_dir . '/index.php?controller=AdminCronJobs&token=' . $cron_job_token; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $cronUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)'); curl_setopt($ch, CURLOPT_TIMEOUT, 60); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); 30 seconds curl_setopt($ch, CURLOPT_BUFFERSIZE, 128000); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); $response = curl_exec($ch); if (curl_errno($ch)) { echo "cURL error: " . curl_error($ch); } else { echo $response; } curl_close($ch); ?> et le script pour TRUNCATE TABLE : <?php ini_set('display_errors', 'on'); include dirname(__FILE__) . '/../config/config.inc.php'; function output_message($message) { echo date('Y-m-d H:i:s') . ": " . $message . "\n<br/>"; } output_message("Cron job started"); try { $db = Db::getInstance(); output_message("Database connection established"); } catch (Exception $e) { output_message("Database connection failed" . $e->getMessage()); die("Database connection failed: " . $e->getMessage() . "\n<br/>"); } $tables = [ 'ps_layered_filter_block', 'ps_connections', 'ps_connections_page', 'ps_guest', 'ps_page_viewed' ]; foreach ($tables as $table) { try { $db->execute('TRUNCATE TABLE `' . $table . '`'); output_message("Table '$table' truncated successfully"); } catch (Exception $e) { output_message("Failed to truncate table '$table': " . $e->getMessage()); } } output_message("Tables emptied successfully"); output_message("Cron job ended"); echo 'Tables emptied successfully<br/>'; ?> Link to comment Share on other sites More sharing options...
Eolia Posted June 17 Share Posted June 17 En fait pour que le script soit utile à tout le monde, quelque soit le préfixe, il faut insérer le DB_PREFIX dans le tableau <?php ini_set('display_errors', 'on'); include dirname(__FILE__).'/../config/config.inc.php'; function output_message($message) { echo date('Y-m-d H:i:s').": ".$message.PHP_EOL); } output_message("Cron job started"); try { $db = Db::getInstance(); output_message("Database connection established"); } catch (Exception $e) { die(output_message("Database connection failed".$e->getMessage())); } $tables = [ _DB_PREFIX_.'layered_filter_block', _DB_PREFIX_.'connections', _DB_PREFIX_.'connections_page', _DB_PREFIX_.'guest', _DB_PREFIX_.'page_viewed' ]; foreach ($tables as $table) { try { $db->execute('TRUNCATE TABLE `'.$table.'`'); output_message("Table '$table' truncated successfully"); } catch (Exception $e) { output_message("Failed to truncate table '$table': ".$e->getMessage()); } } output_message("Tables emptied successfully"); output_message("Cron job ended"); ?> Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now