Commit | Line | Data |
---|---|---|
d9b3d712 RB |
1 | <?php |
2 | /*************************************************************************** | |
3 | * Copyright (C) 2003-2009 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 UserFilterBuilder | |
23 | { | |
24 | private $envprefix; | |
25 | private $fields; | |
26 | private $valid = true; | |
27 | private $ufc = null; | |
28 | ||
29 | /** Constructor | |
30 | * @param $fields An array of UFB_Field objects | |
31 | * @param $envprefix Prefix to use for parts of the query | |
32 | */ | |
33 | public function __construct($fields, $envprefix = '') | |
34 | { | |
35 | $this->fields = $fields; | |
36 | $this->envprefix = $envprefix; | |
37 | } | |
38 | ||
39 | /** Builds the UFC; returns as soon as a field says it is invalid | |
40 | */ | |
41 | private function buildUFC() | |
42 | { | |
43 | if ($this->ufc != null) { | |
44 | return; | |
45 | } | |
46 | $this->ufc = new PFC_And(); | |
47 | ||
48 | foreach ($this->fields as $field) { | |
49 | $this->valid = $field->apply(&$this); | |
50 | if (!$this->valid) { | |
51 | return; | |
52 | } | |
53 | } | |
54 | } | |
55 | ||
56 | public function addCond(PlFilterCondition &$cond) | |
57 | { | |
58 | $this->ufc->addChild($cond); | |
59 | } | |
60 | ||
61 | public function isValid() | |
62 | { | |
63 | $this->buildUFC(); | |
64 | return $this->valid; | |
65 | } | |
66 | ||
67 | /** Returns the built UFC | |
68 | * @return The UFC, or PFC_False() if an error happened | |
69 | */ | |
70 | public function &getUFC() | |
71 | { | |
72 | $this->buildUFC(); | |
73 | if ($this->valid) { | |
74 | return $this->ufc; | |
75 | } else { | |
76 | return new PFC_False(); | |
77 | } | |
78 | } | |
79 | ||
80 | /** Wrappers around Env::i/s/..., to add envprefix | |
81 | */ | |
82 | public function s($key, $def) { | |
83 | return trim(Env::s($this->envprefix . $key, $def)); | |
84 | } | |
85 | ||
86 | public function i($key, $def) { | |
87 | return intval(trim(Env::i($this->envprefix . $key, $def))); | |
88 | } | |
89 | ||
90 | public function v($key, $def) { | |
91 | return Env::v($this->envprefix . $key, $def); | |
92 | } | |
93 | ||
94 | public function has($key) { | |
95 | return Env::has($this->envprefix . $key); | |
96 | } | |
97 | } | |
98 | ||
99 | abstract class UFB_Field | |
100 | { | |
101 | protected $envfield; | |
102 | protected $formtext; | |
103 | ||
104 | protected $empty = false; | |
105 | protected $val = null; | |
106 | ||
107 | /** Constructor | |
108 | * @param $envfield Name of the field in the environment | |
109 | * @param $formtext User-friendly name of that field | |
110 | */ | |
111 | public function __construct($envfield, $formtext = '') | |
112 | { | |
113 | $this->envfield = $envfield; | |
114 | if ($formtext != '') { | |
115 | $this->formtext = $formtext; | |
116 | } else { | |
117 | $formtext = ucfirst($envfield); | |
118 | } | |
119 | } | |
120 | ||
121 | /** Prints the given error message to the user, and returns false | |
122 | * in order to be used as return $this->raise('ERROR'); | |
123 | * | |
124 | * All %s in the $msg will be replaced with the formtext. | |
125 | */ | |
126 | protected function raise($msg) | |
127 | { | |
128 | Platal::page()->trigError(str_replace('%s', $this->formtext, $msg)); | |
129 | return false; | |
130 | } | |
131 | ||
132 | public function apply(UserFilterBuilder &$ufb) { | |
133 | if (!$this->check($ufb)) { | |
134 | return false; | |
135 | } | |
136 | ||
137 | if (!$this->empty) { | |
138 | $ufc = $this->buildUFC($ufb); | |
139 | if ($ufc != null) { | |
140 | $ufb->addCond($ufc); | |
141 | } | |
142 | } | |
143 | return true; | |
144 | } | |
145 | ||
146 | /** Create the UFC associated to the field; won't be called | |
147 | * if the field is "empty" | |
148 | * @param &$ufb UFB to which fields must be added | |
149 | * @return UFC | |
150 | */ | |
151 | abstract protected function buildUFC(UserFilterBuilder &$ufb); | |
152 | ||
153 | /** This function is intended to run consistency checks on the value | |
154 | * @return boolean Whether the input is valid | |
155 | */ | |
156 | abstract protected function check(UserFilterBuilder &$ufb); | |
157 | } | |
158 | ||
159 | abstract class UFBF_Text extends UFB_Field | |
160 | { | |
161 | private $forbiddenchars; | |
162 | private $minlength; | |
163 | private $maxlength; | |
164 | ||
165 | public function __construct($envfield, $formtext = '', $forbiddenchars = '', $minlength = 2, $maxlength = 255) | |
166 | { | |
167 | parent::__construct($envfield, $formtext); | |
168 | $this->forbiddenchars = $forbiddenchars; | |
169 | $this->minlength = $minlength; | |
170 | $this->maxlength = $maxlength; | |
171 | } | |
172 | ||
173 | protected function check(UserFilterBuilder &$ufb) | |
174 | { | |
175 | if (!$ufb->has($this->envfield)) { | |
176 | $this->empty = true; | |
177 | return true; | |
178 | } | |
179 | ||
180 | $this->val = $ufb->s($this->envfield); | |
181 | if (strlen($this->val) < $this->minlength) { | |
182 | return $this->raise("Le champ %s est trop court (minimum {$this->minlength})."); | |
183 | } else if (strlen($this->val) > $this->maxlength) { | |
184 | return $this->raise("Le champ %s est trop long (maximum {$this->maxlength})."); | |
185 | } | |
186 | return true; | |
187 | } | |
188 | } | |
189 | ||
190 | /** Subclass to use for fields which only allow integers within a range | |
191 | */ | |
192 | abstract class UFBF_Range extends UFB_Field | |
193 | { | |
194 | ||
195 | private $min; | |
196 | private $max; | |
197 | ||
198 | public function __construct($envfield, $formtext = '', $min = 0, $max = 65535) | |
199 | { | |
200 | parent::__construct($envfield, $formtext); | |
201 | $this->min = $min; | |
202 | $this->max = $max; | |
203 | } | |
204 | ||
205 | protected function check(UserFilterBuilder &$ufb) | |
206 | { | |
207 | if (!$ufb->has($this->envfield)) { | |
208 | $this->empty = true; | |
209 | return true; | |
210 | } | |
211 | ||
212 | $this->val = $ufb->i($this->envfield); | |
213 | if ($this->val < $this->min) { | |
214 | return $this->raise("Le champs %s est inférieur au minimum ({$this->min})."); | |
215 | } else if ($this->val > $this->max) { | |
216 | return $this->raise("Le champ %s est supérieur au maximum ({$this->max})."); | |
217 | } | |
218 | return true; | |
219 | } | |
220 | } | |
221 | ||
222 | /** Subclass to use for indexed fields | |
223 | */ | |
224 | abstract class UFBF_Index extends UFB_Field | |
225 | { | |
226 | protected function check(UserFilterBuilder &$ufb) | |
227 | { | |
228 | if (!$ufb->has($this->envfield)) { | |
229 | $this->empty = true; | |
230 | } | |
231 | return true; | |
232 | } | |
233 | } | |
234 | ||
235 | /** Subclass to use for fields whose value must belong to a specific set of values | |
236 | */ | |
237 | abstract class UFBF_Enum extends UFB_Field | |
238 | { | |
239 | public function __construct($envfield, $formtext = '', $allowedvalues = array()) | |
240 | { | |
241 | parent::__construct($envfield, $formtext); | |
242 | $this->allowedvalues = $allowedvalues; | |
243 | } | |
244 | ||
245 | protected function check(UserFilterBuilder &$ufb) | |
246 | { | |
247 | if (!$ufb->has($this->envfield)) { | |
248 | $this->empty = true; | |
249 | return true; | |
250 | } | |
251 | ||
252 | $this->val = $ufb->v($this->envfield); | |
253 | if (! in_array($this->val, $this->allowedvalues)) { | |
254 | return $this->raise("La valeur {$this->val} n'est pas valide pour le champ %s."); | |
255 | } | |
256 | return true; | |
257 | } | |
258 | } | |
259 | ||
260 | class UFBF_Name extends UFBF_Text | |
261 | { | |
262 | private $type; | |
263 | ||
264 | public function __construct($envfield, $type, $formtext = '', $forbiddenchars = '', $minlength = 2, $maxlength = 255) | |
265 | { | |
266 | parent::__construct($envfield, $formtext, $forbiddenchars, $minlength, $maxlength); | |
267 | $this->type = $type; | |
268 | } | |
269 | ||
270 | protected function buildUFC(UserFilterBuilder &$ufb) | |
271 | { | |
272 | if ($ufb->i('exact')) { | |
273 | return new UFC_Name($this->type, $this->val, UFC_Name::VARIANTS); | |
274 | } else { | |
275 | return new UFC_Name($this->type, $this->val, UFC_Name::VARIANTS | UFC_Name::CONTAINS); | |
276 | } | |
277 | } | |
278 | } | |
279 | ||
280 | class UFBF_Promo extends UFB_Field | |
281 | { | |
282 | private static $validcomps = array('<', '<=', '=', '>=', '>'); | |
283 | private $comp; | |
284 | private $envfieldcomp; | |
285 | ||
286 | public function __construct($envfield, $fromtext = '', $envfieldcomp) | |
287 | { | |
288 | parent::__construct($envfield, $fromtext); | |
289 | $this->envfieldcomp = $envfieldcomp; | |
290 | } | |
291 | ||
292 | protected function check(UserFilterBuilder &$ufb) | |
293 | { | |
294 | if (!$ufb->has($this->envfield) || !$ufb->has($this->envfieldcomp)) { | |
295 | $this->empty = true; | |
296 | return true; | |
297 | } | |
298 | ||
299 | $this->val = $ubf->i($this->envfield); | |
300 | $this->comp = $ubf->v($this->envfieldcomp); | |
301 | ||
302 | if (!in_array($this->comp, self::$validcomps)) { | |
303 | return $this->raise("Le critère {$this->comp} n'est pas valide pour le champ %s"); | |
304 | } | |
305 | ||
306 | if (preg_match('/^[0-9]{2}$/', $this->val)) { | |
307 | $this->val += 1900; | |
308 | } | |
309 | if ($this->val < 1900 || $this->val > 9999) { | |
310 | return $this->raise("Le champ %s doit être une année à 4 chiffres."); | |
311 | } | |
312 | return true; | |
313 | } | |
314 | ||
315 | protected function buildUFC(UserFilterBuilder &$ufb) { | |
316 | return new UFC_Promo($this->comp, UserFilter::DISPLAY, 'X' . $this->val); | |
317 | } | |
318 | } | |
319 | ||
320 | ?> |