Fetch mobile in profile default query.
[platal.git] / classes / profile.php
CommitLineData
e7b93962
FB
1<?php
2/***************************************************************************
34ade5a6 3 * Copyright (C) 2003-2009 Polytechnique.org *
e7b93962
FB
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
22class Profile
23{
f5642983
FB
24 static private $v_values = array('public' => array('public'),
25 'ax' => array('ax', 'public'),
26 'private' => array('private', 'ax', 'public'));
27 const VISIBILITY_PUBLIC = 'public';
28 const VISIBILITY_AX = 'ax';
29 const VISIBILITY_PRIVATE = 'private';
30
31 const ADDRESS_MAIN = 0x000001;
32 const ADDRESS_PERSO = 0x000002;
33 const ADDRESS_PRO = 0x000004;
34 const ADDRESS_ALL = 0x000006;
35 const ADDRESS_POSTAL = 0x000008;
36
37 const EDUCATION_MAIN = 0x000010;
4bc5b8f0
FB
38 const EDUCATION_EXTRA = 0x000020;
39 const EDUCATION_ALL = 0x000040;
40 const EDUCATION_FINISHED = 0x000080;
41 const EDUCATION_CURRENT = 0x000100;
f5642983 42
4bc5b8f0
FB
43 const JOBS_MAIN = 0x001000;
44 const JOBS_ALL = 0x002000;
45 const JOBS_FINISHED = 0x004000;
46 const JOBS_CURRENT = 0x008000;
f5642983 47
e7b93962
FB
48 private $pid;
49 private $hrpid;
3e53a496
FB
50 private $data = array();
51
f5642983
FB
52 private $visibility = null;
53
b774ddab 54 private function __construct(array $data)
e7b93962 55 {
b774ddab 56 $this->data = $data;
832e6fcb
FB
57 $this->pid = $this->data['pid'];
58 $this->hrpid = $this->data['hrpid'];
e7b93962
FB
59 }
60
61 public function id()
62 {
63 return $this->pid;
64 }
65
66 public function hrid()
67 {
68 return $this->hrpid;
69 }
70
d5e60905
FB
71 public function promo()
72 {
73 return $this->promo;
74 }
75
94b72319
FB
76 /** Print a name with the given formatting:
77 * %s = • for women
78 * %f = firstname
79 * %l = lastname
80 * %F = fullname
81 * %S = shortname
82 * %p = promo
83 */
84 public function name($format)
85 {
86 return str_replace(array('%s', '%f', '%l', '%F', '%S', '%p'),
87 array($this->isFemale() ? '•' : '',
88 $this->first_name, $this->last_name,
89 $this->full_name, $this->short_name,
90 $this->promo), $format);
91 }
92
93 public function fullName($with_promo = false)
94 {
95 if ($with_promo) {
96 return $this->full_name . ' (' . $this->promo . ')';
97 }
98 return $this->full_name;
99 }
100
101 public function shortName($with_promo = false)
102 {
103 if ($with_promo) {
104 return $this->short_name . ' (' . $this->promo . ')';
105 }
106 return $this->short_name;
107 }
108
109 public function firstName()
110 {
08c91036 111 return $this->firstname;
94b72319
FB
112 }
113
114 public function lastName()
115 {
08c91036 116 return $this->lastname;
94b72319
FB
117 }
118
119 public function isFemale()
120 {
121 return $this->sex == PlUser::GENDER_FEMALE;
122 }
123
124 public function data()
125 {
126 $this->first_name;
127 return $this->data;
128 }
129
3e53a496
FB
130 public function __get($name)
131 {
132 if (property_exists($this, $name)) {
133 return $this->$name;
134 }
135
3e53a496
FB
136 if (isset($this->data[$name])) {
137 return $this->data[$name];
138 }
139
140 return null;
141 }
142
143 public function __isset($name)
144 {
145 return property_exists($this, $name) || isset($this->data[$name]);
146 }
147
f5642983
FB
148 public function setVisibilityLevel($visibility)
149 {
150 if ($visibility != self::VISIBILITY_PRIVATE
151 && $visibility != self::VISIBILITY_AX
152 && $visibility != self::VISIBILITY_PUBLIC) {
153 Platal::page()->kill("Visibility invalide: " . $visibility);
154 }
155 $this->visibility = self::$v_values[$visibility];
46e9eb99
FB
156 if ($this->mobile && !in_array($this->modbile_pub, $this->visibility)) {
157 unset($this->data['mobile']);
158 }
f5642983
FB
159 }
160
4bc5b8f0
FB
161
162 /* Addresses
163 */
164 public function getAddresses($flags, $limit = null)
f5642983
FB
165 {
166 $where = XDB::format('pa.pid = {?}', $this->id());
167 if ($flags & self::ADDRESS_MAIN) {
168 $where .= ' AND FIND_IN_SET(\'current\', pa.flags)';
169 }
170 if ($flags & self::ADDRESS_POSTAL) {
171 $where .= ' AND FIND_IN_SET(\'mail\', pa.flags)';
172 }
173 if ($this->visibility) {
174 $where .= ' AND pa.pub IN ' . XDB::formatArray($this->visibility);
175 }
176 $type = array();
177 if ($flags & self::ADDRESS_PRO) {
178 $type[] = 'job';
179 }
180 if ($flags & self::ADDRESS_PERSO) {
181 $type[] = 'home';
182 }
183 if (count($type) > 0) {
184 $where .= ' AND pa.type IN ' . XDB::formatArray($type);
185 }
4bc5b8f0 186 $limit = is_null($limit) ? '' : XDB::format('LIMIT {?}', (int)$limit);
f5642983
FB
187 return XDB::iterator('SELECT pa.text, pa.postalCode, pa.type, pa.latitude, pa.longitude,
188 gl.name AS locality, gas.name AS subAdministrativeArea,
189 ga.name AS administrativeArea, gc.countryFR AS country,
190 FIND_IN_SET(\'current\', pa.flags) AS current,
191 FIND_IN_SET(\'temporary\', pa.flags) AS temporary,
192 FIND_IN_SET(\'secondary\', pa.flags) AS secondary,
193 FIND_IN_SET(\'mail\', pa.flags) AS mail, pa.type
194 FROM profile_addresses AS pa
195 LEFT JOIN geoloc_localities AS gl ON (gl.id = pa.localityId)
196 LEFT JOIN geoloc_administrativeareas AS ga ON (ga.id = pa.administrativeAreaId)
197 LEFT JOIN geoloc_administrativeareas AS gas ON (gas.id = pa.subAdministrativeAreaId)
198 LEFT JOIN geoloc_countries AS gc ON (gc.iso_3166_1_a2 = pa.countryId)
4bc5b8f0
FB
199 WHERE ' . $where . '
200 ORDER BY pa.id
201 ' . $limit);
f5642983
FB
202 }
203
204 public function getMainAddress()
205 {
206 $it = $this->getAddresses(self::ADDRESS_PERSO | self::ADDRESS_MAIN);
207 if ($it->total() == 0) {
208 return null;
209 } else {
210 return $it->next();
211 }
212 }
3e53a496 213
4bc5b8f0
FB
214
215 /* Educations
216 */
217 public function getEducations($flags, $limit = null)
218 {
219 $where = XDB::format('pe.uid = {?}', $this->id());
220 if ($flags & self::EDUCATION_MAIN) {
221 $where .= ' AND FIND_IN_SET(\'primary\', pe.flags)';
222 } else if ($flags & self::EDUCATION_EXTRA) {
223 $where .= ' AND NOT FIND_IN_SET(\'primary\', pe.flags)';
224 } else if ($flags & self::EDUCATION_FINISHED) {
225 $where .= ' AND pe.grad_year <= YEAR(CURDATE())';
226 } else if ($flags & self::EDUCATION_CURRENT) {
227 $where .= ' AND pe.grad_year > YEAR(CURDATE())';
228 }
229 $limit = is_null($limit) ? '' : XDB::format('LIMIT {?}', (int)$limit);
230 return XDB::iterator('SELECT pe.entry_year, pe.grad_year, pe.program,
231 pee.name AS school, pee.abbreviation AS school_short, pee.url AS school_url, gc.countryFR AS country,
232 pede.degree, pede.abbreviation AS degree_short, pede.level AS degree_level, pefe.field,
233 FIND_IN_SET(\'primary\', pe.flags) AS prim
234 FROM profile_education AS pe
235 INNER JOIN profile_education_enum AS pee ON (pe.eduid = pee.id)
236 LEFT JOIN geoloc_countries AS gc ON (gc.iso_3166_1_a2 = pee.country)
237 INNER JOIN profile_education_degree_enum AS pede ON (pe.degreeid = pede.id)
238 LEFT JOIN profile_education_field_enum AS pefe ON (pe.fieldid = pefe.id)
239 WHERE ' . $where . '
240 ORDER BY NOT FIND_IN_SET(\'primary\', pe.flags), pe.entry_year, pe.id
241 ' . $limit);
242 }
243
244 public function getExtraEducations($limit = null)
245 {
246 return $this->getEducations(self::EDUCATION_EXTRA, $limit);
247 }
248
249
e7b93962
FB
250 public function owner()
251 {
252 return User::getSilent($this);
253 }
254
b774ddab
FB
255 private static function fetchProfileData(array $pids)
256 {
257 if (count($pids) == 0) {
258 return array();
259 }
260 return XDB::fetchAllAssoc('SELECT p.*, p.sex = \'female\' AS sex, pe.entry_year, pe.grad_year,
261 pn_f.name AS firstname, pn_l.name AS lastname, pn_n.name AS nickname,
262 IF(pn_uf.name IS NULL, pn_f.name, pn_uf.name) AS firstname_usual,
263 IF(pn_ul.name IS NULL, pn_l.name, pn_ul.name) AS lastname_usual,
46e9eb99
FB
264 pd.promo AS promo, pd.short_name, pd.directory_name AS full_name,
265 pp.display_tel AS mobile, pp.pub AS mobile_pub
b774ddab
FB
266 FROM profiles AS p
267 INNER JOIN profile_display AS pd ON (pd.pid = p.pid)
268 INNER JOIN profile_education AS pe ON (pe.uid = p.pid AND FIND_IN_SET(\'primary\', pe.flags))
269 INNER JOIN profile_name AS pn_f ON (pn_f.pid = p.pid
270 AND pn_f.typeid = ' . self::getNameTypeId('lastname', true) . ')
271 INNER JOIN profile_name AS pn_l ON (pn_l.pid = p.pid
272 AND pn_l.typeid = ' . self::getNameTypeId('firstname', true) . ')
273 LEFT JOIN profile_name AS pn_uf ON (pn_uf.pid = p.pid
274 AND pn_uf.typeid = ' . self::getNameTypeId('lastname_ordinary', true) . ')
275 LEFT JOIN profile_name AS pn_ul ON (pn_ul.pid = p.pid
276 AND pn_ul.typeid = ' . self::getNameTypeId('firstname_ordinary', true) . ')
46e9eb99 277 LEFT JOIN profile_name AS pn_n ON (pn_n.pid = p.pid
b774ddab 278 AND pn_n.typeid = ' . self::getNameTypeId('nickname', true) . ')
46e9eb99 279 LEFT JOIN profile_phones AS pp ON (pp.uid = p.pid AND pp.link_type = \'user\' AND tel_type = \'mobile\')
b774ddab
FB
280 WHERE p.pid IN ' . XDB::formatArray($pids) . '
281 GROUP BY p.pid');
282 }
283
284 public static function getPID($login)
285 {
286 if ($login instanceof PlUser) {
287 return XDB::fetchOneCell('SELECT pid
288 FROM account_profiles
289 WHERE uid = {?} AND FIND_IN_SET(\'owner\', perms)',
290 $login->id());
291 } else if (ctype_digit($login)) {
292 return XDB::fetchOneCell('SELECT pid
293 FROM profiles
294 WHERE pid = {?}', $login);
295 } else {
296 return XDB::fetchOneCell('SELECT pid
297 FROM profiles
298 WHERE hrpid = {?}', $login);
299 }
300 }
301
302
e7b93962
FB
303 /** Return the profile associated with the given login.
304 */
a3118782
FB
305 public static function get($login)
306 {
b774ddab
FB
307 $pid = self::getPID($login);
308 if (!is_null($pid)) {
309 $data = self::fetchProfileData(array($pid));
310 return new Profile(array_pop($data));
311 } else {
efe597c5
FB
312 /* Let say we can identify a profile using the identifiers of its owner.
313 */
455ea0c9
FB
314 if (!($login instanceof PlUser)) {
315 $user = User::getSilent($login);
316 if ($user && $user->hasProfile()) {
317 return $user->profile();
318 }
efe597c5 319 }
3e53a496 320 return null;
e7b93962
FB
321 }
322 }
a3118782 323
b774ddab
FB
324 /** Return profiles for the list of pids.
325 */
326 public static function getBulkProfilesWithPIDs(array $pids)
327 {
328 if (count($pids) == 0) {
329 return array();
330 }
331 $data = self::fetchProfileData($pids);
332 $inv = array_flip($pids);
333 $profiles = array();
334 foreach ($data AS $p) {
335 $p = new Profile($p);
336 $key = $inv[$p->id()];
337 $profiles[$key] = $p;
338 }
339 return $profiles;
340 }
341
342 /** Return profiles for uids.
343 */
344 public static function getBulkProfilesWithUIDS(array $uids)
345 {
346 if (count($uids) == 0) {
347 return array();
348 }
349 $table = XDB::fetchAllAssoc('uid', 'SELECT ap.uid, ap.pid
350 FROM account_profiles AS ap
351 WHERE FIND_IN_SET(\'owner\', ap.perms)
352 AND ap.uid IN ' . XDB::formatArray($uids));
353 return self::getBulkProfilesWithPIDs($table);
354 }
355
a3118782
FB
356 public static function getNameTypeId($type, $for_sql = false)
357 {
358 if (!S::has('name_types')) {
eb6207f7 359 $table = XDB::fetchAllAssoc('type', 'SELECT id, type
32742f84 360 FROM profile_name_enum');
a3118782
FB
361 S::set('name_types', $table);
362 } else {
363 $table = S::v('name_types');
364 }
365 if ($for_sql) {
366 return XDB::escape($table[$type]);
367 } else {
368 return $table[$type];
369 }
370 }
e7b93962
FB
371}
372
373// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
374?>