Merci Eolia. A première vue, avec ChatGpt, nous avons réussi à faire un override de la class Image.php et du controller admin AdminImagesController.php. Testé sur 2 copies du prod, la dernière version semble être ok.
Voici le code de AdminImagesController.php
<?php
/**
* Override anti-cascade pour la suppression/régénération des vignettes
* Phenix/PS 1.6.x – DEV
*/
class AdminImagesController extends AdminImagesControllerCore
{
/**
* SAFE: supprime uniquement les tailles explicites, jamais l’original id.jpg,
* et n'exécute pas de nettoyage récursif global (pas de "cascade" sur les soeurs).
*/
protected function _deleteOldImages($dir, $type, $product = false)
{
// TRACE facultative (décommente pour vérifier l’override)
// @error_log("[IMG] override _deleteOldImages CALLED in ".__FILE__."\n", 3, _PS_ROOT_DIR_."/var/log/img_trace.log");
if (!is_dir($dir)) {
return true;
}
// OK : purge du /img/tmp uniquement
Tools::deleteDirectory(_PS_TMP_IMG_DIR_, false);
// Liste blanche stricte des tailles
if (!is_array($type) || empty($type)) {
return true;
}
$allowed = array();
foreach ($type as $t) {
if (!empty($t['name'])) {
$allowed[] = $t['name'];
}
}
if (empty($allowed)) {
return true;
}
$entries = scandir($dir);
if (!is_array($entries)) {
return true;
}
foreach ($entries as $d) {
// Ne JAMAIS toucher à l'original (ex: 130.jpg)
if (preg_match('/^[0-9]+\.jpe?g$/i', $d)) {
continue;
}
// Supprimer uniquement :
// - id[-id_product]-<type>.jpg|webp
// - <lang>-default-<type>.jpg|webp
foreach ($allowed as $name) {
$reBase = '/^[0-9]+-'.($product ? '[0-9]+-' : '').preg_quote($name,'/').'\.(?:jpe?g|webp)$/i';
$reLang = '/^[a-z]{2}-default-'.preg_quote($name,'/').'\.(?:jpe?g|webp)$/i';
if (preg_match($reBase, $d) || preg_match($reLang, $d)) {
$full = $dir.$d;
if (file_exists($full)) {
@unlink($full);
}
break;
}
}
}
// pas de nettoyage récursif global (source de suppression en cascade)
// if ($product) { $this->cleanAllImages(_PS_PROD_IMG_DIR_); }
return true;
}
/**
* Par sécurité, si du code legacy appelle encore cleanAllImages(),
* on le rend inoffensif (pas de suppression récursive).
*/
public function cleanAllImages($path)
{
// TRACE facultative
// @error_log("[IMG] cleanAllImages bypassed in ".__FILE__."\n", 3, _PS_ROOT_DIR_."/var/log/img_trace.log");
return true;
}
}
et de Image.php
<?php
/**
* Override SAFE de la classe Image (suppression non-destructive)
* - Ne touche jamais à l’original id.jpg
* - Ne supprime que les tailles de l’image courante
* - Pas de nettoyage récursif / pas de prune des dossiers parents
*/
class Image extends ImageCore
{
/**
* Journalise l’appel puis délègue au parent.
* Le parent appellera $this->deleteImage(), qui est overridée ci-dessous.
*/
public function delete()
{
@file_put_contents(
_PS_ROOT_DIR_.'/var/log/img_trace.log',
date('c')." Image::delete id_image={$this->id} id_product={$this->id_product}\n",
FILE_APPEND
);
// On laisse le parent gérer la partie BDD (ps_image*, position, cover…)
return parent::delete();
}
/**
* Suppression des fichiers sur disque (override SAFE)
* $force_delete est ignoré volontairement pour NE PAS supprimer l’original.
*/
public function deleteImage($force_delete = false)
{
// Chemin de base sans extension, ex: /img/p/1/3/0/0/1300
$basePath = $this->getPathForCreation();
$dir = dirname($basePath).'/';
// 1) SUPPRIMER l’original et ses variantes (jpg, png, webp)
$exts = array('jpg','png','webp');
foreach ($exts as $ext) {
$orig = $basePath.'.'.$ext;
if (file_exists($orig)) {
@unlink($orig);
@file_put_contents(
_PS_ROOT_DIR_.'/var/log/img_trace.log',
date('c')." unlink original: ".$orig."\n",
FILE_APPEND
);
}
}
// 2) Supprimer UNIQUEMENT les déclinaisons de CETTE image
$types = ImageType::getImagesTypes('products', false);
$exts = array('jpg','webp'); // on couvre les 2 familles
foreach ($types as $t) {
$name = stripslashes($t['name']);
foreach ($exts as $ext) {
$file = $basePath.'-'.$name.'.'.$ext;
if (file_exists($file)) {
@unlink($file);
@file_put_contents(
_PS_ROOT_DIR_.'/var/log/img_trace.log',
date('c')." unlink variant: ".$file."\n",
FILE_APPEND
);
}
// variante 2x si jamais utilisée
$file2x = $basePath.'-'.$name.'2x'.'.'.$ext;
if (file_exists($file2x)) {
@unlink($file2x);
@file_put_contents(
_PS_ROOT_DIR_.'/var/log/img_trace.log',
date('c')." unlink variant2x: ".$file2x."\n",
FILE_APPEND
);
}
}
}
// 3) NE PAS remonter dans l’arbo, NE PAS pruner les dossiers parents
// (donc pas de rmdir(), pas de cleanAllImages())
// On considère l’opération disque OK même si certaines variantes n’existaient pas.
return true;
}
}
Je ne suis hélas pas dév PHP, je peux y apporter des changements, mais pour créer des overrides, j'ai préféré me faire aider. Car pour la gestion du site, cela commençait à devenir vraiment compliqué, ces disparitions d'images. Pour les anciennes, je pouvais les récupérer du clone d'origine. Mais pour les nouvelles, on est obligé de les renvoyer. Avec, en plus, un souci au niveau de la bdd vu que les anciennes assos img/prod n'étaient pas supprimées.
Pour les erreurs 500, si elles ne peuvent être liées à un script auto de régénération, alors d'où peuvent-elles venir ? J'attends un avis de spécialiste demain chez O2Switch car ni eux, ni moi, n'arrivons à trouver une piste 