fix drupal_alter() implementations
[project/drop_jobs.git] / modules / custom / drop_jobs_recommendation / drop_jobs_recommendation.module
1 <?php
2 /**
3 * @file
4 * Drop Jobs Job Recommendation module.
5 */
6 include_once('drop_jobs_recommendation.features.inc');
7
8 /**
9 * Implements hook_permission().
10 */
11 function drop_jobs_recommendation_permission() {
12 return array(
13 'administer drop_jobs_recommendation' => array(
14 'title' => t('Administer Job Recommendations'),
15 ),
16 'delete own drop_jobs_recommendation' => array(
17 'title' => t('Delete own Job Recommendations'),
18 ),
19 'view drop_jobs_recommendation' => array(
20 'title' => t('View Job Recommendations'),
21 ),
22 );
23 }
24
25 /**
26 * Implements hook_init().
27 */
28 function drop_jobs_recommendation_init() {
29 // Add admin section styles.
30 if (drop_jobs_is_admin_page()) {
31 drupal_add_css(drupal_get_path('module', 'drop_jobs_recommendation') . '/css/drop_jobs_recommendation_admin.css', array('group' => CSS_THEME, 'every_page' => TRUE));
32 }
33 }
34
35 /**
36 * Implements hook_entity_info().
37 */
38 function drop_jobs_recommendation_entity_info() {
39 $info = array();
40
41 $info['drop_jobs_recommendation'] = array(
42 'label' => t('Job Recommendation'),
43 'entity class' => 'DropJobsRecommendation',
44 'controller class' => 'DropJobsRecommendationController',
45 'base table' => 'drop_jobs_recommendation',
46 'fieldable' => FALSE,
47 'entity keys' => array(
48 'id' => 'rid',
49 ),
50 'bundles' => array(),
51 'uri callback' => 'entity_class_uri',
52 'label callback' => 'entity_class_label',
53 'access callback' => 'drop_jobs_recommendation_access',
54 'module' => 'drop_jobs_recommendation',
55 'metadata controller class' => 'DropJobsRecommendationMetadataController',
56 'views controller class' => 'DropJobsRecommendationViewsController',
57 );
58
59 // Support entity cache module.
60 if (module_exists('entitycache')) {
61 $info['recommendation']['entity cache'] = TRUE;
62 // Entity cache obsoletes field cache.
63 $info['recommendation']['field cache'] = FALSE;
64 }
65
66 return $info;
67 }
68
69 /**
70 * Implements hook_menu().
71 */
72 function drop_jobs_recommendation_menu() {
73 $items = array();
74
75 // Admin settings form.
76 $items['admin/config/drop_jobs/recommendation'] = array(
77 'title' => 'Recommendation',
78 'description' => 'Configure Job Recommendations.',
79 'page callback' => 'drupal_get_form',
80 'page arguments' => array('drop_jobs_recommendation_settings'),
81 'access arguments' => array('administer drop_jobs_recommendation'),
82 'file' => 'drop_jobs_recommendation.admin.inc',
83 'type' => MENU_LOCAL_TASK,
84 );
85
86 // For the sake of convenience.
87 $recommendation_uri = 'recommendation/%drop_jobs_recommendation';
88 $recommendation_uri_argument_position = 1;
89
90 // View recommendation.
91 $items[$recommendation_uri] = array(
92 'title callback' => 'drop_jobs_recommendation_page_title',
93 'title arguments' => array($recommendation_uri_argument_position),
94 'page callback' => 'drop_jobs_recommendation_view',
95 'page arguments' => array($recommendation_uri_argument_position),
96 'access callback' => 'entity_access',
97 'access arguments' => array('view', 'drop_jobs_recommendation', $recommendation_uri_argument_position),
98 );
99
100 $items[$recommendation_uri . '/view'] = array(
101 'title' => 'View',
102 'type' => MENU_DEFAULT_LOCAL_TASK,
103 'weight' => -10,
104 );
105
106 // Edit recommendation.
107 $items[$recommendation_uri . '/edit'] = array(
108 'title' => 'Edit',
109 'page callback' => 'drupal_get_form',
110 'page arguments' => array('drop_jobs_recommendation_form', $recommendation_uri_argument_position),
111 'access callback' => 'entity_access',
112 'access arguments' => array('edit', 'drop_jobs_recommendation', $recommendation_uri_argument_position),
113 'file' => 'drop_jobs_recommendation.admin.inc',
114 'type' => MENU_LOCAL_TASK,
115 'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
116 );
117
118 // Delete recommendation.
119 $items[$recommendation_uri . '/delete'] = array(
120 'title' => 'Delete recommendation',
121 'page callback' => 'drupal_get_form',
122 'page arguments' => array('drop_jobs_recommendation_delete_form', $recommendation_uri_argument_position),
123 'access callback' => 'entity_access',
124 'access arguments' => array('edit', 'drop_jobs_recommendation', $recommendation_uri_argument_position),
125 'file' => 'drop_jobs_recommendation.admin.inc',
126 );
127
128 // Devel integration.
129 if (module_exists('devel')) {
130 $devel_path = drupal_get_path('module', 'devel');
131 $items[$recommendation_uri . '/devel'] = array(
132 'title' => 'Devel',
133 'page callback' => 'devel_load_object',
134 'file' => 'devel.pages.inc',
135 'file path' => $devel_path,
136 'page arguments' => array('drop_jobs_recommendation', $recommendation_uri_argument_position),
137 'access arguments' => array('access devel information'),
138 'type' => MENU_LOCAL_TASK,
139 'weight' => 100,
140 );
141
142 $items[$recommendation_uri . '/devel/load'] = array(
143 'title' => 'Load',
144 'type' => MENU_DEFAULT_LOCAL_TASK,
145 );
146
147 $items[$recommendation_uri . '/devel/render'] = array(
148 'title' => 'Render',
149 'page callback' => 'devel_render_object',
150 'page arguments' => array('drop_jobs_recommendation', $recommendation_uri_argument_position),
151 'access arguments' => array('access devel information'),
152 'file' => 'devel.pages.inc',
153 'file path' => $devel_path,
154 'type' => MENU_LOCAL_TASK,
155 'weight' => 100,
156 );
157 }
158
159 return $items;
160 }
161
162 /**
163 * Determines whether the given user has access to a recommendation operation.
164 *
165 * @param $op
166 * The operation being performed. One of 'view', 'update', 'create', 'delete'
167 * or just 'edit' (being the same as 'create' or 'update').
168 * @param $recommendation
169 * Optionally a recommendation to check access for. If nothing is given,
170 * access for all recommendations is determined.
171 * @param $account
172 * The user to check for. Leave it to NULL to check for the current user.
173 * @return boolean
174 * Whether access is allowed or not.
175 */
176 function drop_jobs_recommendation_access($op, $recommendation = NULL, $account = NULL) {
177 if (!isset($account)) {
178 $account = user_uid_optional_load();
179 }
180
181 if (user_access('administer drop_jobs_recommendation')) {
182 return TRUE;
183 }
184
185 $node = node_load($recommendation->nid);
186 $own_recommendation = ($account->uid == $recommendation->uid || $account->uid == $node->uid);
187
188 switch ($op) {
189 case 'delete':
190 return user_access('delete own drop_jobs_recommendation') && $own_recommendation;
191 case 'view':
192 // Allow the user to view the recommendation of its for him or
193 // from one of his jobs.
194 return user_access('view drop_jobs_recommendation') && $own_recommendation;
195 default:
196 return FALSE;
197 }
198 }
199
200 /**
201 * Menu title callback.
202 * Returns page title for recommendation-related menu items.
203 *
204 * @param DropJobsRecommendation
205 * The $recommendation we want to get a title for.
206 * @return string
207 * The recommendation's label.
208 *
209 * @see drop_jobs_recommendation_menu()
210 */
211 function drop_jobs_recommendation_page_title(DropJobsRecommendation $recommendation) {
212 return $recommendation->label();
213 }
214
215 /**
216 * Deletes a recommendation.
217 *
218 * @param DropJobsRecommendation
219 * The recommendation object.
220 */
221 function drop_jobs_recommendation_delete(DropJobsRecommendation $recommendation) {
222 $recommendation->delete();
223 }
224
225 /**
226 * Delete multiple recommendations.
227 *
228 * @param array
229 * An array of recommendation IDs.
230 */
231 function drop_jobs_recommendation_delete_multiple(array $rids) {
232 // Bypass the traditional entity_get_controller() approach because we
233 // need to cancel each recommendation before its deleted.
234 foreach ($rids as $rid) {
235 if ($recommendation = drop_jobs_recommendation_load($rid)) {
236 drop_jobs_recommendation_delete($recommendation);
237 }
238 }
239 }
240
241 /**
242 * Create a new recommendation object.
243 *
244 * @param $values
245 * An array of values to initialize the recommendation with.
246 * @return DropJobsRecommendation
247 * The newly-created recommendation object.
248 */
249 function drop_jobs_recommendation_create(array $values) {
250 return new DropJobsRecommendation($values);
251 }
252
253 /**
254 * Saves a recommendation.
255 *
256 * @param $recommendation
257 * The recommendation object.
258 * @return boolean
259 * Whether the recommendation was saved successfully.
260 */
261 function drop_jobs_recommendation_save(DropJobsRecommendation $recommendation) {
262 return $recommendation->save();
263 }
264
265 /**
266 * Fetch a recommendation object.
267 *
268 * @param $rid
269 * Integer specifying the recommendation id.
270 * @param $reset
271 * A boolean indicating that the internal cache should be reset.
272 * @return
273 * A fully-loaded $recommendation object or FALSE if it cannot be loaded.
274 *
275 * @see drop_jobs_recommendation_load_multiple()
276 */
277 function drop_jobs_recommendation_load($rid, $reset = FALSE) {
278 $recommendations = drop_jobs_recommendation_load_multiple(array($rid), array(), $reset);
279 return reset($recommendations);
280 }
281
282 /**
283 * Load multiple recommendations based on certain conditions.
284 *
285 * @param $rids
286 * An array of recommendation IDs.
287 * @param $conditions
288 * An array of conditions to match against the {drop_jobs_recommendation} table.
289 * @param $reset
290 * A boolean indicating that the internal cache should be reset.
291 * @return
292 * An array of recommendation objects, indexed by ID.
293 *
294 * @see entity_load()
295 * @see drop_jobs_recommendation_load()
296 * @see drop_jobs_recommendation_load_by_user()
297 */
298 function drop_jobs_recommendation_load_multiple($rids = array(), $conditions = array(), $reset = FALSE) {
299 return entity_load('drop_jobs_recommendation', $rids, $conditions, $reset);
300 }
301
302 // @TODO load by user/job
303
304 /**
305 * DropJobsRecommendationcription view callback.
306 * Displays a recommendation entity.
307 *
308 * This is here as opposed to in drop_jobs_recommendation.pages.inc because if Devel is enabled
309 * clicking on Devel->Render will trigger an error as the include is not
310 * automatically included in that case.
311 *
312 * @param DropJobsRecommendation
313 * The $recommendation we want to view.
314 * @return string
315 * The rendered recommendation entity.
316 *
317 * @see drop_jobs_recommendation_menu()
318 */
319 function drop_jobs_recommendation_view(DropJobsRecommendation $recommendation) {
320 drupal_set_title(entity_label('drop_jobs_recommendation', $recommendation));
321 return entity_view('drop_jobs_recommendation', array(entity_id('drop_jobs_recommendation', $recommendation) => $recommendation), 'full');
322 }
323
324 /**
325 * Implements hook_cron().
326 */
327 function drop_jobs_recommendation_cron() {
328 if (variable_get_value('drop_jobs_recommendation_candidate_enable') || variable_get_value('drop_jobs_recommendation_job_enable')) {
329 // Find Job Recommendations for candidates. This actually works both ways
330 // as if a job is recommended for a candidate we can safely assume that
331 // that candidate would be recommended for that job.
332 $candidates = drop_jobs_candidate_get_pids();
333
334 if (!empty($candidates)) {
335 $queue = DrupalQueue::get('drop_jobs_recommendation_queue');
336 foreach ($candidates as $pid) {
337 $candidate = profile2_load($pid);
338 $queue->createItem($candidate);
339 }
340 }
341 }
342 }
343
344 /**
345 * Implements hook_cron_queue_info().
346 */
347 function drop_jobs_recommendation_cron_queue_info() {
348 return array(
349 'drop_jobs_recommendation_queue' => array(
350 'worker callback' => 'drop_jobs_recommendation_cron_run',
351 // Default time setting should be ok.
352 ),
353 );
354 }
355
356 /**
357 * Worker callback.
358 *
359 * Finds Job Recommendations for a given candidate.
360 *
361 * @param Profile
362 * The candidate $profile object.
363 *
364 * @see drop_jobs_recommendation_cron()
365 * @see drop_jobs_recommendation_cron_queue_info()
366 */
367 function drop_jobs_recommendation_cron_run(Profile $candidate) {
368 // @TODO implement this.
369 // $jobs = drop_jobs_recommendation_find($candidate);
370 // include_once drupal_get_path('module', 'devel') . '/krumo/class.krumo.php';
371 // krumo($jobs);die;
372 }
373
374 /**
375 * Find Job Recommendations for a given candidate.
376 *
377 * @param Profile
378 * The candidate profile.
379 * @return array
380 * An array of recommended jobs, keyed by nid.
381 */
382 function drop_jobs_recommendation_find(Profile $candidate) {
383 // @TODO implement this.
384 // include_once drupal_get_path('module', 'devel') . '/krumo/class.krumo.php';
385 // krumo($candidate);
386 // die;
387 }
388
389 /**
390 * Returns a map of job fields to candidate fields.
391 *
392 * @return array
393 * An array where the key is the job field and value is corresponding
394 * candidate field.
395 */
396 function drop_jobs_recommendation_map() {
397 $map = array();
398
399 $map['field_job_field'] = 'field_candidate_exp_field';
400 $map['field_job_study'] = 'field_candidate_edu_field';
401 $map['field_job_type'] = 'field_candidate_pref_occupation';
402 $map['field_job_languages'] = 'field_candidate_language';
403 $map['field_job_experience'] = 'field_candidate_exp_time';
404 $map['title'] = 'field_candidate_pref_title';
405
406 // Allow the map to be altered.
407 drupal_alter('drop_jobs_recommendation', $map);
408 return $map;
409 }
410
411 /**
412 * Returns the bias for each job recommendation field.
413 *
414 * @return array
415 * An array where the key is the field and the value is the bias.
416 */
417 function drop_jobs_recommendation_bias() {
418 $fields = array();
419
420 foreach (drop_jobs_recommendation_map() as $job_field => $candidate_field) {
421 $fields[$job_field] = variable_get("djrb_{$job_field}", 0);
422 }
423
424 return $fields;
425 }
426
427 /**
428 * Implements hook_variable_info().
429 */
430 function drop_jobs_recommendation_variable_info() {
431 $variables = array();
432
433 $variables['drop_jobs_recommendation_candidate_enable'] = array(
434 'title' => t('Recommend jobs for candidates'),
435 'default' => FALSE,
436 'group' => 'drop_jobs_recommendation',
437 'token' => FALSE,
438 );
439
440 $variables['drop_jobs_recommendation_candidate_subs'] = array(
441 'title' => t('Recommend jobs only for candidates with active subscriptions'),
442 'default' => FALSE,
443 'group' => 'drop_jobs_recommendation',
444 'token' => FALSE,
445 );
446
447 $variables['drop_jobs_recommendation_candidate_subs_plans'] = array(
448 'title' => t('Recommend jobs only for candidates with active subscriptions of plans'),
449 'default' => array(),
450 'group' => 'drop_jobs_recommendation',
451 'token' => FALSE,
452 );
453
454 $variables['drop_jobs_recommendation_job_enable'] = array(
455 'title' => t('Recommend candidates for jobs'),
456 'default' => FALSE,
457 'group' => 'drop_jobs_recommendation',
458 'token' => FALSE,
459 );
460
461 $variables['drop_jobs_recommendation_job_subs'] = array(
462 'title' => t("Recommend candidates only for jobs who's employers have active subscriptions"),
463 'default' => FALSE,
464 'group' => 'drop_jobs_recommendation',
465 'token' => FALSE,
466 );
467
468 $variables['drop_jobs_recommendation_job_subs_plans'] = array(
469 'title' => t('Recommend candidates only for jobs with active subscriptions of plans'),
470 'default' => array(),
471 'group' => 'drop_jobs_recommendation',
472 'token' => FALSE,
473 );
474
475 return $variables;
476 }
477
478 /**
479 * Implements hook_help().
480 */
481 function drop_jobs_recommendation_help($path, $arg) {
482 switch ($path) {
483 case 'dashboard/my-recommendations':
484 return t('Here you can view, edit and delete your recommendations.');
485 case 'admin/config/drop_jobs/recommendation':
486 return t('Here you can configure settings for job recommendations. This module can both recommend jobs for candidates as well as candidates for jobs.');
487 case 'admin/drop_jobs/recommendations':
488 return t('Here you can view, edit and delete all job recommendations.');
489 break;
490 }
491 }