source: spip-zone/_plugins_/hash_documents/hash_fonctions.php @ 48997

Last change on this file since 48997 was 32396, checked in by fil@…, 12 years ago

plugin hash_documents, cf. http://www.spip-contrib.net/Le-plugin-hash_documents

File size: 4.7 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, $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                return false;
44        if (!$s = spip_query('SELECT fichier FROM spip_documents WHERE id_document='.$id_document)
45        OR !$t = spip_fetch_array($s)) {
46                spip_log("erreur select doc=$id_document ".var_export($s, true), 'hash');
47                return false;
48        }
49        $src = $t['fichier'];
50
51        // savoir si on a IMG/ devant (en SPIP 1.9.2) ou pas (SPIP 2)
52        $img = preg_match(',^IMG/,', $src)
53                ? 'IMG/' : '';
54        $dir_ref = preg_match(',^IMG/,', $src)
55                ? _DIR_RACINE : _DIR_IMG;
56
57        // si le src n'existe pas, ciao
58        if (!file_exists($dir_ref.$src)) {
59                spip_log("fichier $src n'existe pas", 'hash');
60                return false;
61        }
62
63        if (!$dest = hasher_adresser_document($src, $rev)) {
64                spip_log("erreur hasher_adresser_document($src)", 'hash');
65                return false;
66        }
67
68        // si le dest existe deja, renommer jusqu'a trouver un creneau libre
69        $i = 0;
70        while (file_exists(_DIR_IMG.$dest)) {
71                $i++;
72                $dest = preg_replace(',(-\d+)?(\.[^.]+)$,', '-'.$i.'\2', $dest);
73        }
74
75        // 2. creer au besoin les sous-repertoires
76        if (!is_dir(_DIR_IMG.$dir = dirname($dest))
77        AND !mkdir(_DIR_IMG.$dir, _SPIP_CHMOD, /* recursive, php5 */ true)) {
78                spip_log("erreur mkdir($dir)", 'hash');
79                return false;
80        }
81
82        // 3. Section critique : il faut modifier dans la base *et* deplacer
83        // on note les fichiers en cours de deplacement avec un - devant ; si
84        // ca casse on saura reparer
85        if (!spip_query('UPDATE spip_documents SET fichier=CONCAT("-", fichier) WHERE id_document='.$id_document)) {
86                spip_log("erreur update 1", 'hash');
87                return false;
88        }
89        // on deplace
90        if (!rename($dir_ref.$src, _DIR_IMG.$dest)) {
91                spip_log("erreur rename", 'hash');
92                spip_query('UPDATE spip_documents SET fichier="'.$src.'" WHERE id_document='.$id_document);
93                return false;
94        }
95        // on note la destination finale
96        if (!spip_query('UPDATE spip_documents SET fichier="'.$img.$dest.'" WHERE id_document='.$id_document)) {
97                spip_log("erreur update 2", 'hash');
98                return false;
99        }
100
101        // 4. Ouf c'est fini et sans erreur
102        return true;
103}
104
105
106/* Cette fonction prend les n documents non hashés les plus récents,
107 * et appelle hasher_deplacer_document() sur chacun d'eux. Elle renvoie
108 * un array() contenant les id_document des documents qu'elle a déplacés.
109 * @param int $n
110 * @param bool $rev
111 * @return array
112 * @return bool
113 */
114function hasher_deplacer_n_documents($n, $rev=false) {
115        if (!$n = intval($n)
116        OR !$s = spip_query($q = "SELECT id_document FROM spip_documents WHERE fichier REGEXP '^(IMG/)?[^/]+/"
117        . ($rev ? "./././" : "")
118        ."[^/]+$' AND distant='non' ORDER BY date DESC LIMIT $n")) {
119                spip_log("erreur requete $q", 'hash');
120                return false;
121        }
122
123        $docs = array();
124        while ($t = spip_fetch_array($s)) {
125                $id_document = $t['id_document'];
126                if (hasher_deplacer_document($id_document, $rev))
127                        $docs[] = $id_document;
128        }
129
130        return $docs;
131}
132
133/* Compte les documents hashes et non hashes
134 * @return array
135 */
136function hasher_compter_documents() {
137        $s = spip_query($q = "SELECT COUNT(*) FROM spip_documents WHERE fichier REGEXP '^(IMG/)?[^/]+/"
138        ."[^/]+$' AND distant='non'");
139        $non = array_pop(spip_fetch_array($s));
140        $s = spip_query($q = "SELECT COUNT(*) FROM spip_documents WHERE fichier REGEXP '^(IMG/)?[^/]+/"
141        . "./././"
142        ."[^/]+$' AND distant='non'");
143        $oui = array_pop(spip_fetch_array($s));
144
145        return array($oui, $non);
146}
147
148/* Pipeline post_edition pour agir apres ajout de nouveaux documents via upload
149 * @param array $flux
150 * @return array
151 */
152function hasher_post_edition($flux) {
153        if ($flux['args']['operation'] == 'ajouter_document'
154        AND $id = intval($flux['args']['id_objet'])) {
155                hasher_deplacer_document($id);
156                hasher_deplacer_n_documents(10);
157        }
158        return $flux;
159}
160
161?>
Note: See TracBrowser for help on using the repository browser.