Move the templates required by the core module in the core.
[platal.git] / classes / pluser.php
CommitLineData
5421ab09
VZ
1<?php
2/***************************************************************************
3 * Copyright (C) 2003-2008 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/**
23 * PlUserNotFound is raised when a user id cannot be linked to a real user.
24 * The @p results give the list hruids (useful when several users are found).
25 */
26class UserNotFoundException extends Exception
27{
28 public function __construct($results = array())
29 {
30 $this->results = $results;
31 parent::__construct();
32 }
33}
34
35/**
36 * Represents an user of plat/al (without any further assumption), with a
37 * special focus on always-used properties (identification fields, display name,
38 * forlife/bestalias emails, ...).
39 * NOTE: each implementation of plat/al-code MUST subclass PlUser, and name it
40 * 'User'.
41 */
42abstract class PlUser
43{
44 /**
45 * User data storage.
46 * By convention, null means the information hasn't been fetched yet, and
47 * false means the information is not available.
48 */
49 protected $user_id = null;
50 protected $hruid = null;
51
52 // User main email aliases (forlife is the for-life email address, bestalias
53 // is user-chosen preferred email address).
54 protected $forlife = null;
55 protected $bestalias = null;
56
57 // Display name is user-chosen name to display (eg. in "Welcome
58 // <display name> !"), while full name is the official full name.
59 protected $display_name = null;
60 protected $full_name = null;
61 protected $promo = null;
62
f8b161ad
FB
63 // Permissions
64 protected $perms = null;
65 protected $perm_flags = null;
66
5421ab09
VZ
67 // Other properties are listed in this key-value hash map.
68 protected $data = array();
69
70 /**
71 * Constructs the PlUser object from an identifier (any identifier which is
72 * understood by getLogin() implementation).
73 *
74 * @param $login An user login.
75 * @param $values List of known user properties.
76 */
77 public function __construct($login, $values = array())
78 {
79 $this->fillFromArray($values);
80
81 // If the user id was not part of the known values, determines it from
82 // the login.
83 if (!$this->user_id) {
84 $this->user_id = $this->getLogin($login);
85 }
86
87 // Preloads main properties (assumes the loader will lazily get them
88 // from variables already set in the object).
89 $this->loadMainFields();
90 }
91
92 /**
93 * Get the canonical user id for the @p login.
94 *
95 * @param $login An user login.
96 * @return The canonical user id.
97 * @throws UserNotFoundException when login is not found.
98 */
99 abstract protected function getLogin($login);
100
101 /**
102 * Loads the main properties (hruid, forlife, bestalias, ...) from the
103 * database. Should return immediately when the properties are already
104 * available.
105 */
106 abstract protected function loadMainFields();
107
108 /**
109 * Accessors to the main properties, ie. those available as top level
110 * object variables.
111 */
f8b161ad
FB
112 public function id()
113 {
114 return $this->user_id;
115 }
5421ab09 116
f8b161ad
FB
117 public function login()
118 {
119 return $this->hruid;
120 }
5421ab09 121
f8b161ad
FB
122 public function bestEmail()
123 {
124 return $this->bestalias;
125 }
126 public function forlifeEmail()
127 {
128 return $this->forlife;
129 }
130
131 public function displayName()
132 {
133 return $this->display_name;
134 }
135 public function fullName()
136 {
137 return $this->full_name;
138 }
5421ab09
VZ
139
140 /**
141 * Other properties are available directly through the $data array, or as
142 * standard object variables, using a getter.
143 */
f8b161ad
FB
144 public function data()
145 {
146 return $this->data;
147 }
5421ab09
VZ
148
149 public function __get($name)
150 {
151 if (isset($this->$name)) {
152 return $this->$name;
153 }
154
155 if (isset($this->data[$name])) {
156 return $this->data[$name];
157 }
158
159 return null;
160 }
161
162 public function __isset($name)
163 {
164 return isset($this->$name) || isset($this->data[$name]);
165 }
166
167 /**
168 * Fills the object properties using the @p associative array; the intended
169 * user case is to fill the object using SQL obtained arrays.
170 *
171 * @param $values Key-value array of user properties.
172 */
173 protected function fillFromArray(array $values)
174 {
175 // Merge main properties with existing ones.
176 unset($values['data']);
177 foreach ($values as $key => $value) {
178 if (property_exists($this, $key) && !isset($this->$key)) {
179 $this->$key = $value;
180 }
181 }
182
183 // Merge all value into the $this->data placeholder.
184 $this->data = array_merge($this->data, $values);
185 }
186
187
188 /**
f8b161ad
FB
189 * Build the permissions flags for the user.
190 */
191 abstract protected function buildPerms();
192
193 /**
194 * Check wether the user got the given permission combination.
195 */
196 public function checkPerms($perms)
197 {
198 if (is_null($this->perm_flags)) {
199 $this->buildPerms();
200 }
201 if (is_null($this->perm_flags)) {
202 return false;
203 }
204 return $this->perm_flags->hasFlagCombination($perms);
205 }
206
207
208 /**
5421ab09
VZ
209 * Returns a valid User object built from the @p id and optionnal @p values,
210 * or returns false and calls the callback if the @p id is not valid.
211 */
212 public static function get($login, $callback = false)
213 {
214 return User::getWithValues($login, array(), $callback);
215 }
216
217 public static function getWithValues($login, $values, $callback = false)
218 {
219 if (!$callback) {
220 $callback = array('User', '_default_user_callback');
221 }
222
223 try {
224 return new User($login, $values);
225 } catch (UserNotFoundException $e) {
226 return call_user_func($callback, $login, $e->results);
227 }
228 }
229
230 // Same as above, but using the silent callback as default.
231 public static function getSilent($login)
232 {
233 return User::getWithValues($login, array(), array('User', '_silent_user_callback'));
234 }
235
236 public static function getSilentWithValues($login, $values)
237 {
238 return User::getWithValues($login, $values, array('User', '_silent_user_callback'));
239 }
240
241 /**
40d6b19a
VZ
242 * Retrieves User objects corresponding to the @p logins, and eventually
243 * extracts and returns the @p property. If @p strict mode is disabled, it
244 * also includes logins for which no forlife was found (but it still calls
245 * the callback for them).
5421ab09
VZ
246 * In all cases, email addresses which are not from the local domains are
247 * kept.
248 *
249 * @param $logins Array of user logins.
40d6b19a 250 * @param $property Property to retrieve from the User objects.
5421ab09
VZ
251 * @param $strict Should unvalidated logins be returned as-is or discarded ?
252 * @param $callback Callback to call when a login is unknown to the system.
253 * @return Array of validated user forlife emails.
254 */
40d6b19a 255 private static function getBulkUserProperties($logins, $property, $strict, $callback)
5421ab09
VZ
256 {
257 if (!is_array($logins)) {
258 if (strlen(trim($logins)) == 0) {
259 return null;
260 }
261 $logins = split("[; ,\r\n\|]+", $logins);
262 }
263
264 if ($logins) {
265 $list = array();
266 foreach ($logins as $i => $login) {
267 $login = trim($login);
268 if (empty($login)) {
269 continue;
270 }
271
272 if (($user = User::get($login, $callback))) {
40d6b19a 273 $list[$i] = $user->$property();
5421ab09
VZ
274 } else if (!$strict || User::isForeignEmailAddress($login)) {
275 $list[$i] = $login;
276 }
277 }
278 return $list;
279 }
280 return null;
281 }
282
283 /**
40d6b19a
VZ
284 * Returns hruid corresponding to the @p logins. See getBulkUserProperties()
285 * for details.
286 */
287 public static function getBulkHruid($logins, $callback = false)
288 {
289 return self::getBulkUserProperties($logins, 'login', true, $callback);
290 }
291
292 /**
293 * Returns forlife emails corresponding to the @p logins. See
294 * getBulkUserProperties() for details.
295 */
296 public static function getBulkForlifeEmails($logins, $strict = true, $callback = false)
297 {
298 return self::getBulkUserProperties($logins, 'forlifeEmail', $strict, $callback);
299 }
300
301 /**
5421ab09
VZ
302 * Predefined callbacks for the user lookup; they are called when a given
303 * login is found not to be associated with any valid user. Silent callback
304 * does nothing; default callback is supposed to display an error message,
305 * using the Platal::page() hook.
306 */
307 public static function _silent_user_callback($login, $results)
308 {
309 return;
310 }
311
312 abstract public static function _default_user_callback($login, $results);
313
314 /**
315 * Determines if the @p login is an email address, and an email address not
316 * served locally by plat/al.
317 */
318 abstract public static function isForeignEmailAddress($email);
319}
320
321// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
322?>