source: spip-zone/_plugins_/iterateurs/iterateurs_fonctions.php @ 82867

Last change on this file since 82867 was 82867, checked in by marcimat@…, 7 years ago

Enlever les espaces de fins de ligne

File size: 8.4 KB
Line 
1<?php
2
3if (!defined('_ECRIRE_INC_VERSION')) return;
4
5include_spip('public/iterateur');
6
7// filtre table_valeur
8// permet de recuperer la valeur d'un tableau pour une cle donnee
9// prend en entree un tableau serialise ou non (ce qui permet d'enchainer le filtre)
10// ou un objet
11// Si la cle est de la forme a.b, on renvoie $table[a][b]
12function Iterateurs_table_valeur($table,$cle,$defaut=''){
13        foreach (explode('/', $cle) as $k) if ($k !== "") {
14                $table= is_string($table) ? unserialize($table) : $table;
15
16                if (is_object($table))
17                        $table = isset($table->$k) ? $table->$k : $default;
18                else if (is_array($table))
19                        $table = isset($table[$k]) ? $table[$k] : $defaut;
20                else
21                        $table = $default;
22        }
23        return $table;
24}
25
26
27// {source mode, "xxxxxx", arg, arg, arg}
28function critere_source($idb, &$boucles, $crit) {
29        $boucle = &$boucles[$idb];
30
31        $args = array();
32        foreach ($crit->param as &$param)
33                array_push($args,
34                calculer_liste($param, array(), $boucles, $boucles[$idb]->id_parent));
35
36        $boucle->hash .= '
37        $command[\'sourcemode\'] = '. array_shift($args). ";\n";
38
39        $boucle->hash .= '
40        $command[\'source\'] = array('. join(', ', $args). ");\n";
41
42}
43
44
45// {datasource "xxxxxx", mode}  <= deprecated
46function critere_datasource($idb, &$boucles, $crit) {
47        $boucle = &$boucles[$idb];
48        $boucle->hash .= '
49        $command[\'source\'] = array('.calculer_liste($crit->param[0], array(), $boucles, $boucles[$idb]->id_parent).');
50        $command[\'sourcemode\'] = '.calculer_liste($crit->param[1], array(), $boucles, $boucles[$idb]->id_parent).';';
51}
52
53function critere_datacache($idb, &$boucles, $crit) {
54        $boucle = &$boucles[$idb];
55        $boucle->hash .= '
56        $command[\'datacache\'] = '.calculer_liste($crit->param[0], array(), $boucles, $boucles[$idb]->id_parent).';';
57}
58
59// {tableau #XX} pour compatibilite ascendante boucle POUR
60// ... preferer la notation {datasource #XX,table}
61function critere_tableau($idb, &$boucles, $crit) {
62        $boucle = &$boucles[$idb];
63        $boucle->hash .= '
64        $command[\'source\'] = array('.calculer_liste($crit->param[0], array(), $boucles, $boucles[$idb]->id_parent).');
65        $command[\'sourcemode\'] = \'table\';';
66}
67
68
69/*
70 * Pour passer des arguments a un iterateur non-spip
71 * (php:xxxIterator){args argument1, argument2, argument3}
72 */
73function critere_args($idb, &$boucles, $crit) {
74        $boucle = &$boucles[$idb];
75        $boucle->hash .= '$command[\'args\']=array();';
76        foreach($crit->param as $param) {
77                $boucle->hash .= '
78                        $command[\'args\'][] = '.calculer_liste($param, array(), $boucles, $boucles[$idb]->id_parent).';';
79        }
80}
81
82/*
83 * Passer une liste de donnees a l'iterateur DATA
84 * (DATA){liste X1, X2, X3}
85 */
86function critere_liste($idb, &$boucles, $crit) {
87        $boucle = &$boucles[$idb];
88        $boucle->hash .= "\n\t".'$command[\'liste\'] = array();'."\n";
89        foreach($crit->param as $param) {
90                $boucle->hash .= "\t".'$command[\'liste\'][] = '.calculer_liste($param, array(), $boucles, $boucles[$idb]->id_parent).";\n";
91        }
92}
93
94/*
95 * Extraire un chemin d'un tableau de donnees
96 * (DATA){datapath query.results}
97 */
98function critere_datapath($idb, &$boucles, $crit) {
99        $boucle = &$boucles[$idb];
100        foreach($crit->param as $param) {
101                $boucle->hash .= '
102                        $command[\'datapath\'][] = '.calculer_liste($param, array(), $boucles, $boucles[$idb]->id_parent).';';
103        }
104}
105
106
107/* le critere {si ...} applicable a toutes les boucles */
108function critere_si($idb, &$boucles, $crit) {
109        $boucle = &$boucles[$idb];
110        // il faut initialiser 1 fois le tableau a chaque appel de la boucle
111        // (par exemple lorsque notre boucle est appelee dans une autre boucle)
112        // mais ne pas l'initialiser n fois si il y a n criteres {si } dans la boucle !
113        $boucle->hash .= "\n\tif (!isset(\$si_init)) { \$command['si'] = array(); \$si_init = true; }\n";
114        if ($crit->param) {
115                foreach($crit->param as $param) {
116                        $boucle->hash .= "\t\$command['si'][] = "
117                                        . calculer_liste($param, array(), $boucles, $boucles[$idb]->id_parent) . ";\n";
118                }
119        // interdire {si 0} aussi !
120        } else {
121                        $boucle->hash .= '$command[\'si\'][] = 0;';
122        }
123}
124
125
126// {pagination}
127// {pagination 20}
128// {pagination #ENV{pages,5}} etc
129// {pagination 20 #ENV{truc,chose}} pour utiliser la variable debut_#ENV{truc,chose}
130// http://www.spip.net/@pagination
131// http://doc.spip.org/@critere_pagination
132function critere_pagination($idb, &$boucles, $crit) {
133
134        $boucle = &$boucles[$idb];
135        // definition de la taille de la page
136        $pas = !isset($crit->param[0][0]) ? "''" : calculer_liste(array($crit->param[0][0]), array(), $boucles, $boucle->id_parent);
137
138        if (!preg_match(_CODE_QUOTE, $pas, $r)) {
139                $pas = "((\$a = intval($pas)) ? \$a : 10)";
140        } else {
141                $r = intval($r[2]);
142                $pas = strval($r ? $r : 10);
143        }
144        $type = !isset($crit->param[0][1]) ? "'$idb'" : calculer_liste(array($crit->param[0][1]), array(), $boucles, $boucle->id_parent);
145        $debut = ($type[0]!=="'") ? "'debut'.$type"
146          : ("'debut" .substr($type,1));
147
148        $boucle->modificateur['debut_nom'] = $type;
149        $partie =
150                 // tester si le numero de page demande est de la forme '@yyy'
151                 'isset($Pile[0]['.$debut.']) ? $Pile[0]['.$debut.'] : _request('.$debut.");\n"
152                ."\tif(substr(\$debut_boucle,0,1)=='@'){\n"
153                ."\t\t".'$debut_boucle = $Pile[0]['. $debut.'] = Iterateurs_quete_debut_pagination(\''.$boucle->primary.'\',$Pile[0][\'@'.$boucle->primary.'\'] = substr($debut_boucle,1),'.$pas.',$iter);'."\n"
154                ."\t\t".'$iter->seek(0);'."\n"
155                ."\t}\n"
156                ."\t".'$debut_boucle = intval($debut_boucle)';
157
158
159        $boucle->total_parties = $pas;
160        calculer_parties($boucles, $idb, $partie, 'p+');
161        // ajouter la cle primaire dans le select pour pouvoir gerer la pagination referencee par @id
162        // sauf si pas de primaire, ou si primaire composee
163        // dans ce cas, on ne sait pas gerer une pagination indirecte
164        $t = $boucle->id_table . '.' . $boucle->primary;
165        if ($boucle->primary
166                AND !preg_match('/[,\s]/',$boucle->primary)
167                AND !in_array($t, $boucle->select))
168          $boucle->select[]= $t;
169}
170
171
172
173###### BALISES
174/**
175 * #LISTE{a,b,c,d,e} cree un #ARRAY avec les valeurs, sans preciser les cles
176 *
177 * @param <type> $p
178 * @return <type>
179 */
180function balise_LISTE($p) {
181        $_code = array();
182        $n=1;
183        while ($_val = interprete_argument_balise($n++,$p))
184                $_code[] = $_val;
185        $p->code = 'array(' . join(', ',$_code).')';
186        $p->interdire_scripts = false;
187        return $p;
188}
189
190
191/**
192 * #SAUTER{n} permet de sauter en avant n resultats dans une boucle
193 * La balise modifie le compteur courant de la boucle, mais pas les autres
194 * champs qui restent les valeurs de la boucle avant le saut. Il est donc
195 * preferable d'utiliser la balise juste avant la fermeture </BOUCLE>
196 *
197 * L'argument n doit etre superieur a zero sinon la balise ne fait rien
198 *
199 * @param <type> $p
200 * @return <type>
201 */
202function balise_SAUTER($p){
203        $id_boucle = $p->id_boucle;
204        $boucle = $p->boucles[$id_boucle];
205
206        if (!$boucle) {
207                $msg = array('zbug_champ_hors_boucle', array('champ' => '#SAUTER'));
208                erreur_squelette($msg, $p);
209        }
210        else {
211                $_saut = interprete_argument_balise(1,$p);
212                $_compteur = "\$Numrows['$id_boucle']['compteur_boucle']";
213                $_total = "\$Numrows['$id_boucle']['total']";
214
215                $p->code = "vide($_compteur=\$iter->skip($_saut,$_total))";
216        }
217        $p->interdire_scripts = false;
218        return $p;
219}
220
221// #VALEUR renvoie le champ valeur
222// #VALEUR{x} renvoie #VALEUR|Iterateurs_table_valeur{x}
223// #VALEUR{a/b} renvoie #VALEUR|Iterateurs_table_valeur{a/b}
224function balise_VALEUR($p) {
225        $b = $p->nom_boucle ? $p->nom_boucle : $p->id_boucle;
226        $p->code = index_pile($p->id_boucle, 'valeur', $p->boucles, $b);;
227        if (($v = interprete_argument_balise(1,$p))!==NULL){
228                $p->code = 'Iterateurs_table_valeur('.$p->code.', '.$v.')';
229        }
230        $p->interdire_scripts = true;
231        return $p;
232}
233
234
235function Iterateurs_quete_debut_pagination($primary,$valeur,$pas,$iter){
236        // on ne devrait pas arriver ici si la cle primaire est inexistante
237        // ou composee, mais verifions
238        if (!$primary OR preg_match('/[,\s]/',$primary))
239                return 0;
240
241        $pos = 0;
242        while ($row = $iter->fetch() AND $row[$primary]!=$valeur){
243                $pos++;
244        }
245        // si on a pas trouve
246        if ($row[$primary]!=$valeur)
247                return 0;
248
249        // sinon, calculer le bon numero de page
250        return floor($pos/$pas)*$pas;
251}
252
253// afficher proprement n'importe quoi
254// en cas de table profonde, l'option $join ne s'applique qu'au plus haut niveau
255// c'est VOULU !  Exemple : [(#VALEUR|print{<hr />})] va afficher de gros blocs
256// separes par des lignes, avec a l'interieur des trucs separes par des virgules
257function filtre_print($u, $join=', ') {
258        if (is_string($u))
259                return typo($u);
260
261        if (is_array($u))
262                return join($join, array_map('filtre_print', $u));
263
264        if (is_object($u))
265                return join($join, array_map('filtre_print', (array) $u));
266
267        return $u;
268}
269
Note: See TracBrowser for help on using the repository browser.