[SPIP] ~v3.0.20-->v3.0.25
[lhc/web/clavette_www.git] / www / ecrire / inc / config.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2016 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
8 * *
9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
11 \***************************************************************************/
12
13 if (!defined('_ECRIRE_INC_VERSION')) return;
14
15
16 /**
17 * Appliquer les valeurs par defaut pour les options non initialisees
18 * (pour les langues c'est fait)
19 *
20 * @return null
21 */
22 // http://doc.spip.org/@inc_config_dist
23 function inc_config_dist() {
24 actualise_metas(liste_metas());
25 }
26
27 /**
28 * Expliquer une configuration :
29 * analyser le cfg pour determiner la table, le casier et le sous-casier eventuel
30 *
31 * @param string $cfg
32 * @return array
33 */
34 function expliquer_config($cfg){
35 // par defaut, sur la table des meta
36 $table = 'meta';
37 $casier = null;
38 $sous_casier = array();
39 if (strlen($cfg)){
40 $cfg = explode('/',$cfg);
41 // si le premier argument est vide, c'est une syntaxe /table/ ou un appel vide ''
42 if (!reset($cfg) AND count($cfg)>1) {
43 array_shift($cfg);
44 $table = array_shift($cfg);
45 if (!isset($GLOBALS[$table]))
46 lire_metas($table);
47 }
48 // si on a demande #CONFIG{/meta,'',0}
49 if (count($cfg))
50 $casier = array_shift($cfg);
51
52 if (count($cfg))
53 $sous_casier = $cfg;
54 }
55 return array($table,$casier,$sous_casier);
56 }
57
58 /**
59 * Lecture de la configuration
60 *
61 * lire_config() permet de recuperer une config depuis le php<br>
62 * memes arguments que la balise (forcement)<br>
63 * $cfg: la config, lire_config('montruc') est un tableau<br>
64 * lire_config('/table/champ') lit le valeur de champ dans la table des meta 'spip_table'<br>
65 * lire_config('montruc/sub') est l'element "sub" de cette config equivalent a lire_config('/meta/montruc/sub')<br>
66 *
67 * lire_config('methode::montruc/sub') delegue la lecture a methode_lire_config_dist via un charger_fonction
68 * permet de brancher CFG ou autre outil externe qui etend les methodes de stockage de config
69 *
70 * $unserialize est mis par l'histoire
71 *
72 * @param string $cfg la config
73 * @param mixed $def un défaut optionnel
74 * @param boolean $unserialize n'affecte que le dépôt 'meta'
75 * @return string
76 */
77 function lire_config($cfg='', $def=null, $unserialize=true) {
78 // lire le stockage sous la forme /table/valeur
79 // ou valeur qui est en fait implicitement /meta/valeur
80 // ou casier/valeur qui est en fait implicitement /meta/casier/valeur
81
82 // traiter en priorite le cas simple et frequent
83 // de lecture direct $GLOBALS['meta']['truc'], si $cfg ne contient ni / ni :
84 if ($cfg AND strpbrk($cfg,'/:')===false){
85 $r = isset($GLOBALS['meta'][$cfg])?
86 ((!$unserialize
87 // ne pas essayer de deserialiser autre chose qu'une chaine
88 OR !is_string($GLOBALS['meta'][$cfg])
89 // ne pas essayer de deserialiser si ce n'est visiblement pas une chaine serializee
90 OR strpos($GLOBALS['meta'][$cfg],':')===false
91 OR ($t=unserialize($GLOBALS['meta'][$cfg]))===false)?$GLOBALS['meta'][$cfg]:$t)
92 :$def;
93 return $r;
94 }
95
96 // Brancher sur methodes externes si besoin
97 if ($cfg AND $p=strpos($cfg,'::')){
98 $methode = substr($cfg,0,$p);
99 $lire_config = charger_fonction($methode, 'lire_config');
100 return $lire_config(substr($cfg,$p+2),$def,$unserialize);
101 }
102
103 list($table,$casier,$sous_casier) = expliquer_config($cfg);
104
105 if (!isset($GLOBALS[$table]))
106 return $def;
107
108 $r = $GLOBALS[$table];
109
110 // si on a demande #CONFIG{/meta,'',0}
111 if (!$casier)
112 return $unserialize ? $r : serialize($r);
113
114 // casier principal :
115 // le deserializer si demande
116 // ou si on a besoin
117 // d'un sous casier
118 $r = isset($r[$casier])?$r[$casier]:null;
119 if (($unserialize OR count($sous_casier)) AND $r AND is_string($r))
120 $r = (($t=unserialize($r))===false?$r:$t);
121
122 // aller chercher le sous_casier
123 while(!is_null($r) AND $casier = array_shift($sous_casier))
124 $r = isset($r[$casier])?$r[$casier]:null;
125
126 if (is_null($r)) return $def;
127 return $r;
128 }
129
130 /**
131 * metapack est inclue dans lire_config, mais on traite le cas ou il est explicite
132 * metapack:: dans le $cfg de lire_config.
133 * On renvoie simplement sur lire_config
134 *
135 * @param string $cfg
136 * @param mixed $def
137 * @param bool $unserialize
138 * @return mixed
139 */
140 function lire_config_metapack_dist($cfg='', $def=null, $unserialize=true) {
141 return lire_config($cfg, $def, $unserialize);
142 }
143
144
145 /**
146 * Ecrire une configuration
147 *
148 * @param string $cfg
149 * @param mixed $store
150 * @return bool
151 */
152 function ecrire_config($cfg,$store) {
153 // Brancher sur methodes externes si besoin
154 if ($cfg AND $p=strpos($cfg,'::')){
155 $methode = substr($cfg,0,$p);
156 $ecrire_config = charger_fonction($methode, 'ecrire_config');
157 return $ecrire_config(substr($cfg,$p+2),$store);
158 }
159
160 list($table,$casier,$sous_casier) = expliquer_config($cfg);
161 // il faut au moins un casier pour ecrire
162 if (!$casier) return false;
163
164 // trouvons ou creons le pointeur sur le casier
165 $st = isset($GLOBALS[$table][$casier])?$GLOBALS[$table][$casier]:null;
166 if (!is_array($st) AND ($sous_casier OR is_array($store))) {
167 $st = unserialize($st);
168 if ($st===false) {
169 // ne rien creer si c'est une demande d'effacement
170 if (is_null($store))
171 return false;
172 $st=array();
173 }
174 }
175
176 // si on a affaire a un sous caiser
177 // il faut ecrire au bon endroit sans perdre les autres sous casier freres
178 if ($c = $sous_casier) {
179 $sc = &$st;
180 $pointeurs = array();
181 while (count($c) AND $cc=array_shift($c)) {
182 // creer l'entree si elle n'existe pas
183 if (!isset($sc[$cc])) {
184 // si on essaye d'effacer une config qui n'existe pas
185 // ne rien creer mais sortir
186 if (is_null($store))
187 return false;
188 $sc[$cc] = array();
189 }
190 $pointeurs[$cc] = &$sc;
191 $sc = &$sc[$cc];
192 }
193
194 // si c'est une demande d'effacement
195 if (is_null($store)){
196 $c = $sous_casier;
197 $sous = array_pop($c);
198 // effacer, et remonter pour effacer les parents vides
199 do {
200 unset($pointeurs[$sous][$sous]);
201 } while ($sous = array_pop($c) AND !count($pointeurs[$sous][$sous]));
202
203 // si on a vide tous les sous casiers,
204 // et que le casier est vide
205 // vider aussi la meta
206 if (!$sous AND !count($st))
207 $st = null;
208 }
209 // dans tous les autres cas, on ecrase
210 else
211 $sc = $store;
212
213 // Maintenant que $st est modifiee
214 // reprenons la comme valeur a stocker dans le casier principal
215 $store = $st;
216 }
217
218 if (is_null($store)) {
219 if (is_null($st) AND !$sous_casier)
220 return false; // la config n'existait deja pas !
221 effacer_meta ($casier, $table);
222 if (!count($GLOBALS[$table])
223 OR count($GLOBALS[$table])==1 AND isset($GLOBALS[$table]['charset'])) {
224 effacer_meta('charset', $table); // enlevons cette meta
225 supprimer_table_meta($table); // supprimons la table (si elle est bien vide)
226 }
227 }
228 // les meta ne peuvent etre que des chaines : il faut serializer le reste
229 else {
230 if (!isset($GLOBALS[$table]))
231 installer_table_meta($table);
232 // si ce n'est pas une chaine
233 // il faut serializer
234 if (!is_string($store))
235 $store=serialize($store);
236 ecrire_meta($casier, $store, null, $table);
237 }
238 // verifier que lire_config($cfg)==$store ?
239 return true;
240 }
241
242
243 /**
244 * metapack est inclue dans ecrire_config, mais on traite le cas ou il est explicite
245 * metapack:: dans le $cfg de ecrire_config.
246 * On renvoie simplement sur ecrire_config
247 *
248 * @param string $cfg
249 * @param mixed $store
250 * @return bool
251 */
252 function ecrire_config_metapack_dist($cfg,$store) {
253 // cas particulier en metapack::
254 // si on ecrit une chaine deja serializee, il faut la reserializer pour la rendre
255 // intacte en sortie ...
256 if (is_string($store) AND strpos($store,':') AND unserialize($store))
257 $store = serialize($store);
258 return ecrire_config($cfg, $store);
259 }
260
261 /**
262 * Effacer une configuration : revient a ecrire une valeur null
263 * @param string $cfg
264 * @return bool
265 */
266 function effacer_config($cfg){
267 ecrire_config($cfg, null);
268 return true;
269 }
270
271
272 function lister_configurer($exclure = array()){
273 return array();
274
275 // lister les pages de config deja dans les menus
276 $deja = array();
277 foreach($exclure as $id=>$b) {
278 $url = ($b['url'] ? $b['url'] : $id);
279 if (!$b['url'] or !isset($exclure[$url])) {
280 if (strncmp($url,'configurer_',11)==0) {
281 $deja[$url] = $b;
282 } elseif($b['url']=='configurer' AND preg_match(',cfg=([a-z0-9_]+),i',$b['args'],$match)) {
283 $deja["configurer_".$match[1]] = $b;
284 }
285 }
286
287 }
288 $exclure = $exclure + $deja;
289
290 $icone_defaut = "images/configuration-16.png";
291 $liste = array();
292 $skels = array();
293 $forms = array();
294
295 // trouver toutes les pages configurer_xxx de l'espace prive
296 // et construire un tableau des entrees qui ne sont pas dans $deja
297 $pages = find_all_in_path("prive/squelettes/contenu/", "configurer_.*[.]"._EXTENSION_SQUELETTES.'$');
298
299 foreach($pages as $page) {
300 $configurer = basename($page,"."._EXTENSION_SQUELETTES);
301 if (!isset($exclure[$configurer])) {
302 $liste[$configurer] = array(
303 'parent' => 'bando_configuration',
304 'url' => $configurer,
305 'titre' => _T("configurer:{$configurer}_titre"),
306 'icone' => find_in_theme($i="images/{$configurer}-16.png")?$i:$icone_defaut,
307 );
308 }
309 $skels[$configurer] = $page;
310 }
311
312 // analyser la liste des $skels pour voir les #FORMULAIRE_CONFIGURER_ inclus
313 foreach($skels as $file) {
314 $forms = array_merge($forms, lister_formulaires_configurer($file));
315 }
316 $forms = array_flip($forms);
317
318 // trouver tous les formulaires/configurer_
319 // et construire un tableau des entrees
320 $pages = find_all_in_path("formulaires/", "configurer_.*[.]"._EXTENSION_SQUELETTES.'$');
321 foreach($pages as $page) {
322 $configurer = basename($page,"."._EXTENSION_SQUELETTES);
323 if (!isset($forms[$configurer])
324 AND !isset($liste[$configurer])
325 AND !isset($exclure[$configurer]))
326 $liste[$configurer] = array(
327 'parent' => 'bando_configuration',
328 'url' => 'configurer',
329 'args' => 'cfg='.substr($configurer,11),
330 'titre' => _T("configurer:{$configurer}_titre"),
331 'icone' => find_in_theme($i="images/{$configurer}-16.png")?$i:$icone_defaut,
332 );
333 }
334
335 return $liste;
336 }
337
338
339 /**
340 * Retourne la liste des formulaires de configuration
341 * presents dans le fichier dont l'adresse est donnee
342 *
343 * @param string $file adresse du fichier
344 * @return array liste des formulaires trouves
345 **/
346 function lister_formulaires_configurer($file) {
347 $forms = array();
348
349 lire_fichier($file, $skel);
350 if (preg_match_all(",#FORMULAIRE_(CONFIGURER_[A-Z0-9_]*),", $skel, $matches,PREG_SET_ORDER)) {
351 $matches = array_map('end',$matches);
352 $matches = array_map('strtolower',$matches);
353 $forms = array_merge($forms,$matches);
354 }
355
356 // evaluer le fond en lui passant un exec coherent pour que les pipelines le reconnaissent
357 // et reperer les formulaires CVT configurer_xx insereres par les plugins via pipeline
358 $config = basename(substr($file,0,-strlen("."._EXTENSION_SQUELETTES)));
359 spip_log('Calcul de '."prive/squelettes/contenu/$config");
360 $fond = recuperer_fond("prive/squelettes/contenu/$config", array("exec" => $config));
361
362 // passer dans le pipeline affiche_milieu pour que les plugins puissent ajouter leur formulaires...
363 // et donc que l'on puisse les referencer aussi !
364 $fond = pipeline('affiche_milieu', array('args'=>array("exec" => $config),'data'=>$fond));
365
366 // recuperer les noms des formulaires presents.
367 if (is_array($inputs = extraire_balises($fond,"input"))) {
368 foreach($inputs as $i) {
369 if (extraire_attribut($i,'name')=='formulaire_action') {
370 $forms[] = ($c=extraire_attribut($i,'value'));
371 }
372 }
373 }
374 return $forms;
375 }
376
377
378 // http://doc.spip.org/@liste_metas
379 function liste_metas()
380 {
381 return pipeline('configurer_liste_metas', array(
382 'nom_site' => _T('info_mon_site_spip'),
383 'slogan_site' => '',
384 'adresse_site' => preg_replace(",/$,", "", url_de_base()),
385 'descriptif_site' => '',
386 'activer_logos' => 'oui',
387 'activer_logos_survol' => 'non',
388 'articles_surtitre' => 'non',
389 'articles_soustitre' => 'non',
390 'articles_descriptif' => 'non',
391 'articles_chapeau' => 'non',
392 'articles_texte' => 'oui',
393 'articles_ps' => 'non',
394 'articles_redac' => 'non',
395 'post_dates' => 'non',
396 'articles_urlref' => 'non',
397 'articles_redirection' => 'non',
398 'creer_preview' => 'non',
399 'taille_preview' => 150,
400 'articles_modif' => 'non',
401
402 'rubriques_descriptif' => 'non',
403 'rubriques_texte' => 'oui',
404
405 'accepter_inscriptions' => 'non',
406 'accepter_visiteurs' => 'non',
407 'prevenir_auteurs' => 'non',
408 'suivi_edito' => 'non',
409 'adresse_suivi' =>'',
410 'adresse_suivi_inscription' =>'',
411 'adresse_neuf' => '',
412 'jours_neuf' => '',
413 'quoi_de_neuf' => 'non',
414 'preview' => ',0minirezo,1comite,',
415
416 'syndication_integrale' => 'oui',
417 'charset' => _DEFAULT_CHARSET,
418 'dir_img' => substr(_DIR_IMG,strlen(_DIR_RACINE)),
419
420 'multi_rubriques' => 'non',
421 'multi_secteurs' => 'non',
422 'gerer_trad' => 'non',
423 'langues_multilingue' => '',
424
425 'version_html_max' => 'html4',
426
427 'type_urls' => 'page',
428
429 'email_envoi' => '',
430 'email_webmaster' => '',
431 'auto_compress_http'=>'non',
432 ));
433 }
434
435 // mets les meta a des valeurs conventionnelles quand elles sont vides
436 // et recalcule les langues
437
438 // http://doc.spip.org/@actualise_metas
439 function actualise_metas($liste_meta)
440 {
441 $meta_serveur =
442 array('version_installee','adresse_site','alea_ephemere_ancien','alea_ephemere','alea_ephemere_date','langue_site','langues_proposees','date_calcul_rubriques','derniere_modif','optimiser_table','drapeau_edition','creer_preview','taille_preview','creer_htpasswd','creer_htaccess','gd_formats_read','gd_formats',
443 'netpbm_formats','formats_graphiques','image_process','plugin_header','plugin');
444 // verifier le impt=non
445 sql_updateq('spip_meta',array('impt'=>'non'),sql_in('nom',$meta_serveur));
446
447 while (list($nom, $valeur) = each($liste_meta)) {
448 if (!$GLOBALS['meta'][$nom]) {
449 ecrire_meta($nom, $valeur);
450 }
451 }
452
453 include_spip('inc/rubriques');
454 $langues = calculer_langues_utilisees();
455 ecrire_meta('langues_utilisees', $langues);
456 }
457
458
459
460 //
461 // Gestion des modifs
462 //
463
464 // http://doc.spip.org/@appliquer_modifs_config
465 function appliquer_modifs_config($purger_skel=false) {
466
467 foreach(liste_metas() as $i => $v) {
468 if (($x =_request($i))!==NULL)
469 ecrire_meta($i, $x);
470 elseif (!isset($GLOBALS['meta'][$i]))
471 ecrire_meta($i, $v);
472 }
473
474 if ($purger_skel) {
475 include_spip('inc/invalideur');
476 purger_repertoire(_DIR_SKELS);
477 }
478 }
479
480 /**
481 * Mettre a jour l'adresse du site a partir d'une valeur saisie
482 * (ou auto detection si vide)
483 *
484 * @param $adresse_site
485 * @return void
486 */
487 function appliquer_adresse_site($adresse_site){
488 if ($adresse_site!==NULL){
489 if (!strlen($adresse_site)) {$GLOBALS['profondeur_url']=_DIR_RESTREINT?0:1;$adresse_site = url_de_base();}
490 $adresse_site = preg_replace(",/?\s*$,", "", $adresse_site);
491
492 if (!preg_match(",^[\w]+://,Uims",$adresse_site))
493 $adresse_site = "http://$adresse_site";
494
495 ecrire_meta('adresse_site',$adresse_site);
496 }
497 return $adresse_site;
498 }
499
500 ?>