/[drupal]/contributions/modules/jobsearch/job.module
ViewVC logotype

Contents of /contributions/modules/jobsearch/job.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.19 - (show annotations) (download) (as text)
Fri Jan 2 02:49:21 2009 UTC (10 months, 3 weeks ago) by kbahey
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-6--1
Changes since 1.18: +108 -71 lines
File MIME type: text/x-php
Initial Drupal 6.x port, by xamount. Email does not work yet.
1 <?php
2
3 // $Id$
4
5 // Copyright Khalid Baheyeldin 2006-2009 http://2bits.com
6
7 define('JOB_NODE_TYPE', 'job_node_type_');
8 define('RESUME_NODE_TYPE', 'resume_node_type_');
9
10 define('JOB_EMAIL', 'job_email');
11
12 define('JOB_PERM_APPLY', 'apply for jobs');
13 define('JOB_PERM_MANAGE', 'manage job applications');
14
15 /**
16 * Implementation of hook_help().
17 */
18
19 function job_help($path, $arg) {
20 switch ($path) {
21 case 'admin/help#job':
22 return t('Allows users to apply for jobs posted.');
23 }
24 }
25
26 /**
27 * Implementation of hook_perm().
28 */
29
30 function job_perm() {
31 return array(
32 JOB_PERM_APPLY,
33 JOB_PERM_MANAGE,
34 );
35 }
36
37 /**
38 * Implementation of hook_menu().
39 */
40 function job_menu() {
41 $items['admin/settings/job'] = array(
42 'title' => 'Job',
43 'description' => 'Job settings.',
44 'page callback' => 'drupal_get_form',
45 'page arguments' => array('job_admin_settings'),
46 'access arguments' => array('administer site configuration'),
47 );
48
49 $items['job/apply'] = array(
50 'page callback' => 'job_apply',
51 'type' => MENU_CALLBACK,
52 'access arguments' => array('access content'),
53 );
54
55 $items['job/clear'] = array(
56 'callback' => 'job_clear',
57 'type' => MENU_CALLBACK,
58 'access arguments' => array(JOB_PERM_MANAGE),
59 );
60
61 $items['job/applications'] = array(
62 'page callback' => 'job_view',
63 'title' => 'Job applications',
64 'type' => MENU_SUGGESTED_ITEM,
65 'access arguments' => array(JOB_PERM_MANAGE),
66 );
67
68 return $items;
69 }
70
71 function job_admin_settings() {
72 $set = 'job';
73 $form[$set] = array(
74 '#type' => 'fieldset',
75 '#title' => t('Enable job application for these content types'),
76 );
77
78 foreach(node_get_types() as $type => $name) {
79 $form[$set][JOB_NODE_TYPE . $type] = array(
80 '#type' => 'checkbox',
81 '#title' => $type,
82 '#return_value' => 1,
83 '#default_value' => variable_get(JOB_NODE_TYPE . $type, 0),
84 );
85 }
86
87 return system_settings_form($form);
88 }
89
90 /**
91 * Implementation of hook_link().
92 */
93
94 function job_link($type, $node = null, $teaser = FALSE) {
95 global $user;
96 $links = array();
97 if ($type == 'node') {
98 // We are viewing a node
99 if (variable_get(JOB_NODE_TYPE . $node->type, 0)) {
100 // Node type is enabled for job apply
101 if (!$user->uid) {
102 // User is not logged in
103 $links['job_apply'] = array(
104 'title' => t('Please login or register to apply'),
105 'href' => 'user/login',
106 );
107 }
108 else {
109 // User is logged in
110 if (_job_check($node->nid, $user->uid)) {
111 // User has applied for this job
112 $links['job_apply'] = array(
113 'title' => t('You applied for this job'),
114 );
115 return $links;
116 }
117 else {
118 // User has not applied for this job
119 $links['job_apply'] = array(
120 'title' => t('Apply for this job'),
121 'href' => "job/apply/$node->nid",
122 );
123 }
124 }
125 }
126 }
127 return $links;
128 }
129
130 /**
131 * Implementation of hook_user().
132 */
133
134 function job_user($op, &$edit, &$account, $category = NULL) {
135 global $user;
136 switch ($op) {
137 case 'view':
138 if ($user->uid == $account->uid) {
139 // User is viewing own account
140 if (user_access(JOB_PERM_MANAGE)) {
141 return array(t('Job applications') => array(array('value' => l(t('View job applications'), 'job/applications'))));
142 }
143 }
144 break;
145 }
146 }
147
148 function job_apply() {
149 global $user;
150 $job_nid = (int)arg(2);
151 $resume_nid = (int)arg(3);
152
153 if (!$user->uid) {
154 drupal_set_message(t('Please !login or !register to apply',
155 array(
156 '!login' => l(t('login'), 'user/login'),
157 '!register' => l(t('register'), 'user/register')
158 )));
159 drupal_goto("node/$nid");
160 }
161
162 if (!user_access(JOB_PERM_APPLY)) {
163 drupal_set_message(t('You are not authorized to apply for jobs.'));
164 drupal_goto("node/$job_nid");
165 }
166
167 if (!$job_nid) {
168 drupal_set_message(t('No job specified.'));
169 drupal_goto("node/$job_nid");
170 }
171
172 if ($resume_nid) {
173 job_apply_do($job_nid, $resume_nid);
174 drupal_goto("node/$job_nid");
175 }
176
177 $job = node_load(array('nid' => $job_nid));
178
179 $resume_list = job_resume_list($user->uid);
180
181 if (!$resume_list) {
182 $msg = t('Please !create to apply', array('!create' => l(t('create a resume'), 'node/add')));
183 drupal_set_message($msg);
184 drupal_goto("node/$job_nid");
185 }
186
187 if(count($resume_list) == 1) {
188 drupal_goto("job/apply/$job_nid/$resume_nid{$resume_list[0]['nid']}");
189 }
190
191 $output .= '<br/>' . t('Position: ') . $job->title . '<br>';
192 $output .= '<br/>' . t('Select from your resumes below, or !create',
193 array('!create' => l(t('create a new resume'), "node/add")));
194 $output .= '<br/>';
195
196 foreach($resume_list as $resume) {
197 $view = l(t('view'), 'node/' . $resume['nid']);
198 $apply = l(t('apply'), "job/apply/$job_nid/$resume_nid" . $resume['nid']);
199 $edit = l(t('edit'), 'node/' . $resume['nid'] . '/edit');
200
201 $rows[] = array(
202 $resume['title'],
203 format_interval(time() - $resume['changed']),
204 $view . ' ' . $apply . ' ' . $edit
205 );
206 }
207 $headers = array(t('Resume Title'), t('Last Changed'), t('Operations'));
208
209 $output .= theme('table', $headers, $rows);
210 print theme('page', $output);
211 }
212
213 function job_resume_list($uid) {
214 $resume_types = array();
215 foreach(node_get_types() as $type => $name) {
216 if (variable_get(RESUME_NODE_TYPE . $type, 0)) {
217 $resumes_types[] = "'". $type ."'";
218 }
219 }
220
221 if (!count($resumes_types)) {
222 return array();
223 }
224
225 $result = db_query("SELECT n.nid, n.title, n.changed FROM {node} n
226 WHERE n.type IN (". implode(',', $resumes_types) . ") AND n.uid = %d" , $uid);
227 while($row = db_fetch_array($result)) {
228 $data[] = $row;
229 }
230 return $data;
231 }
232
233 function job_apply_do($job_nid, $resume_nid) {
234 global $user;
235
236 if (job_user_applied($user->uid, $job_nid)) {
237 drupal_set_message(t('You already applied for this position.'));
238 drupal_goto("node/$job_nid");
239 }
240
241 db_query('INSERT INTO {job} (nid, uid, resume_nid, timestamp, status) VALUES (%d, %d, %d, %d, %d)',
242 $job_nid, $user->uid, $resume_nid, time(), 1);
243
244 job_send_email($job_nid, $resume_nid);
245
246 drupal_set_message(t('Thank you. Your application has been submitted.'));
247 drupal_goto("node/$job_nid");
248 }
249
250 function job_user_applied($uid, $job_nid) {
251 if (db_result(db_query("SELECT COUNT(*) FROM {job} j
252 INNER JOIN {node} r ON j.resume_nid = r.nid
253 INNER JOIN {node} n ON n.nid = r.nid
254 WHERE n.uid = %d
255 AND j.nid = %d", $uid, $job_nid))) {
256 return TRUE;
257 }
258 else {
259 return FALSE;
260 }
261 }
262
263 function job_clear($nid, $uid) {
264 if ($nid && $uid) {
265 db_query("UPDATE {job} SET status = 0 WHERE nid = %d AND uid = %d", $nid, $uid);
266 drupal_set_message(t('Job application #@nid has been cleared.', array('@nid' => $nid)));
267 }
268 drupal_goto('job/applications');
269 }
270
271 function job_view() {
272 global $user;
273 print theme('page', theme('job_view', job_get_list($user->uid)));
274 }
275
276 function job_get_list($uid = NULL) {
277 $rows = array();
278 $sql = "SELECT n.nid, j.uid, j.resume_nid, j.timestamp
279 FROM {node} n INNER JOIN {job} j USING(nid)
280 WHERE n.uid = %d
281 AND j.status = 1
282 ORDER by j.timestamp ASC";
283 $result = db_query($sql, $uid);
284 while ($data = db_fetch_object($result)) {
285 $resume = node_load(array('nid' => $data->resume_nid));
286 $job = node_load(array('nid' => $data->nid));
287 $rows[] = array(
288 'applicant' => user_load(array('uid' => $data->uid)),
289 'resume' => $resume,
290 'job' => $job,
291 'timestamp' => $data->timestamp,
292 );
293 }
294 return $rows;
295 }
296
297 function theme_job_view($list = array()) {
298 $rows = array();
299 $header = array(t('Job'), t('Applicant'), t('Resume'), t('Date'), t('Operations'));
300 if (count($list)) {
301 foreach($list as $data) {
302 $applicant = $data['applicant'];
303 $resume = $data['resume'];
304 $job = $data['job'];
305
306 $title = l($job->title, "node/$job->nid");
307 $resume = l($resume->title, "node/" . $resume->nid);
308 $user = l($applicant->name, "user/$applicant->uid");
309 $ops = l(t('Clear'), "job/clear/$job->nid/" . $applicant->uid);
310 $timestamp = format_date($data['timestamp'], 'custom', 'Y-m-d H:i');
311
312 $rows[] = array(
313 'data' => array_merge(
314 array($title),
315 array($user),
316 array($resume),
317 array($timestamp),
318 array($ops)
319 )
320 );
321 }
322 }
323 else {
324 $rows[] = array('data' => array(t('No job applications.')));
325 }
326 return theme('table', $header, $rows);
327 }
328
329 /**
330 * Implemetation of hook_theme().
331 *
332 */
333 function job_theme() {
334 return array(
335 'job_view' => array(
336 'arguments' => array('list' => NULL),
337 ),
338
339 'job_mail' => array(
340 'arguments' => array(
341 'job_node' => NULL,
342 'job_user' => NULL,
343 'resume_node' => NULL,
344 'resume_user' => NULL,
345 ),
346 ),
347
348 'job_search_item' => array(
349 'arguments' => array(
350 'item' => NULL,
351 ),
352 ),
353 );
354 }
355
356 /**
357 * Implementation of hook_nodeapi().
358 */
359
360 function job_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
361 switch ($op) {
362 case 'delete':
363 // Node is being deleted, delete it from the job table
364 db_query("DELETE FROM {job} WHERE nid = %d", $node->nid);
365 break;
366 }
367 }
368
369 function _job_check($nid, $uid) {
370 return db_result(db_query("SELECT COUNT(*) FROM {job} WHERE nid = %d AND uid = %d" , $nid, $uid));
371 }
372
373 function job_send_email($job_nid, $resume_nid) {
374 $job_node = node_load(array('nid' => $job_nid));
375 $job_user = user_load(array('uid' => $job_node->uid));
376 $resume_node = node_load(array('nid' => $resume_nid));
377 $resume_user = user_load(array('uid' => $resume_node->uid));
378
379 $from = $resume_user->mail;
380 $result = theme('job_mail', $job_node, $job_user, $resume_node, $resume_user);
381 drupal_mail('job_apply', $job_user->mail, $result['subject'], $result['body'], $from);
382
383 watchdog('job', t("%name applied for job $job_node->nid.",
384 array('%name' => theme('placeholder', $resume_user->name . " <$from>"))));
385 }
386
387 function theme_job_mail($job_node, $job_user, $resume_node, $resume_user) {
388 global $base_url;
389
390 $site = variable_get('site_name', 'drupal site');
391 $subject = t("[$site] [Job application] for [$job_node->title] by [$resume_user->name]");
392 $body = t("The following user has applied for the above job.\n");
393 $body .= t("\nJob: @title", array('@title' => $job_node->title));
394 $body .= t("\nJob URL: @url", array('@url' => $base_url . url("node/$job_node->nid")));
395 $body .= t("\nApplicant name: @name", array('@name' => $resume_user->name));
396 $body .= t("\nApplicant email: @email", array('@email' => $resume_user->mail));
397 $body .= t("\nApplicant URL: @url", array('@url' => $base_url . url("user/$resume_user->uid")));
398 $body .= t("\nResume: @title", array('@title' => $resume_node->title));
399 $body .= t("\nResume URL: @url", array('@url' => $base_url . url("node/$resume_node->nid")));
400 $body .= t("\n\nManage job applications at @manage", array('@manage' => $base_url . url("job/applications")));
401
402 return(array(
403 'subject' => $subject,
404 'body' => $body,
405 ));
406 }
407
408 function job_search_item($item) {
409 return theme('job_search_item', $item);
410 }
411
412 function theme_job_search_item($item) {
413 $output .= '<div id="job_search">';
414 $output .= l($item['title'], $item['link']) . '<br />';
415 $output .= $item['snippet']. '<br />';
416 $output .= $item['user'] . ' | ' . format_date($item['date'], 'small'). '<br /><br />';
417 $output .= '</div>';
418
419 return $output ;
420 }
421
422
423 /**
424 * Implementation of hook_views_tables():
425 * Present fields and filters for user data.
426 */
427 function job_views_tables() {
428 $tables['job'] = array(
429 'name' => 'job',
430
431 'provider' => 'internal', // won't show up in external list.
432
433 'join' => array(
434 'left' => array(
435 'table' => 'node',
436 'field' => 'nid',
437 ),
438 'right' => array(
439 'field' => 'nid',
440 ),
441 ),
442
443 'fields' => array(
444 'timestamp' => array(
445 'name' => t('Job: Date/Time applied for'),
446 'sortable' => TRUE,
447 'option' => 'integer',
448 'handler' => 'views_handler_field_date_small',
449 'help' => t('Displays the date/time applied for this Job.'),
450 ),
451 'uid' => array(
452 'name' => t('Resume: Applicant Name'),
453 'handler' => 'job_views_handler_field_applicant',
454 'sortable' => TRUE,
455 'help' => t('Displays the name of the applicant.'),
456 ),
457 'resume_nid' => array(
458 'name' => t('Resume: Node ID'),
459 'sortable' => TRUE,
460 'option' => 'integer',
461 'handler' => 'views_handler_field_int',
462 'help' => t('Displays the Node ID of the resume node.'),
463 ),
464 ),
465
466 'sorts' => array(
467 'timestamp' => array(
468 'name' => t('Job: Date/time applied for'),
469 'help' => t("Sort by the date/time applied for this job"),
470 ),
471 ),
472
473 'filters' => array(
474 'status' => array(
475 'name' => t('Job: Application status'),
476 'value-type' => 'integer',
477 'operator' => 'views_handler_operator_eqneq',
478 'list-type' => 'select',
479 'list' => array(
480 0 => t('Job has no applications'),
481 1 => t('Job has one or more applications'),
482 ),
483 'help' => t('Filter by whether a job has applications or not.'),
484 ),
485 'uid' => array(
486 'field' => 'uid',
487 'name' => t('Job: Applicant User ID'),
488 'operator' => 'views_handler_operator_eqneq',
489 'handler' => 'job_views_handler_filter_applicant',
490 'list-type' => 'select',
491 'list' => array(
492 'uid_current' => t('Currently Logged In User'),
493 'uid_all' => t('All Users'),
494 ),
495 'help' => t('This allows you to filter based on favorites nodes.'),
496 ),
497 ),
498 );
499
500 return $tables;
501 }
502
503 function job_views_handler_field_applicant($fieldinfo, $fielddata, $value, $data) {
504 $obj = new stdClass();
505 $obj = user_load(array('uid' => $value));
506 return theme('username', $obj);
507 }
508
509 function job_views_handler_filter_applicant($op, $filter, $filterinfo, &$query) {
510 global $user;
511
512 $table_data = _views_get_tables();
513 $joininfo = $table_data['job']['join'];
514 $joininfo['type'] = 'inner';
515 $table_num = $query->add_table('job', FALSE, 1, $joininfo);
516 $table = $query->get_table_name('job', $table_num);
517 $query->set_distinct();
518
519 switch($filter['value']) {
520 case 'uid_current':
521 if($user->uid) {
522 $query->add_where("$table.uid = $user->uid");
523 }
524 break;
525
526 case 'uid_all':
527 // No special processing needed, since we do an inner join anyways
528 break;
529 }
530 }
531
532 function job_views_arguments() {
533 $args = array();
534
535 $args[] = array(
536 'name' => t('Job: Applied for by User ID'),
537 'handler' => 'job_views_handler_argument_applicant',
538 );
539 return $args;
540 }
541
542 function job_views_handler_argument_applicant($op, &$query, $argtype, $arg = '') {
543 if ($op == 'filter' && $arg) {
544 $table_data = _views_get_tables();
545 $joininfo = $table_data['job']['join'];
546 $joininfo['type'] = 'inner';
547 $table_num = $query->add_table('job', FALSE, 1, $joininfo);
548 $table = $query->get_table_name('job', $table_num);
549 $query->set_distinct();
550
551 $query->add_where("$table.uid = $arg");
552 }
553 }
554
555 function job_views_default_views() {
556
557 $view = new stdClass();
558 $view->name = 'my_applications';
559 $view->description = 'My applications: shows job applications by the currently logged in user.';
560 $view->access = array();
561 $view->view_args_php = '';
562 $view->page = TRUE;
563 $view->page_title = 'My applications';
564 $view->page_header = '';
565 $view->page_header_format = '1';
566 $view->page_footer = '';
567 $view->page_footer_format = '1';
568 $view->page_empty = 'You have not applied for any jobs.';
569 $view->page_empty_format = '1';
570 $view->page_type = 'table';
571 $view->url = 'my_applications';
572 $view->use_pager = TRUE;
573 $view->nodes_per_page = '10';
574 $view->sort = array();
575 $view->argument = array();
576 $view->field = array(
577 array(
578 'tablename' => 'node',
579 'field' => 'title',
580 'label' => '',
581 'handler' => 'views_handler_field_nodelink',
582 'options' => 'link',
583 ),
584 array(
585 'tablename' => 'node',
586 'field' => 'created',
587 'label' => '',
588 'handler' => 'views_handler_field_date_small',
589 ),
590 );
591 $view->filter = array(
592 array(
593 'tablename' => 'job',
594 'field' => 'uid',
595 'operator' => '=',
596 'options' => '',
597 'value' => 'uid_current',
598 ),
599 );
600 $view->exposed_filter = array();
601 $view->requires = array(node, job);
602 $views[$view->name] = $view;
603
604
605 $view = new stdClass();
606 $view->name = 'job_applications';
607 $view->description = 'Job applications: Recruiter/employer view of all jobs applied for.';
608 $view->access = array();
609 $view->view_args_php = '';
610 $view->page = TRUE;
611 $view->page_title = 'Job applications';
612 $view->page_header = '';
613 $view->page_header_format = '1';
614 $view->page_footer = '';
615 $view->page_footer_format = '1';
616 $view->page_empty = 'There are no job applications.';
617 $view->page_empty_format = '1';
618 $view->page_type = 'table';
619 $view->url = 'job_applications';
620 $view->use_pager = TRUE;
621 $view->nodes_per_page = '10';
622 $view->sort = array();
623 $view->argument = array();
624 $view->field = array(
625 array(
626 'tablename' => 'node',
627 'field' => 'title',
628 'label' => 'Job',
629 'handler' => 'views_handler_field_nodelink',
630 'sortable' => '1',
631 'options' => 'link',
632 ),
633 array(
634 'tablename' => 'users',
635 'field' => 'name',
636 'label' => 'Recruiter',
637 'sortable' => '1',
638 ),
639 array(
640 'tablename' => 'job',
641 'field' => 'uid',
642 'label' => 'Applicant',
643 'sortable' => '1',
644 ),
645 array(
646 'tablename' => 'job',
647 'field' => 'timestamp',
648 'label' => 'Date/Time',
649 ),
650 );
651 $view->filter = array(
652 array(
653 'tablename' => 'node',
654 'field' => 'type',
655 'operator' => 'OR',
656 'options' => '',
657 'value' => array(
658 0 => 'job',
659 ),
660 ),
661 array(
662 'tablename' => 'job',
663 'field' => 'status',
664 'operator' => '=',
665 'options' => '',
666 'value' => '1',
667 ),
668 );
669 $view->exposed_filter = array();
670 $view->requires = array(node, users, job);
671 $views[$view->name] = $view;
672
673 $view = new stdClass();
674 $view->name = 'seeker_applications';
675 $view->description = 'Seeker applications: a view that accepts an optional UID argument to list all applications, or a specific user\'s applications';
676 $view->access = array();
677 $view->view_args_php = '';
678 $view->page = TRUE;
679 $view->page_title = 'Seeker applications';
680 $view->page_header = '';
681 $view->page_header_format = '1';
682 $view->page_footer = '';
683 $view->page_footer_format = '1';
684 $view->page_empty = 'There are no job applications.';
685 $view->page_empty_format = '1';
686 $view->page_type = 'table';
687 $view->url = 'seeker_applications';
688 $view->use_pager = TRUE;
689 $view->nodes_per_page = '10';
690 $view->sort = array();
691 $view->argument = array(
692 array(
693 'type' => '0',
694 'argdefault' => '2',
695 'title' => '',
696 'options' => '',
697 'wildcard' => '',
698 'wildcard_substitution' => '',
699 ),
700 );
701 $view->field = array(
702 array(
703 'tablename' => 'node',
704 'field' => 'title',
705 'label' => 'Job',
706 'handler' => 'views_handler_field_nodelink',
707 'sortable' => '1',
708 'options' => 'link',
709 ),
710 array(
711 'tablename' => 'users',
712 'field' => 'name',
713 'label' => 'Recruiter',
714 'sortable' => '1',
715 ),
716 array(
717 'tablename' => 'job',
718 'field' => 'timestamp',
719 'label' => 'Date/Time',
720 ),
721 );
722 $view->filter = array(
723 array(
724 'tablename' => 'node',
725 'field' => 'type',
726 'operator' => 'OR',
727 'options' => '',
728 'value' => array(
729 0 => 'job',
730 ),
731 ),
732 );
733 $view->exposed_filter = array();
734 $view->requires = array(node, users, job);
735 $views[$view->name] = $view;
736 }

  ViewVC Help
Powered by ViewVC 1.1.2