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

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

Compat PHP 5.4

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