1
|
<?php
|
2
|
|
3
|
/**
|
4
|
* @file
|
5
|
* Hooks and field implementations
|
6
|
*/
|
7
|
|
8
|
// Define choice constants
|
9
|
define('MAKEMEETING_ANSWER_PERM', 'answer makemeeting form');
|
10
|
define('MAKEMEETING_EDIT_PERM', 'edit any makemeeting answer');
|
11
|
define('MAKEMEETING_DELETE_PERM', 'delete any makemeeting answer');
|
12
|
define('MAKEMEETING_NO', 0);
|
13
|
define('MAKEMEETING_YES', 1);
|
14
|
define('MAKEMEETING_MAYBE', 2);
|
15
|
|
16
|
/**
|
17
|
* Include required files.
|
18
|
*/
|
19
|
include_once 'makemeeting.field.inc';
|
20
|
|
21
|
/**
|
22
|
* Implements hook_permission().
|
23
|
*/
|
24
|
function makemeeting_permission() {
|
25
|
return array(
|
26
|
MAKEMEETING_ANSWER_PERM => array(
|
27
|
'title' => t('Provide an answer to makemeeting forms'),
|
28
|
'description' => t('Give the ability to make a choice in makemeeting answer forms.'),
|
29
|
),
|
30
|
MAKEMEETING_EDIT_PERM => array(
|
31
|
'title' => t('Edit any makemeeting answers'),
|
32
|
'description' => t('Edit answers given by other users.'),
|
33
|
),
|
34
|
MAKEMEETING_DELETE_PERM => array(
|
35
|
'title' => t('Delete any makemeeting answers'),
|
36
|
'description' => t('Delete answers given by other users.'),
|
37
|
),
|
38
|
);
|
39
|
}
|
40
|
|
41
|
/**
|
42
|
* Implements hook_menu().
|
43
|
*/
|
44
|
function makemeeting_menu() {
|
45
|
$items['makemeeting/delete-answer/%makemeeting_answer'] = array(
|
46
|
'title' => 'Remove an answer',
|
47
|
'page callback' => 'drupal_get_form',
|
48
|
'page arguments' => array('makemeeting_delete_answer', 2),
|
49
|
'access callback' => 'makemeeting_delete_answer_access',
|
50
|
'access arguments' => array(2),
|
51
|
'type' => MENU_CALLBACK,
|
52
|
);
|
53
|
$items['makemeeting/edit-answer/%makemeeting_answer'] = array(
|
54
|
'title' => 'Edit an answer',
|
55
|
'page callback' => 'makemeeting_edit_answer',
|
56
|
'page arguments' => array(2),
|
57
|
'access callback' => 'makemeeting_edit_answer_access',
|
58
|
'access arguments' => array(2),
|
59
|
'type' => MENU_CALLBACK,
|
60
|
);
|
61
|
return $items;
|
62
|
}
|
63
|
|
64
|
/**
|
65
|
* Load an answer
|
66
|
*
|
67
|
* @param $answer_id
|
68
|
* @return mixed
|
69
|
*/
|
70
|
function makemeeting_answer_load($answer_id) {
|
71
|
$answer = db_select('makemeeting_answers', 'm')
|
72
|
->fields('m')
|
73
|
->condition('answer_id', $answer_id)
|
74
|
->execute()
|
75
|
->fetchAssoc();
|
76
|
$answer['value'] = unserialize($answer['value']);
|
77
|
return $answer ? (object) $answer : FALSE;
|
78
|
}
|
79
|
|
80
|
/**
|
81
|
* Access callback: delete an answer
|
82
|
*
|
83
|
* @param $answer
|
84
|
* @return bool
|
85
|
*/
|
86
|
function makemeeting_delete_answer_access($answer) {
|
87
|
global $user;
|
88
|
return user_access(MAKEMEETING_DELETE_PERM) || (user_is_logged_in() && $answer->uid == $user->uid);
|
89
|
}
|
90
|
|
91
|
/**
|
92
|
* Access callback: edit an answer
|
93
|
*
|
94
|
* @param $answer
|
95
|
* @return bool
|
96
|
*/
|
97
|
function makemeeting_edit_answer_access($answer) {
|
98
|
global $user;
|
99
|
return user_access(MAKEMEETING_EDIT_PERM) || (user_is_logged_in() && $answer->uid == $user->uid);
|
100
|
}
|
101
|
|
102
|
/**
|
103
|
* Menu callback: delete an answer
|
104
|
*
|
105
|
* @param $form
|
106
|
* @param $form_state
|
107
|
* @param $answer
|
108
|
* @param bool $redirect
|
109
|
* @return
|
110
|
*/
|
111
|
function makemeeting_delete_answer($form, &$form_state, $answer, $redirect = TRUE) {
|
112
|
$form['#answer'] = $answer;
|
113
|
return confirm_form(
|
114
|
$form,
|
115
|
t('Are you sure you want to delete the answer?'),
|
116
|
''
|
117
|
);
|
118
|
}
|
119
|
|
120
|
/**
|
121
|
* Form callback: confirm answer deletion
|
122
|
*/
|
123
|
function makemeeting_delete_answer_submit($form, &$form_state) {
|
124
|
$answer = $form['#answer'];
|
125
|
db_delete('makemeeting_answers')
|
126
|
->condition('answer_id', $answer->answer_id)
|
127
|
->execute();
|
128
|
|
129
|
_makemeeting_clear_related_entity_cache($answer->entity_type, $answer->entity_id);
|
130
|
}
|
131
|
|
132
|
/**
|
133
|
* Menu callback: edit an answer
|
134
|
*
|
135
|
* @param object $answer
|
136
|
* The loaded answer
|
137
|
* @param string $type
|
138
|
* Ajax or nojs
|
139
|
* @return array|void
|
140
|
* The entire form or just the row depending on ajax
|
141
|
*/
|
142
|
function makemeeting_edit_answer($answer, $type = 'ajax') {
|
143
|
$entities = entity_load($answer->entity_type, array($answer->entity_id));
|
144
|
if (empty($entities)) {
|
145
|
return drupal_not_found();
|
146
|
}
|
147
|
$entity = $entities[$answer->entity_id];
|
148
|
$field = $entity->{$answer->field_name}[$answer->language][$answer->delta];
|
149
|
$form = drupal_get_form('makemeeting_answers_form_' . $answer->entity_id, $field, (array) $answer, $answer);
|
150
|
if ($type == 'ajax') {
|
151
|
$form['#theme'] = 'makemeeting_answer_row';
|
152
|
// Replace 'ajax' word in form action
|
153
|
$form['#action'] = str_replace('/ajax/', '/nojs/', $form['#action']);
|
154
|
$colspan = 1 + count(element_children($form['answers']));
|
155
|
$output = '<tr class="editing"><td colspan="' . $colspan . '">' . drupal_render($form) . '</td></tr>';
|
156
|
$commands = array();
|
157
|
// See ajax_example_advanced.inc for more details on the available commands
|
158
|
// and how to use them.
|
159
|
$commands[] = ajax_command_replace('#answer-' . $answer->answer_id, $output);
|
160
|
$page = array('#type' => 'ajax', '#commands' => $commands);
|
161
|
return ajax_deliver($page);
|
162
|
}
|
163
|
return $form;
|
164
|
}
|
165
|
|
166
|
|
167
|
/**
|
168
|
* Ajax callback in response to an answer that has been edited.
|
169
|
*
|
170
|
* This returns the new form content to replace the form content made obsolete
|
171
|
* by the form submission.
|
172
|
*/
|
173
|
function makemeeting_answer_js($form, $form_state) {
|
174
|
$values = $form_state['values'];
|
175
|
$answer = $values['answer_edited'];
|
176
|
$entities = entity_load($answer->entity_type, array($answer->entity_id));
|
177
|
if (empty($entities)) {
|
178
|
return drupal_not_found();
|
179
|
}
|
180
|
$entity = $entities[$answer->entity_id];
|
181
|
$field = $entity->{$answer->field_name}[$answer->language][$answer->delta];
|
182
|
// We need to empty POST data to prevent the form
|
183
|
// from being processed as submitted
|
184
|
$_POST = array();
|
185
|
$new_form = drupal_get_form('makemeeting_answers_form_' . $answer->entity_id, $field, $values);
|
186
|
// AJaX processing overrides form action, now retrieving the correct one
|
187
|
$query = parse_url($form['#action']);
|
188
|
$parameters = drupal_get_query_array($query['query']);
|
189
|
$new_form['#action'] = $parameters['destination'];
|
190
|
return $new_form;
|
191
|
}
|
192
|
|
193
|
/**
|
194
|
* Implements hook_forms().
|
195
|
*/
|
196
|
function makemeeting_forms($form_id) {
|
197
|
$forms = array();
|
198
|
if (preg_match('/^makemeeting_answers_form_\d+?$/', $form_id)) {
|
199
|
$forms = array(
|
200
|
$form_id => array(
|
201
|
'callback' => 'makemeeting_answers_form',
|
202
|
)
|
203
|
);
|
204
|
}
|
205
|
return $forms;
|
206
|
}
|
207
|
|
208
|
/**
|
209
|
* Form callback: enables users to answer a makemeeting poll
|
210
|
*/
|
211
|
function makemeeting_answers_form($form, &$form_state, $item, $instance, $answer = NULL) {
|
212
|
global $user;
|
213
|
$form = array();
|
214
|
$form['#item'] = $item;
|
215
|
$form['#theme'] = 'makemeeting_answers';
|
216
|
|
217
|
// Force the id of the form as it might get overriden in AJAX-loaded forms
|
218
|
$form['#id'] = 'makemeeting-answers-form';
|
219
|
|
220
|
// Pass entity-related values in the form
|
221
|
foreach (array('field_name', 'entity_type', 'deleted', 'entity_id',
|
222
|
'language', 'delta') as $info) {
|
223
|
$form[$info] = array(
|
224
|
'#type' => 'value',
|
225
|
'#value' => $instance[$info],
|
226
|
);
|
227
|
}
|
228
|
|
229
|
// Pass answer being edited
|
230
|
if ($answer) {
|
231
|
$form['answer_edited'] = array(
|
232
|
'#type' => 'value',
|
233
|
'#value' => $answer,
|
234
|
);
|
235
|
}
|
236
|
// Include current destination for ajax calls
|
237
|
if (!isset($form_state['ajax_destination'])) {
|
238
|
$form_state['ajax_destination'] = drupal_get_destination();
|
239
|
}
|
240
|
|
241
|
// Include the name of the current user
|
242
|
$form['name'] = array(
|
243
|
'#type' => 'textfield',
|
244
|
'#size' => 22,
|
245
|
);
|
246
|
if (!user_is_logged_in()) {
|
247
|
// This is an HTML5 attribute
|
248
|
$form['name']['#attributes'] = array('placeholder' => t('Your name (required)'));
|
249
|
$form['name']['#required'] = TRUE;
|
250
|
}
|
251
|
else {
|
252
|
$form['name']['#default_value'] = format_username($user);
|
253
|
$form['name']['#disabled'] = TRUE;
|
254
|
}
|
255
|
if (!empty($answer)) {
|
256
|
if ($answer->uid > 0) {
|
257
|
$account = user_load($answer->uid);
|
258
|
$form['name']['#default_value'] = format_username($account);
|
259
|
}
|
260
|
else {
|
261
|
$form['name']['#default_value'] = $answer->name;
|
262
|
}
|
263
|
}
|
264
|
|
265
|
// If the form is limited, fetch already submitted answers
|
266
|
$answers = array();
|
267
|
if ($item['limit'] > 0) {
|
268
|
$select = db_select('makemeeting_answers', 'ma')
|
269
|
->fields('ma', array('value'));
|
270
|
foreach (array('field_name', 'entity_type', 'deleted', 'entity_id', 'language', 'delta') as $info) {
|
271
|
$select->condition($info, $instance[$info]);
|
272
|
}
|
273
|
// Filter out answer being edited
|
274
|
if ($answer) {
|
275
|
$select->condition('answer_id', $answer->answer_id, '!=');
|
276
|
}
|
277
|
$results = $select->execute();
|
278
|
// And add each answer to our results array for futher use
|
279
|
foreach ($results as $result) {
|
280
|
$_answer = unserialize($result->value);
|
281
|
if (is_array($_answer)) {
|
282
|
foreach ($_answer as $key => $value) {
|
283
|
if ($value) {
|
284
|
$answers[$key] = empty($answers[$key]) ? 1 : $answers[$key] + 1;
|
285
|
}
|
286
|
}
|
287
|
}
|
288
|
elseif (is_string($_answer) && $_answer) {
|
289
|
$answers[$_answer] = empty($answers[$_answer]) ? 1 : $answers[$_answer] + 1;
|
290
|
}
|
291
|
}
|
292
|
}
|
293
|
|
294
|
// Possible answers
|
295
|
$form['answers'] = array();
|
296
|
foreach ($item['choices'] as $choice) {
|
297
|
$chdate = _makemeeting_date_timestamp($choice['chdate']);
|
298
|
$count = 0;
|
299
|
foreach ($choice['chsuggestions'] as $id => $text) {
|
300
|
// Add a form element only if there's a suggestion label
|
301
|
// or it is the first suggestion for this date
|
302
|
if ($text || (!$text && !$count)) {
|
303
|
_makemeeting_answer_element($form, $item, $id, $chdate, $text, $answers, $answer);
|
304
|
}
|
305
|
$count++;
|
306
|
}
|
307
|
}
|
308
|
|
309
|
$form['submit'] = array(
|
310
|
'#type' => 'submit',
|
311
|
'#value' => t('Submit'),
|
312
|
);
|
313
|
if (!empty($answer)) {
|
314
|
// Modify form submit to include ajax behavior
|
315
|
$form['submit']['#ajax'] = array(
|
316
|
'callback' => 'makemeeting_answer_js',
|
317
|
'wrapper' => 'makemeeting-answers-form',
|
318
|
'effect' => 'fade',
|
319
|
);
|
320
|
}
|
321
|
|
322
|
return $form;
|
323
|
}
|
324
|
|
325
|
/**
|
326
|
* Form validate: validate answers
|
327
|
*/
|
328
|
function makemeeting_answers_form_validate($form, &$form_state) {
|
329
|
// The required attribute won't work, so we display a single message
|
330
|
if (!$form_state['values']['name']) {
|
331
|
drupal_set_message(t('You must enter your name.'), 'error');
|
332
|
}
|
333
|
// Check is the user has already voted
|
334
|
if (user_is_logged_in() && empty($form_state['values']['answer_edited'])) {
|
335
|
global $user;
|
336
|
$select = db_select('makemeeting_answers', 'ma');
|
337
|
foreach (array('field_name', 'entity_type', 'deleted', 'entity_id',
|
338
|
'language', 'delta') as $info) {
|
339
|
$select->condition($info, $form_state['values'][$info]);
|
340
|
}
|
341
|
$result = $select->condition('uid', $user->uid)
|
342
|
->countQuery()
|
343
|
->execute()
|
344
|
->fetchField();
|
345
|
if ($result) {
|
346
|
form_error($form, t('You already voted on this poll.'));
|
347
|
}
|
348
|
}
|
349
|
}
|
350
|
|
351
|
/**
|
352
|
* Form submit: store answers
|
353
|
*/
|
354
|
function makemeeting_answers_form_submit($form, $form_state) {
|
355
|
global $user;
|
356
|
if (!empty($form_state['values']['answer_edited'])) {
|
357
|
db_update('makemeeting_answers')
|
358
|
->fields(array(
|
359
|
'name' => $form_state['values']['name'],
|
360
|
'value' => serialize($form_state['values']['answers']),
|
361
|
))
|
362
|
->condition('answer_id', $form_state['values']['answer_edited']->answer_id)
|
363
|
->execute();
|
364
|
}
|
365
|
else {
|
366
|
$fields = array();
|
367
|
foreach (array('field_name', 'entity_type', 'deleted', 'entity_id',
|
368
|
'language', 'delta', 'name') as $field) {
|
369
|
$fields[$field] = $form_state['values'][$field];
|
370
|
}
|
371
|
db_insert('makemeeting_answers')
|
372
|
->fields($fields + array(
|
373
|
'value' => serialize($form_state['values']['answers']),
|
374
|
'uid' => $user->uid,
|
375
|
))
|
376
|
->execute();
|
377
|
}
|
378
|
|
379
|
// Spoof drupal_get_destination()'s cache for ajax calls
|
380
|
if (current_path() === 'system/ajax') {
|
381
|
$destination = &drupal_static('drupal_get_destination');
|
382
|
$destination = $form_state['ajax_destination'];
|
383
|
}
|
384
|
|
385
|
_makemeeting_clear_related_entity_cache($form_state['values']['entity_type'], $form_state['values']['entity_id']);
|
386
|
}
|
387
|
|
388
|
/**
|
389
|
* Implements hook_theme().
|
390
|
*/
|
391
|
function makemeeting_theme($existing, $type, $theme, $path) {
|
392
|
return array(
|
393
|
'makemeeting_choices' => array(
|
394
|
'render element' => 'form',
|
395
|
'file' => 'makemeeting.theme.inc',
|
396
|
),
|
397
|
'makemeeting_answers' => array(
|
398
|
'render element' => 'form',
|
399
|
'file' => 'makemeeting.theme.inc',
|
400
|
),
|
401
|
'makemeeting_answer_row' => array(
|
402
|
'render element' => 'form',
|
403
|
'file' => 'makemeeting.theme.inc',
|
404
|
),
|
405
|
);
|
406
|
}
|
407
|
|
408
|
|
409
|
/**
|
410
|
* Helper function to convert date field value into an Unix timestamp
|
411
|
*
|
412
|
* @param $array array Date field value (month, day and year)
|
413
|
* @return int Unix timestamp
|
414
|
*/
|
415
|
function _makemeeting_date_timestamp($array) {
|
416
|
$date_str = "{$array['day']}-{$array['month']}-{$array['year']}";
|
417
|
$date = new DateTime($date_str);
|
418
|
return $date->getTimestamp();
|
419
|
}
|
420
|
|
421
|
/**
|
422
|
* Helper function for selecting choices
|
423
|
*
|
424
|
* @param bool $three_choices If should be returning three choices
|
425
|
* @return array An array of options for radios
|
426
|
*/
|
427
|
function _makemeeting_options($three_choices = FALSE) {
|
428
|
$options = array(
|
429
|
MAKEMEETING_NO => t('No'),
|
430
|
MAKEMEETING_MAYBE => t('Maybe'),
|
431
|
MAKEMEETING_YES => t('Yes'),
|
432
|
);
|
433
|
if (!$three_choices) {
|
434
|
unset($options[MAKEMEETING_MAYBE]);
|
435
|
}
|
436
|
return $options;
|
437
|
}
|
438
|
|
439
|
/**
|
440
|
* Helper function to provide an answer form element
|
441
|
*
|
442
|
* @param $form
|
443
|
* Form to be modified
|
444
|
* @param $item
|
445
|
* Item providing settings for the answer form
|
446
|
* @param $id
|
447
|
* Suggestion id
|
448
|
* @param $chdate
|
449
|
* Suggestion date
|
450
|
* @param $text
|
451
|
* Suggestion text
|
452
|
* @param array $answers
|
453
|
* Already submitted answers
|
454
|
* @param null $answer
|
455
|
* Answer being edited
|
456
|
*/
|
457
|
function _makemeeting_answer_element(&$form, $item, $id, $chdate, $text, $answers = array(), $answer = NULL) {
|
458
|
$key = $chdate . ':' . $id;
|
459
|
// If the limit is reached for this option, display a markup text
|
460
|
if ($item['limit'] > 0 && isset($answers[$key]) && $answers[$key] >= $item['limit']) {
|
461
|
$form['answers'][$key] = array(
|
462
|
'#markup' => t('Unavailable'),
|
463
|
);
|
464
|
}
|
465
|
// Else add a form element
|
466
|
else {
|
467
|
$title = format_date($chdate, 'custom', 'l j F Y') . ' ' . $text;
|
468
|
$form['answers'][$key] = array(
|
469
|
'#type' => $item['one_option'] ? 'radio' : ($item['yesnomaybe'] ? 'radios' : 'checkbox'),
|
470
|
'#attributes' => array('title' => check_plain($title)),
|
471
|
'#parents' => array('answers', $key),
|
472
|
);
|
473
|
|
474
|
if ($item['one_option']) {
|
475
|
$form['answers'][$key]['#parents'] = array('answers');
|
476
|
$form['answers'][$key]['#return_value'] = $key;
|
477
|
}
|
478
|
else {
|
479
|
$form['answers'][$key]['#options'] = _makemeeting_options($item['yesnomaybe']);
|
480
|
}
|
481
|
if ($item['yesnomaybe']) {
|
482
|
$form['answers'][$key]['#default_value'] = MAKEMEETING_NO;
|
483
|
}
|
484
|
// Display previous choice if answer is being edited
|
485
|
if ($answer && !empty($answer->value[$key])) {
|
486
|
$form['answers'][$key]['#default_value'] = $answer->value[$key];
|
487
|
}
|
488
|
}
|
489
|
}
|
490
|
|
491
|
/**
|
492
|
* Invalidate related entity caches.
|
493
|
*
|
494
|
* Clear the core page cache and the contrib Entity Cache of the entity.
|
495
|
*
|
496
|
* @param $entity_type
|
497
|
* @param $entity_id
|
498
|
*/
|
499
|
function _makemeeting_clear_related_entity_cache($entity_type, $entity_id) {
|
500
|
// Clear entity_type cache.
|
501
|
entity_get_controller($entity_type)->resetCache();
|
502
|
|
503
|
// Clear core page cache.
|
504
|
if (variable_get('cache', FALSE)) {
|
505
|
$entities = entity_load($entity_type, array($entity_id));
|
506
|
$entity = reset($entities);
|
507
|
|
508
|
global $base_root;
|
509
|
$uri = entity_uri($entity_type, $entity);
|
510
|
// Clear the non-aliased page.
|
511
|
cache_clear_all($base_root . base_path() . $uri['path'], 'cache_page');
|
512
|
// Clear the aliased page.
|
513
|
cache_clear_all(url($uri['path'], array('absolute'=>TRUE)), 'cache_page');
|
514
|
}
|
515
|
|
516
|
// Clear referencing entities cache.
|
517
|
if (module_exists('entityreference')) {
|
518
|
_makemeeting_clear_referencing_entity_cache($entity_type, $entity_id);
|
519
|
}
|
520
|
}
|
521
|
|
522
|
/**
|
523
|
* Invalidate referencing entities caches.
|
524
|
*
|
525
|
* Recursive function clearing the cache for all the entities that references
|
526
|
* the given one using the entityreference module.
|
527
|
*
|
528
|
* @param $entity_type
|
529
|
* @param $entity_id
|
530
|
*/
|
531
|
function _makemeeting_clear_referencing_entity_cache($entity_type, $entity_id) {
|
532
|
$cleared = &drupal_static(__FUNCTION__, array());
|
533
|
// Avoid the cache to be cleared twice for the same entity.
|
534
|
if (!empty($cleared[$entity_type][$entity_id])) {
|
535
|
return;
|
536
|
}
|
537
|
$cleared[$entity_type][$entity_id] = TRUE;
|
538
|
|
539
|
// Get the entity bundle to retreive the field that can reference this kind
|
540
|
// of entities.
|
541
|
$entity = entity_load_single($entity_type, $entity_id);
|
542
|
list(, , $bundle) = entity_extract_ids($entity_type, $entity);
|
543
|
$fields_referencing = _makemeeting_clear_referencing_fields($entity_type, $bundle);
|
544
|
|
545
|
// For each referencing field, get the entities that references the current
|
546
|
// entity using the field and clear their cache.
|
547
|
foreach ($fields_referencing as $field_name) {
|
548
|
$query = new EntityFieldQuery();
|
549
|
$query->fieldCondition($field_name, 'target_id', $entity_id);
|
550
|
foreach ($query->execute() as $referent_entity_type => $referent_entities) {
|
551
|
foreach ($referent_entities as $referent_entity_id => $referent_entity) {
|
552
|
_makemeeting_clear_related_entity_cache($referent_entity_type, $referent_entity_id);
|
553
|
}
|
554
|
}
|
555
|
}
|
556
|
}
|
557
|
|
558
|
/**
|
559
|
* Get all fields referencing a given bundle.
|
560
|
*
|
561
|
* @param $entity_type
|
562
|
* The entity type of the bundle.
|
563
|
* @param $bundle
|
564
|
* The referenced bundle.
|
565
|
* @return array
|
566
|
* An array of field names being able to reference the given bundle.
|
567
|
*/
|
568
|
function _makemeeting_clear_referencing_fields($entity_type, $bundle) {
|
569
|
$static = &drupal_static(__FUNCTION__, array());
|
570
|
// Use a static temporary cache to avoid using too mush resources.
|
571
|
if (array_key_exists($entity_type, $static) && array_key_exists($bundle, $static[$entity_type])) {
|
572
|
return $static[$entity_type][$bundle];
|
573
|
}
|
574
|
|
575
|
$fields = field_info_fields();
|
576
|
$static[$entity_type][$bundle] = array();
|
577
|
foreach ($fields as $field_name => $field) {
|
578
|
// Check if the field is an entityreference field.
|
579
|
if ($field['type'] != 'entityreference') {
|
580
|
continue;
|
581
|
}
|
582
|
// Check if the entity_type match the target_type of the field.
|
583
|
if ($field['settings']['target_type'] != $entity_type) {
|
584
|
continue;
|
585
|
}
|
586
|
// If the field is using the base handler check if the bundle is allowed.
|
587
|
if ($field['settings']['handler'] == 'base' && !in_array($bundle, $field['settings']['handler_settings']['target_bundles'])) {
|
588
|
continue;
|
589
|
}
|
590
|
$static[$entity_type][$bundle][] = $field_name;
|
591
|
}
|
592
|
|
593
|
return $static[$entity_type][$bundle];
|
594
|
}
|
595
|
|
596
|
/**
|
597
|
* Implements hook_field_views_data_alter().
|
598
|
*/
|
599
|
function makemeeting_field_views_data_alter(&$result, $field, $module) {
|
600
|
if ($module == 'makemeeting') {
|
601
|
foreach ($result as $table => $data) {
|
602
|
$field_name = $field['field_name'];
|
603
|
|
604
|
// We will replace the filter handlers with a friendlier one.
|
605
|
$result[$table][$field_name . '_closed']['filter']['handler'] = 'views_handler_filter_boolean_operator';
|
606
|
$result[$table][$field_name . '_hidden']['filter']['handler'] = 'views_handler_filter_boolean_operator';
|
607
|
$result[$table][$field_name . '_one_option']['filter']['handler'] = 'views_handler_filter_boolean_operator';
|
608
|
$result[$table][$field_name . '_yesnomaybe']['filter']['handler'] = 'views_handler_filter_boolean_operator';
|
609
|
}
|
610
|
}
|
611
|
}
|