Add foreign keys for profile tables.
[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 foreach (array('sectorid', 'subsectorid', 'subsubsectorid') as $key) {
234 if ($job[$key] == 0) {
235 $job[$key] = null;
236 }
237 }
238 foreach ($value as $key => &$job) {
239 $ls = true;
240 $this->geocodeAddress($job['w_address'], $s);
241 $ls = ($ls && $s);
242 $this->cleanJob($page, $key, $job, $s);
243 $ls = ($ls && $s);
244 if (!$init) {
245 $success = ($success && $ls);
246 }
247 }
248 return $value;
249 }
250
251 public function save(ProfilePage &$page, $field, $value)
252 {
253 // TODO: use address class to update profile_job_enum once it is done.
254 XDB::execute("DELETE FROM profile_job
255 WHERE pid = {?}",
256 $page->pid());
257 XDB::execute("DELETE FROM profile_addresses
258 WHERE pid = {?} AND type = 'job'",
259 $page->pid());
260 Phone::deletePhones($page->pid(), Phone::LINK_JOB);
261 $terms_values = array();
262 foreach ($value as $id => &$job) {
263 if (isset($job['name']) && $job['name']) {
264 if (isset($job['jobid']) && $job['jobid']) {
265 XDB::execute("INSERT INTO profile_job (pid, id, description, sectorid, subsectorid,
266 subsubsectorid, email, url, pub, email_pub, jobid)
267 VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})",
268 $page->pid(), $id, $job['description'], $job['sector'], $job['subSector'],
269 $job['subSubSector'], $job['w_email'], $job['w_url'], $job['pub'], $job['w_email_pub'], $job['jobid']);
270 } else {
271 XDB::execute("INSERT INTO profile_job (pid, id, description, sectorid, subsectorid,
272 subsubsectorid, email, url, pub, email_pub)
273 VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})",
274 $page->pid(), $id, $job['description'], $job['sector'], $job['subSector'],
275 $job['subSubSector'], $job['w_email'], $job['w_url'], $job['pub'], $job['w_email_pub']);
276 }
277 $address = new ProfileSettingAddress();
278 $address->saveAddress($page->pid(), $id, $job['w_address'], 'job');
279 Phone::savePhones($job['w_phone'], $page->pid(), Phone::LINK_JOB, $id);
280 if (isset($job['terms'])) {
281 foreach ($job['terms'] as $term) {
282 $terms_values[] = '('.XDB::escape($page->pid()).', '. XDB::escape($id).', '.XDB::escape($term['jtid']).', "original")';
283 }
284 }
285 }
286 }
287 if (count($terms_values) > 0) {
288 XDB::execute('INSERT INTO profile_job_term (pid, jid, jtid, computed)
289 VALUES '.implode(', ', $terms_values));
290 }
291 }
292
293 public function getText($value) {
294 $jobs = array();
295 foreach ($value as $id => $job) {
296 $address = new ProfileSettingAddress();
297 $phones = Phone::formArrayToString($job['w_phone']);
298 $jobs[] = 'Entreprise : ' . $job['name'] . ', secteur : ' . $job['subSubSectorName']
299 . ', description : ' . $job['description'] . ', web : ' . $job['w_url']
300 . ', email : ' . $job['w_email']
301 . ($phones ? ', ' . $phones : '') . ', ' . $address->getText($job['w_address']);
302 }
303 return implode(' ; ' , $jobs);
304 }
305 }
306
307 class ProfileSettingCorps implements ProfileSetting
308 {
309 public function value(ProfilePage &$page, $field, $value, &$success)
310 {
311 $success = true;
312 if (is_null($value)) {
313 $res = XDB::query("SELECT original_corpsid AS original, current_corpsid AS current,
314 rankid AS rank, corps_pub AS pub
315 FROM profile_corps
316 WHERE pid = {?}",
317 $page->pid());
318 return $res->fetchOneAssoc();
319 }
320 return $value;
321 }
322
323 public function save(ProfilePage &$page, $field, $value)
324 {
325 XDB::execute('REPLACE INTO profile_corps (original_corpsid, current_corpsid, rankid, corps_pub, pid)
326 VALUES ({?}, {?}, {?}, {?}, {?})',
327 $value['original'], $value['current'], $value['rank'], $value['pub'], $page->pid());
328 }
329
330 public function getText($value)
331 {
332 $corpsList = DirEnum::getOptions(DirEnum::CORPS);
333 $rankList = DirEnum::getOptions(DirEnum::CORPSRANKS);
334 return 'Corps actuel : ' . $corpsList[$value['current']] . ' , rang : ' . $corpsList[$value['rank']]
335 . ' , corps d\'origine : ' . $corpsList[$value['original']] . ' , affichage : ' . $value['pub'];
336 }
337 }
338
339 class ProfileSettingJobs extends ProfilePage
340 {
341 protected $pg_template = 'profile/jobs.tpl';
342
343 public function __construct(PlWizard &$wiz)
344 {
345 parent::__construct($wiz);
346 $this->settings['cv'] = null;
347 $this->settings['corps'] = new ProfileSettingCorps();
348 $this->settings['jobs'] = new ProfileSettingJob();
349 $this->watched = array('cv' => true, 'jobs' => true, 'corps' => true);
350 }
351
352 protected function _fetchData()
353 {
354 // Checkout the CV
355 $res = XDB::query("SELECT cv
356 FROM profiles
357 WHERE pid = {?}",
358 $this->pid());
359 $this->values['cv'] = $res->fetchOneCell();
360
361 // Build the jobs tree
362 $res = XDB::iterRow("SELECT j.id, j.jobid, je.name, j.sectorid, j.subsectorid, j.subsubsectorid,
363 s.name, j.description, j.email, j.email_pub, j.url, j.pub,
364 je.acronym, je.url, je.email,
365 aw.accuracy, aw.text, aw.postalText, aw.postalCode, aw.localityId,
366 aw.subAdministrativeAreaId, aw.administrativeAreaId, aw.countryId,
367 aw.latitude, aw.longitude, aw.pub, aw.updateTime,
368 aw.north, aw.south, aw.east, aw.west,
369 ah.accuracy, ah.text, ah.postalText, ah.postalCode, ah.localityId,
370 ah.subAdministrativeAreaId, ah.administrativeAreaId, ah.countryId,
371 ah.latitude, ah.longitude, ah.pub, ah.updateTime,
372 ah.north, ah.south, ah.east, ah.west
373 FROM profile_job AS j
374 LEFT JOIN profile_job_enum AS je ON (j.jobid = je.id)
375 LEFT JOIN profile_job_subsubsector_enum AS s ON (s.id = j.subsubsectorid)
376 LEFT JOIN profile_addresses AS aw ON (aw.pid = j.pid AND aw.type = 'job'
377 AND aw.id = j.id)
378 LEFT JOIN profile_addresses AS ah ON (ah.jobid = j.jobid AND ah.type = 'hq')
379 WHERE j.pid = {?}
380 ORDER BY j.id",
381 $this->pid());
382 $this->values['jobs'] = array();
383
384 if ($res->numRows() > 0) {
385 while (list($id, $jobid, $name, $sector, $subSector, $subSubSector,
386 $subSubSectorName, $description, $w_email, $w_emailPub, $w_url, $pub,
387 $hq_acronym, $hq_url, $hq_email,
388 $w_accuracy, $w_text, $w_postalText, $w_postalCode, $w_localityId,
389 $w_subAdministrativeAreaId, $w_administrativeAreaId, $w_countryId,
390 $w_latitude, $w_longitude, $w_pub, $w_updateTime,
391 $w_north, $w_south, $w_east, $w_west,
392 $hq_accuracy, $hq_text, $hq_postalText, $hq_postalCode, $hq_localityId,
393 $hq_subAdministrativeAreaId, $hq_administrativeAreaId, $hq_countryId,
394 $hq_latitude, $hq_longitude, $hq_pub, $hq_updateTime,
395 $hq_north, $hq_south, $hq_east, $hq_west,
396 ) = $res->next()) {
397 $this->values['jobs'][] = array(
398 'id' => $id,
399 'jobid' => $jobid,
400 'name' => $name,
401 'sector' => $sector,
402 'subSector' => $subSector,
403 'subSubSector' => $subSubSector,
404 'subSubSectorName' => $subSubSectorName,
405 'description' => $description,
406 'pub' => $pub,
407 'w_email' => $w_email,
408 'w_email_pub' => $w_emailPub,
409 'w_url' => $w_url,
410 'hq_acronym' => $hq_acronym,
411 'hq_url' => $hq_url,
412 'hq_email' => $hq_email,
413 'w_address' => array(
414 'accuracy' => $w_accuracy,
415 'text' => $w_text,
416 'postalText' => $w_postalText,
417 'postalCode' => $w_postalCode,
418 'localityId' => $w_localityId,
419 'subAdministrativeAreaId' => $w_subAdministrativeAreaId,
420 'administrativeAreaId' => $w_administrativeAreaId,
421 'countryId' => $w_countryId,
422 'latitude' => $w_latitude,
423 'longitude' => $w_longitude,
424 'pub' => $w_pub,
425 'updateTime' => $w_updateTime,
426 'north' => $w_north,
427 'south' => $w_south,
428 'east' => $w_east,
429 'west' => $w_west,
430 ),
431 'hq_address' => array(
432 'accuracy' => $hq_accuracy,
433 'text' => $hq_text,
434 'postalText' => $hq_postalText,
435 'postalCode' => $hq_postalCode,
436 'localityId' => $hq_localityId,
437 'subAdministrativeAreaId' => $hq_subAdministrativeAreaId,
438 'administrativeAreaId' => $hq_administrativeAreaId,
439 'countryId' => $hq_countryId,
440 'latitude' => $hq_latitude,
441 'longitude' => $hq_longitude,
442 'pub' => $hq_pub,
443 'updateTime' => $hq_updateTime,
444 'north' => $hq_north,
445 'south' => $hq_south,
446 'east' => $hq_east,
447 'west' => $hq_west,
448 ),
449 );
450 }
451
452 $it = Phone::iterate(array($this->pid()), array(Phone::LINK_JOB));
453 while ($phone = $it->next()) {
454 $this->values['jobs'][$phone->linkId()]['w_phone'][$phone->id()] = $phone->toFormArray();
455 }
456 $res = XDB::iterator("SELECT e.jtid, e.full_name, j.jid AS jobid
457 FROM profile_job_term_enum AS e
458 INNER JOIN profile_job_term AS j USING(jtid)
459 WHERE pid = {?}
460 ORDER BY j.jid",
461 $this->pid());
462 $i = 0;
463 $jobNb = count($this->values['jobs']);
464 while ($term = $res->next()) {
465 $jobid = $term['jobid'];
466 while ($i < $jobNb && $this->values['jobs'][$i]['id'] < $jobid) {
467 $i++;
468 }
469 if ($i >= $jobNb) {
470 break;
471 }
472 $job =& $this->values['jobs'][$i];
473 if ($job['id'] != $jobid) {
474 continue;
475 }
476 if (!isset($job['terms'])) {
477 $job['terms'] = array();
478 }
479 $job['terms'][] = $term;
480 }
481
482 foreach ($this->values['jobs'] as $id => &$job) {
483 $phone = new Phone();
484 if (!isset($job['w_phone'])) {
485 $job['w_phone'] = array(0 => $phone->toFormArray());
486 }
487 }
488
489 $job['w_email_new'] = '';
490 if (!isset($job['hq_fixed'])) {
491 $job['hq_fixed'] = '';
492 }
493 if (!isset($job['hq_fax'])) {
494 $job['hq_fax'] = '';
495 }
496 if (!isset($job['w_email_pub'])) {
497 $job['w_email_pub'] = 'private';
498 }
499 if (!$job['hq_address']['text']) {
500 $job['hq_address'] = array(
501 'text' => '',
502 'accuracy' => '',
503 'postalText' => '',
504 'postalCode' => '',
505 'administrativeAreaId' => '',
506 'subAdministrativeAreaId' => '',
507 'localityId' => '',
508 'countryId' => '',
509 'latitude' => '',
510 'longitude' => '',
511 'north' => '',
512 'south' => '',
513 'east' => '',
514 'west' => '',
515 'cedex' => '',
516 'updateTime' => '',
517 'changed' => '0',
518 'removed' => '0',
519 );
520 }
521 $job['w_address']['cedex'] = '';
522 $job['w_address']['changed'] = '0';
523 $job['w_address']['removed'] = '0';
524 } else {
525 $this->values['jobs'][] = $this->settings['jobs']->emptyJob();
526 }
527 }
528
529 protected function _saveData()
530 {
531 if ($this->changed['cv']) {
532 XDB::execute("UPDATE profiles
533 SET cv = {?}
534 WHERE pid = {?}",
535 $this->values['cv'], $this->pid());
536 }
537 }
538
539 public function _prepare(PlPage &$page, $id)
540 {
541 require_once 'emails.combobox.inc.php';
542 fill_email_combobox($page, $this->owner);
543
544 $res = XDB::query("SELECT id, name AS label
545 FROM profile_job_sector_enum");
546 $page->assign('sectors', $res->fetchAllAssoc());
547
548 $res = XDB::iterator("SELECT id, name
549 FROM profile_corps_enum
550 ORDER BY id = 1 DESC, name");
551 $page->assign('original_corps', $res->fetchAllAssoc());
552
553 $res = XDB::iterator("SELECT id, name
554 FROM profile_corps_enum
555 WHERE still_exists = 1
556 ORDER BY id = 1 DESC, name");
557 $page->assign('current_corps', $res->fetchAllAssoc());
558
559 $res = XDB::iterator("SELECT id, name
560 FROM profile_corps_rank_enum
561 ORDER BY id = 1 DESC, name");
562 $page->assign('corps_rank', $res->fetchAllAssoc());
563 }
564 }
565
566 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
567 ?>