source: spip-zone/_plugins_/compositions/trunk/compositions_fonctions.php @ 57699

Last change on this file since 57699 was 57699, checked in by joseph@…, 8 years ago

dans le contexte Z, le dossier des compositions est déterminer automatiquement. Il ne faut donc pas prendre l'ancienne valeur en base (si elle existe) et on désactive le formulaire de personnalisation

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