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

Last change on this file since 43395 was 43395, checked in by fil@…, 10 years ago
  • changement de syntaxe : {datasource URL,format} est desormais depreciee, il faut utiliser {source format,URL} => Avantages :

-- on peut passer plusieurs arguments au filtre de format :

{source format,arg1,arg2,arg3}

-- on peut mettre des virgules dans les arguments (le compilo ne

le permet pas sur le premier argument, ici desormais, le format)

-- peut-etre est-ce un peu plus logique de nommer le format

avant les arguments, facon fonction(arg1,arg2...)

  • Reparer le tri {par hasard} lorsque le contenu est un objet, cf la demo flickr
  • suppression du patch qui induisait en erreur


File size: 8.0 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        $boucle->hash .= '$command[\'si\'] = array();'."\n";
111        foreach($crit->param as $param) {
112                $boucle->hash .= '
113                        $command[\'si\'][] = '.calculer_liste($param, array(), $boucles, $boucles[$idb]->id_parent).';';
114        }
115}
116
117
118// {pagination}
119// {pagination 20}
120// {pagination #ENV{pages,5}} etc
121// {pagination 20 #ENV{truc,chose}} pour utiliser la variable debut_#ENV{truc,chose}
122// http://www.spip.net/@pagination
123// http://doc.spip.org/@critere_pagination
124function critere_pagination($idb, &$boucles, $crit) {
125
126        $boucle = &$boucles[$idb];
127        // definition de la taille de la page
128        $pas = !isset($crit->param[0][0]) ? "''" : calculer_liste(array($crit->param[0][0]), array(), $boucles, $boucle->id_parent);
129
130        if (!preg_match(_CODE_QUOTE, $pas, $r)) {
131                $pas = "((\$a = intval($pas)) ? \$a : 10)";
132        } else {
133                $r = intval($r[2]);
134                $pas = strval($r ? $r : 10);
135        }
136        $type = !isset($crit->param[0][1]) ? "'$idb'" : calculer_liste(array($crit->param[0][1]), array(), $boucles, $boucle->id_parent);
137        $debut = ($type[0]!=="'") ? "'debut'.$type" 
138          : ("'debut" .substr($type,1));
139
140        $boucle->modificateur['debut_nom'] = $type;
141        $partie =
142                 // tester si le numero de page demande est de la forme '@yyy'
143                 'isset($Pile[0]['.$debut.']) ? $Pile[0]['.$debut.'] : _request('.$debut.");\n"
144                ."\tif(substr(\$debut_boucle,0,1)=='@'){\n"
145                ."\t\t".'$debut_boucle = $Pile[0]['. $debut.'] = Iterateurs_quete_debut_pagination(\''.$boucle->primary.'\',$Pile[0][\'@'.$boucle->primary.'\'] = substr($debut_boucle,1),'.$pas.',$iter);'."\n"
146                ."\t\t".'$iter->seek(0);'."\n"
147                ."\t}\n"
148                ."\t".'$debut_boucle = intval($debut_boucle)';
149
150
151        $boucle->total_parties = $pas;
152        calculer_parties($boucles, $idb, $partie, 'p+');
153        // ajouter la cle primaire dans le select pour pouvoir gerer la pagination referencee par @id
154        // sauf si pas de primaire, ou si primaire composee
155        // dans ce cas, on ne sait pas gerer une pagination indirecte
156        $t = $boucle->id_table . '.' . $boucle->primary;
157        if ($boucle->primary
158                AND !preg_match('/[,\s]/',$boucle->primary)
159                AND !in_array($t, $boucle->select))
160          $boucle->select[]= $t;
161}
162
163
164
165###### BALISES
166/**
167 * #LISTE{a,b,c,d,e} cree un #ARRAY avec les valeurs, sans preciser les cles
168 *
169 * @param <type> $p
170 * @return <type>
171 */
172function balise_LISTE($p) {
173        $_code = array();
174        $n=1;
175        while ($_val = interprete_argument_balise($n++,$p))
176                $_code[] = $_val;
177        $p->code = 'array(' . join(', ',$_code).')';
178        $p->interdire_scripts = false;
179        return $p;
180}
181
182
183/**
184 * #SAUTER{n} permet de sauter en avant n resultats dans une boucle
185 * La balise modifie le compteur courant de la boucle, mais pas les autres
186 * champs qui restent les valeurs de la boucle avant le saut. Il est donc
187 * preferable d'utiliser la balise juste avant la fermeture </BOUCLE>
188 *
189 * L'argument n doit etre superieur a zero sinon la balise ne fait rien
190 *
191 * @param <type> $p
192 * @return <type>
193 */
194function balise_SAUTER($p){
195        $id_boucle = $p->id_boucle;
196        $boucle = $p->boucles[$id_boucle];
197
198        if (!$boucle) {
199                $msg = array('zbug_champ_hors_boucle', array('champ' => '#SAUTER'));
200                erreur_squelette($msg, $p);
201        }
202        else {
203                $_saut = interprete_argument_balise(1,$p);
204                $_compteur = "\$Numrows['$id_boucle']['compteur_boucle']";
205                $_total = "\$Numrows['$id_boucle']['total']";
206
207                $p->code = "vide($_compteur=\$iter->skip($_saut,$_total))";
208        }
209        $p->interdire_scripts = false;
210        return $p;
211}
212
213// #VALEUR renvoie le champ valeur
214// #VALEUR{x} renvoie #VALEUR|Iterateurs_table_valeur{x}
215// #VALEUR{a/b} renvoie #VALEUR|Iterateurs_table_valeur{a/b}
216function balise_VALEUR($p) {
217        $b = $p->nom_boucle ? $p->nom_boucle : $p->id_boucle;
218        $p->code = index_pile($p->id_boucle, 'valeur', $p->boucles, $b);;
219        if (($v = interprete_argument_balise(1,$p))!==NULL){
220                $p->code = 'Iterateurs_table_valeur('.$p->code.', '.$v.')';
221        }
222        $p->interdire_scripts = true;
223        return $p;
224}
225
226
227function Iterateurs_quete_debut_pagination($primary,$valeur,$pas,$iter){
228        // on ne devrait pas arriver ici si la cle primaire est inexistante
229        // ou composee, mais verifions
230        if (!$primary OR preg_match('/[,\s]/',$primary))
231                return 0;
232
233        $pos = 0;
234        while ($row = $iter->next() AND $row[$primary]!=$valeur){
235                $pos++;
236        }
237        // si on a pas trouve
238        if ($row[$primary]!=$valeur)
239                return 0;
240
241        // sinon, calculer le bon numero de page
242        return floor($pos/$pas)*$pas;
243}
244
245// afficher proprement n'importe quoi
246// en cas de table profonde, l'option $join ne s'applique qu'au plus haut niveau
247// c'est VOULU !  Exemple : [(#VALEUR|print{<hr />})] va afficher de gros blocs
248// separes par des lignes, avec a l'interieur des trucs separes par des virgules
249function filtre_print($u, $join=', ') {
250        if (is_string($u))
251                return typo($u);
252
253        if (is_array($u))
254                return join($join, array_map('filtre_print', $u));
255
256        if (is_object($u))
257                return join($join, array_map('filtre_print', (array) $u));
258
259        return $u;
260}
261
Note: See TracBrowser for help on using the repository browser.