source: spip-zone/_plugins_/medias_dereferencer/trunk/medias_dereferencer_fonctions.php @ 96483

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

Un joli bug : le genie lançait la création des htaccess sans prendre en compte les valeurs de la configuration du plugin.
Donc, double vérification : dans le genie et la fonction.
Up de z

File size: 16.5 KB
Line 
1<?php
2
3/**
4 * Fonctions utiles au plugin Déréférencer les médias.
5 *
6 * @plugin     Déréférencer les médias
7 *
8 * @copyright  2015-2016
9 * @author     Teddy Payet
10 * @licence    GNU/GPL
11 */
12if (!defined('_ECRIRE_INC_VERSION')) {
13        return;
14}
15
16/**
17 * Lister les champs de type text (TINYTEXT, TEXT, MEDIUMTEXT, et LONGTEXT) des différentes principales de SPIP.
18 *
19 * @return array
20 *               Tableau avec pour clé le nom de la table.
21 */
22function medias_lister_champs_texte() {
23        include_spip('base/objets');
24        $lister_tables_objets_sql = lister_tables_objets_sql();
25        $lister_tables_principales = array_keys(lister_tables_principales());
26        $champs_texte = array();
27        foreach ($lister_tables_objets_sql as $table => $valeur) {
28                // On ne prend que les objets qui font partis des tables principales de SPIP.
29                // Donc, on ne prend pas les tables telles que spip_visites, spip_referers, etc.
30                // C'est une sécurité.
31                $id_primary_double = preg_match('/,/', $valeur['key']['PRIMARY KEY']); // l'id_primary doit faire référence à un seul champ
32                if (in_array($table, $lister_tables_principales) and $id_primary_double == 0) {
33                        $champs_texte[$table]['id_primary'] = $valeur['key']['PRIMARY KEY'];
34                        $champs_texte[$table]['objet'] = objet_type($champs_texte[$table]['id_primary']);
35                        $champs_texte[$table]['statut'] = (isset($valeur['field']['statut']) ? true : false);
36                        $champs_texte[$table]['publie'] = ($champs_texte[$table]['statut'] ? $valeur['statut'][0]['publie'] : false);
37
38                        foreach ($valeur['field'] as $champs => $descriptif) {
39                                if (preg_match('/text/', $descriptif)) {
40                                        $champs_texte[$table]['texte'][] = $champs;
41                                }
42                        }
43                        if (isset($champs_texte[$table]['texte'])) {
44                                $champs_texte[$table]['texte'] = implode(',', $champs_texte[$table]['texte']);
45                        } else {
46                                unset($champs_texte[$table]);
47                        }
48                }
49        }
50        $champs_texte = array_filter($champs_texte);
51
52        return $champs_texte;
53}
54
55/**
56 * On regarde les raccourcis typo <docXXX> <embXXX> <imgXXX> utilisés
57 * dans les rubriques de la région.
58 *
59 * @return array
60 */
61function medias_lister_medias_used_in_text() {
62        include_spip('base/abstract_sql');
63
64        $tables_texte = medias_lister_champs_texte();
65        $documents = array();
66        foreach ($tables_texte as $table => $champs) {
67                $statut_requete = '';
68                if (isset($champs['statut']) and $champs['statut'] and $champs['objet'] != 'auteur') {
69                        $statut_requete = ', statut';
70                }
71                $resultats = sql_allfetsel($champs['id_primary'] . ' as id_primary, CONCAT(' . $champs['texte'] . ') as texte_tmp' . $statut_requete, $table);
72                foreach ($resultats as $resultat => $value) {
73                        // On recherche les raccourcis typographiques
74                        if (preg_match_all('/(doc|img|emb)([0-9]+)/', $value['texte_tmp'], $docs)) {
75                                // On a au moins un résultat, alors on commence le traitement.
76                                if (isset($value['statut']) and $value['statut'] == $champs['publie']) {
77                                        // l'objet a un statut et est publié ou actif,
78                                        // alors le document doit-être publié aussi.
79                                        $statut = 'publie';
80                                } elseif (isset($value['statut']) and $value['statut'] != $champs['publie']) {
81                                        // l'objet a un statut et n'est publié ou actif,
82                                        // alors le document doit-être en préparation.
83                                        $statut = 'prepa';
84                                } elseif (!isset($value['statut'])) {
85                                        // L'objet n'a pas de statut
86                                        // et donc son affichage n'est pas conditionné par le statut,
87                                        // alors le document sera publié.
88                                        $statut = 'publie';
89                                }
90                                // On stocke maintenant toutes ces infos pour chaque document trouvé.
91                                foreach ($docs[2] as $id_doc) {
92                                        // structure du tableau :
93                                        // 0 : id_document
94                                        // 1 : id_objet
95                                        // 2 : objet
96                                        // 3 : vu (oui ou non)
97                                        // 4 : statut du document
98                                        $documents[] = array(
99                                                'id_document' => $id_doc,
100                                                'id_objet' => $value['id_primary'],
101                                                'objet' => $champs['objet'],
102                                                'vu' => 'oui',
103                                                'statut' => $statut,
104                                        );
105                                }
106                        }
107                }
108        }
109        // asort($documents);
110        // $documents = array_values(array_unique($documents));
111
112        return $documents;
113}
114
115/**
116 * Mettre à jour le statut des documents publiés liés à des objets non publiés.
117 * Ces documents doivent donc avoir un statut 'prepa' et non 'publie'.
118 *
119 * @return bool
120 */
121function medias_maj_documents_lies() {
122        include_spip('base/abstract_sql');
123        include_spip('base/objets');
124        $message_log = array();
125        $message_log[] = "\n-----";
126        $message_log[] = date_format(date_create(), 'Y-m-d H:i:s');
127        $message_log[] = 'Fonction : ' . __FUNCTION__;
128        if (session_get('id_auteur')) {
129                // S'il y a un auteur authentifié, on indique que c'est lui qui a lancé l'action.
130                $message_log[] = "L'action a été lancé par l'auteur #" . session_get('id_auteur') . ', ' . session_get('nom') . ' (' . session_get('statut') . ')';
131        } else {
132                // S'il n'y a pas d'auteur authentifié, c'est SPIP qui lance le script en tâche de fond.
133                $message_log[] = "L'action a été lancé par SPIP en tâche de fond.";
134        }
135
136        // On ne s'occupe que des objets pour lesquels on a des liens avec des documents.
137        $objets_lies = sql_fetsel('DISTINCT objet', 'spip_documents_liens');
138        foreach ($objets_lies as $objet_lie) {
139                // exemple de requête demandée :
140                // SELECT * FROM spip_documents
141                // WHERE id_document IN (SELECT DISTINCT id_document FROM spip_documents_liens WHERE objet='article' AND id_objet IN (SELECT id_article FROM spip_articles WHERE statut NOT IN ('publie')))
142                // AND statut IN ('publie')
143                // ***
144                // Sélectionner tous les documents publiés liés à des objets non publiés
145                // ***
146                $documents = sql_allfetsel('id_document,statut', 'spip_documents', "statut IN ('publie') AND id_document IN (SELECT DISTINCT id_document FROM spip_documents_liens WHERE objet='" . $objet_lie . "' AND id_objet IN (SELECT " . id_table_objet($objet_lie) . ' FROM ' . table_objet_sql($objet_lie) . " WHERE statut NOT IN ('publie')))");
147                if (is_array($documents) and count($documents) > 0) {
148                        foreach ($documents as $document) {
149                                if (sql_updateq('spip_documents', array('statut' => 'prepa'), 'id_document=' . $document['id_document'])) {
150                                        $message_log[] = 'Le statut du document #' . $document['id_document'] . ' lié à l\'objet ' . $objet_lie . ' a bien été mis à jour avec le statut \'' . $document['statut'] . '\'';
151                                }
152                        }
153                }
154        }
155        // Par défaut, le message de log a 4 entrées. Voir en début de la présente fonction.
156        if (count($message_log) == 4) {
157                $message_log[] = 'Il n\'y a pas eu d\'action à faire en base de données.';
158        }
159        // On met l'heure de fin de la procédure dans le message de log
160        $message_log[] = date_format(date_create(), 'Y-m-d H:i:s');
161        $message_log[] = "-----\n";
162        // Et maintenant on stocke les messages dans un fichier de log.
163        spip_log(implode("\n", $message_log), 'medias_dereferencer');
164
165        return true;
166}
167
168/**
169 * Cette fonction récupère les medias qui ont été utilisé par raccourcis typographiques dans les champs de type text. Et crée les liens entre le media et l'objet. Puis met à jour le statut du media.
170 *
171 * @uses   medias_lister_medias_used_in_text()
172 *
173 * @return [type] [description]
174 */
175function medias_maj_documents_non_lies() {
176        include_spip('base/abstract_sql');
177        include_spip('base/objets');
178        $documents_raccourcis = medias_lister_medias_used_in_text();
179        $message_log = array();
180        $message_log[] = "\n-----";
181        // On met l'heure de début de la procédure dans le message de log
182        $message_log[] = date_format(date_create(), 'Y-m-d H:i:s');
183        $message_log[] = 'Fonction : ' . __FUNCTION__;
184        if (session_get('id_auteur')) {
185                // S'il y a un auteur authentifié, on indique que c'est lui qui a lancé l'action.
186                $message_log[] = "L'action a été lancé par l'auteur #" . session_get('id_auteur') . ', ' . session_get('nom') . ' (' . session_get('statut') . ')';
187        } else {
188                // S'il n'y a pas d'auteur authentifié, c'est SPIP qui lance le script en tâche de fond.
189                $message_log[] = "L'action a été lancé par SPIP en tâche de fond.";
190        }
191
192        // On lance les opérations uniquement si on a des documents utilisés en raccourcis.
193        if (is_array($documents_raccourcis) and count($documents_raccourcis) > 0) {
194                foreach ($documents_raccourcis as $document) {
195                        if (sql_countsel('spip_documents_liens', array(
196                                'id_document=' . sql_quote($document['id_document']),
197                                'id_objet=' . sql_quote($document['id_objet']),
198                                'objet=' . sql_quote($document['objet']),
199                                'vu NOT IN (' . sql_quote($document['vu']) . ')',
200                        ))) {
201                                // Le lien de ce media avec l'objet existe mais n'a pas la bonne valeur dans 'vu'
202                                // Donc on met à jour la valeur de 'vu' pour ce lien.
203                                if (sql_updateq('spip_documents_liens', array(
204                                        'vu' => $document['vu'],
205                                ), 'id_document=' . sql_quote($document['id_document']) . ' AND id_objet=' . sql_quote($document['id_objet']) . ' AND objet=' . sql_quote($document['objet']) . ' AND vu NOT IN (' . sql_quote($document['vu']) . ')')) {
206                                        $message_log[] = 'Le lien entre le document #' . $document['id_document'] . ' et l\'objet ' . $document['objet'] . ' #' . $document['id_objet'] . ' a bien été mis à jour avec la vu \'' . $document['vu'] . '\'';
207                                }
208                                // et on met à jour le statut dudit document si le statut est différent uniquement.
209                                if (sql_updateq('spip_documents', array('statut' => $document['statut']), 'id_document=' . sql_quote($document['id_document']) . ' AND statut NOT IN (' . sql_quote($document['statut']) . ')')) {
210                                        $message_log[] = 'Le statut du document #' . $document['id_document'] . ' lié à l\'objet ' . $document['objet'] . ' #' . $document['id_objet'] . ' a bien été mis à jour avec le statut \'' . $document['statut'] . '\'';
211                                }
212                        } elseif (!sql_countsel('spip_documents_liens', array(
213                                'id_document=' . sql_quote($document['id_document']),
214                                'id_objet=' . sql_quote($document['id_objet']),
215                                'objet=' . sql_quote($document['objet']),
216                                'vu IN (' . sql_quote($document['vu']) . ')',
217                        ))
218                        ) {
219                                // Le lien de ce média avec l'objet n'existe pas
220                                // Alors on l'insère dans la table
221                                if (sql_insertq('spip_documents_liens', array(
222                                                'id_document' => $document['id_document'],
223                                                'id_objet' => $document['id_objet'],
224                                                'objet' => $document['objet'],
225                                                'vu' => $document['vu'],
226                                        )) and lire_config('medias_dereferencer/lier_document') === 'oui'
227                                ) {
228                                        $message_log[] = 'Le lien entre le document #' . $document['id_document'] . ' et l\'objet ' . $document['objet'] . ' #' . $document['id_objet'] . ' a bien été inséré en base de données avec la vu \'' . $document['vu'] . '\'';
229                                }
230                                // et on met à jour le statut dudit document si le statut est différent uniquement.
231                                if (sql_updateq('spip_documents', array('statut' => $document['statut']), 'id_document=' . sql_quote($document['id_document']) . ' AND statut NOT IN (' . sql_quote($document['statut']) . ')')) {
232                                        $message_log[] = 'Le statut du document #' . $document['id_document'] . ' lié à l\'objet ' . $document['objet'] . ' #' . $document['id_objet'] . ' a bien été mis à jour avec le statut \'' . $document['statut'] . '\'';
233                                }
234                        }
235                }
236        }
237        // Par défaut, le message de log a 4 entrées. Voir en début de la présente fonction.
238        if (count($message_log) == 4) {
239                $message_log[] = 'Il n\'y a pas eu d\'action à faire en base de données.';
240        }
241        // on met l'heure de fin de la procédure dans le message de log
242        $message_log[] = date_format(date_create(), 'Y-m-d H:i:s');
243        $message_log[] = "-----\n";
244        // Et maintenant on stocke les messages dans un fichier de log.
245        spip_log(implode("\n", $message_log), 'medias_dereferencer');
246
247        return true;
248}
249
250/**
251 * Cette fonction va créer pour chaque répertoire d'extension de documents non publiés un fichier .htaccess
252 * Toutefois, il faut que le répertoire IMG/ext existe et soit accessible en écriture.
253 *
254 * @return bool
255 */
256function md_creation_htaccess_img() {
257        include_spip('inc/config');
258        $config_md = lire_config('medias_dereferencer');
259        $message_log = array();
260        $message_log[] = "\n-----";
261        $message_log[] = date_format(date_create(), 'Y-m-d H:i:s');
262        $message_log[] = 'Fonction : ' . __FUNCTION__;
263        if (session_get('id_auteur')) {
264                // S'il y a un auteur authentifié, on indique que c'est lui qui a lancé l'action.
265                $message_log[] = "L'action a été lancé par l'auteur #" . session_get('id_auteur') . ', ' . session_get('nom') . ' (' . session_get('statut') . ')';
266        } else {
267                // S'il n'y a pas d'auteur authentifié, c'est SPIP qui lance le script en tâche de fond.
268                $message_log[] = "L'action a été lancé par SPIP en tâche de fond.";
269        }
270
271        /*
272         * On sélectionne les extensions des documents avec un statut en prepa,
273         * pour ne pas être trop gourmand en écriture sur le serveur.
274         */
275        $extensions_documents = sql_allfetsel('DISTINCT(extension)', 'spip_documents', "statut='prepa'");
276        if (is_array($extensions_documents) and count($extensions_documents) > 0) {
277                foreach ($extensions_documents as $extension) {
278                        if (is_readable(_DIR_IMG . $extension['extension']) and $config_md['htaccess'] === 'oui') {
279                                $medias_htaccess = recuperer_fond('inclure/medias_htaccess', $extension);
280                                if (function_exists('fopen') and $ht = fopen(_DIR_IMG . $extension['extension'] . '/' . _ACCESS_FILE_NAME, 'w')) {
281                                        fputs($ht, $medias_htaccess);
282                                        fclose($ht);
283                                        @chmod(_DIR_IMG . $extension['extension'] . '/' . _ACCESS_FILE_NAME, _SPIP_CHMOD & 0666);
284                                        $message_log[] = 'Le fichier ' . _ACCESS_FILE_NAME . ' pour ' . _DIR_IMG . $extension['extension'] . ' a été créé. ' . date_format(date_create(), 'Y-m-d H:i:s');
285                                } else {
286                                        $message_log[] = 'Le fichier ' . _ACCESS_FILE_NAME . ' pour ' . _DIR_IMG . $extension['extension'] . " n'a pu être créé. " . date_format(date_create(), 'Y-m-d H:i:s');
287                                }
288                        }
289                }
290        }
291
292        /*
293         * Par défaut, le message de log a 4 entrées. Voir en début de la présente fonction.
294         */
295        if (count($message_log) == 4) {
296                $message_log[] = 'Aucun fichier ' . _ACCESS_FILE_NAME . " n'a été créé. " . date_format(date_create(), 'Y-m-d H:i:s');
297        }
298        // on met l'heure de fin de la procédure dans le message de log
299        $message_log[] = date_format(date_create(), 'Y-m-d H:i:s');
300        $message_log[] = "-----\n";
301        // Et maintenant on stocke les messages dans un fichier de log.
302        spip_log(implode("\n", $message_log), 'medias_dereferencer');
303
304        if (count($message_log) > 7) {
305                return true;
306        }
307
308        return false;
309}
310
311function md_suppression_htaccess_img() {
312        include_spip('inc/config');
313        include_spip('inc/flock');
314        $config_md = lire_config('medias_dereferencer');
315        $message_log = array();
316        $message_log[] = "\n-----";
317        $message_log[] = date_format(date_create(), 'Y-m-d H:i:s');
318        $message_log[] = 'Fonction : ' . __FUNCTION__;
319        if (session_get('id_auteur')) {
320                // S'il y a un auteur authentifié, on indique que c'est lui qui a lancé l'action.
321                $message_log[] = "L'action a été lancé par l'auteur #" . session_get('id_auteur') . ', ' . session_get('nom') . ' (' . session_get('statut') . ')';
322        } else {
323                // S'il n'y a pas d'auteur authentifié, c'est SPIP qui lance le script en tâche de fond.
324                $message_log[] = "L'action a été lancé par SPIP en tâche de fond.";
325        }
326
327        /*
328         * On recherche les extensions des documents sans distinction de statut des documents.
329         */
330        $extensions_documents = sql_allfetsel('DISTINCT(extension)', 'spip_documents');
331        if (is_array($extensions_documents) and count($extensions_documents) > 0) {
332                foreach ($extensions_documents as $extension) {
333                        if (is_readable(_DIR_IMG . $extension['extension'])) {
334                                spip_unlink(_DIR_IMG . $extension['extension'] . '/' . _ACCESS_FILE_NAME);
335                                $message_log[] = 'Le fichier ' . _ACCESS_FILE_NAME . ' pour ' . _DIR_IMG . $extension['extension'] . ' a été supprimé avec succès.';
336                        }
337                }
338        }
339
340        // Par défaut, le message de log a 4 entrées. Voir en début de la présente fonction.
341        if (count($message_log) == 4) {
342                $message_log[] = 'Aucun fichier ' . _ACCESS_FILE_NAME . " n'a été supprimé. " . date_format(date_create(), 'Y-m-d H:i:s');
343        }
344        // on met l'heure de fin de la procédure dans le message de log
345        $message_log[] = date_format(date_create(), 'Y-m-d H:i:s');
346        $message_log[] = "-----\n";
347        // Et maintenant on stocke les messages dans un fichier de log.
348        spip_log(implode("\n", $message_log), 'medias_dereferencer');
349
350        if (count($message_log) > 7) {
351                return true;
352        }
353
354        return false;
355}
356
357function md_adresses_allow() {
358        include_spip('inc/config');
359        $config_md = lire_config('medias_dereferencer');
360        $directive = 'Allow from';
361        if (isset($config_md['adresse_ip']) and empty($config_md['adresse_ip'])) {
362                return false;
363        }
364        if (!is_array($config_md['adresse_ip'])) {
365                $config_md['adresse_ip'] = explode(';', $config_md['adresse_ip']);
366        }
367        if (isset($config_md['apache']) and $config_md['apache'] === 'oui') {
368                $directive = 'Require not ip';
369        }
370        $config_md['adresse_ip'] = array_filter($config_md['adresse_ip']);
371        $string = "    $directive " . implode("\n    $directive ", $config_md['adresse_ip']);
372
373        return $string;
374}
Note: See TracBrowser for help on using the repository browser.