Jump to content

Tâche cron vider tables statistiques avec OVH - ne marche pas


Recommended Posts

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

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

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

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.

PROGERANCE_14062024_zTjchjMHii.thumb.png.0ea29536f1a369be606c21a5c8be9e6a.png

[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 by magicbel (see edit history)
Link to comment
Share on other sites

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.

PROGERANCE_14062024_zTjchjMHii.thumb.png.0ea29536f1a369be606c21a5c8be9e6a.png

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

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.

PROGERANCE_14062024_zTjchjMHii.thumb.png.0ea29536f1a369be606c21a5c8be9e6a.png

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

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

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

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

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

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...