source: spip-zone/_core_/plugins/svp/inc/svp_depoter_local.php @ 67425

Last change on this file since 67425 was 67425, checked in by eric@…, 8 years ago

Report de [67424]
Corrige le ticket [SVP - Anomalie #2895].
Il manquait un include_spip de la liste des langues.

File size: 23.1 KB
Line 
1<?php
2
3/**
4 * Traitement du dépot local
5 *
6 * Le dépot local est la liste de paquets qui sont présents sur l'hébergement
7 * dans un des répertoires de plugins, actifs ou non actifs.
8 *
9 * Dans la base, un dépot local est représenté avec un id_dépot nul.
10 * Il n'y a cependant pas de ligne spécifique décrivant le dépot local
11 * dans la table SQL spip_depots, mais juste des valeurs id_depot=0 dans
12 * la table spip_paquets.
13 *
14 * @plugin SVP pour SPIP
15 * @license GPL
16 * @package SPIP\SVP\Depots
17 */
18
19/**
20 * Met à jour les tables SQL paquets et plugins pour qui concerne
21 * les paquets locaux (ceux présents sur le site).
22 *
23 * On ne met à jour que ce qui a changé, sauf si on force le recalcule
24 * de toutes les informations locales avec var_mode=vider_paquets_locaux
25 * dans l'URL ou en mettant le paramètre $force à true.
26 *
27 * @param bool $force
28 *     - false : n'actualise que les paquets modifiés
29 *     - true : efface et recrée la liste de tous les paquets locaux
30 * @param array $erreurs_xml
31 *     Si des erreurs XML sont présentes, elles se retrouvent dans ce tableau
32 * @return string
33 *     Temps d'exécution
34**/
35function svp_actualiser_paquets_locaux($force = false, &$erreurs_xml = array()) {
36
37        spip_timer('paquets_locaux');
38        $paquets = svp_descriptions_paquets_locaux($erreurs_xml);
39
40        // un mode pour tout recalculer sans désinstaller le plugin... !
41        if ($force OR _request('var_mode') == 'vider_paquets_locaux') { 
42                svp_base_supprimer_paquets_locaux();
43                svp_base_inserer_paquets_locaux($paquets);
44        } else {
45                svp_base_modifier_paquets_locaux($paquets);
46        }
47        svp_base_actualiser_paquets_actifs();
48
49        $temps = spip_timer('paquets_locaux');
50#spip_log('svp_actualiser_paquets_locaux', 'SVP');
51#spip_log($temps, 'SVP');
52        return "Éxécuté en : " . $temps;
53       
54}
55
56
57/**
58 * Calcule la description de chaque paquet local
59 *
60 * Les paquets peuvent être stockés à 3 endroits :
61 * plugins, plugins-dist, plugins-supp définis par les constantes respectives
62 * _DIR_PLUGINS, _DIR_PLUGINS_DIST, _DIR_PLUGINS_SUPP
63 *
64 * @param array $erreurs_xml
65 *     Les erreurs XML éventuelles des paquet.xml se retrouvent dedans s'il y en a
66 * @return array
67 *     Descriptions des paquets (intégrant un hash), stockés par
68 *     constante, puis par chemin.
69 *     array[_DIR_PLUGIN*][$chemin] = description
70**/
71function svp_descriptions_paquets_locaux(&$erreurs_xml = array()) {
72        include_spip('inc/plugin');
73        liste_plugin_files(_DIR_PLUGINS);
74        liste_plugin_files(_DIR_PLUGINS_DIST);
75        $get_infos = charger_fonction('get_infos', 'plugins');
76        $paquets_locaux = array(
77                '_DIR_PLUGINS'    => $get_infos(array(), false, _DIR_PLUGINS),
78                '_DIR_PLUGINS_DIST' => $get_infos(array(), false, _DIR_PLUGINS_DIST),
79        );
80        if (defined('_DIR_PLUGINS_SUPP') and _DIR_PLUGINS_SUPP) {
81                liste_plugin_files(_DIR_PLUGINS_SUPP);
82                $paquets_locaux['_DIR_PLUGINS_SUPP'] = $get_infos(array(), false, _DIR_PLUGINS_SUPP);
83        }
84
85        // creer la liste des signatures
86        foreach($paquets_locaux as $const_dir => $paquets) {
87                foreach ($paquets as $chemin => $paquet) {
88                        // on propose le paquet uniquement s'il n'y a pas eu d'erreur de lecture XML bloquante
89                        if (!isset($paquet['erreur'])) {
90                                $paquets_locaux[$const_dir][$chemin]['signature'] = md5($const_dir . $chemin . serialize($paquet));
91                        } else {
92                                // Erreur XML !
93                                unset($paquets_locaux[$const_dir][$chemin]);
94                                spip_log("Impossible de lire la description XML de $chemin . Erreurs :", 'svp.' . _LOG_ERREUR);
95                                spip_log($paquet['erreur'], 'svp.' . _LOG_ERREUR);
96                                $erreurs_xml[] = $paquet['erreur'][0];
97                        }
98                }
99        }
100
101        return $paquets_locaux;
102}
103
104
105/**
106 * Supprime tous les paquets et plugins locaux.
107**/ 
108function svp_base_supprimer_paquets_locaux() {
109        sql_delete('spip_paquets', 'id_depot = ' . 0); //_paquets locaux en 0
110        sql_delete('spip_plugins', sql_in('id_plugin', sql_get_select('DISTINCT(id_plugin)', 'spip_paquets'), 'NOT'));
111}
112
113
114/**
115 * Actualise les informations en base sur les paquets locaux
116 * en ne modifiant que ce qui a changé.
117 *
118 * @param array $paquets_locaux
119 *     Descriptions des paquets (intégrant un hash), stockés par
120 *     constante, puis par chemin.
121 *     array[_DIR_PLUGIN*][$chemin] = description
122**/
123function svp_base_modifier_paquets_locaux($paquets_locaux) {
124        include_spip('inc/svp_depoter_distant');
125
126        // On ne va modifier QUE les paquets locaux qui ont change
127        // Et cela en comparant les md5 des informations fouries.
128        $signatures = array();
129
130        // recuperer toutes les signatures
131        foreach($paquets_locaux as $const_dir => $paquets) {
132                foreach ($paquets as $chemin => $paquet) {
133                        $signatures[$paquet['signature']] = array(
134                                'constante' => $const_dir,
135                                'chemin'    => $chemin,
136                                'paquet'    => $paquet,
137                        );
138                }
139        }
140
141        // tous les paquets du depot qui ne font pas parti des signatures
142        $anciens_paquets = sql_allfetsel('id_paquet', 'spip_paquets', array('id_depot=' . sql_quote(0), sql_in('signature', array_keys($signatures), 'NOT')));
143        $anciens_paquets = array_map('array_shift', $anciens_paquets);
144
145        // tous les plugins correspondants aux anciens paquets
146        $anciens_plugins = sql_allfetsel('p.id_plugin', array('spip_plugins AS p', 'spip_paquets AS pa'), array('p.id_plugin=pa.id_plugin', sql_in('pa.id_paquet', $anciens_paquets)));
147        $anciens_plugins = array_map('array_shift', $anciens_plugins);
148
149        // suppression des anciens paquets
150        sql_delete('spip_paquets', sql_in('id_paquet', $anciens_paquets));
151       
152        // supprimer les plugins orphelins
153        svp_supprimer_plugins_orphelins($anciens_plugins);
154
155        // on ne garde que les paquets qui ne sont pas presents dans la base
156        $signatures_base = sql_allfetsel('signature', 'spip_paquets', 'id_depot='.sql_quote(0));
157        $signatures_base = array_map('array_shift', $signatures_base);
158        $signatures = array_diff_key($signatures, array_flip($signatures_base));
159
160        // on recree la liste des paquets locaux a inserer
161        $paquets_locaux = array();
162        foreach ($signatures as $s => $infos) {
163                if (!isset($paquets_locaux[$infos['constante']])) {
164                        $paquets_locaux[$infos['constante']] = array();
165                }
166                $paquets_locaux[$infos['constante']][$infos['chemin']] = $infos['paquet'];
167        }
168
169        svp_base_inserer_paquets_locaux($paquets_locaux);
170}
171
172
173/**
174 * Insère en base tous les paquets locaux transmis
175 *
176 * De chaque description est extrait la partie plugin (1 seul plugin
177 * par préfixe de plugin connu) et la partie paquet (il peut y avoir plusieurs
178 * paquets pour un même préfixe de plugin).
179 *
180 * @note
181 *     On essaie au mieux de faire des requêtes d'insertions multiples,
182 *     mieux gérées par les moteurs SQL (particulièrement pour SQLite)
183 *
184 * @param array $paquets_locaux
185 *     Descriptions des paquets (intégrant un hash), stockés par
186 *     constante, puis par chemin.
187 *     array[_DIR_PLUGIN*][$chemin] = description
188**/
189function svp_base_inserer_paquets_locaux($paquets_locaux) {
190        include_spip('inc/svp_depoter_distant');
191       
192        // On initialise les informations specifiques au paquet :
193        // l'id du depot et les infos de l'archive
194        $paquet_base = array(
195                'id_depot' => 0,
196                'nom_archive' => '',
197                'nbo_archive' => '',
198                'maj_archive' => '',
199                'src_archive' => '',
200                'date_modif' => '',
201                'maj_version' => '',
202                'signature' => '',
203        );
204
205        $preparer_sql_paquet = charger_fonction('preparer_sql_paquet', 'plugins');
206
207        // pour chaque decouverte, on insere les paquets en base.
208        // on evite des requetes individuelles, tres couteuses en sqlite...
209        $cle_plugins    = array(); // prefixe => id
210        $insert_plugins = array(); // insertion prefixe...
211        $insert_plugins_vmax = array(); // vmax des nouveaux plugins...
212        $insert_paquets = array(); // insertion de paquet...
213
214        include_spip('inc/config');
215        $recents = lire_config('plugins_interessants');
216        $installes  = lire_config('plugin_installes');
217        $actifs  = lire_config('plugin');
218        $attentes  = lire_config('plugin_attente');
219
220        foreach($paquets_locaux as $const_dir => $paquets) {
221                foreach ($paquets as $chemin => $paquet) {
222                        // Si on est en presence d'un plugin dont la dtd est "paquet" on compile en multi
223                        // les nom, slogan et description a partir des fichiers de langue.
224                        // De cette façon, les informations des plugins locaux et distants seront identiques
225                        // => On evite l'utilisation de _T() dans les squelettes
226                        if ($paquet['dtd'] == 'paquet') {
227                                $multis = svp_compiler_multis($paquet['prefix'], constant($const_dir) . '/' . $chemin);
228                                if (isset($multis['nom']))
229                                        $paquet['nom'] = $multis['nom'];
230                                $paquet['slogan'] = (isset($multis['slogan'])) ? $multis['slogan'] : '';
231                                $paquet['description'] = (isset($multis['description'])) ? $multis['description'] : '';
232                        }
233
234                        $le_paquet = $paquet_base;
235                        #$le_paquet['traductions'] = serialize($paquet['traductions']);
236
237                        if ($champs = $preparer_sql_paquet($paquet)) {
238
239                                // Eclater les champs recuperes en deux sous tableaux, un par table (plugin, paquet)
240                                $champs = eclater_plugin_paquet($champs);
241                                $paquet_plugin = true;
242                               
243                                // On complete les informations du paquet et du plugin
244                                $le_paquet = array_merge($le_paquet, $champs['paquet']);
245                                $le_plugin = $champs['plugin'];
246
247                                // On loge l'absence de categorie ou une categorie erronee et on positionne la categorie par defaut "aucune"
248                                if (!$le_plugin['categorie']) {
249                                        $le_plugin['categorie'] = 'aucune';
250                                } else {
251                                        if (!in_array($le_plugin['categorie'], $GLOBALS['categories_plugin'])) {
252                                                $le_plugin['categorie'] = 'aucune';
253                                        }
254                                }
255
256                                // creation du plugin...
257                                $prefixe = strtoupper( $le_plugin['prefixe'] );
258                                // on fait attention lorqu'on cherche ou ajoute un plugin
259                                // le nom et slogan est TOUJOURS celui de la plus haute version
260                                // et il faut donc possiblement mettre a jour la base...
261                                //
262                                // + on est tolerant avec les versions identiques de plugin deja presentes
263                                //   on permet le recalculer le titre...
264                                if (!isset($cle_plugins[$prefixe])) {
265                                        if (!$res = sql_fetsel('id_plugin, vmax', 'spip_plugins', 'prefixe = '.sql_quote($prefixe))) {
266                                                // on ne stocke pas de vmax pour les plugins locaux dans la bdd... (parait il)
267                                                if (!isset($insert_plugins[$prefixe])) {
268                                                        $insert_plugins[$prefixe] = $le_plugin;
269                                                        $insert_plugins_vmax[$prefixe] = $le_paquet['version'];
270                                                } elseif (spip_version_compare($le_paquet['version'], $insert_plugins_vmax[$prefixe], '>')) {
271                                                        $insert_plugins[$prefixe] = $le_plugin;
272                                                        $insert_plugins_vmax[$prefixe] = $le_paquet['version'];
273                                                }
274                                        } else {
275                                                $id_plugin = $res['id_plugin'];
276                                                $cle_plugins[$prefixe] = $id_plugin;
277                                                // comme justement on ne stocke pas de vmax pour les plugins locaux...
278                                                // il est possible que ce test soit faux. pff.
279                                                if (spip_version_compare($le_paquet['version'], $res['vmax'], '>=')) {
280                                                        sql_updateq('spip_plugins', $le_plugin, 'id_plugin='.sql_quote($id_plugin));
281                                                }
282                                        }
283                                }
284
285                                // ajout du prefixe dans le paquet
286                                $le_paquet['prefixe']     = $prefixe;
287                                $le_paquet['constante']   = $const_dir;
288                                $le_paquet['src_archive'] = $chemin;
289                                $le_paquet['recent']      = isset($recents[$chemin]) ? $recents[$chemin] : 0;
290                                $le_paquet['installe']    = in_array($chemin, $installes) ? 'oui': 'non'; // est desinstallable ?
291                                $le_paquet['obsolete']    = 'non';
292                                $le_paquet['signature']   = $paquet['signature'];
293
294                                // le plugin est il actuellement actif ?
295                                $actif = "non";
296                                if (isset($actifs[$prefixe])
297                                        and ($actifs[$prefixe]['dir_type'] == $const_dir)
298                                        and ($actifs[$prefixe]['dir'] == $chemin)) {
299                                        $actif = "oui";
300                                }
301                                $le_paquet['actif'] = $actif;
302
303                                // le plugin etait il actif mais temporairement desactive
304                                // parce qu'une dependence a disparue ?
305                                $attente = "non";
306                                if (isset($attentes[$prefixe])
307                                        and ($attentes[$prefixe]['dir_type'] == $const_dir)
308                                        and ($attentes[$prefixe]['dir'] == $chemin)) {
309                                        $attente = "oui";
310                                        $le_paquet['actif'] = "oui"; // il est presenté dans la liste des actifs (en erreur).
311                                }
312                                $le_paquet['attente'] = $attente;
313
314                                // on recherche d'eventuelle mises a jour existantes
315                                if ($maj_version = svp_rechercher_maj_version($prefixe, $le_paquet['version'], $le_paquet['etatnum'])) {
316                                        $le_paquet['maj_version'] = $maj_version;
317                                }
318
319                                $insert_paquets[] = $le_paquet;
320                        }
321                }
322        }
323
324        if ($insert_plugins) {
325                sql_insertq_multi('spip_plugins', $insert_plugins);
326                $pls = sql_allfetsel(array('id_plugin', 'prefixe'), 'spip_plugins', sql_in('prefixe', array_keys($insert_plugins)));
327                foreach ($pls as $p) {
328                        $cle_plugins[$p['prefixe']] = $p['id_plugin'];
329                }
330        }
331       
332        if ($insert_paquets) {
333
334                // sert pour le calcul d'obsolescence
335                $id_plugin_concernes = array();
336               
337                foreach ($insert_paquets as $c => $p) {
338                        $insert_paquets[$c]['id_plugin'] = $cle_plugins[$p['prefixe']];
339                        $id_plugin_concernes[ $insert_paquets[$c]['id_plugin'] ] = true;
340
341                        // remettre les necessite, utilise, librairie dans la cle 0
342                        // comme SVP
343                        if ($dep = unserialize($insert_paquets[$c]['dependances']) and is_array($dep)) {
344                                foreach ($dep as $d => $contenu) {
345                                        if ($contenu) {
346                                                $new = array();
347                                                foreach($contenu as $n) {
348                                                        unset($n['id']);
349                                                        $new[ strtolower($n['nom']) ] = $n;
350                                                }
351                                                $dep[$d] = array($new);
352                                        }
353                                }
354                                $insert_paquets[$c]['dependances'] = serialize($dep);
355                        }
356
357                }
358
359                sql_insertq_multi('spip_paquets', $insert_paquets);
360
361                svp_corriger_obsolete_paquets( array_keys($id_plugin_concernes) );
362        }
363}
364
365
366/**
367 * Fait correspondre l'état des métas des plugins actifs & installés
368 * avec ceux en base de données dans spip_paquets pour le dépot local
369**/
370function svp_base_actualiser_paquets_actifs() {
371        $installes  = lire_config('plugin_installes');
372        $actifs  = lire_config('plugin');
373        $attentes  = lire_config('plugin_attente');
374
375        $locaux = sql_allfetsel(
376                array('id_paquet', 'prefixe', 'actif', 'installe', 'attente', 'constante', 'src_archive'),
377                'spip_paquets',
378                'id_depot='.sql_quote(0));
379        $changements = array();
380
381        foreach ($locaux as $l) {
382                $copie = $l;
383                $prefixe = strtoupper($l['prefixe']);
384                // actif ?
385                if (isset($actifs[$prefixe])
386                        and ($actifs[$prefixe]['dir_type'] == $l['constante'])
387                        and ($actifs[$prefixe]['dir'] == $l['src_archive'])) {
388                        $copie['actif'] = "oui";
389                } else {
390                        $copie['actif'] = "non";
391                }
392               
393                // attente ?
394                if (isset($attentes[$prefixe])
395                        and ($attentes[$prefixe]['dir_type'] == $l['constante'])
396                        and ($attentes[$prefixe]['dir'] == $l['src_archive'])) {
397                        $copie['attente'] = "oui";
398                        $copie['actif'] = "oui"; // il est presente dans la liste des actifs (en erreur).
399                } else {
400                        $copie['attente'] = "non";
401                }
402               
403                // installe ?
404                if (in_array($l['src_archive'], $installes)) {
405                        $copie['installe'] = "oui";
406                } else {
407                        $copie['installe'] = "non";
408                }
409
410                if ($copie != $l) {
411                        $changements[ $l['id_paquet'] ] = array(
412                                'actif'    => $copie['actif'],
413                                'installe' => $copie['installe'],
414                                'attente'  => $copie['attente'] );
415                }
416        }
417
418        if (count($changements)) {
419                // On insere, en encapsulant pour sqlite...
420                if (sql_preferer_transaction()) {
421                        sql_demarrer_transaction();
422                }
423
424                foreach ($changements as $id_paquet => $data) {
425                        sql_updateq('spip_paquets', $data, 'id_paquet=' . intval($id_paquet));
426                }
427
428                if (sql_preferer_transaction()) {
429                        sql_terminer_transaction();
430                }
431        }
432
433}
434
435/**
436 * Construit le contenu multilangue (tag <multi>) des balises nom, slogan
437 * et description à partir des items de langue contenus dans le fichier
438 * paquet-prefixe_langue.php
439 *
440 * @param string $prefixe     Préfixe du plugin
441 * @param string $dir_source  Chemin d'accès du plugin
442 * @return array
443 *     Tableau clé => texte multilangue entre <multi> et </multi>
444 *     Les clés peuvent être 'nom', 'slogan' et 'description', mais
445 *     seules les clés ayant une explication dans la chaine de langue
446 *     sont retournées.
447 */
448function svp_compiler_multis($prefixe, $dir_source) {
449
450        $multis =array();
451        // ici on cherche le fichier et les cles avec un prefixe en minuscule systematiquement...
452        $prefixe = strtolower($prefixe);
453        $module = "paquet-$prefixe";
454        $item_nom = $prefixe . "_nom";
455        $item_slogan = $prefixe . "_slogan";
456        $item_description = $prefixe . "_description";
457
458        // On cherche tous les fichiers de langue destines a la traduction du paquet.xml
459        if ($fichiers_langue = glob($dir_source . "/lang/{$module}_*.php")) {
460                include_spip('inc/lang_liste');
461                $nom = $slogan = $description = '';
462                foreach ($fichiers_langue as $_fichier_langue) {
463                        $nom_fichier = basename($_fichier_langue, '.php');
464                        $langue = substr($nom_fichier, strlen($module) + 1 - strlen($nom_fichier));
465                        // Si la langue est reconnue, on traite la liste des items de langue
466                        if (isset($GLOBALS['codes_langues'][$langue])) {
467                                $GLOBALS['idx_lang'] = $langue;
468                                include($_fichier_langue);
469                                foreach ($GLOBALS[$langue] as $_item => $_traduction) {
470                                        if ($_traduction = trim($_traduction)) {
471                                                if ($_item == $item_nom)
472                                                        $nom .= "[$langue]$_traduction";
473                                                if ($_item == $item_slogan)
474                                                        $slogan .= "[$langue]$_traduction";
475                                                if ($_item == $item_description)
476                                                        $description .= "[$langue]$_traduction";
477                                        }
478                                }
479                        }
480                }
481
482                // Finaliser la construction des balises multi
483                if ($nom) $multis['nom'] = "<multi>$nom</multi>";
484                if ($slogan) $multis['slogan'] = "<multi>$slogan</multi>";
485                if ($description) $multis['description'] = "<multi>$description</multi>";
486        }
487
488        return $multis;
489}
490
491
492/**
493 * Met à jour les informations d'obsolescence des paquets locaux.
494 *
495 * L'obsolescence indique qu'un paquet est plus ancien (de version ou état
496 * moins avancé) qu'un autre également présent localement.
497 *
498 * @param array $ids_plugin
499 *     Liste d'identifiants de plugins
500 *     En cas d'absence, passera sur tous les paquets locaux
501**/
502function svp_corriger_obsolete_paquets($ids_plugin = array()) {
503        // on minimise au maximum le nombre de requetes.
504        // 1 pour lister les paquets
505        // 1 pour mettre à jour les obsoletes à oui
506        // 1 pour mettre à jour les obsoletes à non
507
508        $where = array('pa.id_plugin = pl.id_plugin', 'id_depot='.sql_quote(0));
509        if ($ids_plugin) {
510                $where[] = sql_in('pl.id_plugin', $ids_plugin);
511        }
512       
513        // comme l'on a de nouveaux paquets locaux...
514        // certains sont peut etre devenus obsoletes
515        // parmis tous les plugins locaux presents
516        // concernes par les memes prefixes que les plugins ajoutes.
517        $obsoletes = array();
518        $changements = array();
519       
520        $paquets = sql_allfetsel(
521                array('pa.id_paquet', 'pl.prefixe', 'pa.version', 'pa.etatnum', 'pa.obsolete'),
522                array('spip_paquets AS pa', 'spip_plugins AS pl'),
523                $where);
524
525        foreach ($paquets as $c => $p) {
526
527                $obsoletes[$p['prefixe']][] = $c;
528
529                // si 2 paquet locaux ont le meme prefixe, mais pas la meme version,
530                // l'un est obsolete : la version la plus ancienne
531                // Si version et etat sont egaux, on ne decide pas d'obsolescence.
532                if (count($obsoletes[$p['prefixe']]) > 1) {
533                        foreach ($obsoletes[$p['prefixe']] as $cle) {
534                                if ($cle == $c) continue;
535
536                                // je suis plus petit qu'un autre
537                                if (spip_version_compare($paquets[$c]['version'], $paquets[$cle]['version'], '<')) {
538                                        if ($paquets[$c]['etatnum'] <= $paquets[$cle]['etatnum']) {
539                                                if ($paquets[$c]['obsolete'] != 'oui') {
540                                                        $paquets[$c]['obsolete'] = 'oui';
541                                                        $changements[$c] = true;
542                                                }
543                                        }
544                                }
545
546                                // je suis plus grand ou egal a un autre...
547                                else {
548                                        // je suis plus strictement plus grand a un autre...
549                                        if (spip_version_compare($paquets[$c]['version'], $paquets[$cle]['version'], '>')) {
550                                                // si mon etat est meilleur, rendre obsolete les autres
551                                                if ($paquets[$c]['etatnum'] >= $paquets[$cle]['etatnum']) {
552                                                                if ($paquets[$cle]['obsolete'] != 'oui') {
553                                                                        $paquets[$cle]['obsolete'] = 'oui';
554                                                                        $changements[$cle] = true;
555                                                                }
556                                                }
557                                        }
558
559                                        // je suis egal a un autre
560                                        // si mon etat est strictement meilleur, rendre obsolete les autres
561                                        elseif ($paquets[$c]['etatnum'] > $paquets[$cle]['etatnum']) {
562                                                        if ($paquets[$cle]['obsolete'] != 'oui') {
563                                                                $paquets[$cle]['obsolete'] = 'oui';
564                                                                $changements[$cle] = true;
565                                                        }
566                                        }
567                                }
568
569                        }
570                } else {
571                        if ($paquets[$c]['obsolete'] != 'non') {
572                                $paquets[$c]['obsolete'] = 'non';
573                                $changements[$c] = true;
574                        }
575                }
576        }
577
578        if (count($changements)) {
579                $oui = $non = array();
580                foreach ($changements as $c => $null) {
581                        if ($paquets[$c]['obsolete'] == 'oui') {
582                                $oui[] = $paquets[$c]['id_paquet'];
583                        } else {
584                                $non[] = $paquets[$c]['id_paquet'];
585                        }
586                }
587
588                if ($oui) {
589                        sql_updateq('spip_paquets', array('obsolete'=>'oui'), sql_in('id_paquet', $oui));
590                }
591                if ($non) {
592                        sql_updateq('spip_paquets', array('obsolete'=>'non'), sql_in('id_paquet', $non));
593                }
594        }
595}
596
597
598
599
600/**
601 * Supprime les plugins devenus orphelins dans cette liste.
602 *
603 * @param array $ids_plugin
604 *     Liste d'identifiants de plugins
605 * @return array
606 *     Liste de plugins non orphelins
607**/
608function svp_supprimer_plugins_orphelins($ids_plugin) {
609        // tous les plugins encore lies a des depots...
610        if ($ids_plugin) {
611                $p = sql_allfetsel('DISTINCT(p.id_plugin)', array('spip_plugins AS p', 'spip_paquets AS pa'), array(sql_in('p.id_plugin', $ids_plugin), 'p.id_plugin=pa.id_plugin'));
612                $p = array_map('array_shift', $p);
613                $diff = array_diff($ids_plugin, $p);
614                // pour chaque plugin non encore utilise, on les vire !
615                sql_delete('spip_plugins', sql_in('id_plugin', $diff));
616                return $p; // les plugins encore en vie !
617        }
618        return array();
619}
620
621
622/**
623 * Cherche dans les dépots distants un plugin qui serait plus à jour
624 * que le prefixe, version et état que l'on transmet
625 *
626 * @param string $prefixe
627 *              Préfixe du plugin
628 * @param string $version
629 *              Version du paquet à comparer
630 * @param int $etatnum
631 *              État du paquet numérique
632 * @return string
633 *              Version plus à jour, sinon rien
634**/
635function svp_rechercher_maj_version($prefixe, $version, $etatnum) {
636
637        $maj_version = "";
638
639        if ($res = sql_allfetsel(
640                array('pl.id_plugin', 'pa.version'),
641                array('spip_plugins AS pl', 'spip_paquets AS pa'),
642                array(
643                        'pl.id_plugin = pa.id_plugin',
644                        'pa.id_depot>' . sql_quote(0),
645                        'pl.prefixe=' . sql_quote($prefixe),
646                        'pa.etatnum>=' . sql_quote($etatnum))))
647                {
648
649                foreach ($res as $paquet_distant) {
650                        // si version superieure et etat identique ou meilleur,
651                        // c'est que c'est une mise a jour possible !
652                        if (spip_version_compare($paquet_distant['version'],$version,'>')) {
653                                if (!strlen($maj_version) or spip_version_compare($paquet_distant['version'], $maj_version, '>')) {
654                                        $maj_version = $paquet_distant['version'];
655                                }
656                                # a voir si on utilisera...
657                                # "superieur"           => "varchar(3) DEFAULT 'non' NOT NULL",
658                                # // superieur : version plus recente disponible (distant) d'un plugin (actif?) existant
659                        }
660                }
661        }
662
663        return $maj_version;
664}
665
666
667
668
669/**
670 * Actualise l'information 'maj_version' pour tous les paquets locaux
671**/
672function svp_actualiser_maj_version() {
673        $update = array();
674        // tous les paquets locaux
675        if ($locaux = sql_allfetsel(
676                array('id_paquet', 'prefixe', 'version', 'maj_version', 'etatnum'),
677                array('spip_paquets'),
678                array('id_depot=' . sql_quote(0))))
679        {
680                foreach ($locaux as $paquet) {
681                        $new_maj_version = svp_rechercher_maj_version($paquet['prefixe'], $paquet['version'], $paquet['etatnum']);
682                        if ($new_maj_version != $paquet['maj_version']) {
683                                $update[$paquet['id_paquet']] = array('maj_version' => $new_maj_version);
684                        }
685                }
686        }
687        if ($update) {
688                // On insere, en encapsulant pour sqlite...
689                if (sql_preferer_transaction()) {
690                        sql_demarrer_transaction();
691                }
692
693                foreach ($update as $id_paquet => $data) {
694                        sql_updateq('spip_paquets', $data, 'id_paquet=' . intval($id_paquet));
695                }
696
697                if (sql_preferer_transaction()) {
698                        sql_terminer_transaction();
699                }
700        }
701}
702
703?>
Note: See TracBrowser for help on using the repository browser.