source: spip-zone/_plugins_/hash_documents/trunk/hasher_fonctions.php

Last change on this file was 66068, checked in by yffic@…, 8 years ago

Report de 66067 :
Ne faire qu'une seule fois par hit le déplacement de n documents. Sinon dans le cas d'une insertion de plusieurs docs venant d'un zip, on explose le temps de connexion à la base.

File size: 6.3 KB
Line 
1<?php
2
3## fonctions pour hasher les documents
4
5if (!defined("_ECRIRE_INC_VERSION")) return;
6
7
8/* pour un fichier d'origine situé dans IMG/{$ext}/xxxx.ext,
9 * prendre les 3 premiers caractères (a, b, c) du md5(xxxx.ext),
10 * et déplacer le fichier dans IMG/{$ext}/a/b/c/xxxx.ext
11 * attention on ignore le IMG/ eventuel dans $doc, et on retourne sans IMG/
12 * $rev sert a faire l'inverse
13 * @param string $doc
14 * @param bool $rev
15 * @return string
16 */
17function hasher_adresser_document($doc, $rev=false) {
18        switch ($rev) {
19                case false:
20                        if (!preg_match(',^(?:IMG/)?([^/]+)/([^/]+\.\1)$,S', $doc, $r))
21                                return false;
22                        $m = md5($r[2]);
23                        return $r[1].'/'.$m[0].'/'.$m[1].'/'.$m[2].'/'.$r[2];
24                case true:
25                        if (!preg_match(',^(?:IMG/)?([^/]+)/./././([^/]+\.\1)$,S', $doc, $r))
26                                return false;
27                        return $r[1].'/'.$r[2];
28        }
29}
30
31/* Deplacer un fichier et sa reference dans la base de donnees
32 * avec tous les controles d'erreur
33 *
34 * @param int $id_document
35 * @param bool $rev
36 * @return bool
37 */
38function hasher_deplacer_document($id_document, $corriger=false, $rev=false) {
39
40        // 1. recuperer les donnees du document
41        // et verifier qu'on peut le hasher
42        if (!$id_document = intval($id_document)){
43                spip_log("Erreur hasher_deplacer_document intval $id_document", 'hash');
44                return false;
45        }
46        if (!$s = spip_query('SELECT fichier FROM spip_documents WHERE id_document='.$id_document)
47        OR !$t = spip_fetch_array($s)) {
48                spip_log("Erreur hasher_deplacer_document select doc=$id_document ".var_export($s, true), 'hash');
49                return false;
50        }
51        $src = $t['fichier'];
52
53        // savoir si on a IMG/ devant (en SPIP 1.9.2) ou pas (SPIP 2)
54        $img = preg_match(',^IMG/,', $src)
55                ? 'IMG/' : '';
56        $dir_ref = preg_match(',^IMG/,', $src)
57                ? _DIR_RACINE : _DIR_IMG;
58
59        // On fabrique le nom du fichier dest
60        if (!$dest = hasher_adresser_document($src, $rev)) {
61                spip_log("Erreur hasher_adresser_document($src) rev : $rev", 'hash');
62                return false;
63        }
64
65        // si le src n'existe pas, ciao, enfin presque
66        if (!file_exists($dir_ref.$src)) {
67                spip_log("Erreur hasher_deplacer_document id_document $id_document fichier $dir_ref $src n'existe pas", 'hash');
68
69                // si le src n'existe pas, on verifie qu'il n'a pas deja ete déplace (ie le dest existe),
70                // et si oui, on modifie juste le chemin en base...
71                if($corriger) {
72                        if(file_exists(_DIR_IMG.$dest)){
73                                // on note la destination finale
74                                if (!spip_query('UPDATE spip_documents SET fichier="'.$img.$dest.'" WHERE id_document='.$id_document)) {
75                                        spip_log("erreur hasher_deplacer_document update correction $img $dest doc $id_document", 'hash');
76                                        return false;
77                                } else {
78                                        spip_log("hasher_deplacer_document fichier "._DIR_IMG."$dest existe deja, Table corrigee", 'hash');
79                                        return true ;
80                                }
81                        } else {
82                                spip_log("hasher_deplacer_document fichier "._DIR_IMG."$dest n'existe pas", 'hash');
83                        }
84                }
85                return false ;
86        }
87
88        // si le dest existe deja, renommer jusqu'a trouver un creneau libre
89        $i = 0;
90        while (file_exists(_DIR_IMG.$dest)) {
91                $i++;
92                $dest = preg_replace(',(-\d+)?(\.[^.]+)$,', '-'.$i.'\2', $dest);
93        }
94
95        // 2. creer au besoin les sous-repertoires
96        if (!is_dir(_DIR_IMG.$dir = dirname($dest))
97        AND !mkdir(_DIR_IMG.$dir, _SPIP_CHMOD, /* recursive, php5 */ true)) {
98                spip_log("erreur hasher_deplacer_document mkdir($dir)", 'hash');
99                return false;
100        }
101
102        // 3. Section critique : il faut modifier dans la base *et* deplacer
103        // on note les fichiers en cours de deplacement avec un - devant ; si
104        // ca casse on saura reparer
105        if (!spip_query('UPDATE spip_documents SET fichier=CONCAT("-", fichier) WHERE id_document='.$id_document)) {
106                spip_log("erreur hasher_deplacer_document update 1", 'hash');
107                return false;
108        }
109        // on deplace
110        if (!rename($dir_ref.$src, _DIR_IMG.$dest)) {
111                spip_log("erreur hasher_deplacer_document rename", 'hash');
112                spip_query('UPDATE spip_documents SET fichier="'.$src.'" WHERE id_document='.$id_document);
113                return false;
114        }
115        // on note la destination finale
116        if (!spip_query('UPDATE spip_documents SET fichier="'.$img.$dest.'" WHERE id_document='.$id_document)) {
117                spip_log("erreur hasher_deplacer_document update 2", 'hash');
118                return false;
119        }
120
121        // 4. Ouf c'est fini et sans erreur
122        return true;
123}
124
125
126/* Cette fonction prend les n documents non hashés les plus récents,
127 * et appelle hasher_deplacer_document() sur chacun d'eux. Elle renvoie
128 * un array() contenant les id_document des documents qu'elle a déplacés.
129 * @param int $n
130 * @param bool $rev
131 * @return array
132 * @return bool
133 */
134function hasher_deplacer_n_documents($n, $corriger=false, $rev=false) {
135        $docs = array();
136        static $dejafait = false;
137
138        // Une seule fois par hit (cas de l'insertion de plusieurs docs venant d'un zip)
139        if ($dejafait) return $docs ;
140        $dejafait = true;
141
142        if (!$n = intval($n)
143        OR !$s = spip_query($q = "SELECT id_document FROM spip_documents WHERE fichier REGEXP '^(IMG/)?[^/]+/"
144        . ($rev ? "./././" : "")
145        ."[^/]+$' AND distant='non' ORDER BY date DESC LIMIT $n")) {
146                spip_log("erreur hasher_deplacer_n_documents requete $q", 'hash');
147                return false;
148        }
149
150        while ($t = spip_fetch_array($s)) {
151                $id_document = $t['id_document'];
152                if (hasher_deplacer_document($id_document, $corriger, $rev))
153                        $docs[] = $id_document;
154        }
155
156        return $docs;
157}
158
159/* Compte les documents hashes et non hashes
160 * @return array
161 */
162function hasher_compter_documents() {
163
164        $s = spip_query($q = "SELECT COUNT(*) FROM spip_documents WHERE fichier REGEXP '^(IMG/)?[^/]+/"
165        ."[^/]+$' AND distant='non'");
166        $non = array_pop(spip_fetch_array($s));
167        $s = spip_query($q = "SELECT COUNT(*) FROM spip_documents WHERE fichier REGEXP '^(IMG/)?[^/]+/"
168        . "./././"
169        ."[^/]+$' AND distant='non'");
170        $oui = array_pop(spip_fetch_array($s));
171
172        return array($oui, $non);
173}
174
175/* Pipeline post_edition pour agir apres ajout de nouveaux documents via upload
176 * @param array $flux
177 * @return array
178 */
179function hasher_post_edition($flux) {
180        if ($flux['args']['operation'] == 'ajouter_document'
181        AND $id = intval($flux['args']['id_objet'])) {
182                hasher_deplacer_document($id);
183                hasher_deplacer_n_documents(10);
184        }
185        return $flux;
186}
187
188function htaccess_est_installe($htaccess){
189        if (!lire_fichier($htaccess, $contenu)
190        OR !preg_match(',hash_404,', $contenu)) {
191                return false ;
192        } else {
193                return true ;
194        }
195}
196?>
Note: See TracBrowser for help on using the repository browser.