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(); }
/** * Calcule ou modifie la liste des plugins actifs et recompile les fichiers caches * qui leurs sont relatifs * * @note * 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) * * @param string|string[] $plugin * Plugin ou plugins concernés (leur chemin depuis le répertoire plugins) * @param bool $pipe_recherche * ? * @param string $operation * - raz : recalcule tout * - ajoute : ajoute le plugin indiqué à la liste des plugins actifs * - enleve : enleve le plugin indiqué de la liste des plugins actifs * - force : ? * @return bool * true si il y a eu des modifications sur la liste des plugins actifs, false sinon **/ function ecrire_plugin_actifs($plugin, $pipe_recherche = false, $operation = 'raz') { // creer le repertoire cache/ si necessaire ! (installation notamment) $cache = sous_repertoire(_DIR_CACHE, '', false, true); // Si on n'a ni cache accessible, ni connexion SQL, on ne peut pas faire grand chose encore. if (!$cache and !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 = isset($GLOBALS['meta']['plugin']) ? $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 $prepend_code = pipeline_matrice_precompile($plugin_valides, $ordre, $pipe_recherche); // generer le fichier _CACHE_PIPELINE pipeline_precompile($prepend_code); // attendre eventuellement l'invalidation du cache opcode spip_attend_invalidation_opcode_cache(); if (spip_connect()) { // lancer et initialiser les nouveaux crons ! include_spip('inc/genie'); genie_queue_watch_dist(); } return $GLOBALS['meta']['plugin'] != $actifs_avant; }
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(); // 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); } $plugin_valides = is_plugin_dir($plugin_valides); 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']; // 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)); ecrire_meta('plugin_header', substr(strtolower(implode(",", $header)), 0, 900)); // 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; }