Gestion des images

Le stockage centralisé

Grâce au code yacs [image=<id>], il est facile et pratique de réutiliser une image d'une page dans une autre page.

Cependant, la gestion actuelle du stockage des images connaît plusieurs limitations :

  • Lorsque l'on supprime un article avec des images, ces images disparaissent des autres articles qui y feraient appel sans que l'on puisse le savoir ni le corriger
  • impossible de définir des options différentes pour une même image utilisée dans plusieurs pages (par exemple : affichage en taille réelle sur une page et en vignette réduite dans une autre)
  • pas évident de retrouver la page d'origine de l'image pour pouvoir la modifier. Et impossible de savoir quelles pages vont être impactées par cette modification.
  • lorsqu'une image est ajoutée à une page, elle vient écraser l'éventuelle image qui porterait le même nom, sans qu'on en soit averti.

Voici la solution que j'ai implémentée sur mes sites Yacs afin de pallier à ces limitations et repousser les limites de yacs en terme de gestion des images. Sans être une révolution, il s'agit d'une évolution "en profondeur" de la façon dont Yacs gère le stockage des images.

Afin de minimiser au maximum les impacts sur le code et les sites existants, j'ai, malgré tout, calqué au maximum les principes actuels.

[folder=description du fonctionnement]

Stockage physique des images

Actuellement, lorsqu'une image est téléversée dans le serveur yacs à partir d'une page, elle se retrouve "liée" à cette page.

Le fichier de l'image est alors stocké dans un dossier dont le nom correspond au numéro Id de la page en question. Ce dossier est créé dans le dossier "article" ou "section" selon la nature de la page.

On remarque également un sous dossier "thumb" qui sert à stocker l'image réduite (vignette) de l'image si cette dernière est d'une taille dépassant la limite fixée (20 ko par défaut).

Dans le nouveau système que j'ai adopté, les images sont enregistrées dans des dossiers sans rapport avec leur page d'origine.

Plutôt qu'avoir un dossier unique avec des dizaines de milliers d'images dedans (ce qui rend fastidieux, voir impossible, son parcours via des outils comme filezilla), j'adopte un regroupement des images par millier dans des sous-dossier :

  • dossier 1 : images dont l'id va de 1 à 999
  • dossier 2 : images dont l'id va de 1000 à 1999
  • dossier 3 : images dont l'id va de 2000 à 2999
  • etc.

En php, le calcul du chemin d'une image (dont le n° id est stocké dans $id_image) est alors obtenu par : $dossier_image = intval($id_image / 1000) + 1;

Note : Je pensais initialement faire coincider le nom du sous-dossier avec les milliers des id des images mais dans ce cas, les images 1 à 999 se retrouvent dans un dossier intitulé "0" ce qui me complique les tests que je réalise sur la valeur du sous-dossier (genre if ($dossier)...).

Pour chaque image dont la taille dépasse celle définie pour les vignettes, une copie réduite à la taille "vignette" est sauvegardée dans le sous-dossier thumbs du dossier où est stockée l'image à sa taille normale.

Nommage des images

Dans yacs, le nom de l'image d'origine est conservé, moyennant le remplacement de certains caractères indésirables (comme l'underscore ou l'espace) par un tiret.

Cela peut poser plusieurs problèmes :

  • certains nom de fichier vont faire buguer Yacs (par exemple, ceux qui se termineraient par : article 12)
  • En cas de chargement d'une image dont le nom "retouché" correspond à une image déjàprésente dans cette page alors l'image n'est pas ajoutée comme une nouvelle image. Elle vient remplacer l'image existante. Ce fonctionnement est problématique dans le cadre d'une galerie de nombreuses images sur un sujet (par exemple : la page sur Elvis). Il n'est pas improbable que des contributeurs y ajoutent des images "elvis.jpg" qui viennent s'écraser involontairement entre elles...
  • on peut ne pas vouloir que le nom du fichier image d'origine soit affichéaux yeux de tous (par exemple : ce_gros_naze_de_paulo.jpg).

Pour éviter cela, et pour grandement faciliter le codage de la gestion des images, je renomme tous les fichiers des images de la manière suivante :

Nouveau nom du fichier = id de l'image dans la base de données Yacs + extension d'origine (par exemple : 1234.jpg).

Le nom d'origine est conservé dans le titre de l'image afin de pouvoir servir au référencement des moteurs de recherche. Le surfeur a donc le loisir de le supprimer ou de le modifier s'il le souhaite.

Infos en base de données

La table yacs_images est conservée. Y sont mémorisées les infos sur l'image d'origine (titre, description, options).

Remarque : Chaque image devant être associée à une page (anchor), une section dédiée à cette usage est crée.

Il est pratique de pouvoir continuer d'associer des images à une page, notamment pour :

  • pouvoir constituer automatiquement une gallerie d'image associée à la page
  • pouvoir parcourir aisément les images servant à mon article sans devoir me noyer dans les milliers d'images stockées "en central"

Pour mémoriser le lien entre une page et une image, une nouvelle table est donc créée : yacs_images_link (la structure de cette table est la même que celle de yacs_images).

De cette façon, lorsqu'une image existante est associée à une autre page, on peut redéfinir son titre, sa description et ses options (afin de les adapter à la nouvelle page) sans impacter ce qui a été définie pour la page d'origine.

Une même image peut désormais être affichée en taille réelle sur une page et en vignette réduite sur une autre.

Remarque : Par défaut, lorsqu'une image existante est associé à une nouvelle page, elle hérite des titre, description et option définis à l'origine dans la table yacs_images.

Afin de simplifier grandement le codage et pouvant utiliser les fonction actuelles pour gérer à la fois les images "centralisée" et les images "associées à une page", j'ai utilisé une astuce qui consiste à faire commencer les id des enregistrements de la table yacs_images_link au chiffre 8 000 000. De cette manière, l'id de l'image permet aux fonction de savoir quel type d'image elle ont à traiter.

L'impact de cette règle est que l'on divise par 2 le nombre d'images ou d'associations que l'on peut gérer. Mais avec 8 millions d'images possibles sur un site, je pense qu'on a de quoi voir venir...

Association automatique

Lorsque l'édition du contenu d'une page (description, bas de page) est enregistrée, j'analyse celui-ci afin de détecter l'insertion de nouvelles d'images prises dans "le stockage centralisé".

Dans ce cas, je crée automatiquement l'association entre la page et l'image "centralisée".

De cette manière, on est capable de connaître toutes les pages où une image "centralisée" est insérée. Cela permet de mesure précisément l'impact si l'on souhaite modifier l'image "centralisée".

Suppression d'image

Lorsque l'on supprime une image à partir d'une page où elle est associée, l'association avec l'image centrale est supprimée (dans la table yacs_images_link).

S'il n'y a aucune autre page qui utilise cette image alors elle est également supprimée de yacs_images et le fichier et sa vignette sont effacés du stockage central.

Dans le cas contraire, l'image est conservée et les autres pages qui l'utiliseraient ne sont pas impactées.

Migration depuis un Yacs antérieur

Il n'est pas très compliqué de basculer un site yacs existant sur ce nouveau système de gestion des images.

Pour cela, il faut tout d'abord s'occuper des fichiers physiques :

  • créer les dossiers centraux nécessaires
  • déplacer les fichiers image et les vignettes dans les dossiers "centraux" correspondant en les renommant avec leur id.
  • supprimer les anciens dossiers /images/article/ et /images/section/

Puis, on intervient sur le code et les données :

  • mettre à jour les fichiers codes qui ont été modifiés
  • créer la nouvelle table yacs_images_link et la remplir à partir des données de yacs_images
  • modifier l'anchor dans yacs_images

Une fois ces opérations réalisées par les scripts (à développer), les pages existantes continuent d'afficher leur contenu comme auparavant car le code yacs [ image=1234] va continuer d'afficher la même image et de la même manière.

En terme d'utilisation, rien ne change pour l'utilisateur. Les opérations d'ajout, de modification, de suppression et d'insertion d'image dans un article se réalisent exactement comme avant. Le changement du système de stockage des images est donc transparent pour les membres.

Dernière solution envisagée

Nommage des fichiers images

Lorsqu'une nouvelle image est ajoutée, son nom d'origine est préfixé par l'id de l'enregistrement créé dans la table image. Par exemple, le fichier maphoto.jpg est renommé en 1234-maphoto.jpg

Table image

La table image actuelle peut être utilisée seule pour mémoriser les propriétés de chaque image insérée dans une page. Un enregistrement avec un id unique est généré chaque fois qu'une image (nouvelle ou provenant d'une autre page) est ajoutée dans une page. Si l'image existe déjà dansu ne autre page alors l'enregistrement pointe vers le même fichier image.

[/folder]