Browse Source

On branche

v1
yffic@cousumain.info 10 years ago
commit
68d4fcadcb
  1. 8
      .gitattributes
  2. 53
      action/hash_404.php
  3. 87
      exec/hash_documents.php
  4. BIN
      hash_documents.png
  5. 179
      hash_fonctions.php
  6. 26
      hash_tests.php
  7. 21
      lang/hasher_fr.php
  8. 29
      plugin.xml

8
.gitattributes

@ -0,0 +1,8 @@
* text=auto !eol
action/hash_404.php -text
exec/hash_documents.php -text
/hash_documents.png -text
/hash_fonctions.php -text
/hash_tests.php -text
lang/hasher_fr.php -text
/plugin.xml -text

53
action/hash_404.php

@ -0,0 +1,53 @@
<?php
if (!defined("_ECRIRE_INC_VERSION")) return;
## fichier appele par le .htaccess de IMG/ ; lequel doit contenir :
/*
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]
*/
function action_hash_404_dist(){
include_spip("hash_fonctions");
$doc = preg_replace(',^.*?IMG/,', '', $_SERVER['REQUEST_URI']);
if (($dest = hasher_adresser_document($doc)
AND file_exists('./'.$GLOBALS['meta']['dir_img'].$dest))
OR ($dest = hasher_adresser_document($doc, true)
AND file_exists('./'.$GLOBALS['meta']['dir_img'].$dest))
) {
$url = 'http://'.$_SERVER['HTTP_HOST'].preg_replace(',^(.*?IMG/).*,', '\1', $_SERVER['REQUEST_URI']).$dest;
header('HTTP/1.1 301 Moved Permanently');
header('Location: '.$url);
echo '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The requested URL '.htmlspecialchars($_SERVER['REQUEST_URI']).' has moved to <a href="'.$url.'">'.$url.'</a>.</p>
<hr>
'.$_SERVER['SERVER_SIGNATURE'].'
</body></html>
';
}
else {
echo '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL '.htmlspecialchars($_SERVER['REQUEST_URI']).' was not found on this server.</p>
<hr>
'.$_SERVER['SERVER_SIGNATURE'].'
</body></html>
';
}
}
?>

87
exec/hash_documents.php

@ -0,0 +1,87 @@
<?php
if (!defined("_ECRIRE_INC_VERSION")) return;
function exec_hash_documents_dist($class = null)
{
include_spip('hash_fonctions');
//
// affichages
//
include_spip("inc/presentation");
pipeline('exec_init',array('args'=>array('exec'=>'hash_documents'),'data'=>''));
$commencer_page = charger_fonction('commencer_page', 'inc');
echo $commencer_page(_T('hasher:titre'), 'hash_documents');
echo "<br /><br /><br />\n";
echo gros_titre(_T('hasher:titre'), '', false);
// colonne gauche
echo debut_gauche('', true);
echo pipeline('affiche_gauche',array('args'=>array('exec'=>'hash_documents'),'data'=>''));
echo creer_colonne_droite('', true);
echo pipeline('affiche_droite',array('args'=>array('exec'=>'hash_documents'),'data'=>''));
echo debut_droite("", true);
echo debut_cadre_trait_couleur('', true, '', _T('hasher:documents_site'));
$corriger = intval(_request('corriger')) ;
if (($hasher = intval(_request('hasher'))) > 0)
$modif = hasher_deplacer_n_documents($hasher, $corriger);
if (($hasher = intval(_request('hasher'))) < 0)
$modif = hasher_deplacer_n_documents(-$hasher, $corriger, true);
if ($modif) {
echo "<p>"._T('hasher:documents_modifies').join(', ', $modif)."</p>";
}
// centre de la page
list($oui, $non) = hasher_compter_documents();
echo _T('hasher:bilan',array('oui'=>$oui,'non'=>$non)) ;
if (intval($non) > 0) {
$n = min(intval($non), 100);
echo "<p><a href='".parametre_url(parametre_url(self(), 'hasher', $n), 'corriger', '')."'>"._T('hasher:action_hasher',array('n'=>$n))."</a></p>";
echo "<p>"._T('hasher:action_corriger_explication')."<a href='".parametre_url(parametre_url(self(), 'hasher', $n), 'corriger', '1')."'>"._T('hasher:action_corriger',array('n'=>$n))."</a></p>";
}
if (intval($oui) > 0) {
$n = min(intval($oui), 100);
echo "<p><a href='".parametre_url(self(), 'hasher', -$n)."'>"._T('hasher:action_dehasher',array('n'=>$n))."</a></p>";
}
echo fin_cadre_trait_couleur(true);
echo "<br /><br />\n";
echo debut_cadre_trait_couleur('', true, '', _T('hasher:redirections'));
$htaccess = _DIR_IMG.'.htaccess';
if (!lire_fichier($htaccess, $contenu)
OR !preg_match(',hash_404,', $contenu)) {
echo "<p>"._T('hasher:htaccess_a_installer',array('htaccess'=>$htaccess))."</p>";
} else {
echo "<p>"._T('hasher:htaccess_installe',array('htaccess'=>$htaccess))."</p>";
}
echo propre('<cadre>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* ../index.php?action=hash_404 [L]
</cadre>');
echo fin_cadre_trait_couleur(true);
// pied
echo fin_gauche() . fin_page();
}
?>

BIN
hash_documents.png

After

Width: 128  |  Height: 128  |  Size: 10 KiB

179
hash_fonctions.php

@ -0,0 +1,179 @@
<?php
## fonctions pour hasher les documents
if (!defined("_ECRIRE_INC_VERSION")) return;
/* pour un fichier d'origine situé dans IMG/{$ext}/xxxx.ext,
* 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
* attention on ignore le IMG/ eventuel dans $doc, et on retourne sans IMG/
* $rev sert a faire l'inverse
* @param string $doc
* @param bool $rev
* @return string
*/
function hasher_adresser_document($doc, $rev=false) {
switch ($rev) {
case false:
if (!preg_match(',^(?:IMG/)?([^/]+)/([^/]+\.\1)$,S', $doc, $r))
return false;
$m = md5($r[2]);
return $r[1].'/'.$m[0].'/'.$m[1].'/'.$m[2].'/'.$r[2];
case true:
if (!preg_match(',^(?:IMG/)?([^/]+)/./././([^/]+\.\1)$,S', $doc, $r))
return false;
return $r[1].'/'.$r[2];
}
}
/* Deplacer un fichier et sa reference dans la base de donnees
* avec tous les controles d'erreur
*
* @param int $id_document
* @param bool $rev
* @return bool
*/
function hasher_deplacer_document($id_document, $corriger=false, $rev=false) {
// 1. recuperer les donnees du document
// et verifier qu'on peut le hasher
if (!$id_document = intval($id_document))
return false;
if (!$s = spip_query('SELECT fichier FROM spip_documents WHERE id_document='.$id_document)
OR !$t = spip_fetch_array($s)) {
spip_log("Erreur hasher_deplacer_document select doc=$id_document ".var_export($s, true), 'hash');
return false;
}
$src = $t['fichier'];
// savoir si on a IMG/ devant (en SPIP 1.9.2) ou pas (SPIP 2)
$img = preg_match(',^IMG/,', $src)
? 'IMG/' : '';
$dir_ref = preg_match(',^IMG/,', $src)
? _DIR_RACINE : _DIR_IMG;
// On fabrique le nom du fichier dest
if (!$dest = hasher_adresser_document($src, $rev)) {
spip_log("Erreur hasher_adresser_document($src) rev : $rev", 'hash');
return false;
}
// si le src n'existe pas, ciao, enfin presque
if (!file_exists($dir_ref.$src)) {
spip_log("Erreur hasher_deplacer_document fichier $dir_ref $src n'existe pas", 'hash');
// si le src n'existe pas, on verifie qu'il n'a pas deja ete déplace (ie le dest existe),
// et si oui, on modifie juste le chemin en base...
if($corriger) {
if(file_exists(_DIR_IMG.$dest)){
// on note la destination finale
if (!spip_query('UPDATE spip_documents SET fichier="'.$img.$dest.'" WHERE id_document='.$id_document)) {
spip_log("erreur update correction $img $dest doc $id_document", 'hash');
return false;
} else {
spip_log("hasher_deplacer_document fichier "._DIR_IMG."$dest existe deja, Table corrigee", 'hash');
return true ;
}
} else {
spip_log("hasher_deplacer_document fichier "._DIR_IMG."$dest n'existe pas", 'hash');
}
}
return false ;
}
// si le dest existe deja, renommer jusqu'a trouver un creneau libre
$i = 0;
while (file_exists(_DIR_IMG.$dest)) {
$i++;
$dest = preg_replace(',(-\d+)?(\.[^.]+)$,', '-'.$i.'\2', $dest);
}
// 2. creer au besoin les sous-repertoires
if (!is_dir(_DIR_IMG.$dir = dirname($dest))
AND !mkdir(_DIR_IMG.$dir, _SPIP_CHMOD, /* recursive, php5 */ true)) {
spip_log("erreur hasher_deplacer_document mkdir($dir)", 'hash');
return false;
}
// 3. Section critique : il faut modifier dans la base *et* deplacer
// on note les fichiers en cours de deplacement avec un - devant ; si
// ca casse on saura reparer
if (!spip_query('UPDATE spip_documents SET fichier=CONCAT("-", fichier) WHERE id_document='.$id_document)) {
spip_log("erreur update 1", 'hash');
return false;
}
// on deplace
if (!rename($dir_ref.$src, _DIR_IMG.$dest)) {
spip_log("erreur rename", 'hash');
spip_query('UPDATE spip_documents SET fichier="'.$src.'" WHERE id_document='.$id_document);
return false;
}
// on note la destination finale
if (!spip_query('UPDATE spip_documents SET fichier="'.$img.$dest.'" WHERE id_document='.$id_document)) {
spip_log("erreur update 2", 'hash');
return false;
}
// 4. Ouf c'est fini et sans erreur
return true;
}
/* 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.
* @param int $n
* @param bool $rev
* @return array
* @return bool
*/
function hasher_deplacer_n_documents($n, $corriger=false, $rev=false) {
if (!$n = intval($n)
OR !$s = spip_query($q = "SELECT id_document FROM spip_documents WHERE fichier REGEXP '^(IMG/)?[^/]+/"
. ($rev ? "./././" : "")
."[^/]+$' AND distant='non' ORDER BY date DESC LIMIT $n")) {
spip_log("erreur requete $q", 'hash');
return false;
}
$docs = array();
while ($t = spip_fetch_array($s)) {
$id_document = $t['id_document'];
if (hasher_deplacer_document($id_document, $corriger, $rev))
$docs[] = $id_document;
}
return $docs;
}
/* Compte les documents hashes et non hashes
* @return array
*/
function hasher_compter_documents() {
$s = spip_query($q = "SELECT COUNT(*) FROM spip_documents WHERE fichier REGEXP '^(IMG/)?[^/]+/"
."[^/]+$' AND distant='non'");
$non = array_pop(spip_fetch_array($s));
$s = spip_query($q = "SELECT COUNT(*) FROM spip_documents WHERE fichier REGEXP '^(IMG/)?[^/]+/"
. "./././"
."[^/]+$' AND distant='non'");
$oui = array_pop(spip_fetch_array($s));
return array($oui, $non);
}
/* Pipeline post_edition pour agir apres ajout de nouveaux documents via upload
* @param array $flux
* @return array
*/
function hasher_post_edition($flux) {
if ($flux['args']['operation'] == 'ajouter_document'
AND $id = intval($flux['args']['id_objet'])) {
hasher_deplacer_document($id);
hasher_deplacer_n_documents(10);
}
return $flux;
}
?>

26
hash_tests.php

@ -0,0 +1,26 @@
<?php
/*
## tests pour hasher les documents
@require 'ecrire/inc_version.php';
include_spip('hash_fonctions');
# hasher_adresser_document
foreach (array(
'IMG/mp3/toto.mp3' => 'mp3/1/c/9/toto.mp3',
'mp3/toto.mp3' => 'mp3/1/c/9/toto.mp3',
'IMG/mp3/a/b/c/toto.mp3' => false,
'x' => false,
) as $s => $r) {
if (($a = hasher_adresser_document($s)) !== $r)
echo 'hasher_adresser_document: '.var_export($s, true).' => '.var_export($a, true).' != '.var_export($r, true)."\n";
}
#var_dump(hasher_deplacer_document(1));
spip_timer('hash');
var_dump(count(hasher_deplacer_n_documents(10000, true)));
var_dump(spip_timer('hash'));
*/
?>

21
lang/hasher_fr.php

@ -0,0 +1,21 @@
<?php
// S&eacute;curit&eacute;
if (!defined("_ECRIRE_INC_VERSION")) return;
$GLOBALS[$GLOBALS['idx_lang']] = array(
'action_hasher' => 'hasher @n@ documents' ,
'action_dehasher' => 'd&eacute;hasher @n@ documents' ,
'action_corriger' => 'Corriger le chemin en base pour @n@ documents' ,
'action_corriger_explication' => 'Il peut arriver que des documents aient &eacute;t&eacute; d&eacute;plac&eacute;s mais que leur chemin en base n\'ai pas &eacute;t&eacute; corrig&eacute;. Ils apparaissent alors comme &laquo;&nbsp;ne pouvant pas &ecirc;tre hach&eacute;s&nbsp;&raquo;&nbsp;:&nbsp;' ,
'documents_modifies' => 'Documents modifi&eacute;s : ' ,
'documents_site' => 'Documents du site' ,
'bilan' => 'Ce site comporte @oui@ documents hash&eacute;s, et @non@ qui ne le sont pas encore (ou ne peuvent pas l\'&ecirc;tre).' ,
'htaccess_a_installer' => 'Veuillez installer dans @htaccess@ un fichier contenant les codes suivants :' ,
'htaccess_installe' => 'Le fichier @htaccess@ semble correctement install&eacute; ; pour m&eacute;moire, il doit contenir les codes suivants :' ,
'redirections' => 'Redirections' ,
'titre' => 'Hash documents' ,
);
?>

29
plugin.xml

@ -0,0 +1,29 @@
<plugin>
<nom>Hash documents</nom>
<slogan>
<multi>
[fr]Enregistrer les documents dans <code>IMG/mp3/a/b/c/fichier.mp3</code>
[en]Save documents in <code>IMG/mp3/a/b/c/file.mp3</code>
</multi>
</slogan>
<auteur>Fil</auteur>
<licence>GNU/GPL</licence>
<version>1.2.3</version>
<etat>stable</etat>
<description>
<multi>
[fr]Le nombre de documents dans le r&#233;pertoire IMG/extension/ du site peut devenir beaucoup trop important et avoir un impact sur les performances du syst&#232;me de fichiers du serveur. La solution propos&#233;e par ce plugin est de &#171; hasher &#187; le r&#233;pertoire IMG/.
[en]The number of documents in the directory IMG/extension/ site can become too important and affect the performance of the server's file system. The solution proposed by this plugin is to "hash" directory IMG/.
</multi>
</description>
<lien>http://www.spip-contrib.net/Le-plugin-hash_documents</lien>
<prefix>hasher</prefix>
<icon>hash_documents.png</icon>
<pipeline>
<nom>post_edition</nom>
<inclure>hash_fonctions.php</inclure>
</pipeline>
<chemin dir='' />
<necessite id="SPIP" version="[1.9.2;2.1.99]" />
<categorie>performance</categorie>
</plugin>
Loading…
Cancel
Save