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

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

mise à jour du TODO + un soupçon de phpdoc, et up de z

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