Make the quicksearch stuff more flexible so it can be used more widely as
[platal.git] / include / userset.inc.php
1 <?php
2 /***************************************************************************
3 * Copyright (C) 2003-2011 Polytechnique.org *
4 * http://opensource.polytechnique.org/ *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., *
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
20 ***************************************************************************/
21
22 class UserSet extends PlSet
23 {
24 public function __construct(PlFilterCondition $cond, $orders = null)
25 {
26 parent::__construct($cond, $orders);
27 }
28
29 protected function buildFilter(PlFilterCondition $cond, $orders)
30 {
31 return new UserFilter($cond, $orders);
32 }
33 }
34
35 class ProfileSet extends PlSet
36 {
37 public function __construct(PlFilterCondition $cond, $orders = null)
38 {
39 parent::__construct($cond, $orders);
40 }
41
42 protected function buildFilter(PlFilterCondition $cond, $orders)
43 {
44 return new ProfileFilter($cond, $orders);
45 }
46 }
47
48 require_once "ufbuilder.inc.php";
49
50 class SearchSet extends ProfileSet
51 {
52 protected $score = null;
53 protected $valid = true;
54
55 public function __construct(UserFilterBuilder $ufb, PlFilterCondition $cond = null)
56 {
57 if (is_null($cond)) {
58 $conds = new PFC_And();
59 } else if ($cond instanceof PFC_And) {
60 $conds = $cond;
61 } else {
62 $conds = new PFC_And($cond);
63 }
64
65 if (!$ufb->isValid()) {
66 $this->valid = false;
67 return;
68 }
69
70 $ufc = $ufb->getUFC();
71 $conds->addChild($ufc);
72
73 $orders = $ufb->getOrders();
74
75 parent::__construct($conds, $orders);
76 }
77
78 public function isValid()
79 {
80 return $this->valid;
81 }
82
83 /** Add a "rechercher=Chercher" field to the query to simulate the POST
84 * behaviour.
85 */
86 public function args()
87 {
88 $args = parent::args();
89 if (!isset($args['rechercher'])) {
90 $args['rechercher'] = 'Chercher';
91 }
92 return $args;
93 }
94
95 protected function &getFilterResults(PlFilter $pf, PlLimit $limit)
96 {
97 $profiles = $pf->getProfiles($limit, Profile::FETCH_MINIFICHES);
98 return $profiles;
99 }
100 }
101
102 // Specialized SearchSet for quick search.
103 class QuickSearchSet extends SearchSet
104 {
105 public function __construct(PlFilterCondition $cond = null)
106 {
107 if (!S::logged()) {
108 Env::kill('with_soundex');
109 }
110
111 parent::__construct(new UFB_QuickSearch(), $cond);
112 }
113 }
114
115 // Specialized SearchSet for advanced search.
116 class AdvancedSearchSet extends SearchSet
117 {
118 public function __construct($xorg_admin_fields, $ax_admin_fields,
119 PlFilterCondition $cond = null)
120 {
121 parent::__construct(new UFB_AdvancedSearch($xorg_admin_fields, $ax_admin_fields),
122 $cond);
123 }
124 }
125
126 /** Simple set based on an array of User objects
127 */
128 class ArraySet extends ProfileSet
129 {
130 public function __construct(array $users)
131 {
132 $hruids = User::getBulkHruid($users, array('User', '_silent_user_callback'));
133 if (is_null($hruids) || count($hruids) == 0) {
134 $cond = new PFC_False();
135 } else {
136 $cond = new UFC_Hruid($hruids);
137 }
138 parent::__construct($cond);
139 }
140 }
141
142 /** A multipage view for profiles
143 * Allows the display of bounds when sorting by name or promo.
144 */
145 abstract class ProfileView extends MultipageView
146 {
147 protected function getBoundValue($obj)
148 {
149 if ($obj instanceof Profile) {
150 switch ($this->bound_field) {
151 case 'name':
152 $name = $obj->name('%l');
153 return strtoupper($name);
154 case 'promo':
155 return $obj->promo();
156 default:
157 return null;
158 }
159 }
160 return null;
161 }
162
163 public function bounds()
164 {
165 $order = Env::v('order', $this->defaultkey);
166 $show_bounds = 0;
167 if (($order == "name") || ($order == "-name")) {
168 $this->bound_field = "name";
169 $show_bounds = 1;
170 } elseif (($order == "promo") || ($order == "-promo")) {
171 $this->bound_field = "promo";
172 $show_bounds = -1;
173 }
174 if ($order{0} == '-') {
175 $show_bounds = -$show_bounds;
176 }
177 return $show_bounds;
178 }
179 }
180
181 /** An extended multipage view for profiles, as minifiches.
182 * Allows to sort by:
183 * - score (for a search query)
184 * - name
185 * - promo
186 * - latest modification
187 *
188 * Paramaters for this view are:
189 * - with_score: whether to allow ordering by score (set only for a quick search)
190 * - starts_with: show only names beginning with the given letter
191 */
192 class MinificheView extends ProfileView
193 {
194 public function __construct(PlSet $set, array $params)
195 {
196 global $globals;
197 $this->entriesPerPage = $globals->search->per_page;
198 if (@$params['with_score']) {
199 $this->addSort(new PlViewOrder('score', array(
200 new UFO_Score(true),
201 new UFO_ProfileUpdate(true),
202 new UFO_Promo(UserFilter::DISPLAY, true),
203 new UFO_Name(Profile::DN_SORT),
204 ), 'pertinence'));
205 }
206 $this->addSort(new PlViewOrder(
207 'name',
208 array(new UFO_Name(Profile::DN_SORT)),
209 'nom'));
210 $this->addSort(new PlViewOrder('promo', array(
211 new UFO_Promo(UserFilter::DISPLAY, true),
212 new UFO_Name(Profile::DN_SORT),
213 ), 'promotion'));
214 $this->addSort(new PlViewOrder('date_mod', array(
215 new UFO_ProfileUpdate(true),
216 new UFO_Promo(UserFilter::DISPLAY, true),
217 new UFO_Name(Profile::DN_SORT),
218 ), 'dernière modification'));
219 parent::__construct($set, $params);
220 }
221
222 public function apply(PlPage $page)
223 {
224 if (array_key_exists('starts_with', $this->params)
225 && $this->params['starts_with'] != ""
226 && $this->params['starts_with'] != null) {
227
228 $this->set->addCond(
229 new UFC_Name(Profile::LASTNAME,
230 $this->params['starts_with'], UFC_Name::PREFIX)
231 );
232 }
233 return parent::apply($page);
234 }
235
236 public function templateName()
237 {
238 return 'include/plview.minifiche.tpl';
239 }
240 }
241
242 class MentorView extends ProfileView
243 {
244 public function __construct(PlSet $set, array $params)
245 {
246 $this->entriesPerPage = 10;
247 $this->addSort(new PlViewOrder('rand', array(new PFO_Random(S::i('uid'))), 'aléatoirement'));
248 $this->addSort(new PlViewOrder('name', array(new UFO_Name(Profile::DN_SORT)), 'nom'));
249 $this->addSort(new PlViewOrder('promo', array(
250 new UFO_Promo(UserFilter::DISPLAY, true),
251 new UFO_Name(Profile::DN_SORT),
252 ), 'promotion'));
253 $this->addSort(new PlViewOrder('date_mod', array(
254 new UFO_ProfileUpdate(true),
255 new UFO_Promo(UserFilter::DISPLAY, true),
256 new UFO_Name(Profile::DN_SORT),
257 ), 'dernière modification'));
258 parent::__construct($set, $params);
259 }
260
261 public function templateName()
262 {
263 return 'include/plview.referent.tpl';
264 }
265 }
266
267 class TrombiView extends ProfileView
268 {
269 public function __construct(PlSet $set, array $params)
270 {
271 $this->entriesPerPage = 24;
272 $this->defaultkey = 'name';
273 if (@$params['with_score']) {
274 $this->addSort(new PlViewOrder('score', array(
275 new UFO_Score(true),
276 new UFO_ProfileUpdate(true),
277 new UFO_Promo(UserFilter::DISPLAY, true),
278 new UFO_Name(Profile::DN_SORT),
279 ), 'pertinence'));
280 }
281 $set->addCond(new UFC_Photo());
282 $this->addSort(new PlViewOrder('name', array(new UFO_Name(Profile::DN_SORT)), 'nom'));
283 $this->addSort(new PlViewOrder('promo', array(
284 new UFO_Promo(UserFilter::DISPLAY, true),
285 new UFO_Name(Profile::DN_SORT),
286 ), 'promotion'));
287 parent::__construct($set, $params);
288 }
289
290 public function templateName()
291 {
292 return 'include/plview.trombi.tpl';
293 }
294
295 public function apply(PlPage $page)
296 {
297 if (!empty($GLOBALS['IS_XNET_SITE'])) {
298 global $globals;
299 $page->assign('mainsiteurl', 'https://' . $globals->core->secure_domain . '/');
300 }
301 return parent::apply($page);
302 }
303 }
304
305 class GadgetView implements PlView
306 {
307 public function __construct(PlSet $set, array $params)
308 {
309 $this->set =& $set;
310 }
311
312 public function apply(PlPage $page)
313 {
314 $page->assign_by_ref('set', $this->set->get(new PlLimit(5, 0)));
315 }
316
317 public function args()
318 {
319 return null;
320 }
321 }
322
323 class AddressesView implements PlView
324 {
325 private $set;
326
327 public function __construct(PlSet $set, array $params)
328 {
329 $this->set =& $set;
330 }
331
332 public function apply(PlPage $page)
333 {
334 $pids = $this->set->getIds(new PlLimit());
335 $visibility = new ProfileVisibility(ProfileVisibility::VIS_AX);
336 pl_cached_content_headers('text/x-csv', 1);
337
338 $csv = fopen('php://output', 'w');
339 fputcsv($csv, array('adresses'), ';');
340 $res = XDB::query('SELECT pd.public_name, pa.postalText
341 FROM profile_addresses AS pa
342 INNER JOIN profile_display AS pd ON (pd.pid = pa.pid)
343 WHERE pa.type = \'home\' AND pa.pub IN (\'public\', \'ax\') AND FIND_IN_SET(\'mail\', pa.flags) AND pa.pid IN {?}
344 GROUP BY pa.pid', $pids);
345 foreach ($res->fetchAllAssoc() as $item) {
346 fputcsv($csv, $item, ';');
347 }
348 fclose($csv);
349 exit();
350 }
351
352 public function args()
353 {
354 return $this->set->args();
355 }
356 }
357
358 class JSonView implements PlView
359 {
360 private $set;
361 private $params;
362
363 public function __construct(PlSet $set, array $params)
364 {
365 $this->set = $set;
366 $this->params = $params;
367 }
368
369 public function apply(PlPage $page)
370 {
371 $export = array();
372 $start = isset($this->params['offset']) ? $this->params['offset'] : 0;
373 $count = isset($this->params['count']) ? $this->params['count'] : 10;
374 $profiles = $this->set->get(new PlLimit($start, $count));
375 foreach ($profiles as $profile) {
376 $export[] = $profile->export();
377 }
378 $page->jsonAssign('profile_count', $this->set->count());
379 $page->jsonAssign('profiles', $export);
380 }
381
382 public function args()
383 {
384 return $this->set->args();
385 }
386 }
387
388 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
389 ?>