De manière à limiter le nombre d’inode dans chaque sous-dossier de IMG/
, on répartit automatiquement les fichiers dans des sous-sous-répertoires. La structure passe ainsi deIMG/mp3/fichier-son.mp3
à IMG/mp3/a/b/c/fichier-son.mp3
Ce plugin s’occupe de tout pour vous.
En SPIP 2, une page ecrire/?exec=hash_documents
permet d’aller hasher tous les documents déjà installés (mais il n’est pas indispensable de l’utiliser pour que ça fonctionne). On peut à tout moment revenir en arrière (grâce à cette même page). En SPIP3, elle est accessible via la page d’administration des plugins (ecrire/?exec=configurer_hasher
).
Dans tous les cas, la désactivation du plugin n’empêche pas le site de fonctionner normalement.
Ci-dessous, les explications techniques :
Structure du hashage
le sous-répertoire a/b/c/
doit être calculé de manière à ce que la répartition des documents soit homogène et prévisible. On utilisera pour ce faire une fonction de hashage très simple consistant à prendre les n premiers caractères du md5
du nom du fichier.
md5
ayant une représentation hexa, le nombre de sous-répertoires ainsi créés sera de l’ordre de 16^n ; pour répartir correctement un million de documents, on a les possibilités suivantes :
— n=1
16 répertoires * 62500 docs
— n=2
256 rép * 3900 docs
— n=3
4096 rép * 244 docs
Dans cette implémentation, on utilise 3 niveaux de sous-répertoires : pour un fichier d’origine situé dans IMG/{$ext}/xxxx.ext
, le hasher consiste à prendre les 3 premiers caractères (a, b, c) du md5(xxxx.ext)
, et déplacer le fichier dans IMG/$ext/a/b/c/xxxx.ext.
fonction : function hasher_adresser_document(xxxx.ext)
Déplacement d’un document
fonction : function hasher_deplacer_document($id_document) {}
Cette fonction a pour rôle de déplacer un document proprement de sa position non hashée vers sa position hashée. Tous les contrôles d’erreur sont mis en place afin de garantir que tout se passe bien : si la création du sous-répertoire échoue, par exemple, ou si la connexion à la base de données est tombée, il faut pouvoir reprendre.
Elle appelle hasher_adresser_document()
Conversion « batch »
fonction : function hasher_deplacer_n_documents($n) {}
Cette fonction prend les n
documents non hashés les plus récents, et appelle hasher_deplacer_document()
sur chacun d’eux. Elle renvoie un array()
contenant les id_document
des documents qu’elle a déplacés.
Elle peut servir à convertir l’existant (on l’appelle répétitivement jusqu’à épuisement du stock), ou juste après un upload (en SPIP 1.9.2, car en SPIP 2 le cas de l’upload est géré nativement via le pipeline ad hoc), ou un spip2spip, afin de hasher les documents qu’on vient d’ajouter [1].
Elle peut aussi être appelée depuis la page ecrire/?exec=hash_documents
Gestion de redirection
Lorsqu’un document a été déplacé, on souhaite qu’un hit sur son ancienne adresse renvoie vers la nouvelle adresse, avec un code HTTP 301 Moved Permanently
(redirection définitive).
Ceci permet, d’une part, de gérer proprement la migration ; d’autre part, ça implique qu’il n’est pas indispensable de hasher les documents juste après l’upload, donc beaucoup de souplesse dans l’intégration.
On va pour ce faire ajouter un .htaccess
dans le répertoire IMG/
qui lancera, sur les fichiers non trouvés, un script de redirection écrit en PHP ; ce dernier calculera l’adresse hashée du document demandé, vérifiera si ce document est présent, et en fonction du résultat renverra soit un code 301
vers ce document, soit un 404 Not Found
.
Le script PHP est le fichier hash_404.php
présent dans le plugin ; la seule petite difficulté pour son activation, c’est qu’il nécessite la création d’un .htaccess
spécifique dans le répertoire IMG/
contenant le code suivant :
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
# Si spip est range a la racine du domaine
RewriteRule .* ../index.php?action=hash_404 [L]
# Pour un mutualise, vaut mieux travailler en url absolue
#RewriteRule .* /index.php?action=hash_404 [L]
En fonction de la configuration technique de l’hébergeur, il faudra peut-être adapter un peu ce .htaccess
.
Compatibilité
Il est important de noter que la structure proposée pour le code offre nativement une grande compatibilité, puisque, une fois les documents hashés, on peut retirer tout le code de hachage sans impact sur le fonctionnement.
On a pris soin de ne pas utiliser de fonctions « fragiles » de SPIP, qui changeraient d’une version à l’autre, afin que ce plugin soit compatible de SPIP 1.9.2 aux SPIP futurs.
La seule difficulté à prendre en compte est que le nommage des documents dans la table spip_documents
a changé entre SPIP 1.9.2 et la série SPIP 2.0. En SPIP 1.9.2, en effet, spip_documents.fichier
contenait une chaîne de la forme IMG/jpg/postcards.jpg
, tandis qu’en SPIP 2 on a simplement jpg/postcards.jpg
(le IMG/
a été supprimé).
Le plugin fonctionne nativement avec les deux représentations (avec ou sans IMG/
).
Réversibilité
Les fonctions de hashage sont réversibles : un paramètre $rev
permet de revenir à la structure « à plat ». Cela permet de revenir en arrière si finalement on ne souhaitait pas utiliser ce système, ou pour en utiliser un autre. Cela a aussi permis de tester le plugin, lors de son développement, en faisant des allers-retours.
Discussions par date d’activité
3 discussions
Bonjour,
Depuis le passage de SPIP à la version 4.0.2, le plugin ne fonctionne plus : les nouveaux documents sont stockés à la racine du répertoire de l’extension.
De plus, étrangement, s’il est toujours possible de hasher et déhasher les anciens documents (ceux ajoutés avant le passage à la 4.0.2), cela n’est plus possible pour ceux ajouter après le passage (la liste des Id des documents modifiés est vides). Je dis « étrangement » parce que rien dans la base de données ne semble différencier les uns et les autres...
Je viens de tester avec spip 4.0.4 + plugin en v3.0.0 > pas de souci de mon côté.
Est-ce que ça pourrait venir de PHP 8.1 ? Comment le vérifier ?
Cela vient peut-être de PHP8.1 (mais c’était déjà le cas auparavant). Comment le vérifier ?
Ah c’est possible... je vais voir si j’arrive à me mettre une 8.1...
En 8.1 mais avec la version de dev de SPIP : ca marche.
En 8.1 avec spip 4.1.0-alpha : ca marche
En 8.1 avec spip 4.0.4 : j’ai trop de warning pour ne serait-ce qu’arriver à une page d’upload de document.
A vu de nez, je dirais qu’à mon avis vue que spip 4 n’est pas censé être compatible php 8.1 mais uniquement 8.0, cela pourrait venir de là...
J’ai identifié un premier soucis : désormais, les logos apparaissent dans la table spip_documents. Or, le plugin ne les hashe pas.
Lorsque, depuis la page de configuration, on souhaite hasher 100 documents, mais qu’il n’y a que des logos, le plugin ne hashe rien, alors qu’il peut y avoir des documents à hasher en 101è position.
En revanche, je n’ai pas trouvé pourquoi l’adresse n’est pas hashée lorsqu’on ajoute un nouveau document.
Ah oui, car il y a un presupposé dans la regexp que le nom du dossier = le nom de l’extension.
Bon, faut reussi à trovuer une regexp qui passe aussi pour les logos...
Pour le premier problème, peux tu tester la branche suivante :
https://git.spip.net/spip-contrib-extensions/hash_documents/src/branch/bugs_gilles
pour le second problème, difficile de dire, mais vu ce que je te disais sur les compats de spip 4 avec php 8 ce serait pas impossible que le pb viennent de là.
Tu a accès aux logs PHP ?
Cela fonctionne : les logos sont désormais hashés.
Pour le 2d, il semble avoir disparu lorsque j’ai installé cette branche, peut-être une mauvaise installation lors du passage à la 3.0.0 ?
Cela fonctionne : les logos sont désormais hashés.
Pour le 2è problème, il semble avoir disparu avec cette branche.
OK,
et bien c’est releasé sous le numero v3.0.1
Répondre à ce message
Bonjour, le plugin ne fonctionne plus sous SPIP 4.0. Sa mise à jour est-elle prévue ?
Il faudrait tester en modifiant les bornes dans paquet.xnl pour voir si cela marche, et si c’est le alors on pourra modifier la version distribué. Sinon faudra que quelqu’un s’attelle à la tache d’une maj.
Après quelques recherches, il suffit de remplacer la fonction spip_fetch_array() par sql_fetch() dans le fichier hasher_fonctions.php
Je vais en profiter pour corriger tous les appels aux vieilles fonctions.
Répondre à ce message
Pour compléter la documentation, pourrait-on préciser à partir de quand ce plugin devient intéressant. De l’ordre de 10kdocument ? 100kdocument ? 1MDocument ?
Répondre à ce message
Ajouter un commentaire
Avant de faire part d’un problème sur un plugin X, merci de lire ce qui suit :
Merci d’avance pour les personnes qui vous aideront !
Par ailleurs, n’oubliez pas que les contributeurs et contributrices ont une vie en dehors de SPIP.
Suivre les commentaires : |