/** * Fusion des informations de chaque balise plugin d'un plugin.xml en * considérant la compatibilité SPIP * * Pour les balises plugins uniques cette fonction permet de générer une structure * identique pour les balises dites techniques * * On limite le traitement a deux balises plugins maximum, * ce qui est le cas de tous les plugin.xml actuellement connus * * @param array $plugins * Arbre des balises plugins présents dans un plugin.xml * @return array * Fusion des éléments classé par balise, puis par compatibilité à SPIP. * L'index 0 dans la compatibilité est valable quelque soit la version de SPIP. */ function plugins_fusion_plugin($plugins) { global $balises_techniques; $fusion = array(); if (!$plugins) { return $fusion; } if (count($plugins) == 1) { // Balise plugin unique : on ne traite que les balises techniques $fusion = $plugins[0]; foreach ($balises_techniques as $_btech) { if (isset($fusion[$_btech]) and $fusion[$_btech]) { $balise = $fusion[$_btech]; unset($fusion[$_btech]); $fusion[$_btech][0] = $balise; } else { $fusion[$_btech] = array(); } } } else { // On initialise les informations a retourner avec le bloc a priori le plus recent determine par la compatibilite SPIP : // On selectionne le bloc dont la borne min de compatibilite SPIP est la plus elevee $cle_min_max = -1; $borne_min_max = _SVP_VERSION_SPIP_MIN; foreach ($plugins as $_cle => $_plugin) { if (!$_plugin['compatibilite']) { $borne_min = _SVP_VERSION_SPIP_MIN; } $bornes_spip = extraire_bornes($_plugin['compatibilite']); $borne_min = $bornes_spip['min']['valeur'] ? $bornes_spip['min']['valeur'] : _SVP_VERSION_SPIP_MIN; if (spip_version_compare($borne_min_max, $borne_min, '<=')) { $cle_min_max = $_cle; $borne_min_max = $borne_min; } } $fusion = $plugins[$cle_min_max]; // On relit les autres blocs que celui venant d'etre selectionne et on fusionne les informations necessaires // les traitements effectues sont les suivants : // -- nom, prefix, documentation, version, etat, version_base, description : *rien*, on conserve ces informations en l'etat // -- options, fonctions, install : *rien*, meme si certaines pourraient etre fusionnees ces infos ne sont pas stockees // -- auteur, licence : *rien*, l'heuristique pour fusionner ces infos est trop compliquee aujourdhui car c'est du texte libre // -- categorie, logo : si la valeur du bloc selectionne est vide on essaye d'en trouver une non vide dans les autres blocs // -- compatible : on constuit l'intervalle global de compatibilite SPIP // -- necessite, utilise, lib : on construit le tableau par intervalle de compatibilite SPIP $cle_min_min = $cle_min_max == 0 ? 1 : 0; if (!$fusion['categorie'] and $plugins[$cle_min_min]['categorie']) { $fusion['categorie'] = $plugins[$cle_min_min]['categorie']; } if ((!isset($fusion['logo']) or !$fusion['logo']) and $plugins[$cle_min_min]['logo']) { $fusion['logo'] = $plugins[$cle_min_min]['logo']; } $fusion['compatibilite'] = fusionner_intervalles($fusion['compatibilite'], $plugins[$cle_min_min]['compatibilite']); // necessite, utilise, lib, chemin, pipeline, bouton, onglet : on indexe chaque liste de dependances // par l'intervalle de compatibilite sans regrouper les doublons pour l'instant foreach ($balises_techniques as $_btech) { if (!isset($fusion[$_btech]) and !isset($plugins[$cle_min_min][$_btech])) { // Aucun des tableaux ne contient cette balise technique : on la positionne a un array vide $fusion[$_btech] = array(); } else { if (!isset($fusion[$_btech]) or !$fusion[$_btech]) { if ($plugins[$cle_min_min][$_btech]) { // La balise technique est vide dans le tableau de fusion mais non vide dans la deuxieme balise plugin // On range cette balise dans le tableau fusion de sa compatibilite et on cree la cle commune vide $fusion[$_btech][$plugins[$cle_min_min]['compatibilite']] = $plugins[$cle_min_min][$_btech]; $fusion[$_btech][0] = array(); } } else { if (!isset($plugins[$cle_min_min][$_btech]) or !$plugins[$cle_min_min][$_btech]) { // La balise technique est non vide dans le tableau de fusion mais vide dans la deuxieme balise plugin // On deplace cette balise dans le tableau fusion de sa compatibilite et on cree la cle commune vide $balise = $fusion[$_btech]; unset($fusion[$_btech]); $fusion[$_btech][$plugins[$cle_min_max]['compatibilite']] = $balise; $fusion[$_btech][0] = array(); } else { // Les deux tableaux contiennent une balise technique non vide : il faut fusionner cette balise technique ! // On parcourt le premier tableau (fusion) en verifiant une egalite avec le deuxieme tableau foreach ($fusion[$_btech] as $_cle0 => $_balise0) { $balise_commune = false; foreach ($plugins[$cle_min_min][$_btech] as $_cle1 => $_balise1) { if (balise_identique($_balise0, $_balise1)) { // On classe cette balise dans le bloc commun (index 0) et on la supprime dans les // 2 tableaux en cours de comparaison unset($fusion[$_btech][$_cle0]); $fusion[$_btech][0][] = $_balise1; unset($plugins[$cle_min_min][$_btech][$_cle1]); $balise_commune = true; break; } } if (!$balise_commune) { $fusion[$_btech][$plugins[$cle_min_max]['compatibilite']][] = $_balise0; unset($fusion[$_btech][$_cle0]); } if (!isset($fusion[$_btech][0])) { $fusion[$_btech][0] = array(); } } // On traite maintenant les balises restantes du deuxieme tableau if ($plugins[$cle_min_min][$_btech]) { foreach ($plugins[$cle_min_min][$_btech] as $_balise2) { $fusion[$_btech][$plugins[$cle_min_min]['compatibilite']][] = $_balise2; } } } } } } } return $fusion; }
/** * Complète les informations des plugins, d'une liste de plugins donnés, * en compilant certaines informations (compatibilités, dates, branches) * * @param array $ids_plugin * Liste d'identifiants de plugins * @return bool * false si rien à faire, true sinon **/ function svp_completer_plugins($ids_plugin) { if (!$ids_plugin) { return false; } include_spip('inc/svp_outiller'); // -- on recupere tous les paquets associes aux plugins indiques et on compile les infos if ($resultats = sql_allfetsel('id_plugin, compatibilite_spip, date_crea, date_modif', 'spip_paquets', array(sql_in('id_plugin', $ids_plugin), 'id_depot>' . intval(0)), '', 'id_plugin')) { $plugin_en_cours = 0; $inserts = array(); foreach ($resultats as $paquet) { // On finalise le plugin en cours et on passe au suivant if ($plugin_en_cours != $paquet['id_plugin']) { // On met a jour le plugin en cours if ($plugin_en_cours) { // On deduit maintenant les branches de la compatibilite globale $complements['branches_spip'] = compiler_branches_spip($complements['compatibilite_spip']); $inserts[$plugin_en_cours] = $complements; } // On passe au plugin suivant $plugin_en_cours = $paquet['id_plugin']; $complements = array('compatibilite_spip' => '', 'branches_spip' => '', 'date_crea' => 0, 'date_modif' => 0); } // On compile les compléments du plugin avec le paquet courant sauf les branches // qui sont deduites en fin de compilation de la compatibilite if ($paquet['date_modif'] > $complements['date_modif']) { $complements['date_modif'] = $paquet['date_modif']; } if ($complements['date_crea'] === 0 or $paquet['date_crea'] < $complements['date_crea']) { $complements['date_crea'] = $paquet['date_crea']; } if ($paquet['compatibilite_spip']) { if (!$complements['compatibilite_spip']) { $complements['compatibilite_spip'] = $paquet['compatibilite_spip']; } else { $complements['compatibilite_spip'] = fusionner_intervalles($paquet['compatibilite_spip'], $complements['compatibilite_spip']); } } } // On finalise le dernier plugin en cours $complements['branches_spip'] = compiler_branches_spip($complements['compatibilite_spip']); $inserts[$plugin_en_cours] = $complements; // On insere, en encapsulant pour sqlite... if (sql_preferer_transaction()) { sql_demarrer_transaction(); } foreach ($inserts as $id_plugin => $complements) { sql_updateq('spip_plugins', $complements, 'id_plugin=' . intval($id_plugin)); } if (sql_preferer_transaction()) { sql_terminer_transaction(); } } return true; }