Replace sectors by job terms in profile and search (job and mentoring).
[platal.git] / modules / profile / jobs.inc.php
CommitLineData
3950bc21
FB
1<?php
2/***************************************************************************
9f5bd98e 3 * Copyright (C) 2003-2010 Polytechnique.org *
3950bc21
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
12bcf04b 22class ProfileSettingJob extends ProfileSettingGeocoding
37d44b3b
FB
23{
24 private $pub;
541e8d03
SJ
25 private $email_new;
26 private $email;
27 private $url;
f93fb300 28 private $bool;
37d44b3b
FB
29 private $checks;
30
31 public function __construct()
32 {
12bcf04b 33 $this->pub = new ProfileSettingPub();
541e8d03
SJ
34 $this->email
35 = $this->email_new
12bcf04b
RB
36 = new ProfileSettingEmail();
37 $this->url = new ProfileSettingWeb();
38 $this->bool = new ProfileSettingBool();
541e8d03
SJ
39 $this->checks = array('url' => array('w_url'),
40 'email' => array('w_email'),
41 'pub' => array('pub', 'w_email_pub'),
42 );
37d44b3b
FB
43 }
44
afaa2cc7
SJ
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 ),
0b6c8b36 75 'hq_fixed' => '',
afaa2cc7
SJ
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' => '',
3ac45f10
PC
112 ),
113 'terms' => array()),
afaa2cc7
SJ
114 );
115 }
116
b814a8b8 117 private function cleanJob(ProfilePage &$page, $jobid, array &$job, &$success)
37d44b3b
FB
118 {
119 $success = true;
541e8d03
SJ
120 if ($job['w_email'] == "new@example.org") {
121 $job['w_email'] = $job['w_email_new'];
122 }
37d44b3b
FB
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 }
541e8d03 133 if (!$job['subSubSectorName']) {
c7139c07
SJ
134 $res = XDB::query("SELECT name
135 FROM profile_job_subsubsector_enum
136 WHERE id = {?}",
541e8d03
SJ
137 $job['subSubSector']);
138 $job['subSubSectorName'] = $res->fetchOneCell();
c7139c07
SJ
139 } else {
140 $res = XDB::query("SELECT sectorid, subsectorid, id
141 FROM profile_job_subsubsector_enum
142 WHERE name = {?}",
541e8d03 143 $job['subSubSectorName']);
c7139c07
SJ
144 if ($res->numRows() != 1) {
145 $success = false;
146 $job['sector_error'] = true;
147 } else {
541e8d03 148 list($job['sector'], $job['subSector'], $job['subSubSector']) = $res->fetchOneRow();
c7139c07
SJ
149 }
150 }
3ac45f10
PC
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 }
b814a8b8 171 if ($job['name']) {
c7139c07
SJ
172 $res = XDB::query("SELECT id
173 FROM profile_job_enum
174 WHERE name = {?}",
175 $job['name']);
176 if ($res->numRows() != 1) {
4d7d27fc
SJ
177 $this->geocodeAddress($job['hq_address'], $s);
178 if (!$s) {
179 $gmapsGeocoder = new GMapsGeocoder();
180 $job['hq_address'] = $gmapsGeocoder->stripGeocodingFromAddress($job['hq_address']);
181 }
024ec1e5 182 $req = new EntrReq(S::user(), $page->profile, $jobid, $job['name'], $job['hq_acronym'], $job['hq_url'],
4d7d27fc 183 $job['hq_email'], $job['hq_fixed'], $job['hq_fax'], $job['hq_address']);
b814a8b8
SJ
184 $req->submit();
185 $job['jobid'] = null;
858a5b42 186 sleep(1);
c7139c07
SJ
187 } else {
188 $job['jobid'] = $res->fetchOneCell();
189 }
190 }
541e8d03 191 $job['w_address']['pub'] = $this->pub->value($page, 'address_pub', $job['w_address']['pub'], $s);
0b6c8b36 192 $job['w_phone'] = Phone::formatFormArray($job['w_phone'], $s);
afaa2cc7 193
37d44b3b
FB
194 unset($job['removed']);
195 unset($job['new']);
37d44b3b
FB
196 }
197
198 public function value(ProfilePage &$page, $field, $value, &$success)
199 {
a6483c12 200 require_once 'validations.inc.php';
024ec1e5 201 $entreprise = ProfileValidate::get_typed_requests($page->pid(), 'entreprise');
b814a8b8
SJ
202 $entr_val = 0;
203
37d44b3b
FB
204 $init = false;
205 if (is_null($value)) {
206 $value = $page->values['jobs'];
207 $init = true;
208 }
209 $success = true;
a6483c12 210 foreach ($value as $key => &$job) {
b814a8b8 211 $job['name'] = trim($job['name']);
a6483c12 212 if ($job['name'] == '' && $entreprise) {
b814a8b8 213 $job['tmp_name'] = $entreprise[$entr_val]->name;
a6483c12
SJ
214 ++$entr_val;
215 } else if ($job['name'] == '') {
ba6ee875
SJ
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
a6483c12
SJ
223 $job['name_error'] = true;
224 $success = false;
b814a8b8 225 }
b94719c1 226
541e8d03 227 if (isset($job['removed']) && $job['removed']) {
b94719c1
SJ
228 if ($job['name'] == '' && $entreprise) {
229 $entreprise[$entr_val - 1]->clean();
230 }
ed01acac 231 array_splice($value, $key, 1);
37d44b3b
FB
232 }
233 }
a6483c12 234 foreach ($value as $key => &$job) {
37d44b3b 235 $ls = true;
541e8d03 236 $this->geocodeAddress($job['w_address'], $s);
37d44b3b 237 $ls = ($ls && $s);
bde2be3b 238 $this->cleanJob($page, $key, $job, $s);
37d44b3b
FB
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 {
0b6c8b36 249 // TODO: use address class to update profile_job_enum once it is done.
c7139c07 250 XDB::execute("DELETE FROM profile_job
ce0b2c6f 251 WHERE pid = {?}",
a6483c12 252 $page->pid());
541e8d03
SJ
253 XDB::execute("DELETE FROM profile_addresses
254 WHERE pid = {?} AND type = 'job'",
a6483c12 255 $page->pid());
0b6c8b36 256 Phone::deletePhones($page->pid(), Phone::LINK_JOB);
3ac45f10 257 $terms_values = array();
a6483c12 258 foreach ($value as $id => &$job) {
afaa2cc7
SJ
259 if (isset($job['name']) && $job['name']) {
260 if (isset($job['jobid']) && $job['jobid']) {
ce0b2c6f 261 XDB::execute("INSERT INTO profile_job (pid, id, description, sectorid, subsectorid,
afaa2cc7
SJ
262 subsubsectorid, email, url, pub, email_pub, jobid)
263 VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})",
a6483c12 264 $page->pid(), $id, $job['description'], $job['sector'], $job['subSector'],
afaa2cc7
SJ
265 $job['subSubSector'], $job['w_email'], $job['w_url'], $job['pub'], $job['w_email_pub'], $job['jobid']);
266 } else {
ce0b2c6f 267 XDB::execute("INSERT INTO profile_job (pid, id, description, sectorid, subsectorid,
afaa2cc7
SJ
268 subsubsectorid, email, url, pub, email_pub)
269 VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})",
a6483c12 270 $page->pid(), $id, $job['description'], $job['sector'], $job['subSector'],
afaa2cc7
SJ
271 $job['subSubSector'], $job['w_email'], $job['w_url'], $job['pub'], $job['w_email_pub']);
272 }
12bcf04b 273 $address = new ProfileSettingAddress();
a6483c12 274 $address->saveAddress($page->pid(), $id, $job['w_address'], 'job');
0b6c8b36 275 Phone::savePhones($job['w_phone'], $page->pid(), Phone::LINK_JOB, $id);
3ac45f10
PC
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 }
b814a8b8 281 }
37d44b3b 282 }
3ac45f10
PC
283 if (count($terms_values) > 0) {
284 XDB::execute('INSERT INTO profile_job_term (pid, jid, jtid, computed)
285 VALUES '.implode(', ', $terms_values));
286 }
37d44b3b 287 }
a0fce0c6
SJ
288
289 public function getText($value) {
290 $jobs = array();
291 foreach ($value as $id => $job) {
292 $address = new ProfileSettingAddress();
0b6c8b36 293 $phones = Phone::formArrayToString($job['w_phone']);
a0fce0c6
SJ
294 $jobs[] = 'Entreprise : ' . $job['name'] . ', secteur : ' . $job['subSubSectorName']
295 . ', description : ' . $job['description'] . ', web : ' . $job['w_url']
296 . ', email : ' . $job['w_email']
0b6c8b36 297 . ($phones ? ', ' . $phones : '') . ', ' . $address->getText($job['w_address']);
a0fce0c6
SJ
298 }
299 return implode(' ; ' , $jobs);
300 }
37d44b3b
FB
301}
302
603aeb6c
SJ
303class 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
12bcf04b 335class ProfileSettingJobs extends ProfilePage
3950bc21
FB
336{
337 protected $pg_template = 'profile/jobs.tpl';
338
339 public function __construct(PlWizard &$wiz)
340 {
341 parent::__construct($wiz);
37d44b3b 342 $this->settings['cv'] = null;
603aeb6c 343 $this->settings['corps'] = new ProfileSettingCorps();
12bcf04b 344 $this->settings['jobs'] = new ProfileSettingJob();
72e96bc0 345 $this->watched = array('cv' => true, 'jobs' => true, 'corps' => true);
37d44b3b
FB
346 }
347
7c2e0f0d 348 protected function _fetchData()
37d44b3b 349 {
37d44b3b
FB
350 // Checkout the CV
351 $res = XDB::query("SELECT cv
e5bcd851
FB
352 FROM profiles
353 WHERE pid = {?}",
354 $this->pid());
37d44b3b
FB
355 $this->values['cv'] = $res->fetchOneCell();
356
357 // Build the jobs tree
563f86f5 358 $res = XDB::iterRow("SELECT j.id, j.jobid, je.name, j.sectorid, j.subsectorid, j.subsubsectorid,
541e8d03
SJ
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
c7139c07
SJ
369 FROM profile_job AS j
370 LEFT JOIN profile_job_enum AS je ON (j.jobid = je.id)
c7139c07 371 LEFT JOIN profile_job_subsubsector_enum AS s ON (s.id = j.subsubsectorid)
ce0b2c6f 372 LEFT JOIN profile_addresses AS aw ON (aw.pid = j.pid AND aw.type = 'job'
4d7d27fc 373 AND aw.id = j.id)
541e8d03 374 LEFT JOIN profile_addresses AS ah ON (ah.jobid = j.jobid AND ah.type = 'hq')
ce0b2c6f 375 WHERE j.pid = {?}
541e8d03 376 ORDER BY j.id",
a6391000 377 $this->pid());
37d44b3b 378 $this->values['jobs'] = array();
bde2be3b 379
afaa2cc7
SJ
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 );
bde2be3b 446 }
afaa2cc7 447
0b6c8b36
SJ
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();
bde2be3b 451 }
3ac45f10
PC
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
afaa2cc7 478 foreach ($this->values['jobs'] as $id => &$job) {
0b6c8b36 479 $phone = new Phone();
afaa2cc7 480 if (!isset($job['w_phone'])) {
0b6c8b36 481 $job['w_phone'] = array(0 => $phone->toFormArray());
afaa2cc7 482 }
bde2be3b 483 }
aab2ffdd 484
afaa2cc7 485 $job['w_email_new'] = '';
0b6c8b36
SJ
486 if (!isset($job['hq_fixed'])) {
487 $job['hq_fixed'] = '';
bde2be3b 488 }
afaa2cc7
SJ
489 if (!isset($job['hq_fax'])) {
490 $job['hq_fax'] = '';
bde2be3b 491 }
afaa2cc7
SJ
492 if (!isset($job['w_email_pub'])) {
493 $job['w_email_pub'] = 'private';
bde2be3b 494 }
afaa2cc7
SJ
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();
bde2be3b 522 }
37d44b3b
FB
523 }
524
7c2e0f0d 525 protected function _saveData()
37d44b3b
FB
526 {
527 if ($this->changed['cv']) {
e5bcd851 528 XDB::execute("UPDATE profiles
37d44b3b 529 SET cv = {?}
e5bcd851
FB
530 WHERE pid = {?}",
531 $this->values['cv'], $this->pid());
37d44b3b 532 }
3950bc21 533 }
2dcac0f5 534
04334c61 535 public function _prepare(PlPage &$page, $id)
2dcac0f5 536 {
a6483c12 537 require_once 'emails.combobox.inc.php';
4e698dc9 538 fill_email_combobox($page, $this->owner);
b715c1e1 539
33b6f5a0
SJ
540 $res = XDB::query("SELECT id, name AS label
541 FROM profile_job_sector_enum");
541e8d03 542 $page->assign('sectors', $res->fetchAllAssoc());
72e96bc0
SJ
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
e489faf7
SJ
556 FROM profile_corps_rank_enum
557 ORDER BY id = 1 DESC, name");
72e96bc0 558 $page->assign('corps_rank', $res->fetchAllAssoc());
2dcac0f5 559 }
3950bc21
FB
560}
561
562// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
563?>