Replace sectors by job terms in profile and search (job and mentoring).
[platal.git] / modules / profile / jobs.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 ProfileSettingJob extends ProfileSettingGeocoding
23 {
24 private $pub;
25 private $email_new;
26 private $email;
27 private $url;
28 private $bool;
29 private $checks;
30
31 public function __construct()
32 {
33 $this->pub = new ProfileSettingPub();
34 $this->email
35 = $this->email_new
36 = new ProfileSettingEmail();
37 $this->url = new ProfileSettingWeb();
38 $this->bool = new ProfileSettingBool();
39 $this->checks = array('url' => array('w_url'),
40 'email' => array('w_email'),
41 'pub' => array('pub', 'w_email_pub'),
42 );
43 }
44
45 public function emptyJob()
46 {
47 return array(
48 'id' => '0',
49 'jobid' => '',
50 'pub' => 'private',
51 'name' => '',
52 'hq_acronym' => '',
53 'hq_url' => '',
54 'hq_email' => '',
55 'hq_address' => array(
56 'text' => '',
57 'accuracy' => '',
58 'postalText' => '',
59 'postalCode' => '',
60 'administrativeAreaId' => '',
61 'subAdministrativeAreaId' => '',
62 'localityId' => '',
63 'countryId' => '',
64 'latitude' => '',
65 'longitude' => '',
66 'north' => '',
67 'south' => '',
68 'east' => '',
69 'west' => '',
70 'cedex' => '',
71 'updateTime' => '',
72 'changed' => '0',
73 'removed' => '0',
74 ),
75 'hq_fixed' => '',
76 'hq_fax' => '',
77 'subSubSectorName' => null,
78 'sector' => '0',
79 'subSector' => '0',
80 'subSubSector' => '0',
81 'description' => '',
82 'w_url' => '',
83 'w_address' => array(
84 'pub' => 'private',
85 'text' => '',
86 'accuracy' => '',
87 'postalText' => '',
88 'postalCode' => '',
89 'administrativeAreaId' => '',
90 'subAdministrativeAreaId' => '',
91 'localityId' => '',
92 'countryId' => '',
93 'latitude' => '',
94 'longitude' => '',
95 'north' => '',
96 'south' => '',
97 'east' => '',
98 'west' => '',
99 'cedex' => '',
100 'updateTime' => '',
101 'changed' => '0',
102 'removed' => '0',
103 ),
104 'w_email' => '',
105 'w_email_pub' => 'private',
106 'w_email_new' => '',
107 'w_phone' => array(0 => array(
108 'type' => 'fixed',
109 'tel' => '',
110 'pub' => 'private',
111 'comment' => '',
112 ),
113 'terms' => array()),
114 );
115 }
116
117 private function cleanJob(ProfilePage &$page, $jobid, array &$job, &$success)
118 {
119 $success = true;
120 if ($job['w_email'] == "new@example.org") {
121 $job['w_email'] = $job['w_email_new'];
122 }
123 foreach ($this->checks as $obj=>&$fields) {
124 $chk =& $this->$obj;
125 foreach ($fields as $field) {
126 $job[$field] = $chk->value($page, $field, $job[$field], $s);
127 if (!$s) {
128 $success = false;
129 $job[$field . '_error'] = true;
130 }
131 }
132 }
133 if (!$job['subSubSectorName']) {
134 $res = XDB::query("SELECT name
135 FROM profile_job_subsubsector_enum
136 WHERE id = {?}",
137 $job['subSubSector']);
138 $job['subSubSectorName'] = $res->fetchOneCell();
139 } else {
140 $res = XDB::query("SELECT sectorid, subsectorid, id
141 FROM profile_job_subsubsector_enum
142 WHERE name = {?}",
143 $job['subSubSectorName']);
144 if ($res->numRows() != 1) {
145 $success = false;
146 $job['sector_error'] = true;
147 } else {
148 list($job['sector'], $job['subSector'], $job['subSubSector']) = $res->fetchOneRow();
149 }
150 }
151 if (count($job['terms'])) {
152 $termsid = array();
153 foreach ($job['terms'] as $term) {
154 if (!$term['full_name']) {
155 $termsid[] = $term['jtid'];
156 }
157 }
158 if (count($termsid)) {
159 $res = XDB::query("SELECT jtid, full_name
160 FROM profile_job_term_enum
161 WHERE jtid IN {?}",
162 $termsid);
163 $term_id_to_name = $res->fetchAllAssoc('jtid', false);
164 foreach ($job['terms'] as &$term) {
165 if (!$term['full_name']) {
166 $term['full_name'] = $term_id_to_name[$term['jtid']];
167 }
168 }
169 }
170 }
171 if ($job['name']) {
172 $res = XDB::query("SELECT id
173 FROM profile_job_enum
174 WHERE name = {?}",
175 $job['name']);
176 if ($res->numRows() != 1) {
177 $this->geocodeAddress($job['hq_address'], $s);
178 if (!$s) {
179 $gmapsGeocoder = new GMapsGeocoder();
180 $job['hq_address'] = $gmapsGeocoder->stripGeocodingFromAddress($job['hq_address']);
181 }
182 $req = new EntrReq(S::user(), $page->profile, $jobid, $job['name'], $job['hq_acronym'], $job['hq_url'],
183 $job['hq_email'], $job['hq_fixed'], $job['hq_fax'], $job['hq_address']);
184 $req->submit();
185 $job['jobid'] = null;
186 sleep(1);
187 } else {
188 $job['jobid'] = $res->fetchOneCell();
189 }
190 }
191 $job['w_address']['pub'] = $this->pub->value($page, 'address_pub', $job['w_address']['pub'], $s);
192 $job['w_phone'] = Phone::formatFormArray($job['w_phone'], $s);
193
194 unset($job['removed']);
195 unset($job['new']);
196 }
197
198 public function value(ProfilePage &$page, $field, $value, &$success)
199 {
200 require_once 'validations.inc.php';
201 $entreprise = ProfileValidate::get_typed_requests($page->pid(), 'entreprise');
202 $entr_val = 0;
203
204 $init = false;
205 if (is_null($value)) {
206 $value = $page->values['jobs'];
207 $init = true;
208 }
209 $success = true;
210 foreach ($value as $key => &$job) {
211 $job['name'] = trim($job['name']);
212 if ($job['name'] == '' && $entreprise) {
213 $job['tmp_name'] = $entreprise[$entr_val]->name;
214 ++$entr_val;
215 } else if ($job['name'] == '') {
216 if ($job['subSubSectorName'] == '' && $job['description'] == '' && $job['w_url'] == ''
217 && $job['w_address']['text'] == '' && $job['w_email'] == ''
218 && count($job['w_phone']) == 1 && $job['w_phone']['tel'] == '') {
219 array_splice($value, $key, 1);
220 continue;
221 }
222
223 $job['name_error'] = true;
224 $success = false;
225 }
226
227 if (isset($job['removed']) && $job['removed']) {
228 if ($job['name'] == '' && $entreprise) {
229 $entreprise[$entr_val - 1]->clean();
230 }
231 array_splice($value, $key, 1);
232 }
233 }
234 foreach ($value as $key => &$job) {
235 $ls = true;
236 $this->geocodeAddress($job['w_address'], $s);
237 $ls = ($ls && $s);
238 $this->cleanJob($page, $key, $job, $s);
239 $ls = ($ls && $s);
240 if (!$init) {
241 $success = ($success && $ls);
242 }
243 }
244 return $value;
245 }
246
247 public function save(ProfilePage &$page, $field, $value)
248 {
249 // TODO: use address class to update profile_job_enum once it is done.
250 XDB::execute("DELETE FROM profile_job
251 WHERE pid = {?}",
252 $page->pid());
253 XDB::execute("DELETE FROM profile_addresses
254 WHERE pid = {?} AND type = 'job'",
255 $page->pid());
256 Phone::deletePhones($page->pid(), Phone::LINK_JOB);
257 $terms_values = array();
258 foreach ($value as $id => &$job) {
259 if (isset($job['name']) && $job['name']) {
260 if (isset($job['jobid']) && $job['jobid']) {
261 XDB::execute("INSERT INTO profile_job (pid, id, description, sectorid, subsectorid,
262 subsubsectorid, email, url, pub, email_pub, jobid)
263 VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})",
264 $page->pid(), $id, $job['description'], $job['sector'], $job['subSector'],
265 $job['subSubSector'], $job['w_email'], $job['w_url'], $job['pub'], $job['w_email_pub'], $job['jobid']);
266 } else {
267 XDB::execute("INSERT INTO profile_job (pid, id, description, sectorid, subsectorid,
268 subsubsectorid, email, url, pub, email_pub)
269 VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})",
270 $page->pid(), $id, $job['description'], $job['sector'], $job['subSector'],
271 $job['subSubSector'], $job['w_email'], $job['w_url'], $job['pub'], $job['w_email_pub']);
272 }
273 $address = new ProfileSettingAddress();
274 $address->saveAddress($page->pid(), $id, $job['w_address'], 'job');
275 Phone::savePhones($job['w_phone'], $page->pid(), Phone::LINK_JOB, $id);
276 if (isset($job['terms'])) {
277 foreach ($job['terms'] as $term) {
278 $terms_values[] = '('.XDB::escape($page->pid()).', '. XDB::escape($id).', '.XDB::escape($term['jtid']).', "original")';
279 }
280 }
281 }
282 }
283 if (count($terms_values) > 0) {
284 XDB::execute('INSERT INTO profile_job_term (pid, jid, jtid, computed)
285 VALUES '.implode(', ', $terms_values));
286 }
287 }
288
289 public function getText($value) {
290 $jobs = array();
291 foreach ($value as $id => $job) {
292 $address = new ProfileSettingAddress();
293 $phones = Phone::formArrayToString($job['w_phone']);
294 $jobs[] = 'Entreprise : ' . $job['name'] . ', secteur : ' . $job['subSubSectorName']
295 . ', description : ' . $job['description'] . ', web : ' . $job['w_url']
296 . ', email : ' . $job['w_email']
297 . ($phones ? ', ' . $phones : '') . ', ' . $address->getText($job['w_address']);
298 }
299 return implode(' ; ' , $jobs);
300 }
301 }
302
303 class ProfileSettingCorps implements ProfileSetting
304 {
305 public function value(ProfilePage &$page, $field, $value, &$success)
306 {
307 $success = true;
308 if (is_null($value)) {
309 $res = XDB::query("SELECT original_corpsid AS original, current_corpsid AS current,
310 rankid AS rank, corps_pub AS pub
311 FROM profile_corps
312 WHERE pid = {?}",
313 $page->pid());
314 return $res->fetchOneAssoc();
315 }
316 return $value;
317 }
318
319 public function save(ProfilePage &$page, $field, $value)
320 {
321 XDB::execute('REPLACE INTO profile_corps (original_corpsid, current_corpsid, rankid, corps_pub, pid)
322 VALUES ({?}, {?}, {?}, {?}, {?})',
323 $value['original'], $value['current'], $value['rank'], $value['pub'], $page->pid());
324 }
325
326 public function getText($value)
327 {
328 $corpsList = DirEnum::getOptions(DirEnum::CORPS);
329 $rankList = DirEnum::getOptions(DirEnum::CORPSRANKS);
330 return 'Corps actuel : ' . $corpsList[$value['current']] . ' , rang : ' . $corpsList[$value['rank']]
331 . ' , corps d\'origine : ' . $corpsList[$value['original']] . ' , affichage : ' . $value['pub'];
332 }
333 }
334
335 class ProfileSettingJobs extends ProfilePage
336 {
337 protected $pg_template = 'profile/jobs.tpl';
338
339 public function __construct(PlWizard &$wiz)
340 {
341 parent::__construct($wiz);
342 $this->settings['cv'] = null;
343 $this->settings['corps'] = new ProfileSettingCorps();
344 $this->settings['jobs'] = new ProfileSettingJob();
345 $this->watched = array('cv' => true, 'jobs' => true, 'corps' => true);
346 }
347
348 protected function _fetchData()
349 {
350 // Checkout the CV
351 $res = XDB::query("SELECT cv
352 FROM profiles
353 WHERE pid = {?}",
354 $this->pid());
355 $this->values['cv'] = $res->fetchOneCell();
356
357 // Build the jobs tree
358 $res = XDB::iterRow("SELECT j.id, j.jobid, je.name, j.sectorid, j.subsectorid, j.subsubsectorid,
359 s.name, j.description, j.email, j.email_pub, j.url, j.pub,
360 je.acronym, je.url, je.email,
361 aw.accuracy, aw.text, aw.postalText, aw.postalCode, aw.localityId,
362 aw.subAdministrativeAreaId, aw.administrativeAreaId, aw.countryId,
363 aw.latitude, aw.longitude, aw.pub, aw.updateTime,
364 aw.north, aw.south, aw.east, aw.west,
365 ah.accuracy, ah.text, ah.postalText, ah.postalCode, ah.localityId,
366 ah.subAdministrativeAreaId, ah.administrativeAreaId, ah.countryId,
367 ah.latitude, ah.longitude, ah.pub, ah.updateTime,
368 ah.north, ah.south, ah.east, ah.west
369 FROM profile_job AS j
370 LEFT JOIN profile_job_enum AS je ON (j.jobid = je.id)
371 LEFT JOIN profile_job_subsubsector_enum AS s ON (s.id = j.subsubsectorid)
372 LEFT JOIN profile_addresses AS aw ON (aw.pid = j.pid AND aw.type = 'job'
373 AND aw.id = j.id)
374 LEFT JOIN profile_addresses AS ah ON (ah.jobid = j.jobid AND ah.type = 'hq')
375 WHERE j.pid = {?}
376 ORDER BY j.id",
377 $this->pid());
378 $this->values['jobs'] = array();
379
380 if ($res->numRows() > 0) {
381 while (list($id, $jobid, $name, $sector, $subSector, $subSubSector,
382 $subSubSectorName, $description, $w_email, $w_emailPub, $w_url, $pub,
383 $hq_acronym, $hq_url, $hq_email,
384 $w_accuracy, $w_text, $w_postalText, $w_postalCode, $w_localityId,
385 $w_subAdministrativeAreaId, $w_administrativeAreaId, $w_countryId,
386 $w_latitude, $w_longitude, $w_pub, $w_updateTime,
387 $w_north, $w_south, $w_east, $w_west,
388 $hq_accuracy, $hq_text, $hq_postalText, $hq_postalCode, $hq_localityId,
389 $hq_subAdministrativeAreaId, $hq_administrativeAreaId, $hq_countryId,
390 $hq_latitude, $hq_longitude, $hq_pub, $hq_updateTime,
391 $hq_north, $hq_south, $hq_east, $hq_west,
392 ) = $res->next()) {
393 $this->values['jobs'][] = array(
394 'id' => $id,
395 'jobid' => $jobid,
396 'name' => $name,
397 'sector' => $sector,
398 'subSector' => $subSector,
399 'subSubSector' => $subSubSector,
400 'subSubSectorName' => $subSubSectorName,
401 'description' => $description,
402 'pub' => $pub,
403 'w_email' => $w_email,
404 'w_email_pub' => $w_emailPub,
405 'w_url' => $w_url,
406 'hq_acronym' => $hq_acronym,
407 'hq_url' => $hq_url,
408 'hq_email' => $hq_email,
409 'w_address' => array(
410 'accuracy' => $w_accuracy,
411 'text' => $w_text,
412 'postalText' => $w_postalText,
413 'postalCode' => $w_postalCode,
414 'localityId' => $w_localityId,
415 'subAdministrativeAreaId' => $w_subAdministrativeAreaId,
416 'administrativeAreaId' => $w_administrativeAreaId,
417 'countryId' => $w_countryId,
418 'latitude' => $w_latitude,
419 'longitude' => $w_longitude,
420 'pub' => $w_pub,
421 'updateTime' => $w_updateTime,
422 'north' => $w_north,
423 'south' => $w_south,
424 'east' => $w_east,
425 'west' => $w_west,
426 ),
427 'hq_address' => array(
428 'accuracy' => $hq_accuracy,
429 'text' => $hq_text,
430 'postalText' => $hq_postalText,
431 'postalCode' => $hq_postalCode,
432 'localityId' => $hq_localityId,
433 'subAdministrativeAreaId' => $hq_subAdministrativeAreaId,
434 'administrativeAreaId' => $hq_administrativeAreaId,
435 'countryId' => $hq_countryId,
436 'latitude' => $hq_latitude,
437 'longitude' => $hq_longitude,
438 'pub' => $hq_pub,
439 'updateTime' => $hq_updateTime,
440 'north' => $hq_north,
441 'south' => $hq_south,
442 'east' => $hq_east,
443 'west' => $hq_west,
444 ),
445 );
446 }
447
448 $it = Phone::iterate(array($this->pid()), array(Phone::LINK_JOB));
449 while ($phone = $it->next()) {
450 $this->values['jobs'][$phone->linkId()]['w_phone'][$phone->id()] = $phone->toFormArray();
451 }
452 $res = XDB::iterator("SELECT e.jtid, e.full_name, j.jid AS jobid
453 FROM profile_job_term_enum AS e
454 INNER JOIN profile_job_term AS j USING(jtid)
455 WHERE pid = {?}
456 ORDER BY j.jid",
457 $this->pid());
458 $i = 0;
459 $jobNb = count($this->values['jobs']);
460 while ($term = $res->next()) {
461 $jobid = $term['jobid'];
462 while ($i < $jobNb && $this->values['jobs'][$i]['id'] < $jobid) {
463 $i++;
464 }
465 if ($i >= $jobNb) {
466 break;
467 }
468 $job =& $this->values['jobs'][$i];
469 if ($job['id'] != $jobid) {
470 continue;
471 }
472 if (!isset($job['terms'])) {
473 $job['terms'] = array();
474 }
475 $job['terms'][] = $term;
476 }
477
478 foreach ($this->values['jobs'] as $id => &$job) {
479 $phone = new Phone();
480 if (!isset($job['w_phone'])) {
481 $job['w_phone'] = array(0 => $phone->toFormArray());
482 }
483 }
484
485 $job['w_email_new'] = '';
486 if (!isset($job['hq_fixed'])) {
487 $job['hq_fixed'] = '';
488 }
489 if (!isset($job['hq_fax'])) {
490 $job['hq_fax'] = '';
491 }
492 if (!isset($job['w_email_pub'])) {
493 $job['w_email_pub'] = 'private';
494 }
495 if (!$job['hq_address']['text']) {
496 $job['hq_address'] = array(
497 'text' => '',
498 'accuracy' => '',
499 'postalText' => '',
500 'postalCode' => '',
501 'administrativeAreaId' => '',
502 'subAdministrativeAreaId' => '',
503 'localityId' => '',
504 'countryId' => '',
505 'latitude' => '',
506 'longitude' => '',
507 'north' => '',
508 'south' => '',
509 'east' => '',
510 'west' => '',
511 'cedex' => '',
512 'updateTime' => '',
513 'changed' => '0',
514 'removed' => '0',
515 );
516 }
517 $job['w_address']['cedex'] = '';
518 $job['w_address']['changed'] = '0';
519 $job['w_address']['removed'] = '0';
520 } else {
521 $this->values['jobs'][] = $this->settings['jobs']->emptyJob();
522 }
523 }
524
525 protected function _saveData()
526 {
527 if ($this->changed['cv']) {
528 XDB::execute("UPDATE profiles
529 SET cv = {?}
530 WHERE pid = {?}",
531 $this->values['cv'], $this->pid());
532 }
533 }
534
535 public function _prepare(PlPage &$page, $id)
536 {
537 require_once 'emails.combobox.inc.php';
538 fill_email_combobox($page, $this->owner);
539
540 $res = XDB::query("SELECT id, name AS label
541 FROM profile_job_sector_enum");
542 $page->assign('sectors', $res->fetchAllAssoc());
543
544 $res = XDB::iterator("SELECT id, name
545 FROM profile_corps_enum
546 ORDER BY id = 1 DESC, name");
547 $page->assign('original_corps', $res->fetchAllAssoc());
548
549 $res = XDB::iterator("SELECT id, name
550 FROM profile_corps_enum
551 WHERE still_exists = 1
552 ORDER BY id = 1 DESC, name");
553 $page->assign('current_corps', $res->fetchAllAssoc());
554
555 $res = XDB::iterator("SELECT id, name
556 FROM profile_corps_rank_enum
557 ORDER BY id = 1 DESC, name");
558 $page->assign('corps_rank', $res->fetchAllAssoc());
559 }
560 }
561
562 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
563 ?>