source: spip-zone/_plugins_/spip-pmb/trunk/public/pmb.php @ 70443

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

La recherche était castée en int, ça marchait plus. Et look avait une coquille. + renommages de fonction encoquillée…

File size: 24.4 KB
Line 
1<?php
2
3if (!defined('_ECRIRE_INC_VERSION')) return;
4
5include_spip('iterateur/data');
6
7/**
8 * Requeteur pour les boucles (pmb:type_info)
9 * tel que (pmb:notices)
10 *
11 * Analyse si le nom d'info correspond bien a un type permis
12 * et dans ce cas charge l'iterateur PMB avec ce type de donnees.
13 * Affichera une erreur dans le cas contraire.
14 *
15 * @param $boucles Liste des boucles
16 * @param $boucle  La boucle parcourue
17 * @param $id      L'identifiant de la boucle parcourue
18 *
19**/
20function requeteur_pmb_dist(&$boucles, &$boucle, &$id) {
21        $type = 'pmb_' . $boucle->type_requete;
22        if ($h = charger_fonction($type . '_select' , 'inc', true)) {
23                $g = charger_fonction('pmb', 'iterateur');
24                $boucles[$id] = $g($boucle, $type);
25                // from[0] stocke le type de data (pmb_notice, ...)
26                $boucles[$id]->from[] = $type;
27        } else {
28                $boucle->type_requete = false;
29                $msg = array('zbug_requeteur_inconnu',
30                                array(
31                                'requeteur' => 'pmb',
32                                'type' => $type
33                ));
34                erreur_squelette($msg, $boucle);
35        }
36}
37
38
39
40
41/**
42 * Creer une boucle sur un iterateur PMB
43 * (PMB:NOTICES) ...
44 * annonce au compilo les "champs" disponibles
45 *
46 * @param
47 * @return
48**/
49function iterateur_PMB_dist($b, $type) {
50        $b->iterateur = 'PMB'; # designe la classe d'iterateur
51        $b->show = array(
52                'field' => array(
53                        'cle' => 'STRING',
54                        'valeur' => 'STRING',
55                        'rechercher' => 'STRING',
56                        '*' => 'ALL' // Champ joker *
57                )
58        );
59        return $b;
60}
61
62
63
64/**
65 * Extension de l'itérateur Data
66 * pour modifier la procedure de selection
67 *
68**/
69class IterateurPMB extends IterateurData {
70
71        protected $type = '';
72
73
74        /**
75         * Declarer les criteres exceptions
76         * et pouvoir en ajouter au besoin
77         * @return array
78         */
79        public function exception_des_criteres($add = '') {
80                static $exceptions = array('tableau');
81
82                if (!$add) {
83                        return $exceptions;
84                }
85                $exceptions[] = $add;
86        }
87       
88       
89        /**
90         * Aller chercher les donnees
91         * Surcharge la selection de l'iterateur DATA
92         * puisque nous n'operons pas pareil.
93         *
94         *
95         * @throws Exception
96         * @param  $command
97         * @return void
98         */
99        protected function select($command) {
100               
101                $tableau = array();
102                $this->type = strtolower($this->command['from'][0]);
103
104                // on ne garde pas les where vides
105                $this->command['where'] = array_values(array_filter($this->command['where']));
106
107                // Critere {liste X1, X2, X3}
108                if (isset($this->command['liste'])) {
109                        $this->select_liste();
110                }
111
112                // demande sortie du cache ou recalculee
113                $cle = $this->creer_cle_cache();
114                if ($cache = $this->use_cache($cle)) {
115                        // attention, il faut recalculer les filtres
116                        // qui sont a supprimer de la boucle
117                        // sinon l'usage du critere {rechercher} meurt en changeant de pagination :)
118                        if ($exceptions = $this->use_cache($cle . '-filtres')) {
119                                foreach ($exceptions as $ex) {
120                                        $this->exception_des_criteres($ex);
121                                }
122                        }
123                        $this->tableau = $cache;
124                } else {
125                        $select = charger_fonction($this->type . '_select', 'inc', true);
126                        $this->tableau = $select($this->command, $this);
127
128                        // cache d'une heure par defaut.
129                        $ttl = isset($this->command['datacache']) ? $this->command['datacache'] : 3600;
130                       
131                        if (is_array($this->tableau) AND $ttl>0) {
132                                $this->cache_set($cle, $ttl);
133                                $this->cache_set($cle.'-filtres', $ttl, $this->exception_des_criteres());
134                        }
135                }
136
137
138                // Si a ce stade on n'a pas de table, il y a un bug
139                if (!is_array($this->tableau)) {
140                        $this->err = true;
141                        spip_log("erreur datasource ".$src);
142                }
143
144
145                // tri {par x}
146                if ($this->command['orderby']) {
147                        $this->select_orderby();
148                }
149
150                // grouper les resultats {fusion /x/y/z} ;
151                if ($this->command['groupby']) {
152                        $this->select_groupby();
153                }
154
155                $this->rewind();
156                #var_dump($this->tableau);
157        }
158
159
160        /**
161         * Retourne les donnees en caches
162         * pour la boucle demandees
163         * si elles existent et ne sont
164         * pas perimees
165         *
166        **/
167        protected function use_cache($cle) {
168
169                $cache = $this->cache_get($cle);
170
171                // Time to live
172                if (isset($this->command['datacache'])) {
173                        $ttl = intval($this->command['datacache']);
174                }
175               
176                if ($cache AND ($cache['time'] + (isset($ttl) ? $ttl : $cache['ttl']) > time())
177                AND !(_request('var_mode') === 'recalcul' AND include_spip('inc/autoriser') AND autoriser('recalcul'))) {
178                        return $cache['data'];
179                }
180
181                return false;
182        }
183
184
185        /**
186         * Cree une cle unique
187         * pour sauvegarder une analyse de donnees
188         * basee sur les criteres de boucle demandes
189         *
190        **/
191        protected function creer_cle_cache() {
192                $cle = $this->command;
193                $cle['from'][0] = $this->type; 
194                unset($cle['id']); // pas le nom de la boucle
195                $cle = md5(serialize($cle));
196                return $cle;
197        }
198}
199
200
201
202/**
203 * Passer une liste d'identifiants a l'iterateur PMB
204 * (PMB:NOTICES){liste 1,3}
205 *
206 * @param string $idb
207 * @param object $boucles
208 * @param object $crit
209 */
210function critere_PMB_liste_dist($idb, &$boucles, $crit) {
211        return critere_DATA_liste_dist($idb, $boucles, $crit);
212}
213
214
215/**
216 * Modifier la duree du cache des boucles PMB
217 * par defaut a 1 heure (si memoization actif)
218 * {datacache 3600}
219 *
220 * @param string $idb
221 * @param object $boucles
222 * @param object $crit
223 */
224function critere_PMB_datacache_dist($idb, &$boucles, $crit) {
225        return critere_DATA_datacache_dist($idb, $boucles, $crit);
226}
227
228/**
229 * Modifier le critere racine
230 */
231function critere_PMB_racine_dist($idb, &$boucles, $crit) {
232        $c = array("'='", "racine", 1);
233        $boucles[$idb]->where[] = $c;
234}
235
236/**
237 * Modifier le critere id_parent pour la boucle PMB:SECTIONS
238 */
239function critere_PMB_SECTIONS_id_parent_dist($idb, &$boucles, $crit) {
240        $id_section = kwote(calculer_argument_precedent($idb, 'id_section', $boucles));
241        $c = array("'='", "id_parent", $id_section);
242        $boucles[$idb]->where[] = $c;
243}
244
245/**
246 *
247 * Selectionne les notices demandees
248 * et retourne un tableau des elements parsees
249 *
250 * Une ou n notices
251 * (PMB:NOTICES) {id}
252 * (PMB:NOTICES) {id_notice}
253 * (PMB:NOTICES) {liste #TABLEAU_IDS}
254 *
255 * Notices lies a celle(s) donnees
256 * (PMB:NOTICES) {id} {autres_lectures}
257 * (PMB:NOTICES) {liste #TABLEAU_IDS} {autres_lectures}
258 *
259 * Notices issues des syndications d'articles
260 * (PMB:NOTICES) {nouveautes}
261 *
262 * Notices issues des auteurs
263 * (PMB:NOTICES) {id_auteur}
264 *
265 * Notices issues des recherches
266 * (PMB:NOTICES) {rechercher}
267 * (PMB:NOTICES) {rechercher}{look ?}{id_section ?}{id_location ?}{id_location_memo ?}
268 *
269 */
270function inc_pmb_notices_select_dist(&$command, $iterateur) {
271        $criteres = $command['where'];
272
273        // on peut fournir une liste l'id
274        // ou egalement un critere id=x
275        $ids = array();
276
277        // depuis une liste
278        if (is_array($command['liste']) and count($command['liste'])) {
279                $ids = $command['liste'];
280        }
281
282        // depuis un critere id=x ou {id?}
283        // a supprimer ?
284        if ($id = pmb_critere_valeur($criteres, 'id')) {
285                $ids = pmb_intersect_ids($ids, $id);
286        }
287
288        // depuis un critere id_notice=x ou {id_notice?}
289        if ($id = pmb_critere_valeur($criteres, 'id_notice')) {
290                $ids = pmb_intersect_ids($ids, $id);
291        }
292
293        // autres lecteurs : ceux qui ont lu ceci ont aussi emprunte cela
294        if (pmb_recherche_critere($criteres, 'autres_lecteurs')) {
295                $ids = pmb_ids_notices_autres_lecteurs($ids);
296        }
297
298        // nouveautes de la syndication
299        if (pmb_recherche_critere($criteres, 'nouveautes')) {
300                // prendra 50 nouveautes par defaut...
301                // sauf si {nouveautes 3}
302                // /!\ ça ne recupere que 3, pas #ENV{nb,3}, peut etre parce
303                // que c'est le premier argument d'un critere (limitation connue de SPIP).
304                // on peut utiliser : {nouveautes 3}{0,#ENV{nb,3}} pour limiter entre 1 et 3 donc.
305                $nombre = pmb_interprete_argument_critere($criteres, 'nouveautes', 1);
306                $idsn = pmb_ids_notices_nouveautes('', $nombre);
307                $ids = pmb_intersect_ids($ids, $idsn);
308        }
309
310        // id_auteur :     trouver les notices d'un auteur
311        // id_collection : trouver les notices d'une collection
312        // id_editeur :    trouver les notices d'un editeur
313        foreach (array(
314                'auteurs' => 'id_auteur',
315                'collections' => 'id_collection',
316                'editeurs' => 'id_editeur') as $objet => $_id_objet)
317        {
318                if ($ids_objet = pmb_critere_valeur($criteres, $_id_objet)) {
319                        $pmb_extraire_objet_ids = 'pmb_extraire_' . $objet . '_ids';
320                        $objets = $pmb_extraire_objet_ids($ids_objet);
321                        if ($objets) {
322                                $n = array();
323                                foreach ($objets as $o) {
324                                        $n = array_unique(array_merge($n, $o['ids_notice']));
325                                }
326                                $ids = pmb_intersect_ids($ids, $n);
327                        }
328                        unset($objets);
329                }
330        }
331
332
333        // recherche de notices
334        if (pmb_recherche_critere($criteres, 'rechercher')) {
335                // valeur cherchee (parametre)
336                $recherche = pmb_interprete_argument_critere($criteres, 'rechercher', 1);
337                // valeur cherchee (env)
338                if (!$recherche) {
339                        $recherche = pmb_critere_valeur($criteres, 'rechercher');
340
341                        // le premier trouve...
342                        if ($recherche) {
343                                $recherche = array_shift($recherche);
344                        }
345                }
346
347                if (!$recherche) {
348                        $recherche = '';
349                }
350                $iterateur->exception_des_criteres('rechercher');
351
352                $total_resultats = 0; // sera renseigne par la fonction de recherche
353                $demande = array('recherche' => $recherche);
354               
355                // on prend au debut, et on limite la recherche a 100 elements
356                $debut = '0'; $nombre = '5';
357
358                // si la boucle contient une limite {0,50}
359                if ($command['limit']) {
360                        list($debut, $nombre) = explode(',', $command['limit']);
361                }
362               
363                // si la boucle contient une pagination {pagination 5}
364                // on retrouve les valeurs de position et de pas, et on pose un
365                // flag 'pagination' pour un hack sur la recherche
366                // permettant de ne pas demander tous les resultats
367                // mais seulement ceux a afficher dans le cadre en cours
368                $pagination = false;
369                if ($command['pagination']) {
370                        list($debut, $nombre) = $command['pagination'];
371                        if (!$debut) $debut = 0;
372                        $pagination = true;
373                }
374
375                // on affine notre demande avec d'autres contraintes si elles sont presentes.
376                foreach (array(
377                        'id_section' => 'id_section',
378                        'id_section_memo' => 'id_section_parent',
379                        'id_location_memo' => 'id_location',
380                        'id_location' => 'id_location',
381                        'look' => 'look') as $nom=>$requete)
382                {
383                        if ($valeurs = pmb_critere_valeur($criteres, $nom)) {
384                                $iterateur->exception_des_criteres($nom);
385                                // on ajoute le premier venu...
386                                // sauf pour look, où on veut toutes les valeurs...
387                                if ($nom == 'look') {
388                                        $demande[$requete] = $valeurs;
389                                } else {
390                                        $demande[$requete] = array_shift($valeurs);
391                                }
392                        }
393                }
394
395                $idsr = pmb_ids_notices_recherches($demande, $total_resultats, $debut, $nombre, $pagination);
396                $ids = pmb_intersect_ids($ids, $idsr);
397                $iterateur->total = $total_resultats;
398
399        }
400
401        // retourner les notices selectionnees
402        $res = pmb_extraire_notices_ids($ids);
403       
404        return $res;
405}
406
407
408
409
410/**
411 *
412 * Selectionne un ou plusieurs auteurs PMB
413 * et retourne un tableau des elements parsees
414 *
415 * Un auteur
416 * (PMB:AUTEURS) {id_auteur}
417 *
418 * Des auteurs
419 * (PMB:AUTEURS) {liste #TABLEAU_IDS_AUTEUR}
420 *
421 */
422function inc_pmb_auteurs_select_dist(&$command, $iterateur) {
423        return inc_pmb_select_abstract_dist($command, $iterateur, 'auteurs', 'id_auteur');
424}
425
426
427/**
428 *
429 * Selectionne les reservations d'un ou plusieurs auteurs identifies a PMB
430 * et retourne un tableau des elements parsees
431 *
432 * Liste des reservations
433 * (PMB:RESERVATIONS) {pmb_session}
434 * (PMB:RESERVATIONS) {liste #TABLEAU_PMB_SESSIONS}
435 *
436 */
437function inc_pmb_reservations_select_dist(&$command, $iterateur) {
438        return inc_pmb_select_abstract_dist($command, $iterateur, 'reservations', 'pmb_session');
439}
440
441
442/**
443 *
444 * Selectionne les prets d'un ou plusieurs auteurs identifies a PMB
445 * et retourne un tableau des elements parsees
446 *
447 * Liste des prets
448 * (PMB:PRETS) {pmb_session}{type=0} // en retard // todo : ameliorer le nom du critere type :p
449 * (PMB:PRETS) {pmb_session}{type=1} // en cours
450 * (PMB:PRETS) {liste #TABLEAU_PMB_SESSIONS}
451 *
452 */
453function inc_pmb_prets_select_dist(&$command, $iterateur) {
454        $criteres = $command['where'];
455       
456        // on peut fournir une liste l'id
457        // ou egalement un critere id=x
458        $ids = array();
459
460        // depuis une liste
461        if (is_array($command['liste']) and count($command['liste'])) {
462                $ids = $command['liste'];
463        }
464
465        // depuis un critere pmb_session=x ou {pmb_session?}
466        if ($id = pmb_critere_valeur($criteres, 'pmb_session')) {
467                $iterateur->exception_des_criteres('pmb_session'); 
468                $ids = pmb_intersect_ids($ids, $id);
469        }
470
471        $type = 0;
472        // {type=1}
473        if ($types = pmb_critere_valeur($criteres, 'type')) {
474                $iterateur->exception_des_criteres('type');
475                // le premier trouve...
476                $type = array_shift($types);
477        }
478
479        // retourner les objets selectionnees
480        $res = pmb_extraire_prets_ids($ids, $type);
481
482        return $res;
483}
484
485
486/**
487 *
488 * Selectionne une ou plusieurs collections PMB
489 * et retourne un tableau des elements parsees
490 *
491 * Une collection
492 * (PMB:COLLECTIONS) {id_collection}
493 *
494 * Des collections
495 * (PMB:COLLECTIONS) {liste #TABLEAU_IDS_COLLECTION}
496 *
497 */
498function inc_pmb_collections_select_dist(&$command, $iterateur) {
499        return inc_pmb_select_abstract_dist($command, $iterateur, 'collections', 'id_collection');
500}
501
502
503
504/**
505 *
506 * Selectionne une ou plusieurs editeurs PMB
507 * et retourne un tableau des elements parsees
508 *
509 * Un editeur
510 * (PMB:EDITEURS) {id_editeur}
511 *
512 * Des editeurs
513 * (PMB:EDITEURS) {liste #TABLEAU_IDS_EDITEUR}
514 *
515 */
516function inc_pmb_editeurs_select_dist(&$command, $iterateur) {
517        return inc_pmb_select_abstract_dist($command, $iterateur, 'editeurs', 'id_editeur');
518}
519
520
521
522/**
523 *
524 * Selectionne les exemplaires disponibles d'une notice
525 * et retourne un tableau des elements parsees
526 *
527 * Liste des exemplaires
528 * (PMB:EXEMPLAIRES) {id_notice}
529 * (PMB:EXEMPLAIRES) {liste #TABLEAU_IDS_NOTICE}
530 *
531 */
532function inc_pmb_exemplaires_select_dist(&$command, $iterateur) {
533        return inc_pmb_select_abstract_dist($command, $iterateur, 'exemplaires', 'id_notice');
534}
535
536
537
538/**
539 *
540 * Selectionne les documents d'une ou plusieurs notices
541 * et retourne un tableau des elements parsees
542 *
543 * Liste des documents
544 * (PMB:DOCUMENTS) {id_notice}
545 * (PMB:DOCUMENTS) {id_notice}{image=oui} // s'appuie sur le mime type image/
546 * (PMB:DOCUMENTS) {id_notice}{image=non}
547 *
548 */
549function inc_pmb_documents_select_dist(&$command, $iterateur) {
550        // comme boucle_PMB_DOCUMENTS() ne fonctionne pas
551        // on annule certains criteres passes par boucle_DOCUMENTS() de mediatheque
552        $iterateur->exception_des_criteres('.mode'); // hum le .
553        $iterateur->exception_des_criteres('.taille'); // hum le .
554        return inc_pmb_select_abstract_dist($command, $iterateur, 'documents', 'id_notice');
555}
556
557
558
559
560/**
561 * Editeurs, auteurs et collections sont les memes principes
562 * on les regroupe dans une fonction d'abstraction...
563 *
564 * @param array $command
565 *              Le tableau command de l'iterateur
566 *
567 * @param array $iterateur
568 *              L'iterateur complet
569 *
570 * @param string $objet
571 *              Le nom de l'objet (pluriel) ex:auteurs
572 *
573 * @param string $_id_objet
574 *              Le nom de l'identifant de l'objet 'id_auteur'
575**/ 
576//
577function inc_pmb_select_abstract_dist(&$command, $iterateur, $objet, $_id_objet) {
578        $criteres = $command['where'];
579       
580        // on peut fournir une liste l'id
581        // ou egalement un critere id=x
582        $ids = array();
583
584        // depuis une liste
585        if (is_array($command['liste']) and count($command['liste'])) {
586                $ids = $command['liste'];
587        }
588
589        // depuis un critere id_objet=x ou {id_objet?}
590        if ($id = pmb_critere_valeur($criteres, $_id_objet)) {
591                $ids = pmb_intersect_ids($ids, $id);
592                // pas la peine de filtrer dessus... surtout pour {pmb_session} qui n'y est plus ensuite
593                $iterateur->exception_des_criteres($_id_objet);
594        }
595
596        // retourner les objets selectionnees
597        $pmb_extraire_ids = 'pmb_extraire_' . $objet . '_ids';
598        $res = $pmb_extraire_ids($ids);
599
600        return $res;
601}
602
603
604
605
606/**
607 *
608 * Selectionne les lieux de classement des notices
609 * et retourne un tableau des elements parsees
610 * Un lieu est au sens PMB "location"
611 *
612 * - Location : c'est comme un centre de doc physique, une adresse.
613 *              1 PMB permet de gérer plusieurs Locations. On peut dire
614 *              qu'il permet de gérer un groupement de bibliotheques/centre de docs.
615 *
616 * - Section : C'est comme un rayonnage de centre de doc. Un theme de classement en quelque sorte.
617 *              Une section est independante d'une location, au sens ou une meme section
618 *              peut être presente sur plusieurs locations.
619 *
620 * En SPIP, on pourrait dire que
621 * - Location = rubriques racines,
622 * - Sections = Groupes de mots clés (hierarchiques)
623 *
624 * Les centres de docs a la racine
625 * (PMB:LIEUX)
626 * (PMB:LIEUX) {racine}
627 *
628 * (PMB:LIEUX) {id_location}
629 *
630 */
631function inc_pmb_lieux_select_dist(&$command, $iterateur) {
632        $criteres = $command['where'];
633
634        // racine indique... on ne s'occupe pas du reste...
635        // depuis un critere {racine}
636        /*
637        if (pmb_recherche_critere($criteres, 'racine')) {
638                // retourner les auteurs selectionnees
639                $iterateur->exception_des_criteres('racine');
640                return pmb_extraire_locations_racine();
641        }*/
642       
643        $res = pmb_extraire_locations_racine();
644
645        if (pmb_recherche_critere($criteres, 'id_location')) {
646                if (!$ids_location = pmb_critere_valeur($criteres,  'id_location')) {
647                        return array();
648                }
649
650                $iterateur->exception_des_criteres('id_location');
651                foreach ($res as $c => $l) {
652                        if (!in_array($l['id_location'], $ids_location)) {
653                                unset($res[$c]);
654                        }
655                }
656                $res = array_values($res);
657        }
658
659
660
661        return $res;
662}
663
664
665
666
667/**
668 *
669 * Selectionne les themes (sections) de classement des notices
670 * et retourne un tableau des elements parsees
671 * Un lieu est au sens PMB "location"
672 *
673 * Les centres de docs a la racine
674 * (PMB:SECTIONS)
675 * (PMB:SECTIONS) {id_section ?} // la section
676 * (PMB:SECTIONS) {id_parent ?}  // sections enfants
677 * (PMB:SECTIONS) {id_location ?} // sections dans le lieu...
678 *
679 */
680function inc_pmb_sections_select_dist(&$command, $iterateur) {
681        $criteres = $command['where'];
682
683        // on peut fournir une liste l'id
684        // ou egalement un critere id=x
685        $ids = array();
686
687        // depuis une liste
688        if (is_array($command['liste']) and count($command['liste'])) {
689                $ids = $command['liste'];
690        }
691
692        // depuis un critere id_section=x ou {id_section ?}
693        if ($id = pmb_critere_valeur($criteres, 'id_section')) {
694                $ids = pmb_intersect_ids($ids, $id);
695        }
696
697        // testons la presence de id_parent (un id_section) ou id_location
698        if ($ids_parents = pmb_critere_valeur($criteres,  'id_parent')) {
699                $iterateur->exception_des_criteres('id_parent');
700                $sections = pmb_extraire_sections_depuis_sections_ids($ids_parents);
701                return $sections;
702        }
703
704        if ($ids_location = pmb_critere_valeur($criteres,  'id_location')) {
705                $iterateur->exception_des_criteres('id_location');
706                $sections = pmb_extraire_sections_depuis_locations_ids($ids_location);
707                return $sections;
708        }
709
710        return pmb_extraire_sections_ids($ids);
711}
712
713
714
715
716// retourne l'intersection des ids trouves
717// equivalent {...} AND {...}
718function pmb_intersect_ids($anciens, $nouveaux) {
719        if ($anciens) {
720                return array_intersect($anciens, $nouveaux);
721        }
722        return $nouveaux;
723}
724
725/**
726 * Obtenir les identifiants de nouveautes
727 * issues des syndications
728 * @return array liste des identifiants de notices trouvees
729**/
730function pmb_ids_notices_nouveautes($debut, $nombre) {
731        $contexte = array();
732        if (!$debut) {
733                $debut = 0;
734        }
735        $contexte['debut'] = $debut;
736        if ($nombre) {
737                $contexte['nombre'] = $nombre;
738        }
739        $ids = explode(',', trim(recuperer_fond('public/pmb_nouveautes', $contexte)));
740        return $ids;
741}
742
743
744
745/**
746 * Recuperer un critere dans le tableau where selon une contrainte.
747 *
748 * @return array, un element par valeur trouvee
749**/
750function pmb_critere_valeur($criteres, $cle, $op = '=') {
751        $res = array();
752        if (!is_array($criteres) OR !$criteres) {
753                return $res;
754        }
755        foreach ($criteres as $c) {
756                if (is_array($c) AND $c[0] == $op AND $c[1] == $cle) {
757                        // enlever les guillemets si presents
758                        $v = $c[2];
759                        if (($v[0] == "'") and ($v[ count($v)-1 ] == "'")) {
760                                $v = substr($v, 1,-1);
761                        }
762                        $res[] = $v;
763                // ((machin IN ('34','TRUC'))) // magnifique :/
764                // ((look  IN ('PMB','FIRSTACCESS','ALL')))
765                } elseif (is_string($c)) {
766                        // cf iterateurs->calculer_filtres()
767
768                        $op = $c;
769                       
770                        // traiter {cle IN a,b} ou {valeur !IN a,b}
771                        // prendre en compte le cas particulier de sous-requetes
772                        // produites par sql_in quand plus de 255 valeurs passees a IN
773                        if (preg_match_all(',\s+IN\s+(\(.*\)),', $op, $s_req)) {
774                                $req = '';
775                                foreach($s_req[1] as $key => $val) {
776                                        $req .= trim($val, '(,)') . ',';
777                                }
778                                $req = '(' . rtrim($req, ',') . ')';
779                        }
780                        if (preg_match(',^\(\(([\w/]+)(\s+NOT)?\s+IN\s+(\(.*\))\)(?:\s+(AND|OR)\s+\(([\w/]+)(\s+NOT)?\s+IN\s+(\(.*\))\))*\)$,', $op, $regs)) {
781                                // 1 'look'
782                                // 2 NOT
783                                // 3 ('TRUC','CHOSE')
784                                if ($regs[1] == $cle and !$regs[2]) {
785                                        $v = explode(',', trim($regs[3], ' ()'));
786                                        // enlever tous les guillemets entourants
787                                        foreach($v as $a=>$b) { $v[$a] = trim($b, "'"); }
788                                        // comme c'est deja un tableau, on le merge aux resultats deja obtenus
789                                        $res = array_unique(array_merge($res, $v));
790                                }
791                        }
792
793                }
794        }
795        // on enleve les valeurs vides ''
796        $res = array_filter($res);
797        return $res;
798}
799
800
801/**
802 * Chercher la presence d'un critere dans le tableau where.
803 *
804 * @return bool vrai si critere trouve.
805**/
806function pmb_recherche_critere($criteres, $cle) {
807        if (!is_array($criteres) OR !$criteres OR !$cle) {
808                return false;
809        }
810        foreach ($criteres as $c) {
811                // {c}   =>  array('=', 'c', '')
812                // {c=3} =>  array('=', 'c', '3')
813                // {c 3} =>  array('c', '3')
814                if (is_array($c) AND ($c[1] == $cle OR $c[0] == $cle)) {
815                        return true;
816                }
817        }
818        return false;
819}
820
821
822/**
823 * Chercher la valeur d'un parametre dans un critere
824 * {critere un,deux}
825 *
826 * @return mixed, valeur trouvee, sinon null
827**/
828function pmb_interprete_argument_critere($criteres, $cle, $index) {
829        if (!is_array($criteres) OR !$criteres) {
830                return null;
831        }
832        foreach ($criteres as $c) {
833                // {c 3} =>  array('c', '3')
834                if (is_array($c) AND ($c[0] == $cle)) {
835                        if (isset($c[$index])) {
836                                return $c[$index];
837                        }
838                }
839        }
840        return null;
841}
842
843
844
845/**
846 * Boucle PMB:DOCUMENTS
847 * Éviter les traitements automatiques de SPIP sur les boucles Documents
848**/
849function boucle_PMB_DOCUMENTS($id_boucle, &$boucles) {
850        return calculer_boucle($id_boucle, $boucles);
851}
852
853/**
854 *
855 * Critere d'extraction des nouveautes de PMB
856 *
857 * (SYNDIC_ARTICLES){pmb_notices}
858 * (SYNDIC_ARTICLES){!pmb_notices}
859 *
860 * Recherche dans les syndications les articles
861 * ce qui concerne des notices PMB...
862 *
863**/
864function critere_SYNDIC_ARTICLES_pmb_notices($idb, &$boucles, $crit) {
865        $boucle = &$boucles[$idb];
866        $prim = $boucle->primary;
867        $table = $boucle->id_table;
868       
869        $c = array("'REGEXP'", "'$table.url'", "sql_quote('notice_display')");
870
871        if ($crit->not) {
872                $c = array("'NOT'", $c);
873        }
874       
875        $boucle->where[] = $c;
876}
877
878
879/**
880 * Balise #URL_PMB_NOTICE et #URL_PMB_NOTICE{18}
881**/
882function balise_URL_PMB_NOTICE_dist($p) {
883        return pmb_balise_url($p, 'id_notice', 'pmb_notice');
884}
885
886
887/**
888 * Balise #URL_PMB_COLLECTION et #URL_PMB_COLLECTION{18}
889**/
890function balise_URL_PMB_COLLECTION_dist($p) {
891        return pmb_balise_url($p, 'id_collection', 'pmb_collection');
892}
893
894
895/**
896 * Balise #URL_PMB_EDITEUR et #URL_PMB_EDITEUR{18}
897**/
898function balise_URL_PMB_EDITEUR_dist($p) {
899        return pmb_balise_url($p, 'id_editeur', 'pmb_editeur');
900}
901
902/**
903 * Balise #URL_PMB_AUTEUR et #URL_PMB_AUTEUR{18}
904**/
905function balise_URL_PMB_AUTEUR_dist($p) {
906        return pmb_balise_url($p, 'id_auteur', 'pmb_auteur');
907}
908
909/**
910 * Balise URL_PMB_NOUVEAUTES
911**/
912function balise_URL_PMB_NOUVEAUTES_dist($p) {
913        $page = 'pmb_nouveautes';
914        $p->code = "generer_url_public('$page')";
915        $p->interdire_scripts = false;
916        return $p;
917}
918
919/**
920 * Balise URL_PMB_COMPTE
921**/
922function balise_URL_PMB_COMPTE_dist($p) {
923        $page = 'pmb_compte';
924        $p->code = "generer_url_public('$page')";
925        $p->interdire_scripts = false;
926        return $p;
927}
928
929/**
930 * Balise URL_PMB_RECHERCHE
931**/
932function balise_URL_PMB_RECHERCHE_dist($p) {
933        $page = 'pmb_recherche';
934        $p->code = "generer_url_public('$page')";
935        $p->interdire_scripts = false;
936        return $p;
937}
938
939
940/**
941 * Balise URL_PMB_CATALOGUE
942 * et #URL_PMB_CATALOGUE{#ID_LOCATION}
943**/
944function balise_URL_PMB_CATALOGUE_dist($p) {
945        $page = 'pmb_catalogue';
946        if ($id_location = interprete_argument_balise(1, $p)) {
947                $p->code = "parametre_url(generer_url_public('$page'), 'id_location', $id_location)";
948        } else {
949                $p->code = "generer_url_public('$page')";
950        }
951        $p->interdire_scripts = false;
952        return $p;
953}
954
955
956
957function pmb_balise_url($p, $champ, $page) {
958        if (!$id = interprete_argument_balise(1, $p)) {
959                $id = champ_sql($champ, $p);
960        }
961
962        $p->code = "(($id) ? generer_url_public('$page', '$champ='.$id) : '')";
963        $p->interdire_scripts = false;
964        return $p;
965}
966
967
968/**
969 * Pour afficher dans une boucle notices avec {pagination}
970 * "Résultats de x à y sur z ouvrages"
971**/
972function balise_PMB_NOMBRE_RESULTATS_dist($p) {
973        $b = $p->nom_boucle ? $p->nom_boucle : $p->descr['id_mere'];
974       
975        $pas = $p->boucles[$b]->total_parties;
976        $type = $p->boucles[$b]->modificateur['debut_nom'];
977        $nb = "(isset(\$Numrows['$b']['grand_total']) ? \$Numrows['$b']['grand_total'] : \$Numrows['$b']['total'])";
978
979        $p->boucles[$b]->numrows = true;
980        $p->code = "recuperer_fond('inclure/inc-pmb-nombre-resultats', array(
981                'resultats' => $nb,
982                'debut' => _request('debut' . $type),
983                'fin' => $pas))";
984        return $p;
985}
986
987?>
Note: See TracBrowser for help on using the repository browser.