4 if (!defined("_ECRIRE_INC_VERSION")) return;
6 define('_CACHE_AJAX_NOISETTES', 'noisettes_ajax.php');
7 define('_CACHE_CONTEXTE_NOISETTES', 'noisettes_contextes.php');
8 define('_CACHE_DESCRIPTIONS_NOISETTES', 'noisettes_descriptions.php');
9 define('_CACHE_INCLUSIONS_NOISETTES', 'noisettes_inclusions.php');
11 // Pour compatibilité avec PHP4
13 if (!function_exists('array_intersect_key'))
15 function array_intersect_key($isec, $keys)
17 $argc = func_num_args();
20 for ($i = 1; !empty($isec) && $i < $argc; $i++
)
22 $arr = func_get_arg($i);
23 foreach (array_keys($isec) as $key)
25 if (!isset($arr[$key]))
36 foreach (array_keys($isec) as $key)
38 if (isset($keys[$key]))
40 $res[$key] = $isec[$key];
49 * Lister les noisettes disponibles dans les dossiers noisettes/
51 * @staticvar array $liste_noisettes
55 function noizetier_lister_noisettes($type='tout'){
56 static $liste_noisettes = array();
57 if ($type == 'tout') {
58 return noizetier_obtenir_infos_noisettes();
60 if (isset($liste_noisettes[$type])) {
61 return $liste_noisettes[$type];
64 $noisettes = noizetier_obtenir_infos_noisettes();
68 $match = $type."-[^-]*$";
71 foreach($noisettes as $noisette => $description) {
72 if (preg_match("/$match/", $noisette)) {
73 $liste_noisettes[$type][$noisette] = $description;
77 return $liste_noisettes[$type];
83 * Obtenir les infos de toutes les noisettes disponibles dans les dossiers noisettes/
84 * On utilise un cache php pour alleger le calcul.
89 function noizetier_obtenir_infos_noisettes() {
90 static $noisettes = false;
92 // seulement 1 fois par appel, on lit ou calcule tous les contextes
93 if ($noisettes === false) {
94 // lire le cache des descriptions sauvées
95 lire_fichier_securise(_DIR_CACHE
. _CACHE_DESCRIPTIONS_NOISETTES
, $noisettes);
96 $noisettes = @unserialize
($noisettes);
97 // s'il en mode recalcul, on recalcule toutes les descriptions des noisettes trouvees.
98 // ou si le cache est désactivé
99 if (!$noisettes or (_request('var_mode') == 'recalcul') or (defined('_NO_CACHE') and _NO_CACHE
!=0)) {
100 $noisettes = noizetier_obtenir_infos_noisettes_direct();
101 ecrire_fichier_securise(_DIR_CACHE
. _CACHE_DESCRIPTIONS_NOISETTES
, serialize($noisettes));
110 * Obtenir les infos de toutes les noisettes disponibles dans les dossiers noisettes/
111 * C'est un GROS calcul lorsqu'il est a faire.
115 function noizetier_obtenir_infos_noisettes_direct(){
117 $liste_noisettes = array();
119 $match = "[^-]*[.]html$";
120 $liste = find_all_in_path('noisettes/', $match);
123 foreach($liste as $squelette=>$chemin) {
124 $noisette = preg_replace(',[.]html$,i', '', $squelette);
125 $dossier = str_replace($squelette, '', $chemin);
126 // On ne garde que les squelettes ayant un fichier YAML de config
127 if (file_exists("$dossier$noisette.yaml")
128 AND ($infos_noisette = noizetier_charger_infos_noisette_yaml($dossier.$noisette))
130 $liste_noisettes[$noisette] = $infos_noisette;
135 // supprimer de la liste les noisettes necissant un plugin qui n'est pas actif
136 foreach ($liste_noisettes as $noisette => $infos_noisette)
137 if (isset($infos_noisette['necessite']))
138 foreach ($infos_noisette['necessite'] as $plugin)
139 if (!defined('_DIR_PLUGIN_'.strtoupper($plugin)))
140 unset($liste_noisettes[$noisette]);
142 return $liste_noisettes;
147 * Charger les informations contenues dans le YAML d'une noisette
149 * @param string $noisette
150 * @param string $info
153 function noizetier_charger_infos_noisette_yaml($noisette, $info=""){
154 // on peut appeler avec le nom du squelette
155 $fichier = preg_replace(',[.]html$,i','',$noisette).".yaml";
156 include_spip('inc/yaml');
157 include_spip('inc/texte');
158 $infos_noisette = array();
159 if ($infos_noisette = yaml_charger_inclusions(yaml_decode_file($fichier))) {
160 if (isset($infos_noisette['nom']))
161 $infos_noisette['nom'] = _T_ou_typo($infos_noisette['nom']);
162 if (isset($infos_noisette['description']))
163 $infos_noisette['description'] = _T_ou_typo($infos_noisette['description']);
164 if (isset($infos_noisette['icon']))
165 $infos_noisette['icon'] = $infos_noisette['icon'];
167 if (!isset($infos_noisette['parametres']))
168 $infos_noisette['parametres'] = array();
171 if (!isset($infos_noisette['contexte'])) {
172 $infos_noisette['contexte'] = array();
174 if (is_string($infos_noisette['contexte'])) {
175 $infos_noisette['contexte'] = array($infos_noisette['contexte']);
179 if (!isset($infos_noisette['ajax'])) {
180 $infos_noisette['ajax'] = 'oui';
183 if (!isset($infos_noisette['inclusion'])) {
184 $infos_noisette['inclusion'] = 'statique';
189 return $infos_noisette;
191 return isset($infos_noisette[$info]) ?
$infos_noisette[$info] : "";
195 * Charger les informations des paramètres d'une noisette
197 * @param string $noisette
198 * @staticvar array $params_noisettes
201 function noizetier_charger_parametres_noisette($noisette){
202 static $params_noisettes = null;
204 if (is_null($params_noisettes[$noisette])){
205 $noisettes = noizetier_lister_noisettes();
206 $infos = $noisettes[$noisette];
207 $params_noisettes[$noisette] = extrait_parametres_noisette($infos['parametres']);
209 return $params_noisettes[$noisette];
213 * Charger les informations des contexte pour une noisette
215 * @param string $noisette
216 * @staticvar array $params_noisettes
219 function noizetier_charger_contexte_noisette($noisette){
220 static $contexte_noisettes = null;
222 if (is_null($contexte_noisettes[$noisette])){
223 $noisettes = noizetier_lister_noisettes();
224 $contexte_noisettes[$noisette] = $noisettes[$noisette]['contexte'];
226 return $contexte_noisettes[$noisette];
231 * Transforme un tableau au format du plugin saisies en un tableau de parametres dont les clés sont les noms des paramètres
232 * S'il y a de fieldset, les paramètres sont extraits de son entrée saisies
234 * @param string $parametres
237 function extrait_parametres_noisette($parametres){
239 if (is_array($parametres) && count($parametres)>0) {
240 foreach($parametres as $parametre) {
241 if ($parametre['saisie']!='fieldset') {
242 $nom = $parametre['options']['nom'];
243 $res[$nom] = $parametre['options'];
244 $res[$nom]['saisie'] = $parametre['saisie'];
245 if(isset($parametre['verifier']))
246 $res[$nom]['verifier']=$parametre['verifier'];
247 if(isset($res[$nom]['label']))
248 $res[$nom]['label'] = _T_ou_typo($res[$nom]['label']);
249 if(isset($res[$nom]['datas']))
250 foreach($res[$nom]['datas'] as $cle => $valeur)
251 $res[$nom]['datas'][$cle] = _T_ou_typo($res[$nom]['datas'][$cle]);
254 $res = array_merge($res,extrait_parametres_noisette($parametre['saisies']));
262 * Lister les pages pouvant recevoir des noisettes
263 * Par défaut, cette liste est basée sur le contenu du répertoire contenu/
264 * Le tableau de résultats peut-être modifié via le pipeline noizetier_lister_pages.
266 * @staticvar array $liste_pages
269 function noizetier_lister_pages(){
270 static $liste_pages = null;
272 if (is_null($liste_pages)){
273 $liste_pages = array();
274 $match = ".+[.]html$";
276 // lister les fonds disponibles dans le répertoire contenu
277 $rep = defined('_NOIZETIER_REPERTOIRE_PAGES')?_NOIZETIER_REPERTOIRE_PAGES
:'contenu/';
278 $liste = find_all_in_path($rep, $match);
280 foreach($liste as $squelette=>$chemin) {
281 $page = preg_replace(',[.]html$,i', '', $squelette);
282 $dossier = str_replace($squelette, '', $chemin);
283 // Les éléments situés dans prive/contenu sont écartés
284 if (substr($dossier,-14)!='prive/contenu/')
285 if(count($infos_page = noizetier_charger_infos_page($dossier,$page))>0)
286 $liste_pages[$page] = $infos_page;
290 // Dans le cas de Zpip, il faut supprimer la page 'page.html' et la page 'z_apl.html'
291 if (defined('_DIR_PLUGIN_Z')) {
292 unset($liste_pages['page']);
293 unset($liste_pages['z_apl']);
296 // supprimer de la liste les pages necissant un plugin qui n'est pas actif
297 foreach ($liste_pages as $page => $infos_page)
298 if (isset($infos_page['necessite']))
299 foreach ($infos_page['necessite'] as $plugin)
300 if (!defined('_DIR_PLUGIN_'.strtoupper($plugin)))
301 unset($liste_pages[$page]);
303 $liste_pages = pipeline('noizetier_lister_pages',$liste_pages);
305 // On ajoute les compositions du noizetier
306 if(defined('_DIR_PLUGIN_COMPOSITIONS')){
307 $noizetier_compositions = unserialize($GLOBALS['meta']['noizetier_compositions']);
308 // On doit transformer le tableau de [type][compo] en [type-compo]
309 $liste_compos = array();
310 if (is_array($noizetier_compositions)) {
311 foreach($noizetier_compositions as $type => $compos_type)
312 foreach($compos_type as $compo => $infos_compo) {
313 $infos_compo['nom'] = typo($infos_compo['nom']);
314 $infos_compo['description'] = propre($infos_compo['description']);
315 $infos_compo['icon'] = $infos_compo['icon']!='' ?
$infos_compo['icon'] : '';
316 if (isset($liste_pages[$type]))
317 $infos_compo['blocs'] = $liste_pages[$type]['blocs'];
319 $infos_compo['blocs'] = noizetier_blocs_defaut();
320 $liste_compos[$type.'-'.$compo] = $infos_compo;
323 $liste_pages = array_merge($liste_pages,$liste_compos);
330 * Charger les informations d'une page, contenues dans un xml de config s'il existe
332 * @param string $dossier
333 * @param string $page
334 * @param string $info
337 function noizetier_charger_infos_page($dossier,$page, $info=""){
338 // on peut appeler avec le nom du squelette
339 $page = preg_replace(',[.]html$,i','',$page);
341 // On autorise le fait que le fichier xml ne soit pas dans le même plugin que le fichier .html
342 // Au cas où le fichier .html soit surchargé sans que le fichier .xml ne le soit
343 $rep = defined('_NOIZETIER_REPERTOIRE_PAGES')?_NOIZETIER_REPERTOIRE_PAGES
:'contenu/';
344 $fichier = find_in_path("$rep$page.xml");
346 include_spip('inc/xml');
347 include_spip('inc/texte');
348 $infos_page = array();
349 // S'il existe un fichier xml de configuration (s'il s'agit d'une composition on utilise l'info de la composition)
350 if (file_exists($fichier) AND $xml = spip_xml_load($fichier, false) AND count($xml['page']))
351 $xml = reset($xml['page']);
352 elseif (file_exists($fichier) AND $xml = spip_xml_load($fichier, false) AND count($xml['composition']))
353 $xml = reset($xml['composition']);
357 $infos_page['nom'] = _T_ou_typo(spip_xml_aplatit($xml['nom']));
358 $infos_page['description'] = isset($xml['description']) ?
_T_ou_typo(spip_xml_aplatit($xml['description'])) : '';
359 $infos_page['icon'] = isset($xml['icon']) ?
reset($xml['icon']) : '';
360 // Décomposition des blocs
361 if (spip_xml_match_nodes(',^bloc,', $xml, $blocs)){
362 $infos_page['blocs'] = array();
363 foreach (array_keys($blocs) as $bloc){
364 list($balise, $attributs) = spip_xml_decompose_tag($bloc);
365 $infos_page['blocs'][$attributs['id']] = array(
366 'nom' => $attributs['nom'] ?
_T($attributs['nom']) : $attributs['id'],
367 'icon' => isset($attributs['icon']) ?
$attributs['icon'] : '',
368 'description' => _T($attributs['description'])
372 if (spip_xml_match_nodes(',^necessite,', $xml, $necessites)){
373 $infos_page['necessite'] = array();
374 foreach (array_keys($necessites) as $necessite){
375 list($balise, $attributs) = spip_xml_decompose_tag($necessite);
376 $infos_page['necessite'][] = $attributs['id'];
380 // S'il n'y a pas de fichier XML de configuration
381 elseif (defined('_NOIZETIER_LISTER_PAGES_SANS_XML')?_NOIZETIER_LISTER_PAGES_SANS_XML
:true) {
382 $infos_page['nom'] = $page;
383 $infos_page['icon'] = 'img/ic_page.png';
386 // Si les blocs n'ont pas été définis, on applique les blocs par défaut
387 if (count($infos_page)>0 AND !isset($infos_page['blocs']))
388 $infos_page['blocs'] = noizetier_blocs_defaut();
390 // On renvoie les infos
394 return isset($infos_page[$info]) ?
$infos_page[$info] : "";
398 * Charger les informations d'une page, contenues dans un xml de config s'il existe
399 * La liste des blocs par défaut d'une page peut être modifiée via le pipeline noizetier_blocs_defaut.
401 * @staticvar array $blocs_defaut
404 function noizetier_blocs_defaut(){
405 static $blocs_defaut = null;
407 if (is_null($blocs_defaut)){
408 $blocs_defaut = array (
410 'nom' => _T('noizetier:nom_bloc_contenu'),
411 'description' => _T('noizetier:description_bloc_contenu'),
412 'icon' => 'img/ic_bloc_contenu.png'
414 'navigation' => array(
415 'nom' => _T('noizetier:nom_bloc_navigation'),
416 'description' => _T('noizetier:description_bloc_navigation'),
417 'icon' => 'img/ic_bloc_navigation.png'
420 'nom' => _T('noizetier:nom_bloc_extra'),
421 'description' => _T('noizetier:description_bloc_extra'),
422 'icon' => 'img/ic_bloc_extra.png'
425 $blocs_defaut = pipeline('noizetier_blocs_defaut',$blocs_defaut);
427 return $blocs_defaut;
431 * Supprime de spip_noisettes les noisettes liées à une page
436 function supprimer_noisettes_page_noizetier($page) {
437 $type_compo = explode ('-',$page,2);
438 $type = $type_compo[0];
439 $composition = $type_compo[1];
441 sql_delete('spip_noisettes','type='.sql_quote($type).'and composition='.sql_quote($composition));
443 // On invalide le cache
444 include_spip('inc/invalideur');
445 suivre_invalideur($page);
449 * Renvoie le type d'une page
454 function noizetier_page_type($page) {
455 $type_compo = explode ('-',$page,2);
456 return $type_compo[0];
460 * Renvoie la composition d'une page
465 function noizetier_page_composition($page) {
466 $type_compo = explode ('-',$page,2);
467 return $type_compo[1];
471 * Liste les blocs pour lesquels il y a des noisettes à insérer.
473 * @staticvar array $liste_blocs
476 function noizetier_lister_blocs_avec_noisettes(){
477 static $liste_blocs = null;
479 if (is_null($liste_blocs)){
480 $liste_blocs = array();
481 include_spip('base/abstract_sql');
482 $resultats = sql_allfetsel (
483 array('bloc', 'type', 'composition'),
486 array('bloc', 'type', 'composition')
488 foreach ($resultats as $res) {
489 if ($res['composition'])
490 $liste_blocs[] = $res['bloc'].'/'.$res['type'].'-'.$res['composition'];
492 $liste_blocs[] = $res['bloc'].'/'.$res['type'];
499 * Liste d'icônes obtenues en fouillant les répertoires img/ images/ image/ et /img-pack.
501 * @staticvar array $liste_icones
504 function noizetier_lister_icones(){
505 static $liste_icones = null;
507 if (is_null($liste_icones)){
508 $match = ".+[.](jpg|jpeg|png|gif)$";
509 $liste_icones = array(
510 'img' => find_all_in_path('img/', $match),
511 'img-pack' => find_all_in_path('img-pack/', $match),
512 'image' => find_all_in_path('image/', $match),
513 'images' => find_all_in_path('images/', $match)
517 return $liste_icones;
522 * Retourne les elements du contexte uniquement
523 * utiles a la noisette demande.
528 function noizetier_choisir_contexte($noisette, $contexte_entrant, $id_noisette) {
529 $contexte_noisette = array_flip(noizetier_obtenir_contexte($noisette));
531 // On transmet toujours l'id_noisette et les variables se terminant par _$id_noisette (utilisées par exemple par Aveline pour la pagination)
532 $contexte_min = array('id_noisette' => $id_noisette);
534 if (isset($contexte_noisette['env'])) {
535 return array_merge($contexte_entrant,$contexte_min);
538 $l = -1 * (strlen($id_noisette)+
1);
539 foreach ($contexte_entrant as $variable => $valeur)
540 if (substr($variable,$l)=='_'.$id_noisette)
541 $contexte_min[$variable] = $valeur;
543 if (isset($contexte_noisette['aucun'])) {
544 return $contexte_min;
546 if ($contexte_noisette) {
547 return array_merge(array_intersect_key($contexte_entrant, $contexte_noisette),$contexte_min);
550 return $contexte_entrant;
556 * Retourne la liste des contextes donc peut avoir besoin une noisette.
561 function noizetier_obtenir_contexte($noisette) {
562 static $noisettes = false;
564 // seulement 1 fois par appel, on lit ou calcule tous les contextes
565 if ($noisettes === false) {
566 // lire le cache des contextes sauves
567 lire_fichier_securise(_DIR_CACHE
. _CACHE_CONTEXTE_NOISETTES
, $noisettes);
568 $noisettes = @unserialize
($noisettes);
570 // s'il en mode recalcul, on recalcule tous les contextes des noisettes trouvees.
571 if (!$noisettes or (_request('var_mode') == 'recalcul')) {
572 include_spip('inc/noizetier');
573 $infos = noizetier_lister_noisettes();
574 $noisettes = array();
575 foreach ($infos as $cle_noisette => $infos) {
576 $noisettes[$cle_noisette] = ($infos['contexte'] ?
$infos['contexte'] : array());
578 ecrire_fichier_securise(_DIR_CACHE
. _CACHE_CONTEXTE_NOISETTES
, serialize($noisettes));
582 if (isset($noisettes[$noisette])) {
583 return $noisettes[$noisette];
590 * Retourne true ou false pour indiquer si la noisette doit être inclue en ajax
595 function noizetier_ajaxifier_noisette($noisette) {
596 static $noisettes = false;
598 // seulement 1 fois par appel, on lit ou calcule tous les contextes
599 if ($noisettes === false) {
600 // lire le cache des contextes sauves
601 lire_fichier_securise(_DIR_CACHE
. _CACHE_AJAX_NOISETTES
, $noisettes);
602 $noisettes = @unserialize
($noisettes);
604 // s'il en mode recalcul, on recalcule tous les contextes des noisettes trouvees.
605 if (!$noisettes or (_request('var_mode') == 'recalcul')) {
606 include_spip('inc/noizetier');
607 $infos = noizetier_lister_noisettes();
608 $noisettes = array();
609 foreach ($infos as $cle_noisette => $infos) {
610 $noisettes[$cle_noisette] = ($infos['ajax'] == 'non') ?
false : true ;
612 ecrire_fichier_securise(_DIR_CACHE
. _CACHE_AJAX_NOISETTES
, serialize($noisettes));
616 if (isset($noisettes[$noisette])) {
617 return $noisettes[$noisette];
624 * Retourne true ou false pour indiquer si la noisette doit être inclue dynamiquement
629 function noizetier_inclusion_dynamique($noisette) {
630 static $noisettes = false;
632 // seulement 1 fois par appel, on lit ou calcule tous les contextes
633 if ($noisettes === false) {
634 // lire le cache des contextes sauves
635 lire_fichier_securise(_DIR_CACHE
. _CACHE_INCLUSIONS_NOISETTES
, $noisettes);
636 $noisettes = @unserialize
($noisettes);
638 // s'il en mode recalcul, on recalcule tous les contextes des noisettes trouvees.
639 if (!$noisettes or (_request('var_mode') == 'recalcul')) {
640 include_spip('inc/noizetier');
641 $infos = noizetier_lister_noisettes();
642 $noisettes = array();
643 foreach ($infos as $cle_noisette => $infos) {
644 $noisettes[$cle_noisette] = ($infos['inclusion'] == 'dynamique') ?
true : false ;
646 ecrire_fichier_securise(_DIR_CACHE
. _CACHE_INCLUSIONS_NOISETTES
, serialize($noisettes));
650 if (isset($noisettes[$noisette])) {
651 return $noisettes[$noisette];
658 * Retourne le tableau des noisettes et des compositions du noizetier pour les exports
663 function noizetier_tableau_export() {
666 // On calcule le tableau des noisettes
667 $data['noisettes'] = sql_allfetsel(
668 'type, composition, bloc, noisette, parametres',
672 'type, composition, bloc, rang, css'
675 // On remet au propre les parametres
676 foreach ($data['noisettes'] as $cle => $noisette)
677 $data['noisettes'][$cle]['parametres'] = unserialize($noisette['parametres']);
679 // On récupère les compositions du noizetier
680 $noizetier_compositions = unserialize($GLOBALS['meta']['noizetier_compositions']);
681 if (is_array($noizetier_compositions) AND count($noizetier_compositions)>0)
682 $data['noizetier_compositions'] = $noizetier_compositions;
684 $data = pipeline('noizetier_config_export',$data);
690 * Importe une configuration de noisettes et de compositions
692 * @param text $type_import
693 * @param text $import_compos
694 * @param array $config
697 function noizetier_importer_configuration($type_import, $import_compos, $config){
698 if ($type_import!='remplacer')
699 $type_import = 'fusion';
700 if ($import_compos!='oui')
701 $import_compos = 'non';
703 $config = pipeline('noizetier_config_import',$config);
705 // On s'occupe déjà des noisettes
706 $noisettes = $config['noisettes'];
707 include_spip('base/abstract_sql');
708 if (is_array($noisettes) AND count($noisettes)>0) {
709 $noisettes_insert = array();
712 if ($type_import=='remplacer')
713 sql_delete('spip_noisettes','1');
714 foreach($noisettes as $noisette) {
715 $type = $noisette['type'];
716 $composition = $noisette['composition'];
717 if ($type.'-'.$composition!=$page) {
718 $page = $type.'-'.$composition;
720 if ($type_import=='fusion')
721 $rang = sql_getfetsel('rang','spip_noisettes','type='.sql_quote($type).' AND composition='.sql_quote($composition),'','rang DESC') +
1;
726 $noisette['rang']=$rang;
727 $noisette['parametres'] = serialize($noisette['parametres']);
728 $noisettes_insert[] = $noisette;
730 $ok = sql_insertq_multi('spip_noisettes',$noisettes_insert);
733 // On s'occupe des compositions du noizetier
734 if ($import_compos=='oui') {
735 include_spip('inc/meta');
736 $compos_importees = $config['noizetier_compositions'];
737 if (is_array($compos_importees) AND count($compos_importees)>0){
738 if ($type_import=='remplacer')
739 effacer_meta('noizetier_compositions');
741 $noizetier_compositions = unserialize($GLOBALS['meta']['noizetier_compositions']);
743 if (!is_array($noizetier_compositions))
744 $noizetier_compositions = array();
746 foreach($compos_importees as $type => $compos_type)
747 foreach($compos_type as $composition => $info_compo)
748 $noizetier_compositions[$type][$composition] = $info_compo;
750 ecrire_meta('noizetier_compositions',serialize($noizetier_compositions));
755 // On invalide le cache
756 include_spip('inc/invalideur');
757 suivre_invalideur('noizetier-import-config');