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

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

ajout de l'heritage pour les mots depuis leur groupe:

  • fichiers de compo pour le groupe: groupe_mots-machin.xml et groupe_mots-machin.html
  • balise pour l'heritage dans le xml: <branche type="mot" composition="truc" />
File size: 13.2 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                if (isset($desc['field']['id_groupe']))
255                        $select .= "," . 'id_groupe as id_parent';
256                $row = sql_fetsel($select, $table_sql, "$_id_table=".intval($id), '', '', '', '', $serveur);
257                if ($row['composition'] != '')
258                        $retour = $row['composition'];
259                elseif (!$etoile
260                  AND isset($row['id_parent'])
261                  AND $row['id_parent'])
262                        $retour = compositions_heriter($type, $row['id_parent'], $serveur);
263        }
264        return $composition[$etoile][$serveur][$type][$id] = (($retour == '-') ? '' : $retour);
265}
266
267/**
268 * Renvoie la composition heritee par un objet selon sa rubrique
269 * ou son groupe de mot-cles
270 *
271 * @param string $type
272 * @param integer $id_rubrique
273 * @param string $serveur
274 * @return string
275 */
276function compositions_heriter($type, $id_rubrique, $serveur=''){
277        if ($type=='syndic') $type='site'; //grml
278        if (intval($id_rubrique) < 1) return '';
279        static $infos = null;
280        $id_parent = $id_rubrique;
281        $compo_rubrique = '';
282        if (in_array($type, array('article', 'rubrique', 'site'))) {
283                do {
284                        $row = sql_fetsel(array('id_parent','composition'),'spip_rubriques','id_rubrique='.intval($id_parent),'','','','',$serveur);
285                        if (strlen($row['composition']) AND $row['composition']!='-')
286                                $compo_rubrique = $row['composition'];
287                        elseif (strlen($row['composition'])==0) // il faut aussi verifier que la rub parente n'herite pas elle-meme d'une composition
288                                $compo_rubrique = compositions_determiner('rubrique', $id_parent, $serveur='');
289                       
290                        if (strlen($compo_rubrique) AND is_null($infos))
291                                $infos = compositions_lister_disponibles('rubrique');
292                }
293                while ($id_parent = $row['id_parent']
294                        AND
295                        (!strlen($compo_rubrique) OR !isset($infos['rubrique'][$compo_rubrique]['branche'][$type])));
296
297                if (strlen($compo_rubrique) AND isset($infos['rubrique'][$compo_rubrique]['branche'][$type]))
298                        return $infos['rubrique'][$compo_rubrique]['branche'][$type];
299        }
300        elseif ($type == 'mot') {
301                $row = sql_fetsel(array('composition'),'spip_groupes_mots','id_groupe='.intval($id_parent),'','','','',$serveur);
302                if (strlen($row['composition']) AND $row['composition']!='-')
303                        $compo_groupe = $row['composition'];
304                       
305                if (strlen($compo_groupe) AND is_null($infos))
306                        $infos = compositions_lister_disponibles('groupe_mots');
307
308                if (strlen($compo_groupe) AND isset($infos['groupe_mots'][$compo_groupe]['branche'][$type])) {
309                        return $infos['groupe_mots'][$compo_groupe]['branche'][$type];  }       
310        }
311
312        return '';
313}
314
315/**
316 * #COMPOSITION
317 * Renvoie la composition s'appliquant a un objet
318 * en tenant compte, le cas echeant, de l'heritage.
319 *
320 * Sans precision, l'objet et son identifiant sont pris
321 * dans la boucle en cours, mais l'on peut specifier notre recherche
322 * en passant objet et id_objet en argument de la balise :
323 * #COMPOSITION{article, 8}
324 *
325 * #COMPOSITION* renvoie toujours le champs brut, sans tenir compte de l'heritage
326 *
327 * @param array $p      AST au niveau de la balise
328 * @return array        AST->code modifie pour calculer le nom de la composition
329 */
330function balise_COMPOSITION_dist($p) {
331        $_composition = "";
332        if ($_objet = interprete_argument_balise(1, $p)) {
333                $_id_objet = interprete_argument_balise(2, $p);
334        } else {
335                $_composition = champ_sql('composition',$p);
336                $_id_objet = champ_sql($p->boucles[$p->id_boucle]->primary, $p);
337                $_objet = "objet_type('" . $p->boucles[$p->id_boucle]->id_table . "')";
338        }
339        // si on veut le champ brut, et qu'on l'a sous la main, inutile d'invoquer toute la machinerie
340        if ($_composition AND $p->etoile)
341                $p->code = $_composition;
342        else {
343                $connect = $p->boucles[$p->id_boucle]->sql_serveur;
344                $p->code = "compositions_determiner($_objet, $_id_objet, '$connect', ".($p->etoile?'true':'false').")";
345                // ne declencher l'usine a gaz que si composition est vide ...
346                if ($_composition)
347                        $p->code = "((\$zc=$_composition)?(\$zc=='-'?'':\$zc):".$p->code.")";
348        }
349        return $p;
350}
351
352/**
353 * Indique si la composition d'un objet est verrouillee ou non,
354 * auquel cas, seul le webmaster peut la modifier
355 *
356 * @param string $type
357 * @param integer $id
358 * @param string $serveur
359 * @return string
360 */
361function compositions_verrouiller($type, $id, $serveur=''){
362        $config = unserialize($GLOBALS['meta']['compositions']);
363        if ($config['tout_verrouiller'] == 'oui')
364                return true;
365       
366        include_spip('base/abstract_sql');
367        $table = table_objet($type);
368        $table_sql = table_objet_sql($type);
369        $_id_table = id_table_objet($type);
370
371        $trouver_table = charger_fonction('trouver_table', 'base');
372        $desc = $trouver_table($table,$serveur);
373        if (isset($desc['field']['composition_lock']) AND $id){
374                $lock = sql_getfetsel('composition_lock', $table_sql, "$_id_table=".intval($id), '', '', '', '', $serveur);
375                if ($lock)
376                        return true;
377                elseif (isset($desc['field']['id_rubrique'])) {
378                        $id_rubrique = sql_getfetsel('id_rubrique', $table_sql, "$_id_table=".intval($id), '', '', '', '', $serveur);
379                        return compositions_verrou_branche($id_rubrique, $serveur);
380                }
381                else
382                        return false;
383        }
384        else return false;
385}
386
387/**
388 * Indique si les objets d'une branche sont verrouilles
389 * @param integer $id_rubrique
390 * @param string $serveur
391 * @return string
392 */
393function compositions_verrou_branche($id_rubrique, $serveur=''){
394       
395        if (intval($id_rubrique) < 1) return false;
396        if($infos_rubrique = sql_fetsel(array('id_parent','composition_branche_lock'),'spip_rubriques','id_rubrique='.intval($id_rubrique),'','','','',$serveur)) {
397                if ($infos_rubrique['composition_branche_lock'])
398                        return true;
399                else
400                        return compositions_verrou_branche($infos_rubrique['id_parent'],$serveur);
401        }
402        return '';
403}
404?>
Note: See TracBrowser for help on using the repository browser.