source: spip-zone/_plugins_/medias_nettoyage/trunk/medias_nettoyage_fonctions.php @ 82915

Last change on this file since 82915 was 82915, checked in by teddy.spip@…, 7 years ago

On utilise la fonction native de SPIP pour retrouver le type du logo.
Préparation de la fonction avant un 'gros' remaniement pour savoir si un logo est orphelin ou pas.

  • Property svn:executable set to *
File size: 32.0 KB
Line 
1<?php
2/**
3 * Fonctions principales du plugin "Nettoyer la médiathèque"
4 *
5 * @plugin     Nettoyer la médiathèque
6 * @copyright  2014
7 * @author     Teddy Payet
8 * @licence    GNU/GPL
9 * @package    SPIP\Medias_nettoyage\Fonctions
10 */
11
12if (!defined('_ECRIRE_INC_VERSION')) {
13    return;
14}
15include_spip('base/abstract_sql');
16include_spip('inc/documents');
17include_spip('inc/chercher_logo');
18
19/**
20 * Lister les extensions enregistrées dans la table spip_documents.
21 *
22 * @return array
23 *         Tableau des extensions uniques
24 */
25function medias_lister_extensions_documents ()
26{
27    $extensions = array();
28    $extensions_cibles = sql_allfetsel('DISTINCT extension', 'spip_documents');
29    // On vérifie bien qu'on reçoit un tableau.
30    if (is_array($extensions_cibles) and count($extensions_cibles) > 0) {
31        foreach ($extensions_cibles as $extension) {
32            $extensions[] = $extension['extension'];
33        }
34    }
35    // On rajoute le répertoire "vignettes"
36    $extensions[] = 'vignettes';
37    return $extensions ;
38}
39
40/**
41 * Créer les répertoires des extensions des documents enregistrés en BDD.
42 *
43 * @uses medias_lister_extensions_documents()
44 * @uses _DIR_IMG
45 *
46 * @param  string $repertoire_img
47 *         Par défaut, on prend _DIR_IMG en référence.
48 *         On peut l'utiliser aussi pour le répertoire IMG/orphelins
49 * @return void
50 */
51function medias_creer_extensions_repertoires ($repertoire_img = _DIR_IMG)
52{
53    $extensions = medias_lister_extensions_documents();
54
55    if (is_array($extensions) and count($extensions) > 0) {
56        foreach ($extensions as $extension) {
57            if (!is_dir($repertoire_img . $extension)) {
58                @mkdir($repertoire_img . $extension, _SPIP_CHMOD);
59            }
60        }
61    }
62    return;
63}
64
65/**
66 * Créer le répertoire "IMG/orphelins".
67 * Plus pratique d'avoir une fonction qu'on appellera en cas de besoin.
68 *
69 * @uses _MEDIAS_NETTOYAGE_REP_ORPHELINS
70 *
71 * @return void
72 */
73function medias_creer_repertoires_orphelins ()
74{
75    if (!is_dir(_MEDIAS_NETTOYAGE_REP_ORPHELINS)) {
76        @mkdir(_MEDIAS_NETTOYAGE_REP_ORPHELINS, _SPIP_CHMOD);
77    }
78    return;
79}
80
81/**
82 * Lister les répertoires présents dans IMG/ sans les sous-répertoires.
83 *
84 * @param  string $repertoire_img
85 *         Par défaut, on prend _DIR_IMG en référence.
86 *         On peut l'utiliser aussi pour le répertoire IMG/orphelins ou tout autre nom de répertoire.
87 * @return array
88 */
89function medias_lister_repertoires ($repertoire_img = _DIR_IMG)
90{
91    $repertoires = array();
92    // On vérifie que $repertoire_img passé en paramètre est bien un répertoire existant.
93    // cf. ../IMG/orphelins qui ne serait pas encore créé.
94    if (is_dir($repertoire_img)) {
95        // Avec la fonction scandir, on liste le contenu (existant) du répertoire cible.
96        $rep_img = array_diff(scandir($repertoire_img), array('..','.','.svn')); // On ne liste pas le répertoire .svn
97        foreach ($rep_img as $repertoire) {
98            // On vérifie que c'est un répertoire et non un fichier.
99            if (is_dir($repertoire_img . $repertoire)) {
100                $repertoires[] = $repertoire_img . $repertoire;
101            }
102        }
103    }
104
105    return (array) $repertoires;
106}
107
108/**
109 * Lister tous les fichiers non distants enregistrés en BDD
110 *
111 * @uses get_spip_doc()
112 *
113 * @return array
114 *         Tableau contenant les urls des fichiers
115 */
116function medias_lister_documents_bdd ()
117{
118    $docs_fichiers = array();
119
120    $docs_bdd = sql_allfetsel('fichier', 'spip_documents', "distant='non' AND fichier!=''");
121    // On vérifie que nous avons au moins un élément dans le tableau
122    if (count($docs_bdd) > 0) {
123        foreach ($docs_bdd as $doc) {
124            /**
125             * On formate par rapport au répertoire ../IMG/
126             * On évite les doubles // qu'il peut y avoir
127             */
128            $docs_fichiers[] = preg_replace("/\/\//", "/", get_spip_doc($doc['fichier']));
129        }
130        // on enlève les url vides issues de la base :
131        $docs_fichiers = array_filter($docs_fichiers);
132    }
133
134    // On trie dans l'ordre alphabétique :
135    sort($docs_fichiers);
136
137    return (array) $docs_fichiers;
138}
139
140/**
141 * Donner la taille en octets des documents non-distants enregistrés en BDD
142 *
143 * @return integer
144 */
145function medias_lister_documents_bdd_taille()
146{
147    $docs_bdd = sql_fetsel('SUM(taille) AS taille_totale', 'spip_documents', "distant='non' AND fichier!=''");
148    return $docs_bdd['taille_totale'];
149}
150
151/**
152 * Afficher le nombre de documents enregistrés en BDD
153 *
154 * @return integer|string
155 */
156function medias_lister_documents_bdd_complet_compteur ()
157{
158    return sql_countsel('spip_documents');
159}
160
161/**
162 * Donner la taille en octets de tous les documents enregistrés en BDD
163 *
164 * @return integer|string
165 */
166function medias_lister_documents_bdd_complet_taille()
167{
168    $docs_bdd = sql_fetsel('SUM(taille) AS taille_totale', 'spip_documents', "id_document > 0");
169    return $docs_bdd['taille_totale'];
170}
171
172/**
173 * Lister les documents enregistrés en BDD
174 * mais n'ayant plus de fichiers physiques dans IMG/
175 *
176 * @uses medias_lister_documents_bdd()
177 * @uses medias_lister_documents_repertoire()
178 *
179 * @return array
180 */
181function medias_lister_documents_bdd_orphelins()
182{
183    $docs_bdd = array_unique(array_diff(medias_lister_documents_bdd(), medias_lister_documents_repertoire()));
184    sort($docs_bdd);
185    return (array) $docs_bdd;
186}
187
188/**
189 * Donner la taille en octets des documents enregistrés en BDD
190 *
191 * @uses medias_lister_documents_bdd_orphelins()
192 * @uses _DIR_IMG
193 * @uses get_spip_doc()
194 *
195 * @return integer
196 */
197function medias_lister_documents_bdd_orphelins_taille()
198{
199    $docs_orphelins    = medias_lister_documents_bdd_orphelins();
200    $taille         = 0;
201    $pattern_img        = "/" . preg_replace("/\//", "\/", _DIR_IMG) . "/";
202
203    if (count($docs_orphelins) > 0) {
204        $docs_bdd = sql_allfetsel(
205            'fichier,taille',
206            'spip_documents',
207            "fichier IN ('"
208            . join("','", preg_replace($pattern_img, '', $docs_orphelins)) . "')"
209        );
210        if (is_array($docs_bdd) and count($docs_bdd) > 0) {
211            foreach ($docs_bdd as $document_bdd) {
212                if (!file_exists(get_spip_doc($document_bdd['fichier']))) {
213                    $taille = $taille + ($document_bdd['taille']/1000);
214                    // On divise par 1000 pour éviter la limite de l'integer php.
215                }
216            }
217        }
218    }
219    return $taille * 1000;
220}
221
222/**
223 * Lister les documents présents dans le répertoire des extensions de IMG/
224 *
225 * @uses medias_lister_extensions_documents()
226 * @uses medias_lister_logos_fichiers()
227 *
228 * @param string $repertoire_img
229 *        On peut passer un nom de répertoire/chemin en paramètre.
230 *        Par défaut, on prend le répertoire IMG/
231 * @return array
232 */
233function medias_lister_documents_repertoire ($repertoire_img = _DIR_IMG)
234{
235    $docs_fichiers = array();
236
237    foreach (medias_lister_extensions_documents() as $extension) {
238        // Par sécurité, on vérifie que l'extension a bel
239        // et bien un répertoire physique
240        if (is_dir($repertoire_img . $extension)) {
241            // On va chercher dans IMG/$extension/*.*
242            $fichiers = glob($repertoire_img . "$extension/*.*");
243            if (is_array($fichiers) and count($fichiers) > 0) {
244                foreach ($fichiers as $fichier) {
245                    $docs_fichiers[] = preg_replace("/\/\//", "/", $fichier);
246                }
247            }
248        }
249    }
250    // On va chercher dans IMG/*.*
251    $fichiers = glob($repertoire_img . "*.*");
252    // On vérifie que c'est bien un tableau, avec au moins un élément.
253    if (is_array($fichiers) and count($fichiers) > 0) {
254        foreach ($fichiers as $fichier) {
255            $docs_fichiers[] = $fichier;
256        }
257    }
258    $docs_fichiers = array_unique(
259        array_diff(
260            $docs_fichiers,
261            medias_lister_logos_fichiers()
262        )
263    );
264    sort($docs_fichiers);
265
266    return (array) $docs_fichiers;
267}
268
269/**
270 * Retourner la taille en octets des fichiers physiques présents
271 * dans les répertoires d'extensions de IMG
272 *
273 * @uses medias_lister_documents_repertoire()
274 * @uses medias_calculer_taille_fichiers()
275 *
276 * @return integer
277 */
278function medias_lister_documents_repertoire_taille ()
279{
280    return medias_calculer_taille_fichiers(medias_lister_documents_repertoire());
281}
282
283/**
284 * Lister les fichiers physiques présents dans IMG/ mais qui ne sont plus dans la BDD.
285 *
286 * @uses medias_lister_documents_repertoire()
287 * @uses medias_lister_documents_bdd()
288 *
289 * @return array
290 */
291function medias_lister_documents_repertoire_orphelins ()
292{
293    $docs_fichiers = array_unique(array_diff(medias_lister_documents_repertoire(), medias_lister_documents_bdd()));
294    sort($docs_fichiers);
295    return (array) $docs_fichiers;
296}
297
298/**
299 * Retourner la taille en octets des fichiers physiques orphelins
300 * présents dans les répertoires d'extensions de IMG
301 *
302 * @uses medias_lister_documents_repertoire_orphelins()
303 * @uses medias_calculer_taille_fichiers()
304 *
305 * @return integer
306 */
307function medias_lister_documents_repertoire_orphelins_taille ()
308{
309    return medias_calculer_taille_fichiers(medias_lister_documents_repertoire_orphelins());
310}
311
312/**
313 * Lister tous les fichiers contenus dans le répertoire IMG/
314 * y compris les logos.
315 *
316 * @param string $repertoire_img
317 *        On peut passer un nom de répertoire/chemin en paramètre.
318 *        Par défaut, on prend le répertoire IMG/
319 * @return array
320 */
321function medias_lister_documents_repertoire_complet ($repertoire_img = _DIR_IMG)
322{
323    $docs_fichiers = array();
324
325    // On va chercher dans IMG/distant/*/*.*
326        // Exemple : IMG/distant/jpg/nom_fichier.jpg
327    $fichiers = glob($repertoire_img . "*/*/*.*");
328    if (is_array($fichiers) and count($fichiers) > 0) {
329        foreach ($fichiers as $fichier) {
330            $docs_fichiers[] = preg_replace("/\/\//", "/", $fichier);
331            // On évite les doubles slashs '//' qui pourrait arriver comme un cheveu sur la soupe.
332        }
333    }
334
335    // On va chercher dans IMG/*/*.*
336        // Exemple : IMG/pdf/nom_fichier.pdf
337    $fichiers = glob($repertoire_img . "*/*.*");
338    if (is_array($fichiers) and count($fichiers) > 0) {
339        foreach ($fichiers as $fichier) {
340            $docs_fichiers[] = preg_replace("/\/\//", "/", $fichier);
341        }
342    }
343
344    // On va chercher dans IMG/*.*
345        // Exemple : IMG/arton4.png
346    $fichiers = glob($repertoire_img . "*.*");
347    if (is_array($fichiers) and count($fichiers) > 0) {
348        foreach ($fichiers as $fichier) {
349            $docs_fichiers[] = preg_replace("/\/\//", "/", $fichier);
350        }
351    }
352
353    $docs_fichiers = array_unique($docs_fichiers);
354    sort($docs_fichiers);
355
356    return (array) $docs_fichiers;
357}
358
359/**
360 * Retourner la taille en octets des fichiers physiques présents
361 * dans IMG/
362 *
363 * @uses medias_lister_documents_repertoire_complet()
364 * @uses medias_calculer_taille_fichiers()
365 *
366 * @param string $repertoire_img
367 *        On peut passer un nom de répertoire/chemin en paramètre.
368 *        Par défaut, on prend le répertoire IMG/
369 * @return integer
370 */
371function medias_lister_documents_repertoire_complet_taille ($repertoire_img = _DIR_IMG)
372{
373    return medias_calculer_taille_fichiers(medias_lister_documents_repertoire_complet($repertoire_img));
374}
375
376/**
377 * Lister les logos des objets éditoriaux
378 * Prend en compte les cas particuliers suivants :
379 * - articles (art)
380 * - rubriques (rub)
381 * - sites syndiqués (site)
382 * - auteurs (aut)
383 *
384 * @uses lister_tables_principales()
385 *       liste en spip 3 les tables principales reconnues par SPIP
386 * @uses id_table_objet()
387 *       retourne la clé primiare de l'objet
388 * @uses type_du_logo()
389 *       retourne le type de logo tel que `art` depuis le nom de la clé primaire de l'objet
390 *
391 * @param null|string $mode
392 *        + `null` : stockera dans le tableau tous les logos,
393 *        quelque soit le mode du logo
394 *        + `on` : stockera dans le tableau tous les logos du mode "on"
395 *        + `off` : stockera dans le tableau tous les logos du mode "off"
396 * @param string $repertoire_img
397 *        On peut passer un nom de répertoire/chemin en paramètre.
398 *        Par défaut, on prend le répertoire IMG/
399 * @return array
400 */
401function medias_lister_logos_fichiers ($mode = null, $repertoire_img = _DIR_IMG)
402{
403
404    include_spip('inc/chercher_logo');
405
406    if (intval(spip_version()) == 2) {
407        include_spip('base/connect_sql');
408        $tables_objets = (isset($GLOBALS['tables_principales']))
409        ? array_keys($GLOBALS['tables_principales'])
410        : array('spip_articles',
411            'spip_rubriques',
412            'spip_auteurs',
413            'spip_breves',
414            'spip_documents',
415            'spip_syndic',
416            'spip_mots',
417            'spip_forum',
418            'spip_groupes_mots');
419    } elseif (intval(spip_version()) == 3) {
420        include_spip('base/objets');
421        $tables_objets = array_keys(lister_tables_principales());
422    }
423
424    global $formats_logos;
425    $docs_fichiers_on   = array();
426    $docs_fichiers_off  = array();
427    // Avec l'utilisation de type_du_logo(), ceci n'est plus obligatoire
428    // mais à garder par sécurité.
429    $logos_objet        = array('art','rub','breve','site','mot','aut');
430    $fichiers           = array();
431
432    // On va chercher toutes les tables principales connues de SPIP
433    foreach ($tables_objets as $table) {
434        // On cherche son type d'objet et on l'ajoute aux logos
435        // Il y a aussi dans ces objets la référence à `article`,
436        // `rubrique` et `auteur`
437        // Grâce à la fonction `id_table_objet()`, on retrouve le nom de la clé primaire de l'objet.
438        // `type_du_logo()` retourne le type de logo tel que `art` depuis le nom de la clé primaire de l'objet
439        $logos_objet[] = type_du_logo(id_table_objet($table));
440    }
441    // On enlève les doublons
442    $logos_objet = array_unique($logos_objet);
443    sort($logos_objet);
444
445    // On va chercher le logo du site.
446    // On force la recherche sur cet élément même si la recherche "classique"
447    // devrait gérer cela initialement…
448    $logo_site = glob($repertoire_img . "site{on|off}0.*", GLOB_BRACE);
449    // On évite d'utiliser la fonction `glob()` directement dans le if car ça peut créer un bug pour PHP <5.4
450    // S'il n'y a pas de siteon0.ext, `glob()` va retourner un `false`. Donc, on regarde si c'est bien un tableau.
451    // cf. http://contrib.spip.net/Nettoyer-la-mediatheque#forum475712
452    if (is_array($logo_site) and count($logo_site) > 0) {
453        $fichiers = array_merge($fichiers, $logo_site);
454    }
455
456    // On va chercher dans IMG/*(on|off)*.*
457    // On fait un foreach pour ne pas avoir de
458    // "Pattern exceeds the maximum allowed length of 260 characters"
459    // sur glob()
460    foreach ($logos_objet as $logo_pattern) {
461        // la regex de GLOB_BRACE est très basique...
462        $liste = glob($repertoire_img . "{" . $logo_pattern ."}{on,off}*.*", GLOB_BRACE);
463        if (is_array($liste) and count($liste) > 0) {
464            $fichiers = array_merge($fichiers, $liste);
465        }
466    }
467
468    // Il faut avoir au moins un élément dans le tableau de fichiers.
469    if (is_array($fichiers) and count($fichiers) > 0) {
470        foreach ($fichiers as $fichier) {
471            // ... Donc on fait une regex plus poussée avec un preg_match
472            if (
473                preg_match(
474                    "/("
475                    . join("|", $logos_objet)
476                    .")on(\d+).("
477                    . join("|", $formats_logos)
478                    .")$/",
479                    $fichier,
480                    $resultat
481                )
482            ) {
483                $docs_fichiers_on[] = preg_replace("/\/\//", "/", $fichier);
484            }
485            if (
486                preg_match(
487                    "/("
488                    . join("|", $logos_objet)
489                    .")off(\d+).("
490                    . join("|", $formats_logos)
491                    .")$/",
492                    $fichier
493                )
494            ) {
495                $docs_fichiers_off[] = preg_replace("/\/\//", "/", $fichier);
496            }
497        }
498    }
499    if ($mode == 'on') {
500        $docs_fichiers_on = array_unique($docs_fichiers_on);
501        sort($docs_fichiers_on); // On trie dans l'ordre alphabétique
502        return $docs_fichiers_on;
503    } elseif ($mode == 'off') {
504        $docs_fichiers_off = array_unique($docs_fichiers_off);
505        sort($docs_fichiers_off); // On trie dans l'ordre alphabétique
506        return $docs_fichiers_off;
507    } else {
508        $docs_fichiers = array_unique(array_merge($docs_fichiers_on, $docs_fichiers_off));
509        sort($docs_fichiers); // On trie dans l'ordre alphabétique
510        return $docs_fichiers;
511    }
512
513}
514
515/**
516 * Retourner la taille en octets des logos présents
517 * dans IMG/
518 *
519 * @uses medias_lister_logos_fichiers()
520 * @uses medias_calculer_taille_fichiers()
521 *
522 * @param null|string $mode
523 *        + `null` : calculera le poids de tous les logos,
524 *        quelque soit le mode du logo
525 *        + `on` : calculera le poids de tous les logos du mode "on"
526 *        + `off` : calculera le poids de tous les logos du mode "off"
527 * @return integer|string
528 */
529function medias_lister_logos_fichiers_taille ($mode = null)
530{
531    return medias_calculer_taille_fichiers(medias_lister_logos_fichiers($mode));
532}
533
534/**
535 * Vérifier si l'objet associé au logo passé en paramètre est toujours
536 * enresgitré en base de données.
537 *
538 * @param  string $fichier
539 *         nom du fichier de logo
540 * @return bool
541 *         - `true` : si l'objet est toujours en bdd ;
542 *         - `false` : si l'objet n'est plus en bdd.
543 */
544function medias_verifier_logos_objet ($fichier = 'on')
545{
546    if ($fichier == null) {
547        return;
548    }
549    $composer = charger_fonction('composer', 'public');
550    $chercher_logo = charger_fonction('chercher_logo', 'inc');
551}
552
553/**
554 * Fonction générique pour calculer la taille des fichiers passés en paramètre
555 *
556 * @param  array  $fichiers
557 *         Tableau contenant l'url des fichiers physiques
558 * @return integer
559 *         On multiplie par 1000 la variable $taille pour avoir le chiffre réel
560 *         C'est un hack pour contourner la limite d'integer (4 bytes => 0xefffffff).
561 *         Au dessus de 4026531839, il passe à float négatif.
562 *         // a vérifier tout de même selon l'OS 32bit ou 64bit.
563 */
564function medias_calculer_taille_fichiers ($fichiers = array())
565{
566    $taille = 0;
567    if (count($fichiers) > 0) {
568        foreach ($fichiers as $fichier) {
569            if (file_exists($fichier)) {
570                $taille += filesize($fichier) /1000;
571            }
572        }
573        if (is_float($taille) or $taille > 0) {
574            return $taille *1000;
575        } else {
576            return $taille;
577        }
578    } else {
579        return $taille;
580    }
581}
582
583/**
584 * Lister les répertoires à la racine de IMG/orphelins.
585 * Cette fonction vérifie l'existence du répertoire IMG/orphelins
586 * avant de lister les répertoires.
587 *
588 * @uses medias_lister_repertoires()
589 * @uses _MEDIAS_NETTOYAGE_REP_ORPHELINS
590 *
591 * @return array
592 */
593function medias_lister_repertoires_orphelins ()
594{
595    if (is_dir(_MEDIAS_NETTOYAGE_REP_ORPHELINS)) {
596        return medias_lister_repertoires(_MEDIAS_NETTOYAGE_REP_ORPHELINS);
597    } else {
598        return array();
599    }
600}
601
602/**
603 * Lister le contenu du répertoire IMG/orphelins
604 *
605 * @uses medias_lister_documents_repertoire_complet()
606 * @uses _MEDIAS_NETTOYAGE_REP_ORPHELINS
607 *
608 * @return array
609 */
610function medias_lister_repertoires_orphelins_fichiers ()
611{
612    $repertoire_orphelins   = _MEDIAS_NETTOYAGE_REP_ORPHELINS;
613    $docs_fichiers      = array();
614
615    if (is_dir($repertoire_orphelins)) {
616        $docs_fichiers = medias_lister_documents_repertoire_complet($repertoire_orphelins);
617    }
618    return (array) $docs_fichiers;
619}
620
621/**
622 * Lister le contenu du répertoire IMG/orphelins
623 *
624 * @uses medias_calculer_taille_fichiers()
625 * @uses medias_lister_documents_repertoire_complet()
626 * @uses _MEDIAS_NETTOYAGE_REP_ORPHELINS
627 *
628 * @return integer
629 */
630function medias_lister_repertoires_orphelins_fichiers_taille ()
631{
632    $repertoire_orphelins   = _MEDIAS_NETTOYAGE_REP_ORPHELINS;
633    $taille         = 0;
634
635    if (is_dir($repertoire_orphelins)) {
636        return medias_calculer_taille_fichiers(medias_lister_documents_repertoire_complet($repertoire_orphelins));
637    } else {
638        return intval($taille);
639    }
640}
641
642/**
643 * Fonction 'bidon' pour tester une fonction rapidement sur la page ?exec=test_medias
644 *
645 * @return array
646 */
647function test_medias ()
648{
649    $test = array();
650    $test = medias_lister_logos_fichiers();
651    return $test;
652}
653
654/**
655 * Déplacer tous les répertoires de types 'cache-*' et 'icones*'
656 * SPIP normalement, avec la page "réparer la base", devrait répérer ce type
657 * de dossier. Mais il peut arriver parfois qu'on récupère des sites qui
658 * pour X raisons n'ont pas été nettoyé de ces coquilles.
659 *
660 * @uses medias_creer_repertoires_orphelins()
661 * @uses medias_lister_documents_bdd()
662 * @uses _DIR_IMG
663 * @uses _MEDIAS_NETTOYAGE_REP_ORPHELINS
664 *
665 * @return void
666 */
667function medias_deplacer_rep_obsoletes ()
668{
669    spip_log(
670        date_format(date_create(), 'Y-m-d H:i:s')
671        . ' : Début de la procédure de déplacement des répertoires obsolètes.',
672        "medias_nettoyage"
673    );
674
675    $pattern_obsoletes  = array("cache-","icones");
676    $repertoire_img     = _DIR_IMG;
677    $repertoire_orphelins   = _MEDIAS_NETTOYAGE_REP_ORPHELINS;
678    $repertoires_obsoletes  = array();
679    $message_log        = array();
680    $pattern_img        = "/" . preg_replace("/\//", "\/", $repertoire_img) . "/";
681
682    // On crée le répertoire IMG/orphelins
683    medias_creer_repertoires_orphelins();
684
685    // on cherche les fichiers de type IMG/cache-20x20-blabla.ext
686    $fichiers_obsoletes = find_all_in_path('IMG/', '/cache-');
687    // on vérifie tout de même que ces fichiers ne font pas parti des documents en BDD
688    $fichiers_obsoletes = array_unique(array_diff($fichiers_obsoletes, medias_lister_documents_bdd()));
689
690    foreach ($pattern_obsoletes as $pattern) {
691        $repertoires = glob($repertoire_img . $pattern . "*");
692        if (is_array($repertoires) and count($repertoires) > 0) {
693            $repertoires_obsoletes = array_merge($repertoires_obsoletes, $repertoires);
694        }
695    }
696    // on fusionne avec les fichiers obsolètes
697    $repertoires_obsoletes = array_merge($repertoires_obsoletes, $fichiers_obsoletes);
698
699    // on enlève les valeurs vides du tableau.
700    $repertoires_obsoletes = array_filter($repertoires_obsoletes);
701
702    if (count($repertoires_obsoletes) > 0) {
703        foreach ($repertoires_obsoletes as $repertoire_source) {
704            $repertoire_destination = preg_replace($pattern_img, $repertoire_orphelins, $repertoire_source);
705            @rename($repertoire_source, $repertoire_destination);
706            $message_log[] = date_format(date_create(), 'Y-m-d H:i:s')
707            . ' : Déplacement de '
708            . $repertoire_source
709            . ' vers '
710            . $repertoire_destination;
711        }
712    } else {
713        // S'il n'y a pas de dossiers obsolètes, on met un message histoire de ne pas rester dans le brouillard.
714        $message_log[] = date_format(date_create(), 'Y-m-d H:i:s')
715        . ' : Il n\'y a pas de dossiers ou de fichiers obsolètes';
716    }
717    spip_log(
718        "\n-------\n"
719        . join("\n", $message_log)
720        . "\n-------\n",
721        "medias_nettoyage"
722    );
723    spip_log(
724        date_format(date_create(), 'Y-m-d H:i:s')
725        . ' : Fin de la procédure de déplacement des répertoires obsolètes.',
726        "medias_nettoyage"
727    );
728    return;
729}
730
731/**
732 * On déplace tous les fichiers orphelins vers un répertoire orphelins dans IMG/
733 * On ne les supprime pas!
734 *
735 * @uses medias_creer_repertoires_orphelins()
736 * @uses medias_creer_extensions_repertoires()
737 * @uses medias_lister_documents_repertoire_orphelins()
738 * @uses _DIR_IMG
739 * @uses _MEDIAS_NETTOYAGE_REP_ORPHELINS
740 *
741 * @return array
742 */
743function medias_deplacer_documents_repertoire_orphelins ()
744{
745    /**
746     * On crée un log vraiment au début du script.
747     * Ainsi, on sait déjà en regardant les logs
748     * si le script est lancé ou pas.
749     */
750    spip_log(
751        date_format(date_create(), 'Y-m-d H:i:s')
752        . ' : Début de la procédure de déplacement.',
753        "medias_nettoyage"
754    );
755
756    $fichiers_orphelins     = medias_lister_documents_repertoire_orphelins();
757    $fichiers_deplaces  = array();
758    $message_log        = array();
759    $repertoire_orphelins   = _MEDIAS_NETTOYAGE_REP_ORPHELINS;
760    $pattern_img        = "/" . preg_replace("/\//", "\/", _DIR_IMG) . "/";
761
762    // On crée le répertoire IMG/orphelins s'il n'existe pas
763    medias_creer_repertoires_orphelins();
764    // On crée les répertoires d'extensions dans IMG/orphelins
765    medias_creer_extensions_repertoires($repertoire_orphelins);
766
767    // Si on n'a pas de fichiers orphelins, on ne lance pas la procédure.
768    if (count($fichiers_orphelins) > 0) {
769        foreach ($fichiers_orphelins as $fichier) {
770            $destination = preg_replace($pattern_img, $repertoire_orphelins, $fichier);
771            $chemin = explode('/', $destination);
772            $repertoires = '';
773            $profondeur = count($chemin) - 1;
774            $i = 0;
775            // On a déjà créé les répertoires d'extensions,
776            // mais on laisse cette sécu au cas où on a d'autres répertoires à créer.
777            while ($i < $profondeur) {
778                $repertoires = $repertoires . $chemin[$i] . '/';
779                $i++;
780            }
781            if (!is_dir($repertoires)) {
782                @mkdir($repertoires, _SPIP_CHMOD);
783                $message_log[] = date_format(date_create(), 'Y-m-d H:i:s')
784                . ' : le répertoire '
785                . $repertoires
786                . ' a été créé.';
787            }
788            // Hop, on déplace notre fichier vers IMG/orphelins
789            @rename($fichier, $destination);
790            $message_log[] = date_format(date_create(), 'Y-m-d H:i:s')
791            . ' : le fichier '
792            . $fichier
793            . ' a été déplacé vers '
794            . $destination
795            .'.';
796            // On construit un tableau dans le cas où qqn voudrait utiliser cette donnée.
797            // Pour le moment inutilisé.
798            $fichiers_deplaces[] = $destination;
799        }
800    } else {
801        $message_log[] = date_format(date_create(), 'Y-m-d H:i:s')
802        . ' : Il ne semble pas avoir de documents orphelins dans IMG/';
803    }
804
805    spip_log(
806        "\n-------\n"
807        . join("\n", $message_log)
808        . "\n-------\n",
809        "medias_nettoyage"
810    );
811    /**
812     * Et là, on marque bien la fin du script dans les logs.
813     */
814    spip_log(
815        date_format(date_create(), 'Y-m-d H:i:s')
816        . ' : Fin de la procédure de déplacement.',
817        "medias_nettoyage"
818    );
819
820    return true;
821}
822
823/**
824 * Réparer les documents.
825 * Il arrive parfois que suite à un problème de droits,
826 * les documents ne soient plus rangés correctement dans IMG/ext/fichier.ext
827 * mais dans un faux sous répertoire IMG/ext_fichier.ext
828 * Le présent script va recopier les fichiers mal placés,
829 * et changer leur référence dans la table spip_documents ;
830 * il donnera ensuite la liste des fichiers recopiés et
831 * des erreurs recontrées dans un fichier de log.
832 *
833 * Script repris de ce fichier :
834 * http://zone.spip.org/trac/spip-zone/browser/_outils_/repare_doc.html
835 *
836 * @uses medias_lister_logos_fichiers()
837 * @uses _DIR_IMG
838 *
839 * @return bool
840 */
841function medias_reparer_documents_fichiers ()
842{
843    /**
844     * On crée un log vraiment au début du script.
845     * Ainsi, on sait déjà en regardant les logs
846     * si le script est lancé ou pas.
847     */
848    spip_log(
849        date_format(date_create(), 'Y-m-d H:i:s')
850        . ' : Début de la procédure de réparation des documents.',
851        "medias_nettoyage"
852    );
853
854    $repertoire_img     = _DIR_IMG ;
855    $docs_fichiers      = array();
856    $pattern_img        = "/" . preg_replace("/\//", "\/", $repertoire_img) . "/";
857    $message_log        = array();
858
859    // On va chercher dans IMG/*.*
860    $fichiers = glob($repertoire_img . "*.*");
861    if (is_array($fichiers) and count($fichiers) > 0) {
862        foreach ($fichiers as $fichier) {
863            $docs_fichiers[] = $fichier;
864        }
865        $docs_fichiers = array_filter(
866            array_diff(
867                $docs_fichiers,
868                medias_lister_logos_fichiers()
869            )
870        ); // a voir si on n'a pas de logos ce que ça donne comme ça…
871    }
872    $docs_fichiers = preg_replace($pattern_img, '', $docs_fichiers);
873
874    if (count($docs_fichiers) > 0) {
875        // On va échapper chaque valeur d'url de fichier car
876        // il peut arriver d'avoir des apostrophes dans le nom de fichier...
877        // #fail
878        foreach ($docs_fichiers as $url_fichier) {
879            $url_fichiers[] = sql_quote($url_fichier);
880        }
881        $docs_bdd = sql_allfetsel(
882            'id_document,fichier',
883            'spip_documents',
884            "fichier IN ("
885            . join(",", $url_fichiers)
886            . ")"
887        );
888
889        if (is_array($docs_bdd) and count($docs_bdd) > 0) {
890            foreach ($docs_bdd as $document) {
891                $destination = preg_replace(',^([a-z0-3]+)_([^/]+\.(\1))$,i', '$1/$2', $document['fichier']);
892                // On va vérifier si on est bien sous la forme ../IMG/ext/nom_fichier.ext
893                // Sinon, on le construit manuellement.
894                // (ne pas oublier d'enlever '../IMG/' à notre variable de test
895                // car cette variable sera enresgitrée en BDD)
896                $destination_test = preg_replace($pattern_img, '', $destination);
897                if (count(explode("/", $destination_test)) == 1) {
898                    $destination = $document['extension'] . '/' . $destination_test ;
899                }
900                if ($document['fichier'] != $destination
901                    and rename($repertoire_img . $document['fichier'], $repertoire_img . $destination)) {
902                    sql_updateq(
903                        'spip_documents',
904                        array('fichier' => $destination),
905                        'id_document=' . $document['id_document']
906                    );
907                    $message_log[] = date_format(date_create(), 'Y-m-d H:i:s')
908                    . ' : le fichier '
909                    . $repertoire_img
910                    . $document['fichier']
911                    . ' a été déplacé vers '
912                    . $repertoire_img
913                    . $destination
914                    .'.';
915                } else {
916                    $message_log[] = date_format(date_create(), 'Y-m-d H:i:s')
917                    . ' : le fichier '
918                    . $repertoire_img
919                    . $document['fichier']
920                    . ' n\'a pu être déplacé vers '
921                    . $repertoire_img
922                    . $destination
923                    . '.';
924                }
925            }
926        }
927    } else {
928        $message_log[] = date_format(date_create(), 'Y-m-d H:i:s') . ' : Il n\'y a pas de documents à réparer.';
929    }
930
931    spip_log(
932        "\n-------\n"
933        . join("\n", $message_log)
934        . "\n-------\n",
935        "medias_nettoyage"
936    );
937    /**
938     * Et là, on marque bien la fin du script dans les logs.
939     */
940    spip_log(
941        date_format(date_create(), 'Y-m-d H:i:s')
942        . ' : Fin de la procédure de réparation des documents.',
943        "medias_nettoyage"
944    );
945
946    return true;
947}
948
949?>
Note: See TracBrowser for help on using the repository browser.