source: spip-zone/_plugins_/couteau_suisse/cout_utils.php @ 111530

Last change on this file since 111530 was 111530, checked in by patfr@…, 7 months ago

Notice/coquille en moins

File size: 40.0 KB
Line 
1<?php
2#-----------------------------------------------------#
3#  Plugin  : Couteau Suisse - Licence : GPL           #
4#  Auteur  : Patrice Vanneufville, 2006               #
5#  Contact : patrice¡.!vanneufville¡@!laposte¡.!net   #
6#  Infos : https://contrib.spip.net/?article2166      #
7#-----------------------------------------------------#
8#  Fichier contenant les fonctions utilisees pendant  #
9#  la configuration du plugin                         #
10#-----------------------------------------------------#
11if(!defined("_ECRIRE_INC_VERSION")) return;
12
13cs_log("chargement de cout_utils.php");
14$GLOBALS['cs_utils']++;
15
16// $outils : tableau ultra complet avec tout ce qu'il faut savoir sur chaque outil
17// $cs_variables : tableau de toutes les variables que les outils peuvent utiliser et manipuler
18//  - ces deux tableaux ne sont remplis qu'une seule fois, lors d'une initialisation totale
19//    les hits ordinaires ne se servent que des metas, non des fichiers.
20//  - l'initialisation totale insere en premier lieu config_outils.php
21global $outils, $cs_variables;
22$cs_variables = $outils = array();
23// liste des types de variable
24$cs_variables['_chaines'] = $cs_variables['_nombres'] = array();
25define('_format_CHAINE', 10);
26define('_format_NOMBRE', 20);
27
28/*************/
29/* FONCTIONS */
30/*************/
31
32// ajoute un outil a $outils;
33function add_outil($tableau) {
34        global $outils;
35        // sert encore a qqchose ?
36        static $index; $index = isset($index)?$index + 10:0;
37        $tableau['index'] = $index;
38        // grave erreur si pas d'id
39        if(!isset($tableau['id'])) { $tableau['id']='erreur'.count($outils); $tableau['nom'] = couteauprive_T('erreur_id'); }
40        // surcharges perso. Ex : $GLOBALS['mes_outils']['supprimer_numero_perso']
41        // (methode par variable globale depreciee)
42        if(isset($GLOBALS['mes_outils'][$perso = $tableau['id'].'_perso']) && is_array($GLOBALS['mes_outils'][$perso])) {
43                // ici pour compatibilite anterieure
44                $tableau = array_merge($tableau, $GLOBALS['mes_outils'][$perso]);
45                unset($GLOBALS['mes_outils'][$perso]);
46                $tableau['surcharge'] = 1;
47        // surcharges perso. Ex : function supprimer_numero_surcharger_outil($tab) { return $tab; }
48        } elseif(function_exists($perso = $tableau['id'].'_surcharger_outil')) {
49                if(is_array($perso = $perso($tableau))) $tableau = $perso;
50                $tableau['surcharge'] = 1;
51        }
52        // desactiver l'outil si les fichiers distants ne sont pas permis
53        if(defined('_CS_PAS_D_OUTIL_DISTANT') && isset($tableau['fichiers_distants']))
54                $tableau['version-max'] = '0';
55        foreach($tableau as $i=>$v) {           
56                // parametres multiples separes par des virgules
57                if(strpos($i,',')!==false) {
58                        $a = explode(',', $i);
59                        foreach($a as $b) $tableau[trim($b)] = $v;
60                        unset($tableau[$i]);
61                }
62                // liste des fichiers distants eventuels
63                if(strncmp('distant', $i, 7)==0) $tableau['fichiers_distants'][] = $i;
64        }
65        $outils[$tableau['id']] = $tableau;
66}
67
68// ajoute une variable a $cs_variables et fabrique une liste des chaines et des nombres
69function add_variable($tableau) {
70        global $cs_variables;
71        if(isset($tableau['nom'])) $nom = $tableau['nom']; else return;
72        if(isset($cs_variables[$nom])) {
73                cs_log("Variable $nom dupliquee ??");
74                return;
75        }
76        if(isset($tableau['check'])) $tableau['format'] = _format_NOMBRE;
77        // code '%s' par defaut si aucun code n'est defini
78        $test=isset($tableau['code']); 
79        if(!$test) foreach(array_keys($tableau) as $key)
80                if($test=(strncmp('code:', $key, 5)==0)) break;
81        if(!$test) $tableau['code'] = '%s';
82        // enregistrement
83        $cs_variables[$nom] = $tableau;
84        // on fabrique ici une liste des chaines et une liste des nombres
85        if(@$tableau['format']==_format_NOMBRE) $cs_variables['_nombres'][] = $nom;
86                elseif(@$tableau['format']==_format_CHAINE) $cs_variables['_chaines'][] = $nom;
87}
88// idem, arguments variables
89function add_variables() { foreach(func_get_args() as $t) add_variable($t); }
90
91// les 3 fonction suivantes decodent les fichiers de configuration xml
92// et les convertissent (pour l'instant car experimental) dans l'ancien format
93function add_outils_xml($f) {
94        include_spip('inc/xml');
95        $arbre = spip_xml_load($f);
96        if(isset($arbre['variable'])) foreach($arbre['variable'] as $a) 
97                add_variable(parse_variable_xml($a));
98        if(isset($arbre['outil'])) foreach($arbre['outil'] as $a) {
99                $out = parse_outil_xml($a);
100                if(isset($out['nom']) && is_string($out['nom']) && strlen($out['nom']) && strpos($f, ',couteau_suisse/,')!==false)
101                        $outil['nom'] = "<i>$out[nom]</i>";
102                add_outil($out);
103        }
104}
105// Attention : conversion incomplete. ajouter les tests au fur et a mesure
106function parse_variable_xml(&$arbre) {
107        $var = array();
108        if(isset($arbre['id'])) $var['nom'] = $arbre['id'][0];
109        if(isset($arbre['format'])) $var['format'] = $arbre['format'][0]=='string'?_format_CHAINE:_format_NOMBRE;
110        if(isset($arbre['radio'])) {   
111                $temp = &$arbre['radio'][0];
112                if(isset($temp['par_ligne'])) $var['radio/ligne'] = $temp['par_ligne'][0];
113                foreach($temp['item'] as $a) $var['radio'][$a['valeur'][0]] = $a['label'][0];
114        }
115        if(isset($arbre['label'])) $var['label'] = $arbre['label'][0];
116        if(isset($arbre['defaut_php'])) $var['defaut'] = $arbre['defaut_php'][0];
117        if(isset($arbre['code'])) foreach($arbre['code'] as $a) {
118                $temp = isset($a['condition_php'])?'code:'.$a['condition_php'][0]:'code';
119                if(isset($a['script_php'])) $var[$temp] = str_replace('\n', "\n", $a['script_php'][0]);
120        }
121        return $var;
122}
123// Attention : conversion incomplete. ajouter les tests au fur et a mesure
124function parse_outil_xml(&$arbre) {
125        $out = array();
126        foreach(array('id','nom','description','categorie','auteur') as $n) 
127                if(isset($arbre[$n])) $out[$n] = $arbre[$n][0];
128        if(isset($arbre['code'])) foreach($arbre['code'] as $a) {
129                $temp = isset($a['type'])?'code:'.$a['type'][0]:'code';
130                if(isset($a['script_php'])) $out[$temp] = str_replace('\n', "\n", $a['script_php'][0]);
131        }
132        if(isset($arbre['pipeline'])) foreach($arbre['pipeline'] as $a) {
133                if(isset($a['fonction'])) {
134                        $temp = isset($a['nom'])?'pipeline:'.$a['nom'][0]:'pipeline';
135                        $out[$temp] = $a['fonction'][0];
136                } elseif(isset($a['script_php'])) {
137                        $temp = isset($a['nom'])?'pipelinecode:'.$a['nom'][0]:'pipelinecode';
138                        $out[$temp] = $a['script_php'][0];
139                }
140        }
141        if(isset($arbre['version'])) { 
142                $temp = &$arbre['version'][0];
143                if(isset($temp['spip_min'])) $out['version-min'] = $temp['spip_min'][0];
144                if(isset($temp['spip_max'])) $out['version-max'] = $temp['spip_max'][0];
145        }
146        return $out;
147}
148
149// retourne la valeur 'defaut' (format php) de la variable apres compilation du code
150// le resultat comporte des guillemets si c'est une chaine
151function cs_get_defaut($variable) {
152        global $cs_variables;
153        // si la variable n'est pas declaree, serieux pb dans config_outils !
154        if(!isset($cs_variables[$variable])) {
155                spip_log("Erreur - variable '$variable' non declaree dans config_outils.php !");
156                return false;
157        }
158        $variable = &$cs_variables[$variable];
159        if(isset($variable['externe'])) $variable['defaut'] = $variable['externe'];
160        $defaut = !isset($variable['defaut'])?'':$variable['defaut'];
161        if(function_exists($f='initialiser_variable_'.$variable['nom']))
162                $defaut = $f($defaut);
163        if(!strlen($defaut)) $defaut = "''";
164        if(@$variable['format']==_format_NOMBRE) $defaut = "intval($defaut)";
165                elseif(@$variable['format']==_format_CHAINE) $defaut = "strval($defaut)";
166//cs_log("cs_get_defaut() - \$defaut[{$variable['nom']}] = $defaut");
167        eval("\$defaut=$defaut;");
168        $defaut2 = cs_php_format($defaut, @$variable['format']!=_format_NOMBRE, true);
169//cs_log(" -- cs_get_defaut() - \$defaut[{$variable['nom']}] est devenu : $defaut2");
170        return $defaut2;
171}
172
173// $type ici est egal a 'spip_options', 'options' ou 'fonctions'
174function ecrire_fichier_en_tmp(&$infos_fichiers, $type) {
175        $code = '';
176        if(isset($infos_fichiers['inc_'.$type]))
177                foreach ($infos_fichiers['inc_'.$type] as $inc) $code .= "include_spip('outils/$inc');\n";
178        if(isset($infos_fichiers['code_'.$type]))
179                foreach ($infos_fichiers['code_'.$type] as $inline) $code .= $inline."\n";
180        // on optimise avant...
181        $code = str_replace(array('intval("")',"intval('')"), '0', $code);
182        $code = str_replace("\n".'if(strlen($foo="")) ',"\n\$foo=''; //", $code);
183        // ... en avant le code !
184        $fichier_dest = _DIR_CS_TMP . "mes_$type.php";
185if(defined('_LOG_CS')) cs_log("ecrire_fichier_en_tmp($type) : lgr=".strlen($code))." pour $fichier_dest";
186        if(!ecrire_fichier($fichier_dest, '<'."?php\n// Code d'inclusion pour le plugin 'Couteau Suisse'\nisset(\$GLOBALS['cs_$type'])?\$GLOBALS['cs_$type']++:\$GLOBALS['cs_$type']=1;\n$code?".'>', true))
187                cs_log("ERREUR ECRITURE : $fichier_dest");
188}
189
190function set_cs_metas_pipelines(&$infos_pipelines) {
191        global $cs_metas_pipelines;
192        $controle='';
193        foreach($infos_pipelines as $pipe=>$infos) {
194                $code = "\n# Copie du code utilise en eval() pour le pipeline '$pipe(\$flux)'\n";
195                // compilation des differentes facon d'utiliser un pipeline
196                if(is_array(@$infos['inclure'])) foreach ($infos['inclure'] as $inc) {
197                        $code .= "include_spip('$inc');\n";
198                }
199                if(is_array(@$infos['inline'])) foreach ($infos['inline'] as $inc) $code .= "$inc\n";
200                if(is_array(@$infos['fonction'])) foreach ($infos['fonction'] as $fonc)
201                        $code .= "function_exists('$fonc')?\$flux=$fonc(\$flux):cs_deferr('$fonc');\n";
202                $controle .= $cs_metas_pipelines[$pipe] = $code;
203        }
204        $nb = count($infos_pipelines);
205if(defined('_LOG_CS')) cs_log("$nb pipeline(s) actif(s) : strlen=".strlen($controle));
206        ecrire_fichier(_DIR_CS_TMP . "pipelines.php", 
207                '<'."?php\n// Code de controle pour le plugin 'Couteau Suisse' : $nb pipeline(s) actif(s)\n{$controle}?".'>');
208}
209
210// basename sans argument
211function cs_basename($file, $suffix=null) {
212        preg_match('/[^?]*/', $file, $reg); 
213        return basename($reg[0], $suffix);
214}
215
216// fonction ecrire_fichier() tres prudente
217function cs_ecrire_fichier($file, $contenu) {
218        $inf = pathinfo($file);
219        if(!ecrire_fichier($test = $inf['dirname'].'/test_'.$inf['basename'], $contenu)) 
220                return false;
221        $old = $inf['dirname'].'/'.$inf['basename'].'.old';
222        // le fichier actuel, s'il existe, remplace la sauvegarde eventuelle
223        if(@is_readable($file)) { @spip_unlink($old); @rename($file, $old); }
224        return @rename($test, $file); // le fichier test est promu
225}
226
227// est-ce que $pipe est un pipeline ?
228function is_pipeline_outil($pipe, &$set_pipe) {
229        if($ok=(strncmp('pipeline:', $pipe, 9)==0)) $set_pipe = trim(substr($pipe, 9));
230        return $ok;
231}
232// est-ce que $pipe est un pipeline inline?
233function is_pipeline_outil_inline($pipe, &$set_pipe) {
234        if($ok=(strncmp('pipelinecode:', $pipe, 13)==0)) $set_pipe = trim(substr($pipe, 13));
235        return $ok;
236}
237
238// est-ce que $traitement est un traitement ?
239function is_traitements_outil($traitement, $fonction, &$set_traitements_utilises) {
240        if(strncmp('traitement', $traitement, 10)!=0) return false;
241        if($ok = preg_match(',^traitement:([A-Z_]+)/?([a-z]+)?:(pre|post)_([a-zA-Z0-9_-]+)$,', $traitement, $t)) {
242                if(!strlen($t[2])) $t[2] = 0;
243                // 'typo' et 'propre' ne cohabitent pas : le premier l'emporte !
244                if($t[4]=='typo') { if(isset($set_traitements_utilises[$t[1]][$t[2]]['propre'])) $t[4]='propre'; }
245                elseif($t[4]=='propre') { if(isset($set_traitements_utilises[$t[1]][$t[2]]['typo'])) $t[4]='typo'; }
246                $set_traitements_utilises[$t[1]][$t[2]][$t[4]][$t[3]][] = $fonction;
247        } elseif($ok = preg_match(',^traitement:([A-Z]+)$,', $traitement, $t))
248                $set_traitements_utilises[$t[1]][0][0][] = $fonction;
249        return $ok;
250}
251
252// lire un fichier php et retirer si possible les balises ?php
253function cs_lire_fichier_php($file) {
254        $file=find_in_path($file);
255        if($file && lire_fichier($file, $php)) {
256                if(preg_match(',^<\?php(.*)?\?>$,msi', trim($php), $regs)) return trim($regs[1]);
257                return "\n"."?>\n".trim($php)."\n<"."?php\n";
258        }
259        return false;
260}
261
262// retourne les raccourcis ajoutes par l'outil, s'il est actif
263function cs_aide_raccourci($id) {
264        global $outils;
265        // stockage de la liste des fonctions par pipeline, si l'outil est actif...
266        if($outils[$id]['actif']) {
267                include_spip('outils/'.$id);   
268                if(function_exists($f = $id.'_raccourcis')) return $f();
269                if(!preg_match(',:aide(?:<|$),', $x = _T("couteauprive:$id:aide") )) return $x;
270        }
271        return '';
272}
273
274function cs_aide_raccourcis_callback($matches) {
275        return defined($matches[1])?constant($matches[1]):"";
276}
277
278// retourne la liste des raccourcis disponibles
279function cs_aide_raccourcis() {
280        global $outils;
281        $aide = array();
282        foreach ($outils as $outil) 
283                if($a = cs_aide_raccourci($outil['id'])) $aide[] = '<li style="margin: 0.7em 0 0 0;">&bull; ' . $a . '</li>';
284        if(!count($aide)) return '';
285        // remplacement des constantes de forme @_CS_XXXX@
286        $aide = preg_replace_callback(',@(_CS_[a-zA-Z0-9_]+)@,', 'cs_aide_raccourcis_callback', join("\n", $aide));
287        return '<p><b>' . couteauprive_T('raccourcis') . '</b></p><ul class="cs_raccourcis">' . $aide . '</ul>';
288}
289
290// retourne une aide concernant les pipelines utilises par l'outil
291function cs_aide_pipelines($outils_affiches_actifs) {
292        global $cs_metas_pipelines, $outils, $metas_outils;
293        $aide = array();
294        $keys = array_keys($cs_metas_pipelines); sort($keys);
295        foreach ($keys as $pipe) {
296                // stockage de la liste des pipelines et du nombre d'outils actifs concernes
297                $nb=0; foreach($outils as $outil) if($outil['actif'] && (isset($outil['pipeline:'.$pipe]) || isset($outil['pipelinecode:'.$pipe]))) $nb++;
298                if(($len=strlen($pipe))>25) $pipe = substr($pipe, 0, 8).'...'.substr($pipe, $len - 14);
299                if($nb) $aide[] = couteauprive_T('outil_nb'.($nb>1?'s':''), array('pipe'=>$pipe, 'nb'=>$nb));
300        }
301        // nombre d'outils actifs / interdits par les autorisations (hors versionnage SPIP)
302        $nb = $ca2 = 0; 
303        foreach($metas_outils as $o) if(isset($o['actif']) && $o['actif']) $nb++;
304        foreach($outils as $o) if(isset($o['interdit']) && $o['interdit'] && !cs_version_erreur($o)) $ca2++;
305        // nombre d'outils caches de la configuration par l'utilisateur
306        $ca1 = isset($GLOBALS['meta']['tweaks_caches'])?count(unserialize($GLOBALS['meta']['tweaks_caches'])):0;
307        return '<p><b>' . couteauprive_T('outils_actifs') . "</b> $nb"
308                . '<br /><b>' . couteauprive_T('outils_caches') . "</b> $ca1"
309                . (!$ca2?'':('<br /><b>' . couteauprive_T('outils_non_parametrables') . "</b> $ca2"))
310                .'<br /><b>' . couteauprive_T('pipelines') . '</b> '.count($aide)
311                . '</p><p style="font-size:80%; line-height: 1.4em;">' . join("<br />", $aide) . '</p>';
312}
313
314// sauve la configuration dans un fichier tmp/couteau-suisse/config.php
315function cs_sauve_configuration() {
316        global $outils, $metas_vars;
317        $metas = $metas_actifs = $variables = $lesoutils = $actifs = array();
318        foreach($outils as $t) {
319                $lesoutils[] = "\t// ".$t['nom']."\n\t'".$t['id']."' => '".join('|', $t['variables']) . "'";
320                if($t['actif']) {
321                        $actifs[] = $t['id'];
322                        $variables = array_merge($variables, $t['variables']);
323                }
324        }
325        foreach($metas_vars as $i => $v) if($i!='_chaines' && $i!='_nombres') {
326                $metas[] = $temp = "\t'$i' => " . cs_php_format($v, in_array($i, $metas_vars['_chaines']));
327                if(in_array($i, $variables)) $metas_actifs[] = $temp;
328        }
329        $sauve = "// Tous les outils et leurs variables\n\$liste_outils = array(\n" . join(",\n", $lesoutils) . "\n);\n"
330                . "\n// Outils actifs\n\$outils_actifs =\n\t'" . join('|', $actifs) . "';\n"
331                . "\n// Variables actives\n\$variables_actives =\n\t'" . join('|', $variables) . "';\n"
332                . "\n// Valeurs validees en metas\n\$valeurs_validees = array(\n" . join(",\n", $metas) . "\n);\n";
333
334        include_spip('inc/charset');
335        $nom_pack = couteauprive_T('pack_actuel', array('date'=>cs_date()));
336        $fct_pack = md5($nom_pack.time());
337        $sauve .= $temp = "\n######## ".couteauprive_T('pack_actuel_titre')." #########\n\n// "
338                . filtrer_entites(couteauprive_T('pack_actuel_avert')."\n\n"
339                        . "\$GLOBALS['cs_installer']['$nom_pack'] =\t'cs_$fct_pack';\nfunction cs_$fct_pack() { return array(\n\t// "
340                        . couteauprive_T('pack_outils_defaut')."\n"
341                        . "\t'outils' =>\n\t\t'".join(",\n\t\t", $actifs)."',\n"
342                        . "\n\t// ".couteauprive_T('pack_variables_defaut')."\n")
343                . "\t'variables' => array(\n\t" . join(",\n\t", $metas_actifs) . "\n\t)\n);} # $nom_pack #\n";
344
345        ecrire_fichier(_DIR_CS_TMP.'config.php', '<'."?php\n// Configuration de controle pour le plugin 'Couteau Suisse'\n\n$sauve?".'>');
346        if(_request('cmd')=='pack' || (_request('cmd')=='descrip' && _request('outil')=='pack')) $GLOBALS['cs_pack_actuel'] = $temp;
347}
348
349function cs_autorisation_alias(&$tab, $autoriser) {
350        static $ok = array();
351        if(isset($ok[$autoriser])) return;
352        if(function_exists($f='autoriser_'.$autoriser.'_configurer') || function_exists($f.='_dist')) {
353                $g = str_replace('_','',objet_type($autoriser));
354                if($g != $autoriser) {
355                        $tab[] = "function autoriser_{$g}_configurer(\$faire,\$type,\$id,\$qui,\$opt) {\n\treturn function_exists('$f')\n\t?$f(\$faire, \$type, \$id, \$qui, \$opt):true; }";
356                        $ok[$autoriser] = 1;
357                }
358        }
359}
360
361function cs_nom_outil_callback($m) {
362        return _T($m[1]);
363}
364
365function cs_nom_outil(&$outil, $traduit=true) {
366        if($outil['pas_de_nom']) {
367                // outil classique
368                $nom = 'couteauprive:'.$outil['id'].':nom'; $nom_traduit = _T($nom);
369        } else {
370                // outil au nom defini et traduit
371                $nom = ''; $nom_traduit = $outil['nom'];
372        }
373        // si on trouve une chaine de langue dans le nom traduit, le resultat sera forcement traduit
374        if(strpos($nom_traduit, '<:')!==false)
375                return preg_replace_callback(',<:([:a-z0-9_-]+):>,i', 'cs_nom_outil_callback', $nom_traduit);
376        return (!$traduit && strlen($nom))?$nom:$nom_traduit;
377}
378
379// cree les tableaux $infos_pipelines et $infos_fichiers, puis initialise $cs_metas_pipelines
380function cs_initialise_includes($count_metas_outils) {
381        global $outils, $cs_metas_pipelines;
382        // toutes les infos sur les fichiers mes_options/mes_fonctions et sur les pipelines;
383        $infos_pipelines = $infos_fichiers =
384        // liste des traitements utilises
385        $traitements_utilises =
386        // variables temporaires
387        $temp_js_html = $temp_css_html = $temp_css = $temp_js = $temp_jq = $temp_jq_init = $temp_filtre_imprimer = array();
388        @define('_CS_HIT_EXTERNE', 1500);
389        // inclure d'office outils/couteau_suisse_fonctions.php
390        if($temp = cs_lire_fichier_php("outils/cout_fonctions.php"))
391                $infos_fichiers['code_fonctions'][] = $temp;
392        // variable de verification
393        $infos_fichiers['code_options'][] = "\$GLOBALS['cs_verif']=$count_metas_outils;";
394        // horrible hack sur les autorisations SPIP 3.0 (en attendant la correction !!)
395        if(defined('_SPIP30000')) {
396                cs_autorisation_alias($infos_fichiers['code_spip_options'], 'plugins');
397                cs_autorisation_alias($infos_fichiers['code_spip_options'], 'cs');
398                global $cs_variables;
399                for($i=2; $i<count($tmp=array_keys($cs_variables)); $i++)
400                        cs_autorisation_alias($infos_fichiers['code_spip_options'], 'variable_'.$tmp[$i]);
401                foreach ($outils as $i=>$outil) {
402                        cs_autorisation_alias($infos_fichiers['code_spip_options'], 'outil_'.$outil['id']);
403                        if(isset($outil['categorie']))
404                                cs_autorisation_alias($infos_fichiers['code_spip_options'], 'categorie_'.$outil['categorie']);
405                }
406                cs_autorisation_alias($infos_fichiers['code_spip_options'], 'categorie_divers');
407        }
408        // parcours de tous les outils
409        foreach ($outils as $i=>$outil) {
410                $inc = $outil['id'];
411                // stockage de la liste des fonctions par pipeline
412                if($outil['actif']) {
413                        $pipe2 = '';
414                        foreach ($outil as $pipe=>$fonc) {
415                                if(is_pipeline_outil($pipe, $pipe2)) {
416                                        // module a inclure
417                                        if(find_in_path("outils/$inc.php"))
418                                                $infos_pipelines[$pipe2]['inclure'][] = "outils/$inc";
419                                        // inclusion du fichier des pipelines distants. TODO : inclusion mieux ciblee
420                                        if(isset($outil['distant_pipelines']))
421                                                $infos_pipelines[$pipe2]['inclure'][] = "lib/$inc/distant_pipelines_".cs_basename($outil['distant_pipelines'], '.php');
422                                        // fonction a appeler
423                                        if(strlen($fonc)) $infos_pipelines[$pipe2]['fonction'][] = $fonc;
424                                } elseif(is_pipeline_outil_inline($pipe, $pipe2)) {
425                                        // code inline
426                                        if(strlen($fonc)) $infos_pipelines[$pipe2]['inline'][] = cs_optimise_if(cs_parse_code_js($fonc));
427                                } elseif(is_traitements_outil($pipe, $fonc, $traitements_utilises)) {
428                                        // rien a faire : $traitements_utilises est rempli par is_traitements_outil()
429                                }
430                        }
431                        // SPIP>=3.1 : en l'absence du pipeline "ajouter_menus" defini dans l'outil,
432                        // ajouter d'office le bouton de menu "developpement" si l'outil est de categorie "devel"
433                        if(defined('_SPIP30100') && $outil['categorie']=='devel' && !isset($outil['pipeline:ajouter_menus']) && !isset($outil['pipelinecode:ajouter_menus'])) {
434                                $infos_pipelines['ajouter_menus']['inline'][] = "if(autoriser('configurer','$inc')) // cs_ajouter_menus('$inc', '$inc:nom', '');
435        \$flux['menu_developpement']->sousmenu['cs_$inc'] = cs_ajouter_menus('$inc', '".attribut_html(cs_nom_outil($outil, false))."');";
436                        }       
437                        // recherche des fichiers .css, .css.html, .js et .js.html eventuellement present dans outils/
438                        foreach(array('css', 'js') as $f) {
439                                if($file=find_in_path("outils/$inc.$f")) { lire_fichier($file, $ff); ${'temp_'.$f}[] = $ff; }
440                                // en fait on ne peut pas compiler ici car les balises vont devoir etre traitees et les traitements ne sont pas encore dispo !
441                                // le code est mis de cote. il sera compile plus tard au moment du pipeline grace a cs_compile_header()
442                                if($file=find_in_path("outils/$inc.$f.html")) { lire_fichier($file, $ff); ${'temp_'.$f.'_html'}[] = $ff; }
443                                // TODO : librairies distantes placees dans lib/
444/*                              if(isset($outil['distant_'.$f]) && ($file=find_in_path("lib/$inc/distant_{$f}_".cs_basename($outil["distant_$f"])))) etc. */
445                        }
446                        // recherche d'un code inline css/js/jq
447                        foreach(array('css', 'js', 'jq_init', 'jq') as $k) {
448                                if(isset($outil[$k2='code:'.$k.'_prive'])) ${'temp_'.$k}[] = cs_html_partie_privee($outil[$k2]);
449                                if(isset($outil[$k2='code:'.$k.'_public'])) ${'temp_'.$k}[] = cs_html_partie_privee($outil[$k2], false);
450                                if(isset($outil[$k2='code:'.$k])) ${'temp_'.$k}[] = cs_optimise_if(cs_parse_code_js($outil[$k2]));
451                        }
452                        foreach(array('options', 'fonctions', 'spip_options') as $f) {
453                                // recherche d'un code inline
454                                if(isset($outil['code:'.$f])) $infos_fichiers['code_'.$f][] = $outil['code:'.$f];
455                                // recherche d'un fichier monoutil_options.php ou monoutil_fonctions.php pour l'inserer dans le code
456                                // TODO : librairies distantes placees dans lib/
457                                if($temp=cs_lire_fichier_php("outils/{$inc}_{$f}.php")) $infos_fichiers['code_'.$f][] = $temp;
458/*                              if(isset($outil['distant_'.$f]) && find_in_path("lib/$inc/distant_{$f}_".cs_basename($outil["distant_$f"])))
459                                        if($temp=cs_lire_fichier_php("lib/$inc/distant_{$f}_$outil[distant_$f].php"))
460                                                $infos_fichiers['code_'.$f][] = $temp;
461*/                      }
462                } else foreach(array('pre_description_outil', 'fichier_distant') as $p) {
463                        // exceptions pour les outils inactifs
464                        if(isset($outil[$t='pipelinecode:'.$p]))       
465                                $infos_pipelines[$p]['inline'][] = cs_optimise_if(cs_parse_code_js($outil[$t]));
466                        if(isset($outil[$t='pipeline:'.$p])) {
467                                $infos_pipelines[$p]['inclure'][] = "outils/$inc";
468                                $infos_pipelines[$p]['fonction'][] = $outil[$t];
469                        }
470                }
471        }
472        // insertion du css pour la BarreTypo
473        if(isset($infos_pipelines['bt_toolbox']) && defined('_DIR_PLUGIN_BARRETYPOENRICHIE'))
474                $temp_css[] = 'span.cs_BT {background-color:#FFDDAA; font-weight:bold; border:1px outset #CCCC99; padding:0.2em 0.3em;}
475span.cs_BTg {font-size:140%; padding:0 0.3em;}';
476        // prise en compte des css.html et js.html qu'il faudra compiler plus tard
477        if(count($temp_css_html)){
478                $temp_css[] = '<cs_html>'.join("\n", $temp_css_html).'</cs_html>';
479                unset($temp_css_html);
480        }
481        if(count($temp_js_html)){
482                $temp_js[] = '<cs_html>'.join("\n", $temp_js_html).'</cs_html>';
483                unset($temp_js_html);
484        }
485        // concatenation des css inline, js inline et filtres trouves
486        if(strlen(trim($temp_css = join("\n", $temp_css)))) {
487                if(function_exists('compacte_css')) $temp_css = compacte_css($temp_css);
488                if(strlen($temp_css)>_CS_HIT_EXTERNE) {
489                        // hit externe
490                        $cs_metas_pipelines['header_css_ext'] = $temp_css;
491                } else {
492                        // css inline
493                        $temp = array("<style type=\"text/css\">\n<!--/*--><![CDATA[/*><!--*/\n$temp_css\n/*]]>*/-->\n</style>");
494                        if(is_array($cs_metas_pipelines['header_css'])) $temp = array_merge($temp, $cs_metas_pipelines['header_css']);
495                        $cs_metas_pipelines['header_css'] = $cs_metas_pipelines['header_css_prive'] = join("\n", $temp);
496                }
497                unset($temp_css);
498        }
499        if(count($temp_jq_init)) {
500                $temp_js[] = "var cs_init = function() {\n\t".join("\n\t", $temp_jq_init)."\n}\nif(typeof onAjaxLoad=='function') onAjaxLoad(cs_init);";
501                $temp_jq[] = "cs_init.apply(document);";
502                unset($temp_jq_init);
503        }
504        $temp_jq = count($temp_jq)?"\njQuery(document).ready(function(){\n\t".join("\n\t", $temp_jq)."\n});":'';
505        $temp_js[] = "if(window.jQuery) {\nvar cs_sel_jQuery="
506                . (defined('_SPIP30200')?'':"typeof jQuery(document).selector=='undefined'?'@':")
507                . "'';\nvar cs_CookiePlugin=\"<cs_html>#CHEMIN{javascript/jquery.cookie.js}</cs_html>\";$temp_jq\n}";
508        // la fonction prop() remplace attr() sous jQuery 1.6
509        if(!defined('_SPIP30000')) $temp_js[] = "if(typeof jQuery.fn.prop !== 'function') jQuery.fn.prop=function(name, value){
510        if (typeof value === 'undefined') return this.attr(name); else return this.attr(name, value); };";
511        unset($temp_jq);
512        if(count($temp_js)) {
513                $temp_js = "var cs_prive=window.location.pathname.match(/\\/ecrire\\/\$/)!=null;
514jQuery.fn.cs_todo=function(){return this.not('.cs_done').addClass('cs_done');};\n" . join("\n", $temp_js);
515                if(function_exists('compacte_js')) $temp_js = compacte_js($temp_js);
516                if(strlen($temp_js)>_CS_HIT_EXTERNE) {
517                        // hit externe
518                        $cs_metas_pipelines['header_js_ext'] = $temp_js;
519                } else {
520                        // js inline
521                        $temp = array("<script type=\"text/javascript\"><!--\n$temp_js\n// --></script>\n");
522                        if(is_array($cs_metas_pipelines['header_js'])) $temp = array_merge($temp, $cs_metas_pipelines['header_js']);
523                        $cs_metas_pipelines['header_js'] = $cs_metas_pipelines['header_js_prive'] = join("\n", $temp);
524                }
525                unset($temp_js);
526        }
527        // effacement du repertoire temporaire de controle
528        if(@file_exists(_DIR_CS_TMP) && ($handle = @opendir(_DIR_CS_TMP))) {
529                while (($fichier = @readdir($handle)) !== false)
530                        if($fichier[0] != '.')  supprimer_fichier(_DIR_CS_TMP.$fichier);
531                closedir($handle);
532        } else spip_log('Erreur - cs_initialise_includes() : '._DIR_CS_TMP.' introuvable !');
533        // join final...
534        foreach(array('css', 'js') as $type) {
535                $f = 'header_'.$type;
536                if(isset($cs_metas_pipelines[$temp = $f.'_ext'])) {
537                        $fichier_dest = _DIR_CS_TMP . "header.$type.html";
538                        if(!ecrire_fichier($fichier_dest, $cs_metas_pipelines[$temp], true)) cs_log("ERREUR ECRITURE : $fichier_dest");
539                        unset($cs_metas_pipelines[$temp]);
540                        $infos_pipelines['header_prive']['inline'][] = "cs_header_hit(\$flux, '$type', '_prive');";
541                        $infos_pipelines['insert_head'.($type=='css'?'_css':'')]['inline'][] = "cs_header_hit(\$flux, '$type');";
542                }
543        }
544        // liste des pivots pour les traitements que l'on peut decliner sous la forme pre_{pivot} ou post_{pivot}
545        // SPIP 2.0 ajoute les parametres "TYPO" et $connect aux fonctions typo() et propre()
546        // SPIP 3.0 ajoute le parametre $Pile[0]
547        $pp = defined('_SPIP30000')?',$Pile[0])':')';
548        $liste_pivots = defined('_SPIP19300')
549                ?array(
550                        // Fonctions pivots : on peut en avoir plusieurs pour un meme traitement
551                        // Exception : 'typo' et 'propre' ne cohabitent pas ensemble
552                        'typo' => defined('_TRAITEMENT_TYPO')?_TRAITEMENT_TYPO:('typo(%s,"TYPO",$connect'.$pp), // guillemets doubles requises pour le compilo
553                        'propre' => defined('_TRAITEMENT_RACCOURCIS')?_TRAITEMENT_RACCOURCIS:('propre(%s,$connect'.$pp),
554                ):array(
555                        'typo' => 'typo(%s)',
556                        'propre' => 'propre(%s)',
557                );
558        // mise en code des traitements trouves
559        $traitements_post_propre = 0;
560        foreach($traitements_utilises as $bal=>$balise) {
561                foreach($balise as $obj=>$type_objet) {
562                        /* code mort : is_traitements_outil() verifie deja la non compatibilite de propre et typo...
563                        // ici, on fait attention de ne pas melanger propre et typo
564                        if(array_key_exists('typo', $type_objet) && array_key_exists('propre', $type_objet))
565                                die(var_dump($type_objet) . "<br/>>> <b>#$bal/$obj</b><br/>" . couteauprive_T('erreur:traitements')); */
566                        $traitements_type_objet = &$traitements_utilises[$bal][$obj];
567                        foreach($type_objet as $f=>$fonction)  {
568                                // pas d'objet precis
569                                if($f===0)      $traitements_type_objet[$f] = cs_fermer_parentheses(join("(", array_reverse($fonction)).'(%s');
570                                // un objet precis
571                                else {
572                                        if(!isset($liste_pivots[$f])) $liste_pivots[$f] = $f . '(%s)';
573                                        $traitements_type_objet[$f] = !isset($fonction['pre'])?$liste_pivots[$f]
574                                                :str_replace('%s',
575                                                        cs_fermer_parentheses(join('(', $fonction['pre']) . '(%s'), 
576                                                        $liste_pivots[$f]
577                                                );
578                                        if(isset($fonction['post']))
579                                                $traitements_type_objet[$f] = cs_fermer_parentheses(join('(', $fonction['post']) . '(' . $traitements_type_objet[$f]);
580                                }
581                        }
582                        // nombre de fonctions pivot ?
583                        if(count($traitements_type_objet)===1) $temp = join('', $traitements_type_objet);
584                        else {
585                                // compilation de plusieurs pivots
586                                $temp = '%s';
587                                foreach($traitements_type_objet as $t) $temp = str_replace('%s', $t, $temp);
588                        }
589                        // detection d'un traitement post_propre
590                        if(strpos($temp, '(propre(')) {
591                                $traitements_post_propre = 1;
592                                $temp = "cs_nettoie($temp)";
593                        }
594                        // traitement particulier des forums (SPIP>=2.1)
595                        if($obj==='forums') {
596                                if(defined('_SPIP20100')) $temp = "safehtml($temp)";
597                                if(defined('_SPIP30000')) {
598                                        if(in_array($bal, array('TEXTE','TITRE','NOTES','NOM_SITE'))) $temp = str_replace('%s', 'interdit_html(%s)', $temp);
599                                        elseif(in_array($bal, array('URL_SITE','AUTEUR','EMAIL_AUTEUR'))) $temp = str_replace('%s', 'vider_url(%s)', $temp);
600                                }
601                               
602                        }
603                        $traitements_type_objet = "\t\$traitements['$bal'][" . ($obj=='0'?'0':"'$obj'") . "]='$temp';";
604                }
605                $traitements_utilises[$bal] = join("\n", $traitements_utilises[$bal]);
606                // specificite SPIP 3.0 : supprimer_numeros sur les TITRE et les NOM
607                if(defined('_SPIP30000') && ($bal=='TITRE' || $bal=='NOM')) 
608                        $traitements_utilises[$bal] = str_replace('%s', 'supprimer_numero(%s)', $traitements_utilises[$bal]);
609        }
610        // mes_options.php : ajout des traitements (peut-etre les passer en pipeline 'table_des_traitements' inline directement ?)
611        if(count($traitements_utilises))
612                $infos_fichiers['code_options'][] = "\n// Table des traitements sur les balises\nfunction cs_table_des_traitements(&\$traitements) {\n"
613                        . join("\n", $traitements_utilises)     . "\n}" 
614                        . (defined('_SPIP19300')?'':"\ncs_table_des_traitements(\$GLOBALS['table_des_traitements']);");
615        $infos_fichiers['code_options'][] = "\$GLOBALS['cs_post_propre']=$traitements_post_propre;";
616        // ecriture des fichiers mes_options et mes_fonctions
617        ecrire_fichier_en_tmp($infos_fichiers, 'spip_options');
618        ecrire_fichier_en_tmp($infos_fichiers, 'options');
619        ecrire_fichier_en_tmp($infos_fichiers, 'fonctions');
620        // installation de cs_metas_pipelines[]
621        set_cs_metas_pipelines($infos_pipelines);
622}
623
624function cs_fermer_parentheses($expr) {
625        return $expr . str_repeat(')', substr_count($expr, '(') - substr_count($expr, ')'));
626}
627
628// renvoie un code html destine a la partie privee ou publique
629// ce code est entoure des balises <cs_html/> provoquant une future compilation
630function cs_html_partie_privee($texte, $prive=true) {
631        // protection des crochets apres echappement des portions html a compiler plus tard
632        $texte = str_replace(array(']','[','@CHR93@'), array('@CHR93@','[(#CHR{91})]', '[(#CHR{93})]'),
633                        cs_echappe_balises('cs_html', false, cs_optimise_if(cs_parse_code_js($texte))));
634        // moment du test prive/public         
635        return '<cs_html>[(#EVAL{test_espace_prive()}|'.($prive?'oui':'non').')'
636                // balises <cs_html/> eventuelles devenue inutiles (leur interpretation est non recursive)
637                . str_replace(array('<cs_html>','</cs_html>'), '', echappe_retour($texte, 'CS'))
638                . ']</cs_html>';
639}
640
641define('_CS_SPIP_OPTIONS_A', "// Partie reservee au Couteau Suisse. Ne pas modifier, merci");
642define('_CS_SPIP_OPTIONS_B', "// Fin du code. Ne pas modifier ces lignes, merci");
643
644// verifier le fichier d'options _FILE_OPTIONS (ecrire/mes_options.php ou config/mes_options.php)
645function cs_verif_FILE_OPTIONS($activer=false, $ecriture = false) {
646        $include = str_replace('\\','/',realpath(_DIR_CS_TMP.'mes_spip_options.php'));
647        $include = "@include_once \"$include\";\nif(isset(\$GLOBALS['cs_spip_options']) && \$GLOBALS['cs_spip_options']) define('_CS_SPIP_OPTIONS_OK',1);";
648        $inclusion = _CS_SPIP_OPTIONS_A."\n// Please don't modify; this code is auto-generated\n$include\n"._CS_SPIP_OPTIONS_B;
649cs_log("cs_verif_FILE_OPTIONS($activer, $ecriture) : le code d'appel est $include");
650        if($fo = cs_spip_file_options(1)) {
651                if(lire_fichier($fo, $t)) {
652                        // verification du contenu inclu
653                        $ok = preg_match('`\s*('.preg_quote(_CS_SPIP_OPTIONS_A,'`').'.*'.preg_quote(_CS_SPIP_OPTIONS_B,'`').')\s*`ms', $t, $regs);
654                        // s'il faut une inclusion
655                        if($activer) {
656                                // pas besoin de reecrire si le contenu est identique a l'inclusion
657                                if(($regs[1]==$inclusion)) $ecriture = false;
658                                $t2 = $ok?str_replace($regs[0], "\n$inclusion\n\n", $t):preg_replace(',<\?(?:php)?\s*,', '<?'."php\n$inclusion\n\n", $t);
659                        } else {
660                                $t2 = $ok?str_replace($regs[0], "\n", $t):$t;
661                        }
662cs_log(" -- fichier $fo present. Inclusion " . ($ok?" trouvee".($ecriture?" et remplacee":""):"absente".(($ecriture && $activer)?" mais ajoutee":"")));
663                        if($ecriture) if($t2<>$t) {
664                                $ok = ecrire_fichier($fo, $t2);
665                                if(!$ok) cs_log("ERREUR : l'ecriture du fichier $fo a echoue !");
666                        }
667                        return;
668                } else cs_log(" -- fichier $fo illisible. Inclusion non permise");
669        } else 
670                $fo = cs_spip_file_options(2);
671        // creation
672        if($activer) {
673                if($ecriture) $ok=ecrire_fichier($fo, '<?'."php\n".$inclusion."\n\n?".'>');
674cs_log(" -- fichier $fo absent. Fichier '$fo' et inclusion ".((!$ecriture || !$ok)?"non ":"")."crees");
675        }
676}
677
678function cs_retire_guillemets($valeur) {
679        $valeur = trim($valeur);
680        return (strncmp($valeur,$g="'",1)===0 /*|| strncmp($valeur,$g='"',1)===0*/)
681                        && preg_match(",^$g(.*)$g$,s", $valeur, $matches)
682                ?stripslashes($matches[1])
683                :$valeur;
684}
685
686// met en forme une valeur dans le style php
687function cs_php_format($valeur, $is_chaine = true, $dblguill=false) {
688        $valeur = trim($valeur);
689        if( (strncmp($valeur,$g="'",1)===0 || ($dblguill && strncmp($valeur,$g='"',1)===0))
690                        && preg_match(",^$g(.*)$g$,s", $valeur, $matches)) {
691                if($is_chaine) return $valeur;
692                $valeur = stripslashes($matches[1]);           
693        }
694        if(!strlen($valeur)) return $is_chaine?"''":0;
695        return $is_chaine?var_export($valeur, true):$valeur;
696}
697
698// retourne le code compile d'une variable en fonction de sa valeur
699function cs_get_code_php_variable($variable, $valeur) {
700        global $cs_variables;
701        // si la variable n'a pas ete declaree
702        if(!isset($cs_variables[$variable])) return "/* Variable '$variable' inconnue ! */";
703        $cs_variable = &$cs_variables[$variable];
704        // mise en forme php de $valeur
705        if(!strlen($valeur)) {
706                if($cs_variable['format']==_format_NOMBRE) $valeur='0'; else $valeur='""';
707        } else
708                $valeur = cs_php_format($valeur, @$cs_variable['format']!=_format_NOMBRE);
709        $code = '';
710        foreach($cs_variable as $type=>$param) if(preg_match(',^code(:(.*))?$,', $type, $regs)) {
711                $eval = '$test = ' . (isset($regs[2])?str_replace('%s', $valeur, $regs[2]):'true') . ';';
712                $test = false;
713                eval($eval);
714                $code .= $test?str_replace('%s', $valeur, $param):'';
715        }
716        return $code;
717}
718
719
720// remplace les valeurs marquees comme %%toto%% par le code reel prevu par $cs_variables['toto']['code:condition']
721// attention de bien declarer les variables a l'aide de add_variable()
722function cs_parse_code_php($code, $debut='%%', $fin='%%') {
723        global $metas_vars;
724        while(preg_match(",([']?)$debut([a-zA-Z_][a-zA-Z0-9_]*?)$fin([']?),", $code, $matches)) {
725                $cotes = $matches[1]=="'" && $matches[3]=="'";
726                $nom = $matches[2];
727                // la valeur de la variable n'est stockee dans les metas qu'au premier post
728                if(isset($metas_vars[$nom])) {
729                        $rempl = cs_get_code_php_variable($nom, $metas_vars[$nom]);
730                        if(!strlen($rempl)) $code = "/* Pour info : $nom = $metas_vars[$nom] */\n" . $code;
731                } else {
732                        // tant que le webmestre n'a pas poste, on prend la valeur (dynamique) par defaut
733                        $defaut = cs_get_defaut($nom);
734                        $rempl = cs_get_code_php_variable($nom, $defaut);
735                        $code = "/* Par defaut : {$nom} = $defaut */\n" . $code;
736                }
737//echo '<br>',$nom, ':',isset($metas_vars[$nom]), " - $code";
738                if($cotes) $rempl = str_replace("'", "\'", $rempl);
739                $code = str_replace($matches[0], $matches[1].$rempl.$matches[3], $code);
740        }
741        return $code;
742}
743
744// remplace les valeurs marquees comme %%toto%% par la valeur reelle de $metas_vars['toto']
745// si cette valeur n'existe pas encore, la valeur utilisee sera $cs_variables['toto']['defaut']
746// attention de bien declarer les variables a l'aide de add_variable()
747function cs_parse_code_js($code) {
748        global $metas_vars, $cs_variables;
749        // parse d'abord [[%toto%]] pour le code reel de la variable
750        $code = cs_parse_code_php($code, '\[\[%', '%\]\]');
751        // parse ensuite %%toto%% pour la valeur reelle de la variable
752        while(preg_match(',%%([a-zA-Z_][a-zA-Z0-9_]*)%%,U', $code, $matches)) {
753                // la valeur de la variable n'est stockee dans les metas qu'au premier post
754                if(isset($metas_vars[$matches[1]])) {
755                        // la valeur de la variable est directement inseree dans le code js
756                        $rempl = $metas_vars[$matches[1]];
757                } else {
758                        // tant que le webmestre n'a pas poste, on prend la valeur (dynamique) par defaut
759
760
761                        $rempl = cs_retire_guillemets(cs_get_defaut($matches[1]));
762                }
763                $code = str_replace($matches[0], $rempl, $code);
764        } 
765        return $code;
766}
767
768// attention : optimisation tres sommaire, pour codes simples !
769// -> optimise les if(0), if(1), if(false), if(true)
770function cs_optimise_if($code, $root=true) {
771        if($root) {
772                $code = preg_replace(',if\s*\(\s*([^)]*\s*)\)\s*{\s*,imsS', 'if(\\1){', $code);
773                $code = str_replace(array('if(false){', 'if(!1){', 'if()'), 'if(0){', $code);
774                $code = str_replace(array('if(true){', 'if(!0){'), 'if(1){', $code);
775        }
776        if(preg_match_all(',if\(([0-9])+\){(.*)$,msS', $code, $regs, PREG_SET_ORDER))
777        foreach($regs as $r) {
778                $temp = $r[2]; $ouvre = $ferme = -1; $nbouvre = 1;
779                do {
780                        if($ouvre===false) $min = $ferme + 1; else $min = min($ouvre, $ferme) + 1;
781                        $ouvre=strpos($temp, '{', $min);
782                        $ferme=strpos($temp, '}', $min);
783                        if($ferme!==false) { if($ouvre!==false && $ouvre<$ferme) $nbouvre++; else $nbouvre--; }
784                } while($ferme!==false && $nbouvre>0);
785                if($ferme===false) return "/* Erreur sur les accolades : \{$r[2] */";
786                $temp2 = cs_optimise_if($temp3=substr($temp, $ferme+1), false);
787                $temp = substr($temp, 0, $ferme);
788                $rempl = "if($r[1]){".$temp."}$temp3";
789                if(intval($r[1])) $code = str_replace($rempl, "/* optimisation : 'IF($r[1])' */ {$temp}{$temp2}", $code);
790                        else $code = str_replace($rempl, "/* optimisation : 'IF($r[1]) \{$temp\}' */{$temp2}", $code);
791        }
792        return $code;
793}
794
795// lance la fonction d'installation de chaque outil actif, si elle existe.
796// la fonction doit etre ecrite sous la forme monoutil_installe_dist() et placee
797// dans le fichier outils/monoutil.php
798// une surcharge de la fnction native est possible en ecrivant une fonction monoutil_installe()
799function cs_installe_outils() {
800        global $metas_outils;
801        $datas = array();
802        foreach($metas_outils as $nom=>$o) if(isset($o['actif']) && $o['actif']) {
803                include_spip('outils/'.$nom);
804                if(function_exists($f = $nom.'_installe') || function_exists($f = $f.'_dist')) {
805                        if(is_array($tmp=$f())) foreach($tmp as $i=>$v) {
806                                $j=($i && $i!==$nom)?$nom.'_'.$i:$nom;
807                                $datas[$j] = "function cs_data_$j() { return " . var_export($v, true) . ';}';
808                        }
809if(defined('_LOG_CS')) cs_log(" -- $f() : OK !");
810                }
811        }
812        $datas = array('code_outils' => $datas);
813        ecrire_fichier_en_tmp($datas, 'outils');
814        ecrire_metas();
815}
816
817function cs_outils_concernes($key, $off=false){
818        global $outils, $metas_outils; $s='';
819        foreach($outils as $o) if(autoriser('configurer', 'outil', 0, NULL, $o) && isset($o[$key])) 
820                $s .= ($s?' - ':'')."[.->$o[id]]".(isset($metas_outils[$o[id]]['actif']) && $metas_outils[$o[id]]['actif']?' ('.couteauprive_T('outil_actif_court').')':'');
821        if(!$s) return '';
822        $s = couteauprive_T('outils_'.($off?'desactives':'concernes')).$s;
823        return "<q4>$s</q4>";
824}
825?>
Note: See TracBrowser for help on using the repository browser.