Split the SearchSet into QuickSet and AdvancedSet
[platal.git] / include / userset.inc.php
1 <?php
2 /***************************************************************************
3 * Copyright (C) 2003-2010 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(PlFilterCondition $cond = null)
119 {
120 parent::__construct(new UFB_AdvancedSearch(), $cond);
121 }
122 }
123
124 /** Simple set based on an array of User objects
125 */
126 class ArraySet extends ProfileSet
127 {
128 public function __construct(array $users)
129 {
130 $hruids = User::getBulkHruid($users, array('User', '_silent_user_callback'));
131 if (is_null($hruids) || count($hruids) == 0) {
132 $cond = new PFC_False();
133 } else {
134 $cond = new UFC_Hruid($hruids);
135 }
136 parent::__construct($cond);
137 }
138 }
139
140 /** A multipage view for profiles
141 * Allows the display of bounds when sorting by name or promo.
142 */
143 abstract class ProfileView extends MultipageView
144 {
145 protected function getBoundValue($obj)
146 {
147 if ($obj instanceof Profile) {
148 switch ($this->bound_field) {
149 case 'name':
150 $name = $obj->name('%l');
151 return strtoupper($name);
152 case 'promo':
153 return $obj->promo();
154 default:
155 return null;
156 }
157 }
158 return null;
159 }
160
161 public function bounds()
162 {
163 $order = Env::v('order', $this->defaultkey);
164 $show_bounds = 0;
165 if (($order == "name") || ($order == "-name")) {
166 $this->bound_field = "name";
167 $show_bounds = 1;
168 } elseif (($order == "promo") || ($order == "-promo")) {
169 $this->bound_field = "promo";
170 $show_bounds = -1;
171 }
172 if ($order{0} == '-') {
173 $show_bounds = -$show_bounds;
174 }
175 return $show_bounds;
176 }
177 }
178
179 /** An extended multipage view for profiles, as minifiches.
180 * Allows to sort by:
181 * - score (for a search query)
182 * - name
183 * - promo
184 * - latest modification
185 *
186 * Paramaters for this view are:
187 * - with_score: whether to allow ordering by score (set only for a quick search)
188 * - starts_with: show only names beginning with the given letter
189 */
190 class MinificheView extends ProfileView
191 {
192 public function __construct(PlSet &$set, array $params)
193 {
194 global $globals;
195 $this->entriesPerPage = $globals->search->per_page;
196 if (@$params['with_score']) {
197 $this->addSort(new PlViewOrder('score', array(
198 new UFO_Score(true),
199 new UFO_ProfileUpdate(true),
200 new UFO_Promo(UserFilter::DISPLAY, true),
201 new UFO_Name(Profile::DN_SORT),
202 ), 'pertinence'));
203 }
204 $this->addSort(new PlViewOrder(
205 'name',
206 array(new UFO_Name(Profile::DN_SORT)),
207 'nom'));
208 $this->addSort(new PlViewOrder('promo', array(
209 new UFO_Promo(UserFilter::DISPLAY, true),
210 new UFO_Name(Profile::DN_SORT),
211 ), 'promotion'));
212 $this->addSort(new PlViewOrder('date_mod', array(
213 new UFO_ProfileUpdate(true),
214 new UFO_Promo(UserFilter::DISPLAY, true),
215 new UFO_Name(Profile::DN_SORT),
216 ), 'dernière modification'));
217 parent::__construct($set, $params);
218 }
219
220 public function apply(PlPage &$page)
221 {
222 if (array_key_exists('starts_with', $this->params)
223 && $this->params['starts_with'] != ""
224 && $this->params['starts_with'] != null) {
225
226 $this->set->addCond(
227 new UFC_Name(Profile::LASTNAME,
228 $this->params['starts_with'], UFC_Name::PREFIX)
229 );
230 }
231 return parent::apply($page);
232 }
233
234 public function templateName()
235 {
236 return 'include/plview.minifiche.tpl';
237 }
238 }
239
240 class MentorView extends ProfileView
241 {
242 public function __construct(PlSet &$set, array $params)
243 {
244 $this->entriesPerPage = 10;
245 $this->addSort(new PlViewOrder('rand', array(new PFO_Random(S::i('uid'))), 'aléatoirement'));
246 $this->addSort(new PlViewOrder('name', array(new UFO_Name(Profile::DN_SORT)), 'nom'));
247 $this->addSort(new PlViewOrder('promo', array(
248 new UFO_Promo(UserFilter::DISPLAY, true),
249 new UFO_Name(Profile::DN_SORT),
250 ), 'promotion'));
251 $this->addSort(new PlViewOrder('date_mod', array(
252 new UFO_ProfileUpdate(true),
253 new UFO_Promo(UserFilter::DISPLAY, true),
254 new UFO_Name(Profile::DN_SORT),
255 ), 'dernière modification'));
256 parent::__construct($set, $params);
257 }
258
259 public function templateName()
260 {
261 return 'include/plview.referent.tpl';
262 }
263 }
264
265 class TrombiView extends ProfileView
266 {
267 public function __construct(PlSet &$set, array $params)
268 {
269 $this->entriesPerPage = 24;
270 $this->defaultkey = 'name';
271 if (@$params['with_score']) {
272 $this->addSort(new PlViewOrder('score', array(
273 new UFO_Score(true),
274 new UFO_ProfileUpdate(true),
275 new UFO_Promo(UserFilter::DISPLAY, true),
276 new UFO_Name(Profile::DN_SORT),
277 ), 'pertinence'));
278 }
279 $set->addCond(new UFC_Photo());
280 $this->addSort(new PlViewOrder('name', array(new UFO_Name(Profile::DN_SORT)), 'nom'));
281 $this->addSort(new PlViewOrder('promo', array(
282 new UFO_Promo(UserFilter::DISPLAY, true),
283 new UFO_Name(Profile::DN_SORT),
284 ), 'promotion'));
285 parent::__construct($set, $params);
286 }
287
288 public function templateName()
289 {
290 return 'include/plview.trombi.tpl';
291 }
292
293 public function apply(PlPage &$page)
294 {
295 if (!empty($GLOBALS['IS_XNET_SITE'])) {
296 global $globals;
297 $page->assign('mainsiteurl', 'https://' . $globals->core->secure_domain . '/');
298 }
299 return parent::apply($page);
300 }
301 }
302
303 class GadgetView implements PlView
304 {
305 public function __construct(PlSet &$set, array $params)
306 {
307 $this->set =& $set;
308 }
309
310 public function apply(PlPage &$page)
311 {
312 $page->assign_by_ref('set', $this->set->get(new PlLimit(5, 0)));
313 }
314
315 public function args()
316 {
317 return null;
318 }
319 }
320
321 class AddressesView implements PlView
322 {
323 private $set;
324
325 public function __construct(PlSet &$set, array $params)
326 {
327 $this->set =& $set;
328 }
329
330 public function apply(PlPage &$page)
331 {
332 $pids = $this->set->getIds(new PlLimit());
333 $visibility = new ProfileVisibility(ProfileVisibility::VIS_AX);
334 pl_content_headers('text/x-csv');
335
336 $csv = fopen('php://output', 'w');
337 fputcsv($csv, array('adresses'), ';');
338 $res = XDB::query('SELECT pd.public_name, pa.postalText
339 FROM profile_addresses AS pa
340 INNER JOIN profile_display AS pd ON (pd.pid = pa.pid)
341 WHERE pa.type = \'home\' AND pa.pub IN (\'public\', \'ax\') AND FIND_IN_SET(\'mail\', pa.flags) AND pa.pid IN {?}
342 GROUP BY pa.pid', $pids);
343 foreach ($res->fetchAllAssoc() as $item) {
344 fputcsv($csv, $item, ';');
345 }
346 fclose($csv);
347 exit();
348 }
349
350 public function args()
351 {
352 return $this->set->args();
353 }
354 }
355
356 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
357 ?>