[SPIP] +2.1.12
[velocampus/web/www.git] / www / plugins / auto / compositions_v2 / compositions_fonctions.php
1 <?php
2 /*
3 * Plugin Compositions
4 * (c) 2007-2009 Cedric Morin
5 * Distribue sous licence GPL
6 *
7 */
8
9 if (!defined("_ECRIRE_INC_VERSION")) return;
10
11 define('_COMPOSITIONS_MATCH','-([^0-9][^.]*)');
12
13 /**
14 * Retrouver le nom du dossier ou sont stockees les compositions
15 * reglage par defaut, ou valeur personalisee via cfg
16 *
17 * @return string
18 */
19 function compositions_chemin(){
20 $config_chemin = 'compositions/';
21 if (defined('_DIR_PLUGIN_Z') OR defined('_DIR_PLUGIN_ZCORE'))
22 $config_chemin = (isset($GLOBALS['z_blocs'])?reset($GLOBALS['z_blocs']):'contenu/');
23
24 if (isset($GLOBALS['meta']['compositions'])){
25 $config = unserialize($GLOBALS['meta']['compositions']);
26 if (isset ($config['chemin_compositions'])){
27 $config_chemin = rtrim($config['chemin_compositions'],'/').'/';
28 }
29 }
30
31 return $config_chemin;
32 }
33
34 /**
35 * Tester si la stylisation auto est activee
36 * @return string
37 */
38 function compositions_styliser_auto(){
39 $config_styliser = true;
40 if (defined('_DIR_PLUGIN_Z') OR defined('_DIR_PLUGIN_ZCORE')){
41 $config_styliser = false; // Z s'occupe de styliser les compositions
42 }
43 elseif (isset($GLOBALS['meta']['compositions'])){
44 $config = unserialize($GLOBALS['meta']['compositions']);
45 $config_styliser = $config['styliser_auto'] != 'non';
46 }
47 return $config_styliser?' ':'';
48 }
49
50 /**
51 * Lister les compositions disponibles : toutes ou pour un type donne
52 * Si informer est a false, on ne charge pas les infos du xml
53 *
54 * @param string $type
55 * @param bool $informer
56 * @return array
57 */
58 function compositions_lister_disponibles($type, $informer=true){
59 include_spip('inc/compositions');
60 $type = preg_replace(',\W,','',$type);
61 if ($type=='syndic') $type='site'; //grml
62 if (!strlen($type)) $type="[a-z0-9]+";
63
64
65 // rechercher les skel du type article-truc.html
66 // truc ne doit pas commencer par un chiffre pour eviter de confondre avec article-12.html
67 $match = "/($type)("._COMPOSITIONS_MATCH.")?[.]html$";
68
69 // lister les compositions disponibles
70 $liste = find_all_in_path(compositions_chemin(),$match);
71 $res = array();
72 if (count($liste)){
73 foreach($liste as $s) {
74 $base = preg_replace(',[.]html$,i','',$s);
75 if (preg_match(",$match,ims",$s,$regs)
76 AND ($composition = !$informer
77 OR $composition = compositions_charger_infos($base)))
78 $res[$regs[1]][$regs[3]] = $composition;
79 // retenir les skels qui ont un xml associe
80 }
81 }
82 // Pipeline compositions_lister_disponibles
83 if ($type=="[a-z0-9]+")
84 $type = '';
85 $res = pipeline('compositions_lister_disponibles',array(
86 'args'=>array('type' => $type,'informer' => $informer),
87 'data'=> $res
88 )
89 );
90 return $res;
91 }
92
93 /**
94 * Liste les id d'un type donne utilisant une composition donnee
95 *
96 * @param string $type
97 * @param string $composition
98 * @return array
99 */
100 function compositions_lister_utilisations($type,$composition){
101 $table_sql = table_objet_sql($type);
102 if (!in_array($table_sql, sql_alltable())) return;
103 $_id_table_objet = id_table_objet($type);
104 return sql_allfetsel("$_id_table_objet as id,titre", $table_sql, "composition=".sql_quote($composition));
105 }
106
107 /**
108 * Selectionner le fond en fonction du type et de la composition
109 * en prenant en compte la configuration pour le chemin
110 * et le fait que la composition a pu etre supprimee
111 *
112 * @param string $composition
113 * @param string $type
114 * @param string $defaut
115 * @param string $ext
116 * @param bool $fullpath
117 * @param string $vide
118 * @return string
119 */
120 function compositions_selectionner($composition,$type,$defaut="",$ext="html",$fullpath = false, $vide="composition-vide"){
121 if ($type=='syndic') $type='site'; //grml
122 $fond = compositions_chemin() . $type;
123
124 // regarder si compositions/article-xxx est disponible
125 if (strlen($composition)
126 AND $f = find_in_path("$fond-$composition.$ext"))
127 return $fullpath ? $f : $fond . "-$composition";
128 else
129 // sinon regarder si compositions/article-defaut est disponible
130 if (strlen($defaut)
131 AND $f = find_in_path("$fond-$defaut.$ext"))
132 return $fullpath ? $f : $fond . "-$defaut";
133
134 // se rabattre sur compositions/article si disponible
135 if ($f = find_in_path("$fond.$ext"))
136 return $fullpath ? $f : $fond;
137
138 // sinon une composition vide pour ne pas generer d'erreur
139 if ($vide AND $f = find_in_path("$vide.$ext"))
140 return $fullpath ? $f : $vide;
141
142 // rien mais ca fera une erreur dans le squelette si appele en filtre
143 return '';
144 }
145
146 /**
147 * Decrire une composition pour un objet
148 * @param string $type
149 * @param string $composition
150 * @return array|bool|string
151 */
152 function compositions_decrire($type, $composition){
153 static $compositions = array();
154 if (!function_exists('compositions_charger_infos'))
155 include_spip('inc/compositions');
156 if ($type=='syndic') $type='site'; //grml
157 if (isset($compositions[$type][$composition]))
158 return $compositions[$type][$composition];
159 $ext = "html";
160 $fond = compositions_chemin() . $type;
161 if (strlen($composition)
162 AND $f = find_in_path("$fond-$composition.$ext")
163 AND $desc = compositions_charger_infos($f))
164 return $compositions[$type][$composition] = $desc;
165 return $compositions[$type][$composition] = false;
166 }
167
168 /**
169 * Un filtre a utiliser sur [(#COMPOSITION|composition_class{#ENV{type}})]
170 * pour poser des classes generiques sur le <body>
171 * si une balise <class>toto</class> est definie dans la composition c'est elle qui est appliquee
172 * sinon on pose simplement le nom de la composition
173 *
174 * @param string $composition
175 * @param string $type
176 * @return string
177 */
178 function composition_class($composition,$type){
179 if ($desc = compositions_decrire($type, $composition)
180 AND isset($desc['class'])
181 AND strlen($desc['class']))
182 return $desc['class'];
183 return $composition;
184 }
185
186 /**
187 * Liste les types d'objets qui ont une composition
188 * utilise la valeur en cache meta sauf si demande de recalcul
189 * ou pas encore definie
190 *
191 * @staticvar array $liste
192 * @return array
193 */
194 function compositions_types(){
195 static $liste = null;
196 if (is_null($liste)) {
197 if ($GLOBALS['var_mode'] OR !isset($GLOBALS['meta']['compositions_types'])){
198 include_spip('inc/compositions');
199 compositions_cacher();
200 }
201 $liste = explode(',',$GLOBALS['meta']['compositions_types']);
202 }
203 return $liste;
204 }
205
206 /**
207 * Renvoie la composition qui s'applique � un objet
208 * en tenant compte, le cas �ch�ant, de la composition h�rit�e
209 * si etoile=true on renvoi dire le champ sql
210 *
211 * @param string $type
212 * @param integer $id
213 * @param string $serveur
214 * @param bool $etoile
215 * @return string
216 */
217 function compositions_determiner($type, $id, $serveur='', $etoile = false){
218 static $composition = array();
219
220 if (isset($composition[$etoile][$serveur][$type][$id]))
221 return $composition[$etoile][$serveur][$type][$id];
222
223 include_spip('base/abstract_sql');
224 $table = table_objet($type);
225 $table_sql = table_objet_sql($type);
226 $_id_table = id_table_objet($type);
227
228 $retour = '';
229
230 $trouver_table = charger_fonction('trouver_table', 'base');
231 $desc = $trouver_table($table,$serveur);
232 if (isset($desc['field']['composition']) AND $id){
233 $select = "composition";
234 if (isset($desc['field']['id_rubrique']))
235 $select .= "," . (($type == 'rubrique') ? 'id_parent' : 'id_rubrique as id_parent');
236 $row = sql_fetsel($select, $table_sql, "$_id_table=".intval($id), '', '', '', '', $serveur);
237 if ($row['composition'] != '')
238 $retour = $row['composition'];
239 elseif (!$etoile
240 AND isset($row['id_parent'])
241 AND $row['id_parent'])
242 $retour = compositions_heriter($type, $row['id_parent'], $serveur);
243 }
244 return $composition[$etoile][$serveur][$type][$id] = (($retour == '-') ? '' : $retour);
245 }
246
247 /**
248 * Renvoie la composition h�rit�e par un objet selon sa rubrique
249 *
250 * @param string $type
251 * @param integer $id_rubrique
252 * @param string $serveur
253 * @return string
254 */
255 function compositions_heriter($type, $id_rubrique, $serveur=''){
256 if ($type=='syndic') $type='site'; //grml
257 if (intval($id_rubrique) < 1) return '';
258 static $infos = null;
259 $id_parent = $id_rubrique;
260 $compo_rubrique = '';
261 do {
262 $row = sql_fetsel(array('id_parent','composition'),'spip_rubriques','id_rubrique='.intval($id_parent),'','','','',$serveur);
263 if (strlen($row['composition']) AND $row['composition']!='-')
264 $compo_rubrique = $row['composition'];
265 elseif (strlen($row['composition'])==0) // il faut aussi verifier que la rub parente n'herite pas elle-meme d'une composition
266 $compo_rubrique = compositions_determiner('rubrique', $id_parent, $serveur='');
267
268 if (strlen($compo_rubrique) AND is_null($infos))
269 $infos = compositions_lister_disponibles('rubrique');
270 }
271 while ($id_parent = $row['id_parent']
272 AND
273 (!strlen($compo_rubrique) OR !isset($infos['rubrique'][$compo_rubrique]['branche'][$type])));
274
275 if (strlen($compo_rubrique) AND isset($infos['rubrique'][$compo_rubrique]['branche'][$type]))
276 return $infos['rubrique'][$compo_rubrique]['branche'][$type];
277
278 return '';
279 }
280
281 /**
282 * #COMPOSITION
283 * Renvoie la composition s'appliquant � un objet
284 * en tenant compte, le cas �ch�ant, de l'h�ritage.
285 *
286 * Sans precision, l'objet et son identifiant sont pris
287 * dans la boucle en cours, mais l'on peut sp�cifier notre recherche
288 * en passant objet et id_objet en argument de la balise :
289 * #COMPOSITION{article, 8}
290 *
291 * #COMPOSITION* renvoie toujours le champs brut, sans tenir compte de l'heritage
292 *
293 * @param array $p AST au niveau de la balise
294 * @return array AST->code modifi� pour calculer le nom de la composition
295 */
296 function balise_COMPOSITION_dist($p) {
297 $_composition = "";
298 if ($_objet = interprete_argument_balise(1, $p)) {
299 $_id_objet = interprete_argument_balise(2, $p);
300 } else {
301 $_composition = champ_sql('composition',$p);
302 $_id_objet = champ_sql($p->boucles[$p->id_boucle]->primary, $p);
303 $_objet = "objet_type('" . $p->boucles[$p->id_boucle]->id_table . "')";
304 }
305 // si on veut le champ brut, et qu'on l'a sous la main, inutile d'invoquer toute la machinerie
306 if ($_composition AND $p->etoile)
307 $p->code = $_composition;
308 else {
309 $connect = $p->boucles[$p->id_boucle]->sql_serveur;
310 $p->code = "compositions_determiner($_objet, $_id_objet, '$connect', ".($p->etoile?'true':'false').")";
311 // ne declencher l'usine a gaz que si composition est vide ...
312 if ($_composition)
313 $p->code = "((\$zc=$_composition)?(\$zc=='-'?'':\$zc):".$p->code.")";
314 }
315 return $p;
316 }
317
318 /**
319 * Indique si la composition d'un objet est verrouill�e ou non,
320 * auquel cas, seul le webmaster peut la modifier
321 *
322 * @param string $type
323 * @param integer $id
324 * @param string $serveur
325 * @return string
326 */
327 function compositions_verrouiller($type, $id, $serveur=''){
328 $config = unserialize($GLOBALS['meta']['compositions']);
329 if ($config['tout_verrouiller'] == 'oui')
330 return true;
331
332 include_spip('base/abstract_sql');
333 $table = table_objet($type);
334 $table_sql = table_objet_sql($type);
335 $_id_table = id_table_objet($type);
336
337 $trouver_table = charger_fonction('trouver_table', 'base');
338 $desc = $trouver_table($table,$serveur);
339 if (isset($desc['field']['composition_lock']) AND $id){
340 $lock = sql_getfetsel('composition_lock', $table_sql, "$_id_table=".intval($id), '', '', '', '', $serveur);
341 if ($lock)
342 return true;
343 elseif (isset($desc['field']['id_rubrique'])) {
344 $id_rubrique = sql_getfetsel('id_rubrique', $table_sql, "$_id_table=".intval($id), '', '', '', '', $serveur);
345 return compositions_verrou_branche($id_rubrique, $serveur);
346 }
347 else
348 return false;
349 }
350 else return false;
351 }
352
353 /**
354 * Indique si les objets d'une branche sont verrouill�s
355 * @param integer $id_rubrique
356 * @param string $serveur
357 * @return string
358 */
359 function compositions_verrou_branche($id_rubrique, $serveur=''){
360
361 if (intval($id_rubrique) < 1) return false;
362 if($infos_rubrique = sql_fetsel(array('id_parent','composition_branche_lock'),'spip_rubriques','id_rubrique='.intval($id_rubrique),'','','','',$serveur)) {
363 if ($infos_rubrique['composition_branche_lock'])
364 return true;
365 else
366 return compositions_verrou_branche($infos_rubrique['id_parent'],$serveur);
367 }
368 return '';
369 }
370 ?>