source: spip-zone/_plugins_/albums/trunk/autocomplete_albums_fonctions.php @ 83580

Last change on this file since 83580 was 83580, checked in by tcharlss@…, 6 years ago

Filtres de l'albumothèque : squelette qui fournit une liste d'objets pour l'autocomplétion des champs de recherche.
D'ailleurs, il s'agit d'un squelette générique qui peut être ré-utilisé ailleurs : on peut chercher n'importe quel type d'objet, en fonction de ses liens avec d'autres objets et d'un terme de recherche.
Cf. notes dans les 2 fichiers.

File size: 7.1 KB
Line 
1<?php
2/**
3 * Fonctions utiles au squelette «autocomplete_albums»
4 *
5 * @plugin     Albums
6 * @copyright  2014
7 * @author     Romy Tetue, Charles Razack
8 * @licence    GNU/GPL
9 * @package    SPIP\Albums\Fonctions
10 */
11
12// Sécurité
13if (!defined('_ECRIRE_INC_VERSION')) return;
14
15/**
16 * Retourne une liste d'objets, correspondants éventuellement à un terme de recherche.
17 *
18 * On peut restreindre la sélection en fonction des liaisons avec un autre type d'objet.
19 * Si un terme est donné, on cherche les occurences dans 2 champs :
20 *
21 * - le champ servant de clé primaire id_xxx.
22 * - le champ contenant le titre tel que défini dans la déclaration de la table,
23 *   ou un champ spécifique donné en argument.
24 *
25 * @example
26 *
27 * - Albums avec `toto` dans le titre :
28 *   `...autocomplete('album','','','toto')`
29 * - Articles avec `toto` dans le titre et ayant des albums liés :
30 *   `...autocomplete('article','album',true,'toto')`
31 * - Auteurs ayant `toto` dans leur email et liés à des albums :
32 *   `...autocomplete('auteur','album','','toto','email')`
33 * - Mot-clés liés à des albums :
34 *   `...autocomplete('mot','album')`
35 *
36 * @param string $type
37 *     Type d'objet recherché
38  * @param string $type2
39 *     Type d'objet lié
40 * @param bool $pivot2
41 *     `true` pour définir l'objet secondaire comme pivot.
42 *     Le pivot est l'objet qui porte la table de liens
43 *     dont on se sert pour récupérer les liaisons.
44 *     Par défaut on cherche dans la table de liens de l'objet principal.
45 * @param string $term
46 *     Terme de recherche (optionnel)
47 * @param string $champ
48 *     Champ spécial dans lequel le terme doit être recherché.
49 *     Par défaut, on cherche dans le champ correspondant au titre de l'objet,
50 *     tel que précisé dans la déclaration de la table sql.
51 * @param int|string $nb
52 *     Nombre maximal de résultats, 20 par défaut.
53 * @return array
54 *     tableau contenant une sélection des objets avec leur identifiant et leur titre.
55 */
56function filtre_albums_autocomplete($type='',$type2='',$pivot2=false,$terme='',$champ='',$nb=''){
57
58        // vérifications préliminaires
59        if (
60                (!$type = objet_info($type,'type')) // type d'objet valide
61                OR ($type2 AND !$type2 = objet_info($type2,'type')) // type d'objet secondaire valide
62        )
63                return;
64
65        // Objet principal (celui recherché)
66        $table_objet_sql = table_objet_sql($type); // ex. spip_mots
67        $table_objet = table_objet($type); // ex. mots
68        // champ contenant le titre d'après la déclaration sql de la table (une chaîne du genre «titre, '' AS lang»)
69        $champ_titre = objet_info($type,'titre');
70        // champ utilisé pour la recherche : s'il est donné on vérifie qu'il est valide, sinon on prend le champ de titre
71        $champ = ($champ and in_array($champ,array_keys(objet_info($type,'field')))) ? $champ.' AS titre' : $champ_titre;
72        // nombre maximal de résultats
73        if (!intval($nb) OR is_null($nb)) $nb = 20;
74        else $nb = intval($nb);
75
76        // Objet secondaire (optionnel)
77        if ($type2) {
78                $table_objet_sql2 = table_objet_sql($type2);
79                $table_objet2 = table_objet($type2);
80        }
81
82        // En fonction du pivot qui porte les liens, on fait des requêtes différentes.
83        // Comme on ne peut pas utiliser l'alias «titre» du SELECT dans le WHERE,
84        // on fait des sous-requêtes.
85        $pivot = ($type2) ? ($pivot2) ? 'secondaire' : 'principal' : '';
86        $res = array();
87        switch ($pivot){
88
89                /*
90                1) pas de pivot : on cherche des `$type` tout simplement
91                exemple: des albums...
92                SELECT titre,id
93                FROM (
94                        SELECT id_album AS id, titre, lang AS lang
95                        FROM spip_albums
96                ) sub
97                WHERE sub.titre LIKE '%terme%'
98                */
99                case '':
100                        // clé primaire de l'objet (id_xxx)
101                        $id_table_objet = id_table_objet($type);
102                        // préparer la requête
103                        $alias = 'sub'; // alias de la sous-requête
104                        $select = array(
105                                "$id_table_objet AS id",
106                                $champ
107                        );
108                        $from = $table_objet_sql;
109                        $getselect = '('.sql_get_select($select, $from).') '.$alias;
110                        if ($terme) {
111                                $where[] = ($id=intval($terme)) ?
112                                        array('OR', "$alias.titre LIKE ".sql_quote("%$terme%"), "$alias.id=".$id)
113                                        : "$alias.titre LIKE ".sql_quote("%$terme%");
114                        }
115                        $groupby = "id";
116                        $orderby = '';
117                        $limit = "0,$nb";
118                        $res = sql_allfetsel('titre,id',$getselect,$where,$groupby,$orderby,$limit);
119                        //var_dump(sql_allfetsel('titre,id',$getselect,$where,'','','','','',false));
120                        break;
121
122                /*
123                2) l'objet principal sert de pivot : on cherche des `$type` liés à des `$type2`
124                exemple: auteurs liés à des albums
125                SELECT titre,id
126                FROM (
127                        SELECT T1.id_auteur AS id, nom AS titre, '' AS lang
128                        FROM spip_auteurs AS T1
129                        INNER JOIN spip_auteurs_liens AS L1 ON (L1.id_auteur = T1.id_auteur)
130                        WHERE L1.objet = 'album'
131                ) sub
132                WHERE sub.titre LIKE '%terme%'
133                */
134                case 'principal':
135                        // clé primaire de l'objet (id_xxx) et sa table de liens
136                        include_spip('action/editer_liens');
137                        if (!$a = objet_associable($type)) return;
138                        list($id_table_objet, $table_objet_sql_liens) = $a;
139                        // préparer la requête
140                        $alias = 'sub'; // alias de la sous-requête
141                        $select = array(
142                                "T1.$id_table_objet AS id",
143                                $champ
144                        );
145                        $from = "$table_objet_sql AS T1"
146                                ." INNER JOIN $table_objet_sql_liens AS L1"
147                                ." ON (L1.$id_table_objet = T1.$id_table_objet)";
148                        $where_sub[] = "L1.objet=".sql_quote($type2);
149                        $getselect = '('.sql_get_select($select, $from, $where_sub).') '.$alias;
150                        if ($terme) {
151                                $where[] = ($id=intval($terme)) ?
152                                        array('OR', "$alias.titre LIKE ".sql_quote("%$terme%"), "$alias.id=".$id)
153                                        : "$alias.titre LIKE ".sql_quote("%$terme%");
154                        }
155                        $groupby = "id";
156                        $orderby = '';
157                        $limit = "0,$nb";
158                        // requête
159                        $res = sql_allfetsel('titre,id',$getselect,$where,$groupby,$orderby,$limit);
160                        //var_dump(sql_allfetsel('titre,id',$getselect,$where,'','','','','',false));
161                        break;
162 
163                /*
164                3) l'objet secondaire sert de pivot : on cherche des `$type` auxquels sont liés des `$type2`
165                exemple: articles auxquels sont liés des albums
166                SELECT titre,id
167                FROM (
168                        SELECT T1.id_article AS id, titre, lang
169                        FROM spip_articles AS T1
170                        INNER JOIN spip_albums_liens AS L2 ON ( L2.objet = 'article' AND L2.id_objet = T1.id_article )
171                ) sub
172                WHERE sub.titre LIKE '%terme%'
173                */
174                case 'secondaire':
175                        // clé primaire de l'objet (id_xxx) et sa table de liens
176                        include_spip('action/editer_liens');
177                        if (!$a = objet_associable($type2)) return;
178                        list($id_table_objet2, $table_objet_sql_liens2) = $a;
179                        $id_table_objet = id_table_objet($type);
180                        // préparer la requête
181                        $alias = 'sub'; // alias de la sous-requête
182                        $select = array(
183                                "T1.$id_table_objet AS id",
184                                $champ
185                        );
186                        $from = "$table_objet_sql AS T1"
187                                ." INNER JOIN $table_objet_sql_liens2 AS L2"
188                                ." ON ( L2.objet = ".sql_quote($type)." AND L2.id_objet = T1.$id_table_objet )";
189                        $getselect = '('.sql_get_select($select, $from).') '.$alias;
190                        if ($terme) {
191                                $where[] = ($id=intval($terme)) ?
192                                        array('OR', "$alias.titre LIKE ".sql_quote("%$terme%"), "$alias.id=".$id)
193                                        : "$alias.titre LIKE ".sql_quote("%$terme%");
194                        }
195                        $groupby = "id";
196                        $orderby = '';
197                        $limit = "0,$nb";
198                        // requête
199                        $res = sql_allfetsel('titre,id',$getselect,$where,$groupby,$orderby,$limit);
200                        //var_dump(sql_allfetsel('titre,id',$getselect,$where,'','','','','',false));
201                        break;
202
203        }
204
205        return $res;
206}
207
208?>
Note: See TracBrowser for help on using the repository browser.