mirror of
https://github.com/YunoHost-Apps/spip_ynh.git
synced 2024-09-03 20:25:59 +02:00
789 lines
27 KiB
PHP
789 lines
27 KiB
PHP
<?php
|
|
|
|
/***************************************************************************\
|
|
* SPIP, Systeme de publication pour l'internet *
|
|
* *
|
|
* Copyright (c) 2001-2014 *
|
|
* Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
|
|
* *
|
|
* Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
|
|
* Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
|
|
\***************************************************************************/
|
|
|
|
if (!defined('_ECRIRE_INC_VERSION')) return;
|
|
|
|
// l'adresse du repertoire de telechargement et de decompactage des plugins
|
|
define('_DIR_PLUGINS_AUTO', _DIR_PLUGINS.'auto/');
|
|
|
|
#include_spip('inc/texte'); // ????? Appelle public/parametrer trop tot avant la reconstruction du chemin des plugins.
|
|
include_spip('plugins/installer');
|
|
|
|
// lecture des sous repertoire plugin existants
|
|
// $dir_plugins pour forcer un repertoire (ex: _DIR_PLUGINS_DIST)
|
|
// _DIR_PLUGINS_SUPPL pour aller en chercher ailleurs
|
|
// (chemins relatifs a la racine du site, separes par des ":")
|
|
// http://doc.spip.org/@liste_plugin_files
|
|
function liste_plugin_files($dir_plugins = null){
|
|
static $plugin_files=array();
|
|
if (is_null($dir_plugins))
|
|
$dir_plugins = _DIR_PLUGINS;
|
|
if (!isset($plugin_files[$dir_plugins])
|
|
OR count($plugin_files[$dir_plugins]) == 0){
|
|
$plugin_files[$dir_plugins] = array();
|
|
foreach (fast_find_plugin_dirs($dir_plugins) as $plugin) {
|
|
$plugin_files[$dir_plugins][] = substr($plugin,strlen($dir_plugins));
|
|
}
|
|
|
|
sort($plugin_files[$dir_plugins]);
|
|
// et on lit le XML de tous les plugins pour le mettre en cache
|
|
// et en profiter pour nettoyer ceux qui n'existent plus du cache
|
|
$get_infos = charger_fonction('get_infos','plugins');
|
|
$get_infos($plugin_files[$dir_plugins],false,$dir_plugins,true);
|
|
}
|
|
return $plugin_files[$dir_plugins];
|
|
}
|
|
|
|
function fast_find_plugin_dirs($dir, $max_prof=100) {
|
|
$fichiers = array();
|
|
// revenir au repertoire racine si on a recu dossier/truc
|
|
// pour regarder dossier/truc/ ne pas oublier le / final
|
|
$dir = preg_replace(',/[^/]*$,', '', $dir);
|
|
if ($dir == '') $dir = '.';
|
|
|
|
if (!is_dir($dir))
|
|
return $fichiers;
|
|
if (is_plugin_dir($dir,'')) {
|
|
$fichiers[] = $dir;
|
|
return $fichiers;
|
|
}
|
|
if ($max_prof<=0)
|
|
return $fichiers;
|
|
|
|
$subdirs = array();
|
|
if (@is_dir($dir) AND is_readable($dir) AND $d = @opendir($dir)) {
|
|
while (($f = readdir($d)) !== false) {
|
|
if ($f[0] != '.' # ignorer . .. .svn etc
|
|
AND $f != 'CVS'
|
|
AND is_dir($f = "$dir/$f"))
|
|
$subdirs[] = $f;
|
|
}
|
|
closedir($d);
|
|
}
|
|
|
|
foreach($subdirs as $d){
|
|
$fichiers = array_merge($fichiers,fast_find_plugin_dirs("$d/",$max_prof-1));
|
|
}
|
|
return $fichiers;
|
|
}
|
|
|
|
function is_plugin_dir($dir,$dir_plugins = null){
|
|
if (is_array($dir)){
|
|
foreach($dir as $k=>$d){
|
|
if (!is_plugin_dir($d,$dir_plugins))
|
|
unset($dir[$k]);
|
|
}
|
|
return $dir;
|
|
}
|
|
if (is_null($dir_plugins))
|
|
$dir_plugins = _DIR_PLUGINS;
|
|
$search = array("$dir_plugins$dir/plugin.xml","$dir_plugins$dir/paquet.xml");
|
|
|
|
foreach($search as $s){
|
|
if (file_exists($s)){
|
|
return $dir;
|
|
}
|
|
}
|
|
return '';
|
|
}
|
|
|
|
// Regexp d'extraction des informations d'un intervalle de compatibilité
|
|
define('_EXTRAIRE_INTERVALLE', ',^[\[\(\]]([0-9.a-zRC\s\-]*)[;]([0-9.a-zRC\s\-\*]*)[\]\)\[]$,');
|
|
|
|
/**
|
|
* Teste si le numéro de version d'un plugin est dans un intervalle donné.
|
|
*
|
|
* Cette fonction peut être volontairement trompée (phase de développement) :
|
|
* voir commentaire infra sur l'utilisation de la constante _DEV_PLUGINS
|
|
*
|
|
* @param string $intervalle
|
|
* Un intervalle entre 2 versions. ex: [2.0.0-dev;2.1.*]
|
|
* @param string $version
|
|
* Un numéro de version. ex: 3.1.99]
|
|
* @param string $avec_quoi
|
|
* Ce avec quoi est testée la compatibilité. par défaut ('')
|
|
* avec un plugin (cas des 'necessite'), parfois ('spip')
|
|
* avec SPIP.
|
|
* @return bool
|
|
* True si dans l'intervalle, false sinon.
|
|
**/
|
|
function plugin_version_compatible($intervalle, $version, $avec_quoi = '') {
|
|
|
|
if (!strlen($intervalle)) return true;
|
|
if (!preg_match(_EXTRAIRE_INTERVALLE,$intervalle,$regs)) return false;
|
|
// Extraction des bornes et traitement de * pour la borne sup :
|
|
// -- on autorise uniquement les ecritures 3.0.*, 3.*
|
|
$minimum = $regs[1];
|
|
$maximum = $regs[2];
|
|
|
|
// si une borne de compatibilité supérieure a été définie (dans
|
|
// mes_options.php, sous la forme : define('_DEV_PLUGINS', '3.1.99');
|
|
// on l'utilise (phase de dev, de test...) mais *que* en cas de comparaison
|
|
// avec la version de SPIP (ne nuit donc pas aux tests de necessite
|
|
// entre plugins)
|
|
if (defined('_DEV_PLUGINS') && $avec_quoi == 'spip') {
|
|
$maximum = _DEV_PLUGINS.']';
|
|
}
|
|
|
|
$minimum_inc = $intervalle{0}=="[";
|
|
$maximum_inc = substr($intervalle,-1)=="]";
|
|
|
|
if (strlen($minimum)){
|
|
if ($minimum_inc AND spip_version_compare($version,$minimum,'<')) return false;
|
|
if (!$minimum_inc AND spip_version_compare($version,$minimum,'<=')) return false;
|
|
}
|
|
if (strlen($maximum)){
|
|
if ($maximum_inc AND spip_version_compare($version,$maximum,'>')) return false;
|
|
if (!$maximum_inc AND spip_version_compare($version,$maximum,'>=')) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
// Construire la liste des infos strictement necessaires aux plugins a activer
|
|
// afin de les memoriser dans une meta pas trop grosse
|
|
// http://doc.spip.org/@liste_plugin_valides
|
|
function liste_plugin_valides($liste_plug, $force = false)
|
|
{
|
|
$liste_ext = liste_plugin_files(_DIR_PLUGINS_DIST);
|
|
$get_infos = charger_fonction('get_infos','plugins');
|
|
$infos = array(
|
|
// lister les extensions qui sont automatiquement actives
|
|
'_DIR_PLUGINS_DIST' => $get_infos($liste_ext, $force, _DIR_PLUGINS_DIST),
|
|
'_DIR_PLUGINS' => $get_infos($liste_plug, $force, _DIR_PLUGINS)
|
|
);
|
|
|
|
// creer une premiere liste non ordonnee mais qui ne retient
|
|
// que les plugins valides, et dans leur derniere version en cas de doublon
|
|
$infos['_DIR_RESTREINT'][''] = $get_infos('./',$force,_DIR_RESTREINT);
|
|
$infos['_DIR_RESTREINT']['SPIP']['version'] = $GLOBALS['spip_version_branche'];
|
|
$infos['_DIR_RESTREINT']['SPIP']['chemin'] = array();
|
|
$liste_non_classee = array('SPIP'=>array(
|
|
'nom' => 'SPIP',
|
|
'etat' => 'stable',
|
|
'version' => $GLOBALS['spip_version_branche'],
|
|
'dir_type' => '_DIR_RESTREINT',
|
|
'dir'=> '',
|
|
)
|
|
);
|
|
|
|
foreach($liste_ext as $plug){
|
|
if (isset($infos['_DIR_PLUGINS_DIST'][$plug]))
|
|
plugin_valide_resume($liste_non_classee, $plug, $infos, '_DIR_PLUGINS_DIST');
|
|
}
|
|
foreach($liste_plug as $plug) {
|
|
if (isset($infos['_DIR_PLUGINS'][$plug]))
|
|
plugin_valide_resume($liste_non_classee, $plug, $infos, '_DIR_PLUGINS');
|
|
}
|
|
|
|
if (defined('_DIR_PLUGINS_SUPPL') and _DIR_PLUGINS_SUPPL) {
|
|
$infos['_DIR_PLUGINS_SUPPL'] = $get_infos($liste_plug, false, _DIR_PLUGINS_SUPPL);
|
|
foreach($liste_plug as $plug) {
|
|
if (isset($infos['_DIR_PLUGINS_SUPPL'][$plug]))
|
|
plugin_valide_resume($liste_non_classee, $plug, $infos, '_DIR_PLUGINS_SUPPL');
|
|
}
|
|
}
|
|
|
|
// les procure de core.xml sont consideres comme des plugins proposes,
|
|
// mais surchargeables (on peut activer un plugin qui procure ca pour l'ameliorer,
|
|
// donc avec le meme prefixe)
|
|
foreach($infos['_DIR_RESTREINT']['']['procure'] as $procure) {
|
|
$p = strtoupper($procure['nom']);
|
|
if (!isset($liste_non_classee[$p])){
|
|
$procure['etat'] = '?';
|
|
$procure['dir_type'] = '_DIR_RESTREINT';
|
|
$procure['dir'] = '';
|
|
$liste_non_classee[$p] = $procure;
|
|
}
|
|
}
|
|
|
|
return array($infos, $liste_non_classee);
|
|
}
|
|
|
|
// Ne retenir un plugin que s'il est valide
|
|
// et dans leur plus recente version compatible
|
|
// avec la version presente de SPIP
|
|
|
|
function plugin_valide_resume(&$liste, $plug, $infos, $dir)
|
|
{
|
|
$i = $infos[$dir][$plug];
|
|
if (isset($i['erreur']) AND $i['erreur'])
|
|
return;
|
|
if (!plugin_version_compatible($i['compatibilite'], $GLOBALS['spip_version_branche'],'spip'))
|
|
return;
|
|
$p = strtoupper($i['prefix']);
|
|
if (!isset($liste[$p])
|
|
OR spip_version_compare($i['version'],$liste[$p]['version'],'>')) {
|
|
$liste[$p] = array(
|
|
'nom' => $i['nom'],
|
|
'etat' => $i['etat'],
|
|
'version'=> $i['version'],
|
|
'dir'=> $plug,
|
|
'dir_type' => $dir
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* extrait les chemins d'une liste de plugin
|
|
* selectionne au passage ceux qui sont dans $dir_plugins uniquement
|
|
* si valeur non vide
|
|
*
|
|
* @param array $liste
|
|
* @param string $dir_plugins
|
|
* @return array
|
|
*/
|
|
function liste_chemin_plugin($liste, $dir_plugins=_DIR_PLUGINS){
|
|
foreach ($liste as $prefix=>$infos) {
|
|
if (!$dir_plugins
|
|
OR (
|
|
defined($infos['dir_type'])
|
|
AND constant($infos['dir_type'])==$dir_plugins))
|
|
$liste[$prefix] = $infos['dir'];
|
|
else
|
|
unset($liste[$prefix]);
|
|
}
|
|
return $liste;
|
|
}
|
|
|
|
/**
|
|
* Liste les chemins vers les plugins actifs du dossier fourni en argument
|
|
* a partir d'une liste d'elelements construits par plugin_valide_resume
|
|
*
|
|
* @return array
|
|
*/
|
|
// http://doc.spip.org/@liste_chemin_plugin_actifs
|
|
function liste_chemin_plugin_actifs($dir_plugins=_DIR_PLUGINS){
|
|
include_spip('plugins/installer');
|
|
return liste_chemin_plugin(liste_plugin_actifs(), $dir_plugins);
|
|
}
|
|
|
|
// Pour tester utilise, il faut connaitre tous les plugins
|
|
// qui seront forcement pas la a la fin,
|
|
// car absent de la liste des plugins actifs.
|
|
// Il faut donc construire une liste ordonnee
|
|
// Cette fonction detecte des dependances circulaires,
|
|
// avec un doute sur un "utilise" qu'on peut ignorer.
|
|
// Mais ne pas inserer silencieusement et risquer un bug sournois latent
|
|
|
|
function plugin_trier($infos, $liste_non_classee)
|
|
{
|
|
$toute_la_liste = $liste_non_classee;
|
|
$liste = $ordre = array();
|
|
$count = 0;
|
|
while ($c=count($liste_non_classee) AND $c!=$count){ // tant qu'il reste des plugins a classer, et qu'on ne stagne pas
|
|
#echo "tour::";var_dump($liste_non_classee);
|
|
$count = $c;
|
|
foreach($liste_non_classee as $p=>$resume) {
|
|
$plug = $resume['dir'];
|
|
$dir_type = $resume['dir_type'];
|
|
$info1 = $infos[$dir_type][$plug];
|
|
// si des plugins sont necessaires,
|
|
// on ne peut inserer qu'apres eux
|
|
foreach($info1['necessite'] as $need){
|
|
$nom = strtoupper($need['nom']);
|
|
$compat = isset($need['compatibilite']) ? $need['compatibilite'] : '';
|
|
if (!isset($liste[$nom]) OR !plugin_version_compatible($compat,$liste[$nom]['version'])) {
|
|
$info1 = false;
|
|
break;
|
|
}
|
|
}
|
|
if (!$info1) continue;
|
|
// idem si des plugins sont utiles,
|
|
// sauf si ils sont de toute facon absents de la liste
|
|
foreach($info1['utilise'] as $need){
|
|
$nom = strtoupper($need['nom']);
|
|
$compat = isset($need['compatibilite']) ? $need['compatibilite'] : '';
|
|
if (isset($toute_la_liste[$nom])) {
|
|
if (!isset($liste[$nom]) OR
|
|
!plugin_version_compatible($compat, $liste[$nom]['version'])) {
|
|
$info1 = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if ($info1) {
|
|
$ordre[$p] = $info1;
|
|
$liste[$p] = $liste_non_classee[$p];
|
|
unset($liste_non_classee[$p]);
|
|
}
|
|
}
|
|
}
|
|
return array($liste, $ordre, $liste_non_classee);
|
|
}
|
|
|
|
// Collecte les erreurs dans la meta
|
|
|
|
function plugins_erreurs($liste_non_classee, $liste, $infos, $msg=array())
|
|
{
|
|
static $erreurs = array();
|
|
foreach($liste_non_classee as $p=>$resume){
|
|
$dir_type = $resume['dir_type'];
|
|
$plug = $resume['dir'];
|
|
$k = $infos[$dir_type][$plug];
|
|
$plug = constant($dir_type) . $plug;
|
|
if (!isset($msg[$p])) {
|
|
if (!$msg[$p] = plugin_necessite($k['necessite'], $liste))
|
|
$msg[$p] = plugin_necessite($k['utilise'], $liste);
|
|
} else {
|
|
foreach($msg[$p] as $c => $l)
|
|
$msg[$p][$c] = plugin_controler_lib($l['nom'], $l['lien']);
|
|
}
|
|
$erreurs[$plug] = $msg[$p];
|
|
}
|
|
ecrire_meta('plugin_erreur_activation', serialize($erreurs));
|
|
}
|
|
|
|
function plugin_donne_erreurs($raw=false, $raz=true) {
|
|
if (!isset($GLOBALS['meta']['plugin_erreur_activation'])) return $raw?array():'';
|
|
$list = @unserialize($GLOBALS['meta']['plugin_erreur_activation']);
|
|
// Compat ancienne version
|
|
if (!$list)
|
|
$list = $raw?array():$GLOBALS['meta']['plugin_erreur_activation'];
|
|
elseif(!$raw) {
|
|
foreach($list as $plug => $msg)
|
|
$list[$plug] = "<li>" . _T('plugin_impossible_activer', array('plugin' => $plug))
|
|
. "<ul><li>" . implode("</li><li>", $msg) . "</li></ul></li>";
|
|
$list ="<ul>" . join("\n", $list) . "</ul>";
|
|
}
|
|
if ($raz)
|
|
effacer_meta('plugin_erreur_activation');
|
|
return $list;
|
|
}
|
|
|
|
/**
|
|
* Teste des dependances
|
|
* Et verifie que chaque dependance est presente
|
|
* dans la liste de plugins donnee
|
|
*
|
|
* @param array $n
|
|
* Tableau de dependances dont on souhaite verifier leur presence
|
|
* @param array $liste
|
|
* Tableau des plugins presents
|
|
* @return array
|
|
* Tableau des messages d'erreurs recus. Il sera vide si tout va bien.
|
|
*
|
|
**/
|
|
function plugin_necessite($n, $liste) {
|
|
$msg = array();
|
|
foreach($n as $need){
|
|
$id = strtoupper($need['nom']);
|
|
if ($r = plugin_controler_necessite($liste, $id, $need['compatibilite'])) {
|
|
$msg[] = $r;
|
|
}
|
|
}
|
|
return $msg;
|
|
}
|
|
|
|
/**
|
|
* Verifie qu'une dependance (plugin) est bien presente.
|
|
*
|
|
* @param $liste
|
|
* Liste de description des plugins
|
|
* @param $nom
|
|
* Le plugin donc on cherche la presence
|
|
* @param $version
|
|
* L'éventuelle intervalle de compatibilité de la dependance. ex: [1.1.0;]
|
|
* @return string.
|
|
* Vide si ok,
|
|
* Message d'erreur lorsque la dependance est absente.
|
|
**/
|
|
function plugin_controler_necessite($liste, $nom, $version)
|
|
{
|
|
if (isset($liste[$nom]) AND plugin_version_compatible($version,$liste[$nom]['version'])) {
|
|
return '';
|
|
}
|
|
// retrouver le minimum
|
|
if (preg_match(_EXTRAIRE_INTERVALLE, $version, $regs)) {
|
|
$minimum = $regs[1];
|
|
if ($minimum) {
|
|
return _T('plugin_necessite_plugin', array(
|
|
'plugin' => $nom,
|
|
'version' => $minimum));
|
|
}
|
|
}
|
|
return _T('plugin_necessite_plugin_sans_version', array('plugin' => $nom));
|
|
}
|
|
|
|
function plugin_controler_lib($lib, $url)
|
|
{
|
|
/* Feature sortie du core, voir STP
|
|
* if ($url) {
|
|
include_spip('inc/charger_plugin');
|
|
$url = '<br />' . bouton_telechargement_plugin($url, 'lib');
|
|
}*/
|
|
return _T('plugin_necessite_lib', array('lib'=>$lib)) . " <a href='$url'>$url</a>";
|
|
}
|
|
|
|
// Pour compatibilite et lisibilite du code
|
|
function actualise_plugins_actifs($pipe_recherche = false){
|
|
return ecrire_plugin_actifs('', $pipe_recherche, 'force');
|
|
}
|
|
|
|
// mise a jour du meta en fonction de l'etat du repertoire
|
|
// Les ecrire_meta() doivent en principe aussi initialiser la valeur a vide
|
|
// si elle n'existe pas
|
|
// risque de pb en php5 a cause du typage ou de null (verifier dans la doc php)
|
|
// @return true/false si il y a du nouveau
|
|
// http://doc.spip.org/@ecrire_plugin_actifs
|
|
function ecrire_plugin_actifs($plugin,$pipe_recherche=false,$operation='raz') {
|
|
|
|
// creer le repertoire cache/ si necessaire ! (installation notamment)
|
|
sous_repertoire(_DIR_CACHE, '', false,true);
|
|
|
|
if (!spip_connect()) return false;
|
|
if ($operation!='raz') {
|
|
$plugin_valides = liste_chemin_plugin_actifs();
|
|
$plugin_valides = is_plugin_dir($plugin_valides);
|
|
if(defined('_DIR_PLUGINS_SUPPL') && _DIR_PLUGINS_SUPPL){
|
|
$plugin_valides_supp = liste_chemin_plugin_actifs(_DIR_PLUGINS_SUPPL);
|
|
$plugin_valides_supp = is_plugin_dir($plugin_valides_supp,_DIR_PLUGINS_SUPPL);
|
|
$plugin_valides = array_merge($plugin_valides,$plugin_valides_supp);
|
|
}
|
|
// si des plugins sont en attentes (coches mais impossible a activer)
|
|
// on les reinjecte ici
|
|
if (isset($GLOBALS['meta']['plugin_attente'])
|
|
AND $a = unserialize($GLOBALS['meta']['plugin_attente']))
|
|
$plugin_valides = $plugin_valides + liste_chemin_plugin($a);
|
|
|
|
if ($operation=='ajoute')
|
|
$plugin = array_merge($plugin_valides,$plugin);
|
|
elseif ($operation=='enleve')
|
|
$plugin = array_diff($plugin_valides,$plugin);
|
|
else $plugin = $plugin_valides;
|
|
}
|
|
$actifs_avant = $GLOBALS['meta']['plugin'];
|
|
|
|
// si une fonction de gestion de dependances existe, l'appeler ici
|
|
if ($ajouter_dependances = charger_fonction("ajouter_dependances","plugins",true)){
|
|
$plugin = $ajouter_dependances($plugin);
|
|
}
|
|
|
|
// recharger le xml des plugins a activer
|
|
// on forcer le reload ici, meme si le fichier xml n'a pas change
|
|
// pour ne pas rater l'ajout ou la suppression d'un fichier fonctions/options/administrations
|
|
// pourra etre evite quand on ne supportera plus les plugin.xml
|
|
// en deplacant la detection de ces fichiers dans la compilation ci dessous
|
|
list($infos,$liste) = liste_plugin_valides($plugin,true);
|
|
// trouver l'ordre d'activation
|
|
list($plugin_valides,$ordre,$reste) = plugin_trier($infos, $liste);
|
|
if ($reste) plugins_erreurs($reste, $liste, $infos);
|
|
// Ignorer les plugins necessitant une lib absente
|
|
// et preparer la meta d'entete Http
|
|
$err = $msg = $header = array();
|
|
foreach($plugin_valides as $p => $resume) {
|
|
$header[]= $p.($resume['version']?"(".$resume['version'].")":"");
|
|
if ($resume['dir']){
|
|
foreach($infos[$resume['dir_type']][$resume['dir']]['lib'] as $l) {
|
|
if (!find_in_path($l['nom'], 'lib/')) {
|
|
$err[$p] = $resume;
|
|
$msg[$p][] = $l;
|
|
unset($plugin_valides[$p]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ($err) plugins_erreurs($err, '', $infos, $msg);
|
|
|
|
if (isset($GLOBALS['meta']['message_crash_plugins']))
|
|
effacer_meta('message_crash_plugins');
|
|
ecrire_meta('plugin',serialize($plugin_valides));
|
|
$liste = array_diff_key($liste,$plugin_valides);
|
|
ecrire_meta('plugin_attente',serialize($liste));
|
|
$header = strtolower(implode(",",$header));
|
|
ecrire_meta('plugin_header',substr($header,0,900));
|
|
if (!isset($GLOBALS['spip_header_silencieux']) OR !$GLOBALS['spip_header_silencieux'])
|
|
ecrire_fichier(_DIR_VAR."config.txt", (defined('_HEADER_COMPOSED_BY') ? _HEADER_COMPOSED_BY:"Composed-By: SPIP") . ' '. $GLOBALS['spip_version_affichee'] . " @ www.spip.net + " . $header);
|
|
else
|
|
@unlink(_DIR_VAR."config.txt");
|
|
// generer charger_plugins_chemin.php
|
|
plugins_precompile_chemin($plugin_valides, $ordre);
|
|
// generer les fichiers
|
|
// charger_plugins_options.php
|
|
// charger_plugins_fonctions.php
|
|
// et retourner les fichiers a verifier
|
|
plugins_precompile_xxxtions($plugin_valides, $ordre);
|
|
// mise a jour de la matrice des pipelines
|
|
pipeline_matrice_precompile($plugin_valides, $ordre, $pipe_recherche);
|
|
// generer le fichier _CACHE_PIPELINE
|
|
pipeline_precompile();
|
|
|
|
// lancer et initialiser les nouveaux crons !
|
|
include_spip('inc/genie');
|
|
genie_queue_watch_dist();
|
|
|
|
return ($GLOBALS['meta']['plugin'] != $actifs_avant);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
function plugins_precompile_xxxtions($plugin_valides, $ordre)
|
|
{
|
|
$contenu = array('options' => '', 'fonctions' =>'');
|
|
$boutons = array();
|
|
$onglets = array();
|
|
$sign = "";
|
|
|
|
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'];
|
|
$dir = constant($dir_type);
|
|
$root_dir_type = str_replace('_DIR_','_ROOT_',$dir_type);
|
|
if ($info['menu'])
|
|
$boutons = array_merge($boutons,$info['menu']);
|
|
if ($info['onglet'])
|
|
$onglets = array_merge($onglets,$info['onglet']);
|
|
foreach($contenu as $charge => $v){
|
|
// si pas declare/detecte a la lecture du paquet.xml,
|
|
// detecer a nouveau ici puisque son ajout ne provoque pas une modif du paquet.xml
|
|
// donc ni sa relecture, ni sa detection
|
|
if (!isset($info[$charge])
|
|
AND $dir // exclure le cas du plugin "SPIP"
|
|
AND file_exists("$dir$plug/paquet.xml") // uniquement pour les paquet.xml
|
|
){
|
|
if (is_readable("$dir$plug/".($file=$info['prefix']."_".$charge.".php"))){
|
|
$info[$charge] = array($file);
|
|
}
|
|
}
|
|
if (isset($info[$charge])){
|
|
$files = $info[$charge];
|
|
foreach($files as $k=>$file){
|
|
// on genere un if file_exists devant chaque include
|
|
// pour pouvoir garder le meme niveau d'erreur general
|
|
$file = trim($file);
|
|
if (!is_readable("$dir$plug/$file")
|
|
// uniquement pour les paquet.xml
|
|
AND file_exists("$dir$plug/paquet.xml")){
|
|
unset($info[$charge][$k]);
|
|
}
|
|
else {
|
|
$_file = $root_dir_type . ".'$plug/$file'";
|
|
$contenu[$charge] .= "include_once_check($_file);\n";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
$sign .= md5(serialize($info));
|
|
}
|
|
}
|
|
|
|
$contenu['options'] = "define('_PLUGINS_HASH','".md5($sign)."');\n" . $contenu['options'];
|
|
$contenu['fonctions'] .= plugin_ongletbouton("boutons_plugins", $boutons)
|
|
. plugin_ongletbouton("onglets_plugins", $onglets);
|
|
|
|
ecrire_fichier_php(_CACHE_PLUGINS_OPT, $contenu['options']);
|
|
ecrire_fichier_php(_CACHE_PLUGINS_FCT, $contenu['fonctions']);
|
|
}
|
|
|
|
function plugin_ongletbouton($nom, $val)
|
|
{
|
|
if (!$val) $val = array();
|
|
define("_UPDATED_$nom",$val = serialize($val));
|
|
define("_UPDATED_md5_$nom",$md5=md5($val));
|
|
$val = "unserialize('".str_replace("'","\'",$val)."')";
|
|
return
|
|
"if (!function_exists('$nom')) {\n"
|
|
."function $nom(){return defined('_UPDATED_$nom')?unserialize(_UPDATED_$nom):$val;}\n"
|
|
."function md5_$nom(){return defined('_UPDATED_md5_$nom')?_UPDATED_md5_$nom:'".$md5."';}\n"
|
|
."}\n";
|
|
}
|
|
|
|
// creer le fichier CACHE_PLUGIN_VERIF a partir de
|
|
// $GLOBALS['spip_pipeline']
|
|
// $GLOBALS['spip_matrice']
|
|
|
|
function pipeline_matrice_precompile($plugin_valides, $ordre, $pipe_recherche)
|
|
{
|
|
static $liste_pipe_manquants=array();
|
|
if (($pipe_recherche)&&(!in_array($pipe_recherche,$liste_pipe_manquants)))
|
|
$liste_pipe_manquants[]=$pipe_recherche;
|
|
|
|
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'];
|
|
$root_dir_type = str_replace('_DIR_','_ROOT_',$dir_type);
|
|
$plug = $plugin_valides[$p]['dir'];
|
|
$prefix = (($info['prefix']=="spip")?"":$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;
|
|
// une action vide est une declaration qui ne doit pas etre compilee !
|
|
if (!isset($GLOBALS['spip_pipeline'][$nom])) // creer le pipeline eventuel
|
|
$GLOBALS['spip_pipeline'][$nom]="";
|
|
if ($action){
|
|
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]= '';
|
|
}
|
|
|
|
// precompilation des pipelines
|
|
// http://doc.spip.org/@pipeline_precompile
|
|
function pipeline_precompile(){
|
|
global $spip_pipeline, $spip_matrice;
|
|
|
|
$content = "";
|
|
foreach($spip_pipeline as $action=>$pipeline){
|
|
$s_inc = "";
|
|
$s_call = "";
|
|
$pipe = array_filter(explode('|',$pipeline));
|
|
// Eclater le pipeline en filtres et appliquer chaque filtre
|
|
foreach ($pipe as $fonc) {
|
|
$fonc = trim($fonc);
|
|
$s_call .= '$val = minipipe(\''.$fonc.'\', $val);'."\n";
|
|
if (isset($spip_matrice[$fonc])){
|
|
$file = $spip_matrice[$fonc];
|
|
$file = "'$file'";
|
|
// si un _DIR_XXX: est dans la chaine, on extrait la constante
|
|
if (preg_match(",(_(DIR|ROOT)_[A-Z_]+):,Ums",$file,$regs)){
|
|
$dir = $regs[1];
|
|
$root_dir = str_replace('_DIR_','_ROOT_',$dir);
|
|
if (defined($root_dir))
|
|
$dir = $root_dir;
|
|
$file = str_replace($regs[0],"'.".$dir.".'",$file);
|
|
$file = str_replace("''.","",$file);
|
|
$file = str_replace(constant($dir), '', $file);
|
|
}
|
|
$s_inc .= "include_once_check($file);\n";
|
|
}
|
|
}
|
|
if (strlen($s_inc))
|
|
$s_inc = "static \$inc=null;\nif (!\$inc){\n$s_inc\$inc=true;\n}\n";
|
|
$content .= "// Pipeline $action \n"
|
|
. "function execute_pipeline_$action(&\$val){\n"
|
|
. $s_inc
|
|
. $s_call
|
|
. "return \$val;\n}\n";
|
|
}
|
|
ecrire_fichier_php(_CACHE_PIPELINES, $content);
|
|
clear_path_cache();
|
|
}
|
|
|
|
|
|
// http://doc.spip.org/@plugin_est_installe
|
|
function plugin_est_installe($plug_path){
|
|
$plugin_installes = isset($GLOBALS['meta']['plugin_installes'])?unserialize($GLOBALS['meta']['plugin_installes']):array();
|
|
if (!$plugin_installes) return false;
|
|
return in_array($plug_path,$plugin_installes);
|
|
}
|
|
|
|
|
|
function plugin_installes_meta()
|
|
{
|
|
$installer_plugins = charger_fonction('installer', 'plugins');
|
|
$meta_plug_installes = array();
|
|
foreach (unserialize($GLOBALS['meta']['plugin']) as $prefix=>$resume) {
|
|
if ($plug = $resume['dir']){
|
|
$infos = $installer_plugins($plug, 'install', $resume['dir_type']);
|
|
if ($infos){
|
|
if (!is_array($infos) OR $infos['install_test'][0])
|
|
$meta_plug_installes[] = $plug;
|
|
if (is_array($infos)){
|
|
list($ok, $trace) = $infos['install_test'];
|
|
include_spip('inc/filtres_boites');
|
|
echo "<div class='install-plugins svp_retour'>"
|
|
.boite_ouvrir(_T('plugin_titre_installation', array('plugin' => typo($infos['nom']))), ($ok ? 'success' : 'error'))
|
|
.$trace
|
|
."<div class='result'>"
|
|
.($ok ? ((isset($infos['upgrade']) && $infos['upgrade']) ? _T("plugin_info_upgrade_ok") : _T("plugin_info_install_ok")) : _T("avis_operation_echec"))
|
|
."</div>"
|
|
.boite_fermer()
|
|
."</div>";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
ecrire_meta('plugin_installes',serialize($meta_plug_installes),'non');
|
|
}
|
|
|
|
function ecrire_fichier_php($nom, $contenu, $comment='')
|
|
{
|
|
ecrire_fichier($nom,
|
|
'<'.'?php' . "\n" . $comment ."\nif (defined('_ECRIRE_INC_VERSION')) {\n". $contenu . "}\n?".'>');
|
|
}
|
|
?>
|