Ejemplo n.º 1
0
function plugins_afficher_plugin_dist($url_page, $plug_file, $checked, $actif, $expose = false, $class_li = "item", $dir_plugins = _DIR_PLUGINS)
{
    static $id_input = 0;
    static $versions = array();
    $force_reload = _request('var_mode') == 'recalcul';
    $get_infos = charger_fonction('get_infos', 'plugins');
    $info = $get_infos($plug_file, $force_reload, $dir_plugins);
    $prefix = $info['prefix'];
    $cfg = "";
    $checkable = $dir_plugins !== _DIR_PLUGINS_DIST;
    $nom = plugin_nom($info, $dir_plugins, $plug_file);
    if (!plugin_version_compatible($info['compatibilite'], $GLOBALS['spip_version_branche'], 'spip')) {
        $info['slogan'] = _T('plugin_info_non_compatible_spip');
        $erreur = http_img_pack("plugin-dis-32.png", _T('plugin_info_non_compatible_spip'), " class='picto_err'", _T('plugin_info_non_compatible_spip'));
        $class_li .= " disabled";
        $checkable = false;
    } elseif (isset($info['erreur'])) {
        $class_li .= " error";
        $erreur = http_img_pack("plugin-err-32.png", _T('plugin_info_erreur_xml'), " class='picto_err'", _T('plugin_info_erreur_xml')) . "<div class='erreur'>" . join('<br >', $info['erreur']) . "</div>";
        $checkable = false;
    } elseif (isset($GLOBALS['erreurs_activation_raw'][$dir_plugins . $plug_file])) {
        $class_li .= " error";
        $erreur = http_img_pack("plugin-err-32.png", _T('plugin_impossible_activer', array('plugin' => $nom)), " class='picto_err'", _T('plugin_impossible_activer', array('plugin' => $nom))) . "<div class='erreur'>" . implode("<br />", $GLOBALS['erreurs_activation_raw'][$dir_plugins . $plug_file]) . "</div>";
    } else {
        $cfg = $actif ? plugin_bouton_config($plug_file, $info, $dir_plugins) : "";
    }
    // numerotons les occurrences d'un meme prefix
    $versions[$prefix] = $id = isset($versions[$prefix]) ? $versions[$prefix] + 1 : '';
    $class_li .= ($actif ? " actif" : "") . ($expose ? " on" : "");
    return "<li id='{$prefix}{$id}' class='{$class_li}'>" . ((!$checkable and !$checked) ? '' : plugin_checkbox(++$id_input, $plug_file, $checked)) . plugin_resume($info, $dir_plugins, $plug_file, $url_page) . $cfg . $erreur . (($dir_plugins !== _DIR_PLUGINS_DIST and plugin_est_installe($plug_file)) ? plugin_desintalle($plug_file, $nom) : '') . "<div class='details'>" . (!$expose ? '' : affiche_bloc_plugin($plug_file, $info)) . "</div>" . "</li>";
}
Ejemplo n.º 2
0
/**
 * lecture d'un texte conforme a la DTD paquet.dtd
 * et conversion en tableau PHP identique a celui fourni par plugin.xml
 * manque la description
 *
 * @param $desc
 * @param string $plug
 * @param string $dir_plugins
 * @return array
 */
function plugins_infos_paquet($desc, $plug = '', $dir_plugins = _DIR_PLUGINS)
{
    static $process = array('debut' => 'paquet_debutElement', 'fin' => 'paquet_finElement', 'text' => 'paquet_textElement');
    $valider_xml = charger_fonction('valider', 'xml');
    $vxml = $valider_xml($desc, false, $process, 'paquet.dtd', "utf-8");
    if (!$vxml->err) {
        // On veut toutes les variantes selon la version de SPIP
        if (!$plug) {
            return $vxml->versions;
        }
        // compatibilite avec l'existant:
        $tree = $vxml->versions['0'];
        // l'arbre renvoie parfois un tag vide... etrange. Pas la peine de garder ca.
        if (isset($tree['']) and !strlen($tree[''])) {
            unset($tree['']);
        }
        $tree['slogan'] = $tree['prefix'] . "_slogan";
        $tree['description'] = $tree['prefix'] . "_description";
        paquet_readable_files($tree, "{$dir_plugins}{$plug}/");
        if (!$tree['chemin']) {
            $tree['chemin'] = array(array('path' => ''));
        }
        // initialiser par defaut
        // On verifie qu'il existe des balises spip qu'il faudrait rajouter dans
        // la structure d'infos du paquet en fonction de la version spip courante
        if (count($vxml->versions) > 1) {
            $vspip = $GLOBALS['spip_version_branche'];
            foreach ($vxml->versions as $_compatibilite => $_version) {
                if ($_version['balise'] == 'spip' and plugin_version_compatible($_compatibilite, $vspip, 'spip')) {
                    // on merge les sous-balises de la balise spip compatible avec celles de la
                    // balise paquet
                    foreach ($_version as $_index => $_balise) {
                        if ($_index and $_index != 'balise') {
                            $tree[$_index] = array_merge($tree[$_index], $_balise);
                        }
                    }
                }
            }
        }
        return $tree;
    }
    // Prendre les messages d'erreur sans les numeros de lignes
    $msg = array_map('array_shift', $vxml->err);
    // Construire le lien renvoyant sur l'application du validateur XML
    $h = $GLOBALS['meta']['adresse_site'] . '/' . substr("{$dir_plugins}{$plug}/", strlen(_DIR_RACINE)) . 'paquet.xml';
    $h = generer_url_ecrire('valider_xml', "var_url={$h}");
    $t = _T('plugins_erreur', array('plugins' => $plug));
    array_unshift($msg, "<a href='{$h}'>{$t}</a>");
    return array('erreur' => $msg);
}
Ejemplo n.º 3
0
/**
 * Teste la compatibilité d'un intervalle de compatibilité avec une version
 * donnée de SPIP
 *
 * @uses  plugin_version_compatible()
 * @param string $intervalle
 *     Intervalle de compatibilité, tel que [2.1;3.0]
 * @param string $version_spip
 *     Version de SPIP, tel que 3.0.4 (par défaut la version de SPIP en cours)
 * @return bool
 *     true si l'intervalle est compatible, false sinon
 */
function svp_verifier_compatibilite_spip($intervalle, $version_spip = '')
{
    if (!$version_spip) {
        $version_spip = $GLOBALS['spip_version_branche'] . "." . $GLOBALS['spip_version_code'];
    }
    return plugin_version_compatible($intervalle, $version_spip, 'spip');
}
Ejemplo n.º 4
0
 /**
  * Pour une description de paquet donnée, vérifie sa validité.
  *
  * Teste la version de SPIP, les librairies nécessitées, ses dépendances
  * (et tente de les trouver et ajouter si elles ne sont pas là)
  *
  * Lorsqu'une dépendance est activée, on entre en récursion
  * dans cette fonction avec la description de la dépendance
  *
  * @param array $info
  *     Description du paquet
  * @param int $prof
  *     Profondeur de récursion
  * @return bool
  *     false si erreur (dépendance non résolue, incompatibilité...), true sinon
  **/
 public function verifier_dependances_plugin($info, $prof = 0)
 {
     $this->log("- [{$prof}] verifier dependances " . $info['p']);
     $id = $info['i'];
     $err = false;
     // variable receptionnant parfois des erreurs
     $cache = array();
     // cache des actions realisees dans ce tour
     // 1
     // tester la version de SPIP de notre paquet
     // si on ne valide pas, on retourne une erreur !
     // mais normalement, on ne devrait vraiment pas pouvoir tomber sur ce cas
     if (!svp_verifier_compatibilite_spip($info['compatibilite_spip'])) {
         $this->invalider($info);
         $this->erreur($id, _T('svp:message_incompatibilite_spip', array('plugin' => $info['n'])));
         return false;
     }
     // 2
     // ajouter les librairies necessaires a notre paquet
     if (is_array($info['dl']) and count($info['dl'])) {
         foreach ($info['dl'] as $l) {
             // $l = array('nom' => 'x', 'lien' => 'url')
             $lib = $l['nom'];
             $this->log("## Necessite la librairie : " . $lib);
             // on verifie sa presence OU le fait qu'on pourra la telecharger
             if ($lib and !$this->est_presente_lib($lib)) {
                 // peut on ecrire ?
                 if (!is_writable(_DIR_LIB)) {
                     $this->invalider($info);
                     $this->erreur($id, _T('svp:message_erreur_ecriture_lib', array('plugin' => $info['n'], 'lib_url' => $l['lien'], 'lib' => $lib)));
                     $err = true;
                 } else {
                     $this->change(array('i' => md5(serialize($l)), 'p' => $lib, 'n' => $lib, 'v' => $l['lien']), 'getlib');
                     $this->log("- La librairie {$lib} sera a télécharger");
                 }
             }
         }
         if ($err) {
             return false;
         }
     }
     // 3
     // Trouver les dependences aux necessites
     // et les activer au besoin
     if (is_array($info['dn']) and count($info['dn'])) {
         foreach ($info['dn'] as $n) {
             $p = $n['nom'];
             $v = $n['compatibilite'];
             if ($p == 'SPIP') {
                 // c'est pas la que ça se fait !
                 // ca ne devrait plus apparaitre comme dependence a un plugin.
             } elseif (array_key_exists($p, $this->procure) and plugin_version_compatible($v, $this->procure[$p], 'spip')) {
                 // rien a faire...
                 $this->log("-- est procure par le core ({$p})");
             } else {
                 $this->log("-- verifier : {$p}");
                 // nous sommes face a une dependance de plugin
                 // on regarde s'il est present et a la bonne version
                 // sinon on le cherche et on l'ajoute
                 if ($ninfo = $this->sera_actif($p) and !($err = $this->en_erreur($ninfo['i'])) and plugin_version_compatible($v, $ninfo['v'])) {
                     // il est deja actif ou a activer, et tout est ok
                     $this->log('-- dep OK pour ' . $info['p'] . ' : ' . $p);
                 } else {
                     // absent ou erreur ou pas compatible
                     $etat = $err ? 'erreur' : ($ninfo ? 'conflit' : 'absent');
                     // conflit signifie qu'il existe le prefixe actif, mais pas a la version demandee
                     $this->log("Dependance " . $p . " a resoudre ! ({$etat})");
                     switch ($etat) {
                         // commencons par le plus simple :
                         // en cas d'absence, on cherche ou est ce plugin !
                         case 'absent':
                             // on choisit par defaut le meilleur etat de plugin.
                             // de preference dans les plugins locaux, sinon en distant.
                             if (!$this->sera_off($p) and $new = $this->chercher_plugin_compatible($p, $v) and $this->verifier_dependances_plugin($new, ++$prof)) {
                                 // si le plugin existe localement et possede maj_version,
                                 // c'est que c'est peut etre une mise a jour + activation a faire
                                 // si le plugin
                                 // nouveau est local   => non
                                 // nouveau est distant => oui peut etre
                                 $cache[] = $new;
                                 $i = array();
                                 if (!$new['local']) {
                                     $i = $this->infos_courtes(array('pl.prefixe=' . sql_quote($new['p']), 'pa.maj_version=' . sql_quote($new['v'])), true);
                                 }
                                 if ($i and isset($i['p'][$new['p']]) and count($i['p'][$new['p']])) {
                                     // c'est une mise a jour
                                     $vieux = $i['p'][$new['p']][0];
                                     $this->change($vieux, 'upon');
                                     $this->log("-- update+active : {$p}");
                                 } else {
                                     // tout nouveau tout beau
                                     $this->change($new, $new['local'] ? 'on' : 'geton');
                                     if ($new['local']) {
                                         $this->log("-- nouveau present : {$p}");
                                     } else {
                                         $this->log("-- nouveau distant : {$p}");
                                     }
                                 }
                                 $this->add($new);
                             } else {
                                 $this->log("-- !erreur : {$p}");
                                 // on ne trouve pas la dependance !
                                 $this->invalider($info);
                                 $this->erreur($id, $v ? _T('svp:message_dependance_plugin_version', array('plugin' => $info['n'], 'dependance' => $p, 'version' => $v)) : _T('svp:message_dependance_plugin', array('plugin' => $info['n'], 'dependance' => $p)));
                             }
                             unset($new, $vieux);
                             break;
                         case 'erreur':
                             break;
                             // present, mais conflit de version
                             // de deux choses l'une :
                             // soit on trouve un paquet meilleur...
                             // soit pas :)
                         // present, mais conflit de version
                         // de deux choses l'une :
                         // soit on trouve un paquet meilleur...
                         // soit pas :)
                         case 'conflit':
                             $this->log("  conflit -> demande {$v}, present : " . $ninfo['v']);
                             if (!$this->sera_off($p) and $new = $this->chercher_plugin_compatible($p, $v) and $this->verifier_dependances_plugin($new, ++$prof)) {
                                 // on connait le nouveau...
                                 $cache[] = $new;
                                 $this->remove($ninfo);
                                 $this->add($new);
                                 $this->change($ninfo, 'up');
                                 $this->log("-- update : {$p}");
                             } else {
                                 $this->log("-- !erreur : {$p}");
                                 // on ne trouve pas la dependance !
                                 $this->invalider($info);
                                 $this->erreur($id, $v ? _T('svp:message_dependance_plugin_version', array('plugin' => $info['n'], 'dependance' => $p, 'version' => $v)) : _T('svp:message_dependance_plugin', array('plugin' => $info['n'], 'dependance' => $p)));
                             }
                             break;
                     }
                 }
             }
             if ($this->sera_invalide($info['p'])) {
                 break;
             }
         }
         unset($n, $v, $p, $ninfo, $present, $conflit, $erreur, $err);
         // si le plugin est devenu invalide...
         // on invalide toutes les actions qu'on vient de faire !
         if ($this->sera_invalide($info['p'])) {
             $this->log("> Purge du cache");
             foreach ($cache as $i) {
                 $this->invalider($i);
             }
             return false;
         }
     }
     return true;
 }
function plugins_verifie_conformite_dist($plug, &$arbre, $dir_plugins = _DIR_PLUGINS)
{
    static $etats = array('dev', 'experimental', 'test', 'stable');
    $matches = array();
    $silence = false;
    $p = null;
    // chercher la declaration <plugin spip='...'> a prendre pour cette version de SPIP
    if ($n = spip_xml_match_nodes(",^plugin(\\s|\$),", $arbre, $matches)) {
        // version de SPIP
        $vspip = $GLOBALS['spip_version_branche'];
        foreach ($matches as $tag => $sous) {
            list($tagname, $atts) = spip_xml_decompose_tag($tag);
            if ($tagname == 'plugin' and is_array($sous)) {
                // On rajoute la condition sur $n :
                // -- en effet si $n==1 on a pas plus a choisir la balise que l'on ait
                //    un attribut spip ou pas. Cela permet de traiter tous les cas mono-balise
                //    de la meme facon.
                if (!isset($atts['spip']) or $n == 1 or plugin_version_compatible($atts['spip'], $vspip, 'spip')) {
                    // on prend la derniere declaration avec ce nom
                    $p = end($sous);
                    $compat_spip = isset($atts['spip']) ? $atts['spip'] : '';
                }
            }
        }
    }
    if (is_null($p)) {
        $arbre = array('erreur' => array(_T('erreur_plugin_tag_plugin_absent') . " : {$plug}"));
        $silence = true;
    } else {
        $arbre = $p;
    }
    if (!is_array($arbre)) {
        $arbre = array();
    }
    // verification de la conformite du plugin avec quelques
    // precautions elementaires
    if (!isset($arbre['nom'])) {
        if (!$silence) {
            $arbre['erreur'][] = _T('erreur_plugin_nom_manquant');
        }
        $arbre['nom'] = array("");
    }
    if (!isset($arbre['version'])) {
        if (!$silence) {
            $arbre['erreur'][] = _T('erreur_plugin_version_manquant');
        }
        $arbre['version'] = array("");
    }
    if (!isset($arbre['prefix'])) {
        if (!$silence) {
            $arbre['erreur'][] = _T('erreur_plugin_prefix_manquant');
        }
        $arbre['prefix'] = array("");
    } else {
        $prefix = trim(end($arbre['prefix']));
        if (strtoupper($prefix) == 'SPIP' and $plug != "./") {
            $arbre['erreur'][] = _T('erreur_plugin_prefix_interdit');
        }
        if (isset($arbre['etat'])) {
            $etat = trim(end($arbre['etat']));
            if (!in_array($etat, $etats)) {
                $arbre['erreur'][] = _T('erreur_plugin_etat_inconnu') . " : '{$etat}'";
            }
        }
        if (isset($arbre['options'])) {
            foreach ($arbre['options'] as $optfile) {
                $optfile = trim($optfile);
                if (!@is_readable($dir_plugins . "{$plug}/{$optfile}")) {
                    if (!$silence) {
                        $arbre['erreur'][] = _T('erreur_plugin_fichier_absent') . " : {$optfile}";
                    }
                }
            }
        }
        if (isset($arbre['fonctions'])) {
            foreach ($arbre['fonctions'] as $optfile) {
                $optfile = trim($optfile);
                if (!@is_readable($dir_plugins . "{$plug}/{$optfile}")) {
                    if (!$silence) {
                        $arbre['erreur'][] = _T('erreur_plugin_fichier_absent') . " : {$optfile}";
                    }
                }
            }
        }
        $fonctions = array();
        if (isset($arbre['fonctions'])) {
            $fonctions = $arbre['fonctions'];
        }
        $liste_methodes_reservees = array('__construct', '__destruct', 'plugin', 'install', 'uninstall', strtolower($prefix));
        $extraire_pipelines = charger_fonction("extraire_pipelines", "plugins");
        $arbre['pipeline'] = $extraire_pipelines($arbre);
        foreach ($arbre['pipeline'] as $pipe) {
            if (!isset($pipe['nom'])) {
                if (!$silence) {
                    $arbre['erreur'][] = _T("erreur_plugin_nom_pipeline_non_defini");
                }
            }
            if (isset($pipe['action'])) {
                $action = $pipe['action'];
            } else {
                $action = $pipe['nom'];
            }
            // verif que la methode a un nom autorise
            if (in_array(strtolower($action), $liste_methodes_reservees)) {
                if (!$silence) {
                    $arbre['erreur'][] = _T("erreur_plugin_nom_fonction_interdit") . " : {$action}";
                }
            }
            if (isset($pipe['inclure'])) {
                $inclure = $dir_plugins . "{$plug}/" . $pipe['inclure'];
                if (!@is_readable($inclure)) {
                    if (!$silence) {
                        $arbre['erreur'][] = _T('erreur_plugin_fichier_absent') . " : {$inclure}";
                    }
                }
            }
        }
        $necessite = array();
        $spip_trouve = false;
        if (spip_xml_match_nodes(',^necessite,', $arbre, $needs)) {
            foreach (array_keys($needs) as $tag) {
                list($tag, $att) = spip_xml_decompose_tag($tag);
                if (!isset($att['id'])) {
                    if (!$silence) {
                        $arbre['erreur'][] = _T('erreur_plugin_attribut_balise_manquant', array('attribut' => 'id', 'balise' => $att));
                    }
                } else {
                    $necessite[] = $att;
                }
                if (strtolower($att['id']) == 'spip') {
                    $spip_trouve = true;
                }
            }
        }
        if ($compat_spip and !$spip_trouve) {
            $necessite[] = array('id' => 'spip', 'version' => $compat_spip);
        }
        $arbre['necessite'] = $necessite;
        $utilise = array();
        if (spip_xml_match_nodes(',^utilise,', $arbre, $uses)) {
            foreach (array_keys($uses) as $tag) {
                list($tag, $att) = spip_xml_decompose_tag($tag);
                if (!isset($att['id'])) {
                    if (!$silence) {
                        $arbre['erreur'][] = _T('erreur_plugin_attribut_balise_manquant', array('attribut' => 'id', 'balise' => $att));
                    }
                } else {
                    $utilise[] = $att;
                }
            }
        }
        $arbre['utilise'] = $utilise;
        $procure = array();
        if (spip_xml_match_nodes(',^procure,', $arbre, $uses)) {
            foreach (array_keys($uses) as $tag) {
                list($tag, $att) = spip_xml_decompose_tag($tag);
                $procure[] = $att;
            }
        }
        $arbre['procure'] = $procure;
        $path = array();
        if (spip_xml_match_nodes(',^chemin,', $arbre, $paths)) {
            foreach (array_keys($paths) as $tag) {
                list($tag, $att) = spip_xml_decompose_tag($tag);
                $att['path'] = $att['dir'];
                // ancienne syntaxe
                $path[] = $att;
            }
        } else {
            $path = array(array('dir' => ''));
        }
        // initialiser par defaut
        $arbre['path'] = $path;
        // exposer les noisettes
        if (isset($arbre['noisette'])) {
            foreach ($arbre['noisette'] as $k => $nut) {
                $nut = preg_replace(',[.]html$,uims', '', trim($nut));
                $arbre['noisette'][$k] = $nut;
                if (!@is_readable($dir_plugins . "{$plug}/{$nut}.html")) {
                    if (!$silence) {
                        $arbre['erreur'][] = _T('erreur_plugin_fichier_absent') . " : {$nut}";
                    }
                }
            }
        }
        $traduire = array();
        if (spip_xml_match_nodes(',^traduire,', $arbre, $trads)) {
            foreach (array_keys($trads) as $tag) {
                list($tag, $att) = spip_xml_decompose_tag($tag);
                $traduire[] = $att;
            }
        }
        $arbre['traduire'] = $traduire;
    }
}
Ejemplo n.º 6
0
/**
 * Met à jour les informations d'obsolescence des paquets locaux.
 *
 * L'obsolescence indique qu'un paquet est plus ancien (de version ou état
 * moins avancé) qu'un autre également présent localement.
 * 
 * @param array $ids_plugin
 *     Liste d'identifiants de plugins
 *     En cas d'absence, passera sur tous les paquets locaux
**/
function svp_corriger_obsolete_paquets($ids_plugin = array())
{
    // on minimise au maximum le nombre de requetes.
    // 1 pour lister les paquets
    // 1 pour mettre à jour les obsoletes à oui
    // 1 pour mettre à jour les obsoletes à non
    $where = array('pa.id_plugin = pl.id_plugin', 'id_depot=' . sql_quote(0));
    if ($ids_plugin) {
        $where[] = sql_in('pl.id_plugin', $ids_plugin);
    }
    // comme l'on a de nouveaux paquets locaux...
    // certains sont peut etre devenus obsoletes
    // parmis tous les plugins locaux presents
    // concernes par les memes prefixes que les plugins ajoutes.
    $obsoletes = array();
    $changements = array();
    $paquets = sql_allfetsel(array('pa.id_paquet', 'pl.prefixe', 'pa.version', 'pa.etatnum', 'pa.obsolete', 'pa.compatibilite_spip'), array('spip_paquets AS pa', 'spip_plugins AS pl'), $where);
    // L'obsolescence doit tenir compte de la compatibilité avec notre version de SPIP en cours
    foreach ($paquets as $c => $p) {
        $paquets[$c]['compatible'] = plugin_version_compatible($p['compatibilite_spip'], $GLOBALS['spip_version_branche'], 'spip');
    }
    foreach ($paquets as $c => $p) {
        $obsoletes[$p['prefixe']][] = $c;
        // si 2 paquet locaux ont le meme prefixe,
        // sont compatibles avec notre SPIP,
        // mais pas la meme version,
        // l'un est obsolete : la version la plus ancienne
        // Si version et etat sont egaux, on ne decide pas d'obsolescence.
        if (count($obsoletes[$p['prefixe']]) > 1) {
            foreach ($obsoletes[$p['prefixe']] as $cle) {
                if ($cle == $c) {
                    continue;
                }
                if (!$paquets[$c]['compatible']) {
                    continue;
                }
                // je suis plus petit qu'un autre
                if (spip_version_compare($paquets[$c]['version'], $paquets[$cle]['version'], '<')) {
                    if ($paquets[$c]['etatnum'] <= $paquets[$cle]['etatnum']) {
                        if ($paquets[$c]['obsolete'] != 'oui') {
                            $paquets[$c]['obsolete'] = 'oui';
                            $changements[$c] = true;
                        }
                    }
                } else {
                    // je suis strictement plus grand qu'un autre...
                    if (spip_version_compare($paquets[$c]['version'], $paquets[$cle]['version'], '>')) {
                        // si mon etat est meilleur, rendre obsolete les autres
                        if ($paquets[$c]['etatnum'] >= $paquets[$cle]['etatnum']) {
                            if ($paquets[$cle]['obsolete'] != 'oui') {
                                $paquets[$cle]['obsolete'] = 'oui';
                                $changements[$cle] = true;
                            }
                        }
                    } elseif ($paquets[$c]['etatnum'] > $paquets[$cle]['etatnum']) {
                        if ($paquets[$cle]['obsolete'] != 'oui') {
                            $paquets[$cle]['obsolete'] = 'oui';
                            $changements[$cle] = true;
                        }
                    }
                }
            }
        } else {
            if ($paquets[$c]['obsolete'] != 'non') {
                $paquets[$c]['obsolete'] = 'non';
                $changements[$c] = true;
            }
        }
    }
    if (count($changements)) {
        $oui = $non = array();
        foreach ($changements as $c => $null) {
            if ($paquets[$c]['obsolete'] == 'oui') {
                $oui[] = $paquets[$c]['id_paquet'];
            } else {
                $non[] = $paquets[$c]['id_paquet'];
            }
        }
        if ($oui) {
            sql_updateq('spip_paquets', array('obsolete' => 'oui'), sql_in('id_paquet', $oui));
        }
        if ($non) {
            sql_updateq('spip_paquets', array('obsolete' => 'non'), sql_in('id_paquet', $non));
        }
    }
}
Ejemplo n.º 7
0
Archivo: plugin.php Proyecto: spip/SPIP
function plugins_precompile_chemin($plugin_valides, $ordre)
{
    $chemins = array();
    $contenu = "";
    foreach ($ordre as $p => $info) {
        // $ordre peur contenir des plugins en attente et non valides pour ce hit
        if (isset($plugin_valides[$p])) {
            $dir_type = $plugin_valides[$p]['dir_type'];
            $plug = $plugin_valides[$p]['dir'];
            // definir le plugin, donc le path avant l'include du fichier options
            // permet de faire des include_spip pour attraper un inc_ du plugin
            $dir = $dir_type . ".'" . $plug . "/'";
            $prefix = strtoupper(preg_replace(',\\W,', '_', $info['prefix']));
            if ($prefix !== "SPIP") {
                $contenu .= "define('_DIR_PLUGIN_{$prefix}',{$dir});\n";
                foreach ($info['chemin'] as $chemin) {
                    if (!isset($chemin['version']) or plugin_version_compatible($chemin['version'], $GLOBALS['spip_version_branche'], 'spip')) {
                        $dir = $chemin['path'];
                        if (strlen($dir) and $dir[0] == "/") {
                            $dir = substr($dir, 1);
                        }
                        if (strlen($dir) and $dir == "./") {
                            $dir = '';
                        }
                        if (strlen($dir)) {
                            $dir = rtrim($dir, '/') . '/';
                        }
                        if (!isset($chemin['type']) or $chemin['type'] == 'public') {
                            $chemins['public'][] = "_DIR_PLUGIN_{$prefix}" . (strlen($dir) ? ".'{$dir}'" : "");
                        }
                        if (!isset($chemin['type']) or $chemin['type'] == 'prive') {
                            $chemins['prive'][] = "_DIR_PLUGIN_{$prefix}" . (strlen($dir) ? ".'{$dir}'" : "");
                        }
                    }
                }
            }
        }
    }
    if (count($chemins)) {
        $contenu .= "if (_DIR_RESTREINT) _chemin(implode(':',array(" . implode(',', array_reverse($chemins['public'])) . ")));\n" . "else _chemin(implode(':',array(" . implode(',', array_reverse($chemins['prive'])) . ")));\n";
    }
    ecrire_fichier_php(_CACHE_PLUGINS_PATH, $contenu);
}
Ejemplo n.º 8
0
/**
 * Phrase la liste des balises <archive>
 *
 * Chaque bloc XML est constitue de 3 sous-blocs principaux :
 * - <zip> : contient les balises d'information sur le zip (obligatoire)
 * - <traductions> : contient la compilation des informations de traduction (facultatif)
 * - <plugin> ou <paquet> suivant la DTD : le contenu du fichier plugin.xml ou paquet.xml (facultatif)
 *
 * @param array $archives
 *     Tableau de la liste des archives trouvées dans la description d'un dépot
 * @param array $md5_cache
 *     Tableau des descriptions d'archives déjà connues : on supprime
 *     à la fin celles qui ne font plus parties du dépot.
 * @return array
 *     Tableau décrivant chaque archive, avec en index l'url de l'archive.
 *     Tableau (url => Tableau de description de l'archive)
 */
function svp_phraser_archives($archives, &$md5_cache = array())
{
    include_spip('inc/plugin');
    $seen = array();
    $paquets = array();
    $version_spip = $GLOBALS['spip_version_branche'] . "." . $GLOBALS['spip_version_code'];
    // On verifie qu'il existe au moins une archive
    if (!$archives) {
        return $paquets;
    }
    // On phrase chacune des archives
    // Seul le bloc <zip> est obligatoire
    foreach ($archives as $_cle => $_archive) {
        // quand version spip ou mode runtime changent,
        // il faut mettre le xml a jour pour voir les plugins compatibles ou non
        $md5 = md5($_archive . ":{$version_spip}:" . _SVP_MODE_RUNTIME);
        if (isset($md5_cache[$md5])) {
            if (is_array($p = $md5_cache[$md5])) {
                $paquets[$p['file']] = $p;
            }
            // ce paquet est connu
            $seen[] = $md5;
        } elseif (preg_match(_SVP_REGEXP_BALISE_ZIP, $_archive, $matches)) {
            // Extraction de la balise <zip>
            $zip = svp_phraser_zip($matches[1]);
            if ($zip) {
                // Extraction de la balise traductions
                $traductions = array();
                if (preg_match(_SVP_REGEXP_BALISE_TRADUCTIONS, $_archive, $matches)) {
                    $traductions = svp_phraser_traductions($matches[1]);
                }
                // La balise <archive> peut posseder un attribut qui precise la DTD utilisee pour les plugins (plugin ou paquet)
                // Sinon, c'est la DTD plugin qui est utilisee
                list($tag, $attributs) = spip_xml_decompose_tag($_archive);
                // -- On stocke la DTD d'extraction des infos du plugin
                $dtd = (isset($attributs['dtd']) and $attributs['dtd']) ? $attributs['dtd'] : _SVP_DTD_PLUGIN;
                // Extraction *des balises* plugin ou *de la balise* paquet suivant la DTD et la version SPIP
                // -- DTD : si on utilise plugin.xml on extrait la balise <plugin> sinon la balise <paquet>
                $xml = svp_phraser_plugin($dtd, $_archive);
                // Si on est en mode runtime, on est seulement interesse par les plugins compatibles avec
                // la version courant de SPIP. On ne stocke donc pas les autres plugins.
                // Si on est pas en mode runtime on prend tout !
                if (!_SVP_MODE_RUNTIME or _SVP_MODE_RUNTIME and isset($xml['compatibilite']) and plugin_version_compatible($xml['compatibilite'], $version_spip, 'spip')) {
                    $paquets[$zip['file']] = $zip;
                    $paquets[$zip['file']]['traductions'] = $traductions;
                    $paquets[$zip['file']]['dtd'] = $dtd;
                    $paquets[$zip['file']]['plugin'] = $xml;
                    $paquets[$zip['file']]['md5'] = $md5;
                    $md5_cache[$md5] = $paquets[$zip['file']];
                    $seen[] = $md5;
                } else {
                    $md5_cache[$md5] = $zip['file'];
                    $seen[] = $md5;
                }
            }
        }
    }
    // supprimer du cache les zip qui ne sont pas dans le nouveau $archives
    $oldies = array_diff(array_keys($md5_cache), $seen);
    foreach ($oldies as $old_md5) {
        unset($md5_cache[$old_md5]);
    }
    return $paquets;
}
Ejemplo n.º 9
0
function plugins_verifie_conformite_dist($plug, &$arbre, $dir_plugins = _DIR_PLUGINS){
	static $etats = array('dev','experimental','test', 'stable');

	$matches = array();
	$silence = false;
	$p = null;
	// chercher la declaration <plugin spip='...'> a prendre pour cette version de SPIP
	if ($n = spip_xml_match_nodes(",^plugin(\s|$),", $arbre, $matches)){
		// version de SPIP
		$vspip = $GLOBALS['spip_version_branche'];
		foreach($matches as $tag=>$sous){
			list($tagname,$atts) = spip_xml_decompose_tag($tag);
			if ($tagname=='plugin' AND is_array($sous)){
				if (!isset($atts['spip'])
					OR plugin_version_compatible($atts['spip'],$vspip)) {
					// on prend la derniere declaration avec ce nom
					$p = end($sous);
					$compat_spip = isset($atts['spip']) ? $atts['spip'] : '';
				}
			}
		}
	}
	if (is_null($p)){
		$arbre = array('erreur' => array(_T('erreur_plugin_tag_plugin_absent')." : $plug"));
		$silence = true;
	}
	else
		$arbre = $p;
	if (!is_array($arbre)) $arbre = array();
  // verification de la conformite du plugin avec quelques
  // precautions elementaires
	if (!isset($arbre['nom'])){
		if (!$silence)
			$arbre['erreur'][] = _T('erreur_plugin_nom_manquant');
		$arbre['nom'] = array("");
	}
	if (!isset($arbre['version'])){
	  	if (!$silence)
			$arbre['erreur'][] = _T('erreur_plugin_version_manquant');
		$arbre['version'] = array("");
	}
	if (!isset($arbre['prefix'])){
	  	if (!$silence)
			$arbre['erreur'][] = _T('erreur_plugin_prefix_manquant');
		$arbre['prefix'] = array("");
	} else{
		$prefix = trim(end($arbre['prefix']));
		if (strtoupper($prefix)=='SPIP'){
			$arbre['erreur'][] = _T('erreur_plugin_prefix_interdit');
		}
		if (isset($arbre['etat'])){
			$etat = trim(end($arbre['etat']));
			if (!in_array($etat, $etats))
				$arbre['erreur'][] = _T('erreur_plugin_etat_inconnu')." : '$etat'";
		}
		if (isset($arbre['options'])){
			foreach($arbre['options'] as $optfile){
				$optfile = trim($optfile);
				if (!@is_readable($dir_plugins."$plug/$optfile"))
  				if (!$silence)
						$arbre['erreur'][] = _T('erreur_plugin_fichier_absent')." : $optfile";
			}
		}
		if (isset($arbre['fonctions'])){
			foreach($arbre['fonctions'] as $optfile){
				$optfile = trim($optfile);
				if (!@is_readable($dir_plugins."$plug/$optfile"))
  				if (!$silence)
						$arbre['erreur'][] = _T('erreur_plugin_fichier_absent')." : $optfile";
			}
		}
		$fonctions = array();
		if (isset($arbre['fonctions']))
			$fonctions = $arbre['fonctions'];
	    $liste_methodes_reservees = array('__construct','__destruct','plugin','install','uninstall',strtolower($prefix));

		$extraire_pipelines = charger_fonction("extraire_pipelines","plugins");
	    $arbre['pipeline'] = $extraire_pipelines($arbre);
		foreach($arbre['pipeline'] as $pipe){
			if (!isset($pipe['nom']))
				if (!$silence)
					$arbre['erreur'][] = _T("erreur_plugin_nom_pipeline_non_defini");
			if (isset($pipe['action'])) $action = $pipe['action'];
			else $action = $pipe['nom'];
			// verif que la methode a un nom autorise
			if (in_array(strtolower($action),$liste_methodes_reservees)){
				if (!$silence)
					$arbre['erreur'][] = _T("erreur_plugin_nom_fonction_interdit")." : $action";
			}
			if (isset($pipe['inclure'])) {
				$inclure = $dir_plugins."$plug/".$pipe['inclure'];
				if (!@is_readable($inclure))
	  			if (!$silence)
						$arbre['erreur'][] = _T('erreur_plugin_fichier_absent')." : $inclure";
			}
		}
		$necessite = array();
		$spip_trouve = false;
		if (spip_xml_match_nodes(',^necessite,',$arbre,$needs)){
			foreach(array_keys($needs) as $tag){
				list($tag,$att) = spip_xml_decompose_tag($tag);
				$necessite[] = $att;
				if (strtolower($att['id']) == 'spip')
					$spip_trouve = true;
			}
		}
		if ($compat_spip AND !$spip_trouve)
				$necessite[] = array('id' => 'spip', 'version' => $compat_spip);
		$arbre['necessite'] = $necessite;
		$utilise = array();
		if (spip_xml_match_nodes(',^utilise,',$arbre,$uses)){
			foreach(array_keys($uses) as $tag){
				list($tag,$att) = spip_xml_decompose_tag($tag);
				$utilise[] = $att;
			}
		}
		$arbre['utilise'] = $utilise;
		$path = array();
		if (spip_xml_match_nodes(',^chemin,',$arbre,$paths)){
			foreach(array_keys($paths) as $tag){
				list($tag,$att) = spip_xml_decompose_tag($tag);
				$path[] = $att;
			}
		}
		else
			$path = array(array('dir'=>'')); // initialiser par defaut
		$arbre['path'] = $path;
		// exposer les noisettes
		if (isset($arbre['noisette'])){
			foreach($arbre['noisette'] as $k=>$nut){
				$nut = preg_replace(',[.]html$,uims','',trim($nut));
				$arbre['noisette'][$k] = $nut;
				if (!@is_readable($dir_plugins."$plug/$nut.html"))
  				if (!$silence)
						$arbre['erreur'][] = _T('erreur_plugin_fichier_absent')." : $nut";
			}
		}
		$traduire = array();
		if (spip_xml_match_nodes(',^traduire,',$arbre,$trads)){
			foreach(array_keys($trads) as $tag){
				list($tag,$att) = spip_xml_decompose_tag($tag);
				$traduire[] = $att;
			}
		}
		$arbre['traduire'] = $traduire;
	}
}
Ejemplo n.º 10
0
function ecrire_plugin_actifs($plugin,$pipe_recherche=false,$operation='raz') {
	static $liste_pipe_manquants=array();

	// creer le repertoire cache/ si necessaire ! (installation notamment)
	sous_repertoire(_DIR_CACHE, '', false,true);

	$liste_fichier_verif = array();
	if (($pipe_recherche)&&(!in_array($pipe_recherche,$liste_pipe_manquants)))
		$liste_pipe_manquants[]=$pipe_recherche;

	if ($operation!='raz'){
		$plugin_actifs = liste_chemin_plugin_actifs();
		$plugin_liste = liste_plugin_files();
		$plugin_valides = array_intersect($plugin_actifs,$plugin_liste);
		if ($operation=='ajoute')
			$plugin = array_merge($plugin_valides,$plugin);
		if ($operation=='enleve')
			$plugin = array_diff($plugin_valides,$plugin);
	}

	// recharger le xml des plugins a activer
	list($plugin_valides,$ordre,$infos) = liste_plugin_valides($plugin,true);

	ecrire_meta('plugin',serialize($plugin_valides));
	effacer_meta('message_crash_plugins'); // baisser ce flag !
	$plugin_header_info = array();
	foreach($plugin_valides as $p=>$resume){
		$plugin_header_info[]= $p.($resume['version']?"(".$resume['version'].")":"");
	}
	ecrire_meta('plugin_header',substr(strtolower(implode(",",$plugin_header_info)),0,900));

	$start_file = "<"."?php\nif (defined('_ECRIRE_INC_VERSION')) {\n";
	$end_file = "}\n?".">";

	if (is_array($infos)){
		// construire tableaux de boutons et onglets
		$liste_boutons = array();
		$liste_onglets = array();
		foreach($ordre as $p){
			$dir_type = $plugin_valides[$p]['dir_type'];
			$plug = $plugin_valides[$p]['dir'];
			$info = $infos[$dir_type][$plug];
			if (isset($info['bouton'])){
				$liste_boutons = array_merge($liste_boutons,$info['bouton']);
			}
			if (isset($info['onglet'])){
				$liste_onglets = array_merge($liste_onglets,$info['onglet']);
			}
		}
	}

	// generer les fichier
	// charger_plugins_options.php
	// charger_plugins_fonctions.php
	if (defined('_DIR_PLUGINS_SUPPL'))
		$dir_plugins_suppl = implode(array_filter(explode(':',_DIR_PLUGINS_SUPPL)),'|');

	foreach(array('chemins'=>_CACHE_PLUGINS_PATH,'options'=>_CACHE_PLUGINS_OPT,'fonctions'=>_CACHE_PLUGINS_FCT) as $charge=>$fileconf){
		$s = "";
		$splugs = "";
		$chemins = array();
		if (is_array($infos)){
			foreach($ordre as $p){
				$dir_type = $plugin_valides[$p]['dir_type'];
				$plug = $plugin_valides[$p]['dir'];
				$info = $infos[$dir_type][$plug];
				if($dir_plugins_suppl && preg_match(',('.$dir_plugins_suppl.'),',$plugin_valides[$p]['dir'])){
					//$plugin_valides[$p]['dir_type'] = '_DIR_RACINE';
					$dir_type = '_DIR_RACINE';
					//if(!test_espace_prive())
						$plug = str_replace('../','',$plug);
				}
				$root_dir_type = str_replace('_DIR_','_ROOT_',$dir_type);
				$dir = $dir_type.".'" . $plug ."/'";
				// definir le plugin, donc le path avant l'include du fichier options
				// permet de faire des include_spip pour attraper un inc_ du plugin
				if ($charge=='chemins'){
					$prefix = strtoupper(preg_replace(',\W,','_',$info['prefix']));
					$splugs .= "define('_DIR_PLUGIN_$prefix',$dir);\n";
					foreach($info['path'] as $chemin){
						if (!isset($chemin['version']) OR plugin_version_compatible($chemin['version'],$GLOBALS['spip_version_branche'])){
							$dir = $chemin['dir'];
							if (strlen($dir) AND $dir{0}=="/") $dir = substr($dir,1);
							if (!isset($chemin['type']) OR $chemin['type']=='public')
								$chemins['public'][]="_DIR_PLUGIN_$prefix".(strlen($dir)?".'$dir'":"");
							if (!isset($chemin['type']) OR $chemin['type']=='prive')
								$chemins['prive'][]="_DIR_PLUGIN_$prefix".(strlen($dir)?".'$dir'":"");
							#$splugs .= "if (".(($chemin['type']=='public')?"":"!")."_DIR_RESTREINT) ";
							#$splugs .= "_chemin(_DIR_PLUGIN_$prefix".(strlen($dir)?".'$dir'":"").");\n";
						}
					}
				}
				// concerne uniquement options et fonctions
				if (isset($info[$charge])){
					foreach($info[$charge] as $file){
						// on genere un if file_exists devant chaque include pour pouvoir garder le meme niveau d'erreur general
						$file = trim($file);

						if (strlen(constant($dir_type)) && (strpos($plug, constant($dir_type)) === 0)) {
							$dir = str_replace("'".constant($dir_type), $root_dir_type.".'", "'$plug/'");
						}
						if($root_dir_type == '_ROOT_RACINE'){
							$plug = str_replace('../','',$plug);
						}
						else
							$dir = $root_dir_type.".'$plug/'";
						$s .= "if (file_exists(\$f=$dir.'".trim($file)."')){ include_once \$f;}\n";
						$liste_fichier_verif[] = "$root_dir_type:$plug/".trim($file);
					}
				}
			}
		}
		if ($charge=='chemins'){
			if (count($chemins)){
				$splugs .= "if (_DIR_RESTREINT) _chemin(implode(':',array(".implode(',',array_reverse($chemins['public'])).")));\n";
				$splugs .= "else _chemin(implode(':',array(".implode(',',array_reverse($chemins['prive'])).")));\n";
			}
		}
		if ($charge=='options'){
			$s .= "if (!function_exists('boutons_plugins')){function boutons_plugins(){return unserialize('".str_replace("'","\'",serialize($liste_boutons))."');}}\n";
			$s .= "if (!function_exists('onglets_plugins')){function onglets_plugins(){return unserialize('".str_replace("'","\'",serialize($liste_onglets))."');}}\n";
		}
		ecrire_fichier($fileconf, $start_file . $splugs . $s . $end_file);
	}

	if (is_array($infos)){
		// construire tableaux de pipelines et matrices et boutons
		// $GLOBALS['spip_pipeline']
		// $GLOBALS['spip_matrice']
		$liste_boutons = array();
		foreach($ordre as $p){
			$dir_type = $plugin_valides[$p]['dir_type'];
			$root_dir_type = str_replace('_DIR_','_ROOT_',$dir_type);
			$plug = $plugin_valides[$p]['dir'];
			$info = $infos[$dir_type][$plug];
			$prefix = "";
			$prefix = $info['prefix']."_";
			if (isset($info['pipeline']) AND is_array($info['pipeline'])){
				foreach($info['pipeline'] as $pipe){
					$nom = $pipe['nom'];
					if (isset($pipe['action']))
						$action = $pipe['action'];
					else
						$action = $nom;
					$nomlower = strtolower($nom);
					if ($nomlower!=$nom 
					  AND isset($GLOBALS['spip_pipeline'][$nom]) 
					  AND !isset($GLOBALS['spip_pipeline'][$nomlower])){
						$GLOBALS['spip_pipeline'][$nomlower] = $GLOBALS['spip_pipeline'][$nom];
						unset($GLOBALS['spip_pipeline'][$nom]);
					}
					$nom = $nomlower;
					if (!isset($GLOBALS['spip_pipeline'][$nom])) // creer le pipeline eventuel
						$GLOBALS['spip_pipeline'][$nom]="";
					if (strpos($GLOBALS['spip_pipeline'][$nom],"|$prefix$action")===FALSE)
						$GLOBALS['spip_pipeline'][$nom] = preg_replace(",(\|\||$),","|$prefix$action\\1",$GLOBALS['spip_pipeline'][$nom],1);
					if (isset($pipe['inclure'])){
						$GLOBALS['spip_matrice']["$prefix$action"] =
							"$root_dir_type:$plug/".$pipe['inclure'];
					}
				}
			}
		}
	}
	
	// on charge les fichiers d'options qui peuvent completer 
	// la globale spip_pipeline egalement
	if (@is_readable(_CACHE_PLUGINS_PATH))
		include_once(_CACHE_PLUGINS_PATH); // securite : a priori n'a pu etre fait plus tot 
	if (@is_readable(_CACHE_PLUGINS_OPT)) {
		include_once(_CACHE_PLUGINS_OPT);
	} else {
		spip_log("pipelines desactives: impossible de produire " . _CACHE_PLUGINS_OPT);
	}
	
	// on ajoute les pipe qui ont ete recenses manquants
	foreach($liste_pipe_manquants as $add_pipe)
		if (!isset($GLOBALS['spip_pipeline'][$add_pipe]))
			$GLOBALS['spip_pipeline'][$add_pipe]= '';

	$liste_fichier_verif2 = pipeline_precompile();
	$liste_fichier_verif = array_merge($liste_fichier_verif,$liste_fichier_verif2);

	// on note dans tmp la liste des fichiers qui doivent etre presents,
	// pour les verifier "souvent"
	// ils ne sont verifies que depuis l'espace prive, mais peuvent etre reconstruit depuis l'espace public
	// dans le cas d'un plugin non declare, spip etant mis devant le fait accompli
	// hackons donc avec un "../" en dur dans ce cas, qui ne manquera pas de nous embeter un jour...
	foreach ($liste_fichier_verif as $k => $f){
		// si un _DIR_XXX: est dans la chaine, on extrait la constante
		if (preg_match(",(_(DIR|ROOT)_[A-Z_]+):,Ums",$f,$regs))
			$f = str_replace($regs[0],$regs[2]=="ROOT"?constant($regs[1]):(_DIR_RACINE?"":"../").constant($regs[1]),$f);
		$liste_fichier_verif[$k] = $f;
	}
	ecrire_fichier(_CACHE_PLUGINS_VERIF,
		serialize($liste_fichier_verif));
	clear_path_cache();
}