Par construction PrestaShop ne peut pas gĂ©rer les images avec des ID supĂ©rieurs Ă 9 999 999 (7 chiffres). Câest dĂ©jĂ beaucoup et on a pas souvent besoin de plus mais jâai eu affaire Ă un script dâimport qui impose les ID dâimages et donc ça arrive.
Pourquoi PrestaShop ne les gĂšrent pas ?
En fait, PrestaShop nâa pas de soucis avec les ID de 8 chiffres ou plus, tant que la base de donnĂ©es lâaccepte, lui aussi. Le problĂšme vient de la façon dâaccĂ©der aux images.
LâURL dâune image est https://example.com/123-large/mon-image.jpg
soit [url de la boutique]/[ID de l'image]-[format à afficher]/[texte pour le référencement].jpg
et le fichier .htaccess
explique au serveur que quand on a une url de ce type, il faut aller chercher le fichier quâil faut dans le dossier des images /img/p/
Le fichier .htaccess de PrestaShop ressemble à ça
RewriteRule ^([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$1$2$3.jpg [L]
RewriteRule ^([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$1$2$3$4.jpg [L]
RewriteRule ^([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$1$2$3$4$5.jpg [L]
RewriteRule ^([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$4/$1$2$3$4$5$6.jpg [L]
RewriteRule ^([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$4/$5/$1$2$3$4$5$6$7.jpg [L]
RewriteRule ^([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$4/$5/$6/$1$2$3$4$5$6$7$8.jpg [L]
RewriteRule ^([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$4/$5/$6/$7/$1$2$3$4$5$6$7$8$9.jpg [L]
Donc quand le serveur reçoit lâURL https://example.com/123-large/mon-image.jpg
il affiche le fichier /img/p/1/2/3/123-large.jpg
. Câest rapide et ça ne demande pas de ressource, PrestaShop nâest mĂȘme pas appelĂ© quand on veut afficher une image produit.
Mais on ne peut pas utiliser $10 dans un fichier .htaccess, il est interprĂ©tĂ© comme $1 puis le caractĂšre 0. Comme dans la derniĂšre ligne de lâextrait ci-dessus on utilise $9, on ne peut pas aller plus loin.
Ma solution
Si on appelle lâURL https://example.com/123456789-large/mon-image.jpg
, le serveur ne reconnait pas ce format et essaye simplement dâafficher le fichier /123456789-large/mon-image.jpg
qui nâexiste pas et renvoie donc une erreur 404. PrestaShop affiche donc une jolie page pour dire que le fichier nâa pas Ă©tĂ© trouvĂ©e.
Lâastuce consiste Ă utiliser cette page pour afficher lâimage demandĂ©e en complĂ©tant le controller PageNotFound.
<?php
class PageNotFoundController extends PageNotFoundControllerCore
{
public function initContent()
{
list($filename) = explode('?', $_SERVER['REQUEST_URI']);
if (preg_match('/([0-9]+)(\-[_a-zA-Z0-9-]*)?\/.*\.jpg/', $filename, $matches)) {
$path = _PS_ROOT_DIR_.'/img/p/'.implode('/', str_split($matches[1], 1)).'/'.$matches[1].$matches[2].'.jpg';
if (file_exists($path)) {
header('Content-Type: '.mime_content_type($path)?:'image/jpg');
readfile($path);
die();
} else {
header('HTTP/1.1 404 Not Found');
header('Status: 404 Not Found');
header('Content-Type: image/gif');
readfile(_PS_ROOT_DIR_.'/img/404.gif');
die();
}
}
return parent::initContent();
}
}
Code Ă placer dans /override/controllers/front/PageNotFoundController.php
Fichier disponible sur Github
Le principe est le suivant :
- quand le controller PageNotFound est appelĂ©, on regarde si lâURL correspond Ă celle dâune image produit,
- si oui on regarde si elle existe,
- si oui on lâaffiche et câest terminĂ©
- si non on affiche une image dâerreur
- si non on laisse le controller gérer
Sources :