source: spip-zone/_core_/plugins/svp/inc/svp_decider.php

Last change on this file was 117891, checked in by marcimat@…, 4 months ago

Ticket #4383 : Bien prendre en compte les nécessite / utilise des paquets.xml qui ont une balise <spip> intégrée.

  • Property svn:eol-style set to native
File size: 36.9 KB
RevLine 
[55381]1<?php
2
[64679]3/**
4 * Gestion du décideur : il calcule en fonction d'une demande d'action
5 * sur les plugins tous les enchainements que cela implique sur les
6 * dépendances.
7 *
8 * @plugin SVP pour SPIP
9 * @license GPL
[64981]10 * @package SPIP\SVP\Decideur
[64679]11 */
[55381]12
[93627]13if (!defined("_ECRIRE_INC_VERSION")) {
14        return;
15}
16
[55396]17include_spip('plugins/installer'); // pour spip_version_compare()
[55597]18include_spip('inc/svp_rechercher'); // svp_verifier_compatibilite_spip()
19# include_spip('inc/plugin'); // plugin_version_compatible() [inclu dans svp_rechercher]
[55381]20
[64679]21/**
22 * Le décideur calcule les actions qui doivent être faites en fonction
23 * de ce qui est demandé et des différentes dépendances des plugins.
24 *
[64981]25 * @package SPIP\SVP\Actionner
[93627]26 **/
[55381]27class Decideur {
28
[64679]29        /**
30         * Plugins actifs en cours avant toute modification
[93627]31         *
[64679]32         * @var array
33         *     Index 'i' : plugins triés par identifiant en base [i][32] = tableau de description
34         *     Index 'p' : plugins triés par prefixe de plugin [p][MOTS] = tableau de description
35         */
[93656]36        public $start = array(
[55381]37                'i' => array(),
38                'p' => array(),
39        );
40
[64679]41        /**
42         * Plugins actifs à la fin des modifications effectuées
[93627]43         *
[64679]44         * @var array
45         *     Index 'i' : plugins triés par identifiant en base [i][32] = tableau de description
46         *     Index 'p' : plugins triés par prefixe de plugin [p][MOTS] = tableau de description
47         */
[93656]48        public $end = array(
[59476]49                'i' => array(),
50                'p' => array(),
51        );
[55381]52
[64679]53        /**
54         * Plugins procure par SPIP
[93627]55         *
[64679]56         * @var array
57         *     Tableau ('PREFIXE' => numéro de version)
58         */
[93656]59        public $procure = array();
[55381]60
[64679]61        /**
62         * Toutes les actions à faire demandées
63         * (ce que l'on demande à l'origine)
[93627]64         *
[64679]65         * @var array
66         *     Tableau ('identifiant' => tableau de description)
67         */
[93656]68        public $ask = array();
[55381]69
[64679]70        /**
71         * Toutes les actions à faire demandées et consécutives aux dépendances
[93627]72         *
[64679]73         * @var array
74         *     Tableau ('identifiant' => tableau de description)
75         */
[93656]76        public $todo = array();
[55381]77
[64679]78        /**
79         * Toutes les actions à faire consécutives aux dépendances
80         *
81         * C'est à dire les actions à faire en plus de celles demandées.
[93627]82         *
[64679]83         * @var array
84         *     Tableau ('identifiant' => tableau de description)
85         */
[93656]86        public $changes = array();
[55381]87
[64679]88        /**
89         * Tous les plugins à arrêter (désactiver ou désinstaller)
[93627]90         *
[64679]91         * @var array
92         *     Tableau ('PREFIXE' => tableau de description)
93         */
[93656]94        public $off = array();
[60027]95
[64679]96        /**
97         * Tous les plugins invalidés (suite a des dependances introuvables, mauvaise version de SPIP...)
[93627]98         *
[64679]99         * @var array
100         *     Tableau ('PREFIXE' => tableau de description)
101         */
[93656]102        public $invalides = array();
[64679]103
104        /**
105         * Liste des erreurs
[93627]106         *
[64679]107         * @var array
108         *     Tableau ('identifiant' => liste des erreurs)
109         */
[93656]110        public $err = array();
[64679]111
112        /**
113         * État de santé (absence d'erreur)
[93627]114         *
[64679]115         * Le résultat true permettra d'effectuer toutes les actions.
116         * Passe à false dès qu'une erreur est présente !
[93627]117         *
118         * @var bool
119         */
[93656]120        public $ok = true;
[64679]121
122        /**
123         * Loguer les différents éléments
[93627]124         *
[64679]125         * Sa valeur sera initialisée par la configuration 'mode_log_verbeux' de SVP
[93627]126         *
127         * @var bool
128         */
[93656]129        public $log = false;
[64679]130
131        /**
132         * Générer une erreur si on demande une mise à jour d'un plugin
133         * alors qu'on ne la connait pas.
[93627]134         *
135         * @var bool
136         */
[93656]137        public $erreur_sur_maj_introuvable = true;
[64679]138
139        /**
140         * Constructeur
[93627]141         *
[64679]142         * Initialise la propriété $log en fonction de la configuration
143         */
[93656]144        public function __construct() {
[56080]145                include_spip('inc/config');
146                $this->log = (lire_config('svp/mode_log_verbeux') == 'oui');
147        }
[55381]148
149
[64679]150        /**
151         * Liste des plugins déjà actifs
152         *
153         * @var array
154         *     Index 'i' : plugins triés par identifiant en base [i][32] = tableau de description
155         *     Index 'p' : plugins triés par prefixe de plugin [p][MOTS] = tableau de description
156         */
[93656]157        public function liste_plugins_actifs() {
[93627]158                return $this->infos_courtes(array('pa.actif=' . sql_quote('oui'), 'pa.attente=' . sql_quote('non')));
[55381]159        }
[64679]160
161        /**
162         * Teste si un paquet (via son identifiant) est en attente
163         *
164         * Les plugins en attente ont un statut spécial : à la fois dans la
165         * liste des plugins actifs, mais désactivés. Un plugin passe 'en attente'
166         * lorsqu'il est actif mais perd accidentellement une dépendance,
167         * par exemple si une dépendance est supprimée par FTP.
168         * Dès que sa dépendance revient, le plugin se réactive.
169         *
170         * L'interface de gestion des plugins de SVP, elle, permet pour ces plugins
171         * de les désactiver ou réactiver (retéléchargeant alors la dépendance si possible).
172         *
173         * @param int $id
174         *     Identifiant du plugin
175         * @return bool
176         *     Le plugin est-il en attente ?
177         */
[93656]178        public function est_attente_id($id) {
[59476]179                static $attente = null;
180                if (is_null($attente)) {
181                        $attente = $this->infos_courtes('pa.attente=' . sql_quote('oui'));
182                }
[93627]183
[59476]184                return isset($attente['i'][$id]) ? $attente['i'][$id] : false;
185        }
[55381]186
[64679]187        /**
188         * Liste des plugins procurés par SPIP
189         *
190         * Calcule la liste des plugins que le core de SPIP déclare procurer.
191         *
192         * @return array
193         *     Tableau ('PREFIXE' => version)
194         */
[93656]195        public function liste_plugins_procure() {
[59476]196                $procure = array();
[93627]197                $get_infos = charger_fonction('get_infos', 'plugins');
198                $infos['_DIR_RESTREINT'][''] = $get_infos('./', false, _DIR_RESTREINT);
[55381]199
[93627]200                foreach ($infos['_DIR_RESTREINT']['']['procure'] as $_procure) {
[60581]201                        $prefixe = strtoupper($_procure['nom']);
[59476]202                        $procure[$prefixe] = $_procure['version'];
203                }
[55381]204
[59476]205                return $procure;
206        }
[55381]207
[64679]208        /**
209         * Écrit un log
210         *
211         * Écrit un log si la propriété $log l'autorise.
[93627]212         *
[64679]213         * @param mixed $quoi
214         *     La chose à logguer (souvent un texte)
[93627]215         **/
[93656]216        public function log($quoi) {
[55381]217                if ($this->log) {
[93627]218                        spip_log($quoi, 'decideur');
[55381]219                }
220        }
221
[64679]222        /**
[93627]223         * Retourne le tableau de description d'un paquet (via son identifiant)
[64679]224         *
225         * @note
226         *     Attention, retourne un tableau complexe.
227         *     La description sera dans : ['i'][$id]
228         * @param int $id
229         *     Identifiant du paquet
230         * @return array
231         *     Index 'i' : plugins triés par identifiant en base [i][32] = tableau de description
232         *     Index 'p' : plugins triés par prefixe de plugin [p][MOTS] = tableau de description
[93627]233         **/
[93656]234        public function infos_courtes_id($id) {
[55381]235                // on cache ceux la
236                static $plug = array();
237                if (!isset($plug[$id])) {
[55736]238                        $plug[$id] = $this->infos_courtes('pa.id_paquet=' . sql_quote($id));
[55381]239                }
[93627]240
[55381]241                return $plug[$id];
242        }
243
244        /**
[64679]245         * Récupérer les infos utiles des paquet
[55381]246         *
[64679]247         * Crée un tableau de description pour chaque paquet dans une
248         * écriture courte comme index ('i' pour identifiant) tel que :
249         * - i = identifiant
250         * - p = prefixe (en majuscule)
251         * - n = nom du plugin
252         * - v = version
253         * - e = etat
254         * - a = actif
255         * - du = dépendances utilise
256         * - dn = dépendances nécessite
257         * - dl = dépendances librairie
[93161]258         * - procure = prefixes procurés
[64679]259         * - maj = mise à jour
[93627]260         *
261         *
[64679]262         * On passe un where ($condition) et on crée deux tableaux, l'un des paquets
263         * triés par identifiant, l'autre par prefixe.
264         *
265         * @param array|string $condition
266         *     Condition where
267         * @param bool $multiple
268         *     Si multiple, le tableau par préfixe est un sous-tableau (il peut alors
269         *     y avoir plusieurs paquets pour un même prefixe, classés par états décroissants)
270         * @return array
271         *     Index 'i' : plugins triés par identifiant en base [i][32] = tableau de description
272         *     Index 'p' : plugins triés par prefixe de plugin [p][MOTS] = tableau de description
273         *                 ou, avec $multiple=true : [p][MOTS][] = tableau de description
[55381]274         */
[93656]275        public function infos_courtes($condition, $multiple = false) {
[55381]276                $plugs = array(
[93627]277                        'i' => array(),
278                        'p' => array()
[55381]279                );
280
[59476]281                $from = array('spip_paquets AS pa', 'spip_plugins AS pl');
[55389]282                $orderby = $multiple ? 'pa.etatnum DESC' : '';
[59476]283                $where = array('pa.id_plugin = pl.id_plugin');
[93627]284                if (is_array($condition)) {
[59476]285                        $where = array_merge($where, $condition);
[93627]286                } else {
[59476]287                        $where[] = $condition;
[93627]288                }
[55653]289
[59476]290                include_spip('inc/filtres'); // extraire_multi()
[55412]291                $res = sql_allfetsel(array(
[55389]292                        'pa.id_paquet AS i',
293                        'pl.nom AS n',
294                        'pl.prefixe AS p',
295                        'pa.version AS v',
296                        'pa.etatnum AS e',
[55597]297                        'pa.compatibilite_spip',
[55389]298                        'pa.dependances',
[92791]299                        'pa.procure',
[55582]300                        'pa.id_depot',
[55389]301                        'pa.maj_version AS maj',
[93627]302                        'pa.actif AS a'
303                ), $from, $where, '', $orderby);
[55412]304                foreach ($res as $r) {
[93627]305                        $r['p'] = strtoupper($r['p']); // on s'assure du prefixe en majuscule.
306
[55582]307                        // savoir si un paquet est en local ou non...
308                        $r['local'] = ($r['id_depot']) == 0 ? true : false;
309                        unset($r['id_depot']);
[93627]310
[55381]311                        $d = unserialize($r['dependances']);
312                        // voir pour enregistrer en bdd simplement 'n' et 'u' (pas la peine d'encombrer)...
[93627]313                        $deps = array('necessite' => array(array()), 'utilise' => array(array()), 'librairie' => array(array()));
314                        if (!$d) {
315                                $d = $deps;
316                        }
317
[55381]318                        unset($r['dependances']);
[93656]319                        if (!$r['procure'] or !$proc = unserialize($r['procure'])) {
[92791]320                                $proc = array();
321                        }
322                        $r['procure'] = $proc;
[55381]323
324                        /*
325                         * On extrait les multi sur le nom du plugin
326                         */
327                        $r['n'] = extraire_multi($r['n']);
328
329                        $plugs['i'][$r['i']] = $r;
[55582]330
[93627]331
[55582]332                        // pour chaque type de dependences... (necessite, utilise, librairie)
[55634]333                        // on cree un tableau unique [$dependence] = array()
[55582]334                        // au lieu de plusieurs tableaux par version de spip
335                        // en ne mettant dans 0 que ce qui concerne notre spip local
[93627]336                        foreach ($deps as $cle => $defaut) {
[55582]337                                if (!isset($d[$cle])) {
338                                        $d[$cle] = $defaut;
339                                }
[93627]340
[55582]341                                // gerer les dependences autres que dans 0 (communs ou local) !!!!
342                                // il peut exister des cles info[dn]["[version_spip_min;version_spip_max]"] de dependences
[93656]343                                if (!isset($d[$cle][0]) or count($d[$cle]) > 1) {
[55582]344                                        $dep = array();
345                                        $dep[0] = isset($d[$cle][0]) ? $d[$cle][0] : array();
346                                        unset($d[$cle][0]);
347                                        foreach ($d[$cle] as $version => $dependences) {
[55597]348                                                if (svp_verifier_compatibilite_spip($version)) {
[117891]349                                                        $dep[0] = array_merge($dep[0], $dependences);
[55582]350                                                }
351                                        }
352                                        $d[$cle] = $dep;
353                                }
354                        }
[55734]355                        // passer les prefixes en majuscule
[93627]356                        foreach ($d['necessite'][0] as $i => $n) {
[55734]357                                $d['necessite'][0][$i]['nom'] = strtoupper($n['nom']);
358                        }
[55634]359                        $plugs['i'][$r['i']]['dn'] = $d['necessite'][0];
360                        $plugs['i'][$r['i']]['du'] = $d['utilise'][0];
361                        $plugs['i'][$r['i']]['dl'] = $d['librairie'][0];
[55381]362
[55582]363
[55381]364                        if ($multiple) {
365                                $plugs['p'][$r['p']][] = &$plugs['i'][$r['i']]; // alias
366                        } else {
367                                $plugs['p'][$r['p']] = &$plugs['i'][$r['i']]; // alias
368                        }
[93161]369
[55381]370                }
[93627]371
[55381]372                return $plugs;
373        }
374
375
[64679]376        /**
377         * Ajoute une erreur sur un paquet
378         *
379         * Passe le flag OK à false : on ne pourra pas faire les actions demandées.
[93627]380         *
[64679]381         * @param int $id
382         *     Identifiant de paquet
383         * @param string $texte
384         *     Texte de l'erreur
385         */
[93656]386        public function erreur($id, $texte = '') {
[55381]387                $this->log("erreur: $id -> $texte");
[93656]388                if (!isset($this->err[$id]) or !is_array($this->err[$id])) {
[62572]389                        $this->err[$id] = array();
390                }
[55381]391                $this->err[$id][] = $texte;
392                $this->ok = false;
393        }
394
[64679]395        /**
396         * Teste si une erreur est présente sur un paquet (via son identifiant)
397         *
398         * @param int $id
399         *     Identifiant de paquet
400         * @return bool|array
401         *     false si pas d'erreur, tableau des erreurs sinon.
402         */
[93656]403        public function en_erreur($id) {
[55381]404                return isset($this->err[$id]) ? $this->err[$id] : false;
405        }
406
407
[64679]408        /**
409         * Vérifie qu'un plugin plus récent existe pour un préfixe et une version donnée
410         *
411         * @param string $prefixe
412         *     Préfixe du plugin
413         * @param string $version
414         *     Compatibilité à comparer, exemple '[1.0;]'
415         * @return bool|array
416         *     false si pas de plugin plus récent trouvé
417         *     tableau de description du paquet le plus récent sinon
418         */
[93656]419        public function chercher_plugin_recent($prefixe, $version) {
[93627]420                $news = $this->infos_courtes(array(
421                        'pl.prefixe=' . sql_quote($prefixe),
422                        'pa.obsolete=' . sql_quote('non'),
423                        'pa.id_depot > ' . sql_quote(0)
424                ), true);
[55381]425                $res = false;
426                if ($news and count($news['p'][$prefixe]) > 0) {
427                        foreach ($news['p'][$prefixe] as $new) {
[93627]428                                if (spip_version_compare($new['v'], $version, '>')) {
429                                        if (!$res or version_compare($new['v'], $res['v'], '>')) {
[55381]430                                                $res = $new;
431                                        }
432                                }
433                        }
434                }
[93627]435
[55381]436                return $res;
437        }
438
[64679]439        /**
440         * Vérifie qu'un plugin existe pour un préfixe et une version donnée
[93627]441         *
[64679]442         * @param string $prefixe
443         *     Préfixe du plugin
444         * @param string $version
445         *     Compatibilité à comparer, exemple '[1.0;]'
446         * @return bool|array
447         *     false si pas de plugin plus récent trouvé
448         *     tableau de description du paquet le plus récent sinon
449         */
[93656]450        public function chercher_plugin_compatible($prefixe, $version) {
[89161]451                $plugin = array();
452
[92791]453                $v = '000.000.000';
[55583]454                // on choisit en priorite dans les paquets locaux !
455                $locaux = $this->infos_courtes(array(
456                        'pl.prefixe=' . sql_quote($prefixe),
457                        'pa.obsolete=' . sql_quote('non'),
[93627]458                        'pa.id_depot=' . sql_quote(0)
459                ), true);
[62572]460                if ($locaux and isset($locaux['p'][$prefixe]) and count($locaux['p'][$prefixe]) > 0) {
[55583]461                        foreach ($locaux['p'][$prefixe] as $new) {
[61742]462                                if (plugin_version_compatible($version, $new['v'])
[93627]463                                        and svp_verifier_compatibilite_spip($new['compatibilite_spip'])
464                                        and ($new['v'] > $v)
465                                ) {
[89161]466                                        $plugin = $new;
467                                        $v = $new['v'];
[55381]468                                }
469                        }
470                }
[89161]471
[92791]472                // qu'on ait trouve ou non, on verifie si un plugin local ne procure pas le prefixe
473                // dans une version plus recente
474                $locaux_procure = $this->infos_courtes(array(
[93627]475                        'pa.procure LIKE ' . sql_quote('%' . $prefixe . '%'),
[92791]476                        'pa.obsolete=' . sql_quote('non'),
[93627]477                        'pa.id_depot=' . sql_quote(0)
478                ), true);
[92791]479                foreach ($locaux_procure['i'] as $new) {
480                        if (isset($new['procure'][$prefixe])
[93656]481                                and plugin_version_compatible($version, $new['procure'][$prefixe])
482                                and svp_verifier_compatibilite_spip($new['compatibilite_spip'])
483                                and spip_version_compare($new['procure'][$prefixe], $v, ">")
[93627]484                        ) {
[92791]485                                $plugin = $new;
486                                $v = $new['v'];
487                        }
488                }
489
490                // sinon dans les paquets distants (mais on ne sait pas encore y trouver les procure)
[89161]491                if (!$plugin) {
492                        $distants = $this->infos_courtes(array(
493                                'pl.prefixe=' . sql_quote($prefixe),
494                                'pa.obsolete=' . sql_quote('non'),
[93627]495                                'pa.id_depot>' . sql_quote(0)
496                        ), true);
[89161]497                        if ($distants and isset($distants['p'][$prefixe]) and count($distants['p'][$prefixe]) > 0) {
498                                foreach ($distants['p'][$prefixe] as $new) {
499                                        if (plugin_version_compatible($version, $new['v'])
[93627]500                                                and svp_verifier_compatibilite_spip($new['compatibilite_spip'])
501                                                and ($new['v'] > $v)
502                                        ) {
[89161]503                                                $plugin = $new;
504                                                $v = $new['v'];
505                                        }
[55583]506                                }
507                        }
508                }
[89161]509
510                return ($plugin ? $plugin : false);
[55381]511        }
512
513
[64679]514        /**
515         * Indique qu'un paquet passe à on (on l'active)
516         *
517         * @param array $info
518         *     Description du paquet
[93627]519         **/
[93656]520        public function add($info) {
[55381]521                $this->end['i'][$info['i']] = $info;
522                $this->end['p'][$info['p']] = &$this->end['i'][$info['i']];
523        }
524
[64679]525        /**
526         * Indique qu'un paquet passe à off (on le désactive ou désinstalle)
527         *
528         * @param array $info
529         *     Description du paquet
530         * @param bool $recur
531         *     Passer à off les plugins qui en dépendent, de façon récursive ?
[93627]532         **/
[93656]533        public function off($info, $recur = false) {
[55381]534                $this->log('- stopper ' . $info['p']);
535                $this->remove($info);
536                $this->off[$info['p']] = $info;
[55732]537
[55381]538                // si recursif, on stoppe aussi les plugins dependants
539                if ($recur) {
[93161]540                        $prefixes = array_merge(array($info['p']), array_keys($info['procure']));
[55381]541                        foreach ($this->end['i'] as $id => $plug) {
542                                if (is_array($plug['dn']) and $plug['dn']) {
543                                        foreach ($plug['dn'] as $n) {
[93161]544                                                if (in_array($n['nom'], $prefixes)) {
[55381]545                                                        $this->change($plug, 'off');
546                                                        $this->off($plug, true);
547                                                }
548                                        }
549                                }
550                        }
551                }
552        }
553
[64679]554        /**
555         * Teste qu'un paquet (via son préfixe) sera passé off (désactivé ou désinstallé)
556         *
557         * @param string $prefixe
558         *     Prefixe du paquet
559         * @return bool
560         *     Le paquet sera t'il off ?
[93627]561         **/
[93656]562        public function sera_off($prefixe) {
[55381]563                return isset($this->off[$prefixe]) ? $this->off[$prefixe] : false;
564        }
565
[64679]566        /**
567         * Teste qu'un paquet (via son identifiant) sera passé off (désactivé ou désinstallé)
568         *
569         * @param int $id
570         *     Identifiant du paquet
571         * @return bool
572         *     Le paquet sera t'il off ?
[93627]573         **/
[93656]574        public function sera_off_id($id) {
[55381]575                foreach ($this->off as $info) {
576                        if ($info['i'] == $id) {
577                                return $info;
578                        }
579                }
[93627]580
[55381]581                return false;
582        }
583
[64679]584        /**
[92791]585         * Teste qu'un paquet (via son préfixe) sera actif directement
586         * ou par l'intermediaire d'un procure
[64679]587         *
588         * @param string $prefixe
589         *     Préfixe du paquet
590         * @return bool
591         *     Le paquet sera t'il actif ?
[93627]592         **/
[93656]593        public function sera_actif($prefixe) {
[93162]594                if (isset($this->end['p'][$prefixe])) {
595                        return $this->end['p'][$prefixe];
596                }
[92791]597                // sinon regarder les procure
598                $v = "0.0.0";
599                $plugin = false;
[94475]600                foreach ($this->end['p'] as $endp => $end) {
[93162]601                        if (isset($end['procure'][$prefixe])
[93656]602                                and spip_version_compare($end['procure'][$prefixe], $v, ">")
[93627]603                        ) {
[92791]604                                $v = $end['procure'][$prefixe];
[94475]605                                $plugin = $this->end['p'][$endp];
[92791]606                        }
607                }
[93627]608
[92791]609                return $plugin;
[55381]610        }
611
[64679]612        /**
613         * Teste qu'un paquet (via son identifiant) sera actif
614         *
615         * @param int $id
616         *     Identifiant du paquet
617         * @return bool
618         *     Le paquet sera t'il actif ?
[93627]619         **/
[93656]620        public function sera_actif_id($id) {
[55381]621                return isset($this->end['i'][$id]) ? $this->end['i'][$id] : false;
622        }
623
[64679]624        /**
625         * Ajouter une action/paquet à la liste des demandées
626         *
627         * L'ajoute aussi à la liste de toutes les actions !
[93627]628         *
[64679]629         * @param array $info
630         *     Description du paquet concerné
631         * @param string $quoi
632         *     Type d'action (on, off, kill, upon...)
633         */
[93656]634        public function ask($info, $quoi) {
[55381]635                $this->ask[$info['i']] = $info;
636                $this->ask[$info['i']]['todo'] = $quoi;
637                $this->todo($info, $quoi);
638        }
639
[64679]640        /**
641         * Ajouter une action/paquet à la liste des changements en plus
642         * par rapport à la demande initiale
643         *
644         * L'ajoute aussi à la liste de toutes les actions !
[93627]645         *
[64679]646         * @param array $info
647         *     Description du paquet concerné
648         * @param string $quoi
649         *     Type d'action (on, off, kill, upon...)
650         */
[93656]651        public function change($info, $quoi) {
[55381]652                $this->changes[$info['i']] = $info;
653                $this->changes[$info['i']]['todo'] = $quoi;
654                $this->todo($info, $quoi);
655        }
656
[64679]657
658        /**
659         * Annule une action (automatique) qui finalement était réellement demandée.
[93627]660         *
[64679]661         * Par exemple, une mise à 'off' de paquet entraîne d'autres mises à
662         * 'off' des paquets qui en dépendent. Si une action sur un des paquets
663         * dépendants était aussi demandée, il faut annuler l'action automatique.
664         *
665         * @param array $info
666         *     Description du paquet concerné
667         */
[93656]668        public function annule_change($info) {
[55381]669                unset($this->changes[$info['i']]);
670        }
671
[64679]672        /**
673         * Ajouter une action/paquet à la liste de toutes les actions à faire
674         *
675         * @param array $info
676         *     Description du paquet concerné
677         * @param string $quoi
678         *     Type d'action (on, off, kill, upon...)
679         */
[93656]680        public function todo($info, $quoi) {
[55381]681                $this->todo[$info['i']] = $info;
682                $this->todo[$info['i']]['todo'] = $quoi;
683        }
684
[64679]685        /**
686         * Retire un paquet de la liste des paquets à activer
687         *
688         * @param array $info
689         *     Description du paquet concerné
690         */
[93656]691        public function remove($info) {
[62733]692                // aucazou ce ne soit pas les memes ids entre la demande et la bdd,
693                // on efface aussi avec l'id donne par le prefixe.
694                // Lorsqu'on desactive un plugin en "attente", il n'est pas actif !
695                // on teste tout de meme donc qu'il est la ce prefixe !
696                $i = false;
697                if (isset($this->end['p'][$info['p']])) {
698                        $i = $this->end['p'][$info['p']];
699                }
700                // on enleve les cles par id indique et par prefixe
701                unset($this->end['i'][$info['i']], $this->end['p'][$info['p']]);
702                // ainsi que l'id aucazou du prefixe
703                if ($i) {
704                        unset($this->end['i'][$i['i']]);
705                }
706
[55381]707        }
708
[64679]709
710        /**
711         * Invalide un plugin (il est introuvable, ne correspond pas à notre version de SPIP...)
712         *
713         * @param array $info
714         *     Description du paquet concerné
715         */
[93656]716        public function invalider($info) {
[55381]717                $this->log("-> invalider $info[p]");
718                $this->remove($info); // suffisant ?
719                $this->invalides[$info['p']] = $info;
720                $this->annule_change($info);
721                unset($this->todo[$info['i']]);
722        }
723
[64679]724        /**
725         * Teste qu'un paquet (via son préfixe) est déclaré invalide
726         *
727         * @param string $p
728         *     Prefixe du paquet
729         * @return bool
730         *     Le paquet est t'il invalide ?
[93627]731         **/
[93656]732        public function sera_invalide($p) {
[55381]733                return isset($this->invalides[$p]) ? $this->invalides[$p] : false;
734        }
735
[64679]736        /**
737         * Teste qu'une librairie (via son nom) est déjà présente
738         *
739         * @param string $lib
740         *     Nom de la librairie
741         * @return bool
742         *     La librairie est-elle présente ?
[93627]743         **/
[93656]744        public function est_presente_lib($lib) {
[55381]745                static $libs = false;
746                if ($libs === false) {
[55396]747                        include_spip('inc/svp_outiller');
748                        $libs = svp_lister_librairies();
[55381]749                }
[93627]750
[55381]751                return isset($libs[$lib]) ? $libs[$lib] : false;
752        }
753
754
[64679]755        /**
756         * Ajoute les actions demandées au décideur
757         *
758         * Chaque action est analysée et elles sont redispatchées dans différents
759         * tableaux via les méthodes :
760         * - ask  : ce qui est demandé (ils y vont tous)
761         * - todo : ce qui est à faire (ils y vont tous aussi)
762         * - add  : les plugins activés,
763         * - off  : les plugins désactivés
764         *
765         * La fonction peut lever des erreurs sur les actions tel que :
766         * - Paquet demandé inconnu
767         * - Mise à jour introuvable
768         * - Paquet à désactiver mais qui n'est pas actif
769         *
770         * @param array $todo
771         *     Ce qui est demandé de faire
772         *     Tableau identifiant du paquet => type d'action (on, off, up...)
773         * @return bool
774         *     False en cas d'erreur, true sinon
775         */
[93656]776        public function actionner($todo = null) {
[55381]777                if (is_array($todo)) {
778                        foreach ($todo as $id => $t) {
779                                // plusieurs choses nous interessent... Sauf... le simple telechargement
780                                // et la suppression des fichiers (qui ne peuvent etre fait
781                                // que si le plugin n'est pas actif)
782                                $this->log("-- todo: $id/$t");
783
784                                switch ($t) {
[55601]785                                        case 'getlib':
786                                                break;
[55381]787                                        case 'on':
[55582]788                                        case 'geton':
[55381]789                                                // ajouter ce plugin dans la liste
790                                                if (!$this->sera_actif_id($id)) {
791                                                        $i = $this->infos_courtes_id($id);
[56081]792                                                        if ($i = $i['i'][$id]) {
[93627]793                                                                $this->log("--> $t : " . $i['p'] . ' en version : ' . $i['v']);
[56081]794
795                                                                // se mefier : on peut tenter d'activer
796                                                                // un plugin de meme prefixe qu'un autre deja actif
797                                                                // mais qui n'est pas de meme version ou de meme etat
798                                                                // par exemple un plugin obsolete ou un plugin au contraire plus a jour.
799                                                                // dans ce cas, on desactive l'ancien (sans desactiver les dependences)
800                                                                // et on active le nouveau.
801                                                                // Si une dependance ne suit pas, une erreur se produira du coup.
[93627]802                                                                if (isset($this->end['p'][$i['p']])) {
803                                                                        $old = $this->end['p'][$i['p']];
804                                                                        $this->log("-->> off : " . $old['p'] . ' en version : ' . $old['v']);
[56081]805                                                                        $this->ask($old, 'off');
806                                                                        $this->todo($old, 'off');
[64679]807                                                                        // désactive l'ancien plugin, mais pas les dépendances qui en dépendent
808                                                                        // car normalement, ça devrait suivre...
[93627]809                                                                        $this->off($old, false);
[56081]810
811                                                                }
[93627]812
[56081]813                                                                // pas de prefixe equivalent actif...
814                                                                $this->add($i);
[93627]815                                                                $this->ask($i, $i['local'] ? 'on' : 'geton');
816
[55381]817                                                        } else {
818                                                                // la c'est vraiment pas normal... Erreur plugin inexistant...
819                                                                // concurrence entre administrateurs ?
[93627]820                                                                $this->erreur($id, _T('svp:message_nok_plugin_inexistant', array('plugin' => $id)));
[55381]821                                                        }
822                                                }
823                                                break;
824                                        case 'up':
825                                        case 'upon':
826                                                // le plugin peut etre actif !
827                                                // ajouter ce plugin dans la liste et retirer l'ancien
828                                                $i = $this->infos_courtes_id($id);
829                                                if ($i = $i['i'][$id]) {
[93627]830                                                        $this->log("--> $t : " . $i['p'] . ' en version : ' . $i['v']);
[56081]831
[55381]832                                                        // new : plugin a installer
833                                                        if ($new = $this->chercher_plugin_recent($i['p'], $i['v'])) {
[93627]834                                                                $this->log("--> maj : " . $new['p'] . ' en version : ' . $new['v']);
[55381]835                                                                // ajouter seulement si on l'active !
836                                                                // ou si le plugin est actuellement actif
837                                                                if ($t == 'upon' or $this->sera_actif_id($id)) {
838                                                                        $this->remove($i);
839                                                                        $this->add($new);
840                                                                }
841                                                                $this->ask($i, $t);
842                                                        } else {
[60027]843                                                                if ($this->erreur_sur_maj_introuvable) {
844                                                                        // on n'a pas trouve la nouveaute !!!
[93627]845                                                                        $this->erreur($id, _T('svp:message_nok_maj_introuvable', array('plugin' => $i['n'], 'id' => $id)));
[60027]846                                                                }
[55381]847                                                        }
848                                                } else {
849                                                        // mauvais identifiant ?
850                                                        // on n'a pas trouve le plugin !!!
[93627]851                                                        $this->erreur($id, _T('svp:message_erreur_maj_inconnu', array('id' => $id)));
[55381]852                                                }
853                                                break;
854                                        case 'off':
855                                        case 'stop':
856                                                // retirer ce plugin
857                                                // (il l'est peut etre deja)
858                                                if ($info = $this->sera_actif_id($id)
[93627]859                                                        or $info_off = $this->sera_off_id($id)
860                                                        // un plugin en attente (desactive parce que sa dependance a disparu certainement par ftp)
861                                                        // peut etre desactive
862                                                        or $info = $this->est_attente_id($id)
863                                                ) {
[55381]864                                                        // annuler le signalement en "proposition" (due a une mise a 'off' recursive)
[56050]865                                                        // de cet arret de plugin, vu qu'on le demande reellement
[55381]866                                                        if (!$info) {
867                                                                $info = $info_off;
868                                                                $this->annule_change($info);
869                                                        }
[93627]870                                                        $this->log("--> $t : " . $info['p'] . ' en version : ' . denormaliser_version($info['v']));
[55381]871                                                        $this->ask($info, $t);
872                                                        $this->todo($info, $t);
[64679]873                                                        // désactive tous les plugins qui en dépendent aussi.
[55381]874                                                        $this->off($info, true);
875
876                                                } else {
877                                                        // pas normal... plugin deja inactif...
878                                                        // concurrence entre administrateurs ?
[55599]879                                                        $this->erreur($id, _T('svp:message_erreur_plugin_non_actif'));
[55381]880                                                }
881                                                break;
882                                        case 'null':
883                                        case 'get':
884                                        case 'kill':
885                                                if ($info = $this->infos_courtes_id($id)) {
[93627]886                                                        $this->log("--> $t : " . $info['i'][$id]['p'] . ' en version : ' . $info['i'][$id]['v']);
[55381]887                                                        $this->ask($info['i'][$id], $t);
888                                                } else {
889                                                        // pas normal... plugin inconnu... concurrence entre administrateurs ?
[93627]890                                                        $this->erreur($id, _T('svp:message_erreur_plugin_introuvable', array('plugin' => $id, 'action' => $t)));
[55381]891                                                }
892                                                break;
893                                }
894                        }
895                }
[93627]896
[55381]897                return $this->ok;
898        }
899
900
[64679]901        /**
902         * Initialise les listes de plugins pour le calcul de dépendances
903         *
904         * Les propriété $start et $end reçoivent la liste des plugins actifs
905         * $procure celle des plugins procurés par le Core
906         */
[93656]907        public function start() {
[55381]908                $this->start = $this->end = $this->liste_plugins_actifs();
[64679]909                $this->procure = $this->liste_plugins_procure();
[55381]910        }
911
[64679]912        /**
913         * Vérifier (et activer) les dépendances
914         *
915         * Pour chaque plugin qui sera actif, vérifie qu'il respecte
916         * ses dépendances.
917         *
918         * Si ce n'est pas le cas, le plugin n'est pas activé et le calcul
919         * de dépendances se refait sans lui. À un moment on a normalement
920         * rapidement une liste de plugins cohérents (au pire on ne boucle
921         * que 100 fois maximum - ce qui ne devrait jamais se produire).
922         *
923         * Des erreurs sont levées lorsqu'un plugin ne peut honorer son activation
924         * à cause d'un problème de dépendance. On peut les récupérer dans la
925         * propriété $err.
926         *
927         * @api
928         * @param array $todo
929         *     Ce qui est demandé de faire
930         *     Tableau identifiant du paquet => type d'action (on, off, up...)
931         * @return bool
932         *     False en cas d'erreur, true sinon
933         */
[93656]934        public function verifier_dependances($todo = null) {
[55381]935
936                $this->start();
937
938                // ajouter les actions
939                if (!$this->actionner($todo)) {
940                        $this->log("! Todo en echec !");
[92778]941                        $this->log($this->err);
[93627]942
[55381]943                        return false;
944                }
945
946                // doit on reverifier les dependances ?
947                // oui des qu'on modifie quelque chose...
948                // attention a ne pas boucler infiniment !
949
950                $supersticieux = 0;
951                do {
952                        $try_again = 0;
953                        $supersticieux++;
954
955                        // verifier chaque dependance de chaque plugin a activer
956                        foreach ($this->end['i'] as $info) {
957                                if (!$this->verifier_dependances_plugin($info)) {
958                                        $try_again = true;
959                                }
960                        }
961                        unset($id, $info);
962                        $this->log("--------> try_again: $try_again, supersticieux: $supersticieux");
963                } while ($try_again > 0 and $supersticieux < 100); # and !count($this->err)
964
965                $this->log("Fin !");
966                $this->log("Ok: " . $this->ok);
[93627]967
[55381]968                # $this->log($this->todo);
969
970                return $this->ok;
971        }
972
973
[64679]974        /**
975         * Pour une description de paquet donnée, vérifie sa validité.
976         *
977         * Teste la version de SPIP, les librairies nécessitées, ses dépendances
978         * (et tente de les trouver et ajouter si elles ne sont pas là)
979         *
980         * Lorsqu'une dépendance est activée, on entre en récursion
981         * dans cette fonction avec la description de la dépendance
[93627]982         *
[64679]983         * @param array $info
984         *     Description du paquet
985         * @param int $prof
986         *     Profondeur de récursion
987         * @return bool
988         *     false si erreur (dépendance non résolue, incompatibilité...), true sinon
[93627]989         **/
[93656]990        public function verifier_dependances_plugin($info, $prof = 0) {
[55381]991                $this->log("- [$prof] verifier dependances " . $info['p']);
992                $id = $info['i'];
[62572]993                $err = false; // variable receptionnant parfois des erreurs
[55381]994                $cache = array(); // cache des actions realisees dans ce tour
995
[55601]996                // 1
997                // tester la version de SPIP de notre paquet
[55582]998                // si on ne valide pas, on retourne une erreur !
[55597]999                // mais normalement, on ne devrait vraiment pas pouvoir tomber sur ce cas
[55598]1000                if (!svp_verifier_compatibilite_spip($info['compatibilite_spip'])) {
[55597]1001                        $this->invalider($info);
[93627]1002                        $this->erreur($id, _T('svp:message_incompatibilite_spip', array('plugin' => $info['n'])));
1003
[55597]1004                        return false;
1005                }
[59476]1006
[62572]1007
[55601]1008                // 2
1009                // ajouter les librairies necessaires a notre paquet
[55634]1010                if (is_array($info['dl']) and count($info['dl'])) {
1011                        foreach ($info['dl'] as $l) {
[55601]1012                                // $l = array('nom' => 'x', 'lien' => 'url')
1013                                $lib = $l['nom'];
[93627]1014                                $this->log("## Necessite la librairie : " . $lib);
[55601]1015
[55582]1016                                // on verifie sa presence OU le fait qu'on pourra la telecharger
1017                                if ($lib and !$this->est_presente_lib($lib)) {
1018                                        // peut on ecrire ?
1019                                        if (!is_writable(_DIR_LIB)) {
1020                                                $this->invalider($info);
[93627]1021                                                $this->erreur($id, _T('svp:message_erreur_ecriture_lib',
1022                                                        array('plugin' => $info['n'], 'lib_url' => $l['lien'], 'lib' => $lib)));
[55601]1023                                                $err = true;
[55418]1024                                        }
[55601]1025                                        // ajout, pour info
1026                                        // de la librairie dans la todo list
1027                                        else {
[55604]1028                                                $this->change(array(
[55601]1029                                                        'i' => md5(serialize($l)),
1030                                                        'p' => $lib,
[55620]1031                                                        'n' => $lib,
[55601]1032                                                        'v' => $l['lien'],
1033                                                ), 'getlib');
[59476]1034                                                $this->log("- La librairie $lib sera a télécharger");
[55601]1035                                        }
1036                                }
[55418]1037                        }
[55601]1038                        if ($err) {
1039                                return false;
1040                        }
[55582]1041                }
1042
[55601]1043                // 3
1044                // Trouver les dependences aux necessites
[55582]1045                // et les activer au besoin
[55634]1046                if (is_array($info['dn']) and count($info['dn'])) {
1047                        foreach ($info['dn'] as $n) {
[55381]1048
[55734]1049                                $p = $n['nom'];
[95518]1050                                $v = isset($n['compatibilite']) ? $n['compatibilite'] : '';
[55381]1051
[55582]1052                                if ($p == 'SPIP') {
[55412]1053                                        // c'est pas la que ça se fait !
[55582]1054                                        // ca ne devrait plus apparaitre comme dependence a un plugin.
[100310]1055                                } 
1056                                // le core procure le paquet que l'on demande !
1057                                elseif (
1058                                        array_key_exists($p, $this->procure)
1059                                        and plugin_version_compatible($v, $this->procure[$p])
[93627]1060                                ) {
[59476]1061                                        // rien a faire...
1062                                        $this->log("-- est procure par le core ($p)");
[55381]1063
[93627]1064                                } // pas d'autre alternative qu'un vrai paquet a activer
[55583]1065                                else {
[55412]1066                                        $this->log("-- verifier : $p");
[55381]1067                                        // nous sommes face a une dependance de plugin
1068                                        // on regarde s'il est present et a la bonne version
1069                                        // sinon on le cherche et on l'ajoute
[55583]1070                                        if ($ninfo = $this->sera_actif($p)
[93627]1071                                                and !$err = $this->en_erreur($ninfo['i'])
1072                                                and plugin_version_compatible($v, $ninfo['v'])
1073                                        ) {
[55583]1074                                                // il est deja actif ou a activer, et tout est ok
[93627]1075                                                $this->log('-- dep OK pour ' . $info['p'] . ' : ' . $p);
1076                                        } // il faut le trouver et demander a l'activer
[55583]1077                                        else {
[93627]1078
[55381]1079                                                // absent ou erreur ou pas compatible
1080                                                $etat = $err ? 'erreur' : ($ninfo ? 'conflit' : 'absent');
[55583]1081                                                // conflit signifie qu'il existe le prefixe actif, mais pas a la version demandee
[93159]1082                                                $this->log("Dependance " . $p . " a resoudre ! ($etat)");
[55381]1083
1084                                                switch ($etat) {
1085                                                        // commencons par le plus simple :
1086                                                        // en cas d'absence, on cherche ou est ce plugin !
1087                                                        case 'absent':
1088                                                                // on choisit par defaut le meilleur etat de plugin.
[55584]1089                                                                // de preference dans les plugins locaux, sinon en distant.
[55381]1090                                                                if (!$this->sera_off($p)
[93627]1091                                                                        and $new = $this->chercher_plugin_compatible($p, $v)
1092                                                                        and $this->verifier_dependances_plugin($new, ++$prof)
1093                                                                ) {
[55583]1094                                                                        // si le plugin existe localement et possede maj_version,
[60194]1095                                                                        // c'est que c'est peut etre une mise a jour + activation a faire
1096                                                                        // si le plugin
1097                                                                        // nouveau est local   => non
1098                                                                        // nouveau est distant => oui peut etre
[55381]1099                                                                        $cache[] = $new;
[60194]1100                                                                        $i = array();
1101                                                                        if (!$new['local']) {
1102                                                                                $i = $this->infos_courtes(array(
[93627]1103                                                                                        'pl.prefixe=' . sql_quote($new['p']),
1104                                                                                        'pa.maj_version=' . sql_quote($new['v'])
1105                                                                                ), true);
[60194]1106                                                                        }
1107                                                                        if ($i and isset($i['p'][$new['p']]) and count($i['p'][$new['p']])) {
[55381]1108                                                                                // c'est une mise a jour
1109                                                                                $vieux = $i['p'][$new['p']][0];
1110                                                                                $this->change($vieux, 'upon');
1111                                                                                $this->log("-- update+active : $p");
1112                                                                        } else {
1113                                                                                // tout nouveau tout beau
[55583]1114                                                                                $this->change($new, $new['local'] ? 'on' : 'geton');
[60194]1115                                                                                if ($new['local']) {
1116                                                                                        $this->log("-- nouveau present : $p");
1117                                                                                } else {
1118                                                                                        $this->log("-- nouveau distant : $p");
1119                                                                                }
[55381]1120                                                                        }
1121                                                                        $this->add($new);
1122                                                                } else {
1123                                                                        $this->log("-- !erreur : $p");
1124                                                                        // on ne trouve pas la dependance !
1125                                                                        $this->invalider($info);
[102745]1126                                                                        $this->erreur($id, $this->presenter_erreur_dependance($info, $p, $v));
[55381]1127                                                                }
1128                                                                unset($new, $vieux);
1129                                                                break;
1130
1131                                                        case 'erreur':
1132                                                                break;
1133
1134                                                        // present, mais conflit de version
1135                                                        // de deux choses l'une :
1136                                                        // soit on trouve un paquet meilleur...
1137                                                        // soit pas :)
1138                                                        case 'conflit':
1139                                                                $this->log("  conflit -> demande $v, present : " . $ninfo['v']);
1140                                                                if (!$this->sera_off($p)
[93627]1141                                                                        and $new = $this->chercher_plugin_compatible($p, $v)
1142                                                                        and $this->verifier_dependances_plugin($new, ++$prof)
1143                                                                ) {
[55381]1144                                                                        // on connait le nouveau...
1145                                                                        $cache[] = $new;
1146                                                                        $this->remove($ninfo);
1147                                                                        $this->add($new);
[93627]1148                                                                        $this->change($ninfo, 'up');
[55381]1149                                                                        $this->log("-- update : $p");
1150                                                                } else {
1151                                                                        $this->log("-- !erreur : $p");
1152                                                                        // on ne trouve pas la dependance !
1153                                                                        $this->invalider($info);
[102745]1154                                                                        $this->erreur($id, $this->presenter_erreur_dependance($info, $p, $v));
[55381]1155                                                                }
1156                                                                break;
1157                                                }
1158
[93627]1159                                        }
[55381]1160                                }
1161
1162                                if ($this->sera_invalide($info['p'])) {
1163                                        break;
1164                                }
1165                        }
1166                        unset($n, $v, $p, $ninfo, $present, $conflit, $erreur, $err);
1167
1168                        // si le plugin est devenu invalide...
1169                        // on invalide toutes les actions qu'on vient de faire !
1170                        if ($this->sera_invalide($info['p'])) {
1171                                $this->log("> Purge du cache");
1172                                foreach ($cache as $i) {
1173                                        $this->invalider($i);
1174                                }
[93627]1175
[55381]1176                                return false;
1177                        }
1178                }
[93627]1179
[55381]1180                return true;
1181        }
1182
[64679]1183        /**
[102745]1184         * Retourne le texte d'erreur adapté à une dépendance donnée
1185         */
1186        public function presenter_erreur_dependance($info, $dependance, $intervalle) {
1187                // prendre en compte les erreurs de dépendances à PHP
1188                // ou à une extension PHP avec des messages d'erreurs dédiés.
1189                $type = 'plugin';
1190                if ($dependance === 'PHP') {
1191                        $type = 'php';
1192                } elseif (strncmp($dependance, 'PHP:', 4) === 0) {
1193                        $type = 'extension_php';
1194                        list(,$dependance) = explode(':', $dependance, 2);
1195                }
1196
[102754]1197                if ($intervalle) {
1198                        $info_dependance = svp_afficher_intervalle($intervalle, $dependance);
[102745]1199                } else {
[102754]1200                        $info_dependance = $dependance;
[102745]1201                }
1202
[102754]1203                $err = _T('svp:message_dependance_' . $type, array(
1204                        'plugin' => $info['n'],
1205                        'dependance' => $info_dependance,
1206                ));
1207
[102745]1208                return $err;
1209        }
1210
1211        /**
[93627]1212         * Retourne un tableau des différentes actions qui seront faites
[64679]1213         *
1214         * @param string $quoi
1215         *     Type de demande
1216         *     - ask : les actions demandées
1217         *     - changes : les actions en plus par rapport à ce qui était demandé
[93627]1218         *     - todo : toutes les actions
[64679]1219         * @return array
1220         *     Liste des actions (joliement traduites et expliquées)
[93627]1221         **/
[93656]1222        public function presenter_actions($quoi) {
[55381]1223                $res = array();
[93627]1224                foreach ($this->$quoi as $id => $info) {
[91517]1225                        $trads = array(
[93627]1226                                'plugin' => $info['n'],
[91517]1227                                'version' => denormaliser_version($info['v']),
1228                        );
1229                        if (isset($info['maj'])) {
1230                                $trads['version_maj'] = denormaliser_version($info['maj']);
1231                        }
[93627]1232                        $res[] = _T('svp:message_action_' . $info['todo'], $trads);
[55381]1233                }
[93627]1234
[55381]1235                return $res;
1236        }
1237}
1238
[55727]1239
1240/**
[93627]1241 * Gère la partie vérifier des formulaires utilisant le Décideur
[55727]1242 *
[64756]1243 * @param array $a_actionner
1244 *     Tableau des actions par paquet (id_paquet => action)
1245 * @param array $erreurs
1246 *     Tableau d'erreurs de verifier (CVT)
1247 * @return bool
1248 *     true si tout va bien, false sinon (erreur pour trouver les dépendances, ...)
[93627]1249 **/
[55727]1250function svp_decider_verifier_actions_demandees($a_actionner, &$erreurs) {
1251        $decideur = new Decideur;
[60027]1252        $decideur->erreur_sur_maj_introuvable = false;
[55727]1253        $decideur->verifier_dependances($a_actionner);
1254
1255        if (!$decideur->ok) {
1256                $erreurs['decideur_erreurs'] = array();
[93627]1257                foreach ($decideur->err as $id => $errs) {
1258                        foreach ($errs as $err) {
[55727]1259                                $erreurs['decideur_erreurs'][] = $err;
1260                        }
1261                }
[93627]1262
[55727]1263                return false;
1264        }
1265
[89058]1266        // On construit la liste des libellés d'actions
1267        $actions = array();
1268        $actions['decideur_propositions'] = $decideur->presenter_actions('changes');
[93627]1269        $actions['decideur_demandes'] = $decideur->presenter_actions('ask');
1270        $actions['decideur_actions'] = $decideur->presenter_actions('todo');
[89058]1271        set_request('_libelles_actions', $actions);
[55727]1272
1273        // On construit la liste des actions pour la passer au formulaire en hidden
1274        $todo = array();
1275        foreach ($decideur->todo as $_todo) {
1276                $todo[$_todo['i']] = $_todo['todo'];
1277        }
1278        set_request('_todo', serialize($todo));
[93627]1279
[55727]1280        return true;
1281}
Note: See TracBrowser for help on using the repository browser.