1
|
<?php
|
2
|
|
3
|
/**
|
4
|
* Returns HTML for an admin poll form for choices.
|
5
|
*/
|
6
|
function theme_makemeeting_choices($variables) {
|
7
|
$form = $variables['form'];
|
8
|
|
9
|
// Add appropriate CSS.
|
10
|
drupal_add_css(drupal_get_path('module', 'makemeeting') . '/makemeeting.css');
|
11
|
|
12
|
$rows = array();
|
13
|
$headers = array(t('Date'));
|
14
|
$headers_added = FALSE;
|
15
|
|
16
|
foreach (element_children($form) as $key) {
|
17
|
// Build the table rows.
|
18
|
$row = array();
|
19
|
$row[] = array(
|
20
|
'data' => drupal_render($form[$key]['chdate']) . drupal_render($form[$key]['chremove']),
|
21
|
'class' => 'makemeeting-choice-date',
|
22
|
);
|
23
|
$delta = 0;
|
24
|
foreach (element_children($form[$key]['chsuggestions']) as $key2) {
|
25
|
$delta++;
|
26
|
// Add sugesstion headers for the first line
|
27
|
if (!$headers_added) {
|
28
|
$headers[] = t('Suggestion %num', array('%num' => $delta));
|
29
|
}
|
30
|
$row[] = drupal_render($form[$key]['chsuggestions'][$key2]);
|
31
|
}
|
32
|
$headers_added = TRUE;
|
33
|
$rows[] = $row;
|
34
|
}
|
35
|
|
36
|
$output = theme('table', array(
|
37
|
'header' => $headers,
|
38
|
'rows' => $rows,
|
39
|
'attributes' => array('id' => 'poll-choice-table')
|
40
|
));
|
41
|
$output .= drupal_render_children($form);
|
42
|
return $output;
|
43
|
}
|
44
|
|
45
|
|
46
|
/**
|
47
|
* Function used to render a single answer row as a form
|
48
|
*/
|
49
|
function theme_makemeeting_answer_row($vars) {
|
50
|
$form = $vars['form'];
|
51
|
$element = array(
|
52
|
'#prefix' => '<table><tr>',
|
53
|
'first_cell' => array(),
|
54
|
'other_cells' => array('#markup' => ''),
|
55
|
'#suffix' => '</tr></table>',
|
56
|
);
|
57
|
|
58
|
// Render suggestions
|
59
|
foreach (element_children($form['answers']) as $answer_key) {
|
60
|
$element['other_cells']['#markup'] .= _theme_table_cell(array(
|
61
|
'data' => drupal_render($form['answers'][$answer_key]),
|
62
|
'class' => $form['answers'][$answer_key]['#type'],
|
63
|
));
|
64
|
}
|
65
|
|
66
|
// Render name, submit and the rest of hidden children
|
67
|
$first_cell = drupal_render($form['name']) . drupal_render($form['submit']);
|
68
|
$first_cell .= drupal_render_children($form);
|
69
|
$element['first_cell']['#markup'] = _theme_table_cell($first_cell);
|
70
|
|
71
|
return drupal_render($element);
|
72
|
}
|
73
|
|
74
|
|
75
|
/**
|
76
|
* Function used to render answers' table
|
77
|
*/
|
78
|
function theme_makemeeting_answers($vars) {
|
79
|
global $user;
|
80
|
$form = $vars['form'];
|
81
|
$item = $form['#item'];
|
82
|
|
83
|
// Add appropriate CSS.
|
84
|
drupal_add_css(drupal_get_path('module', 'makemeeting') . '/makemeeting.css');
|
85
|
|
86
|
// Initialize variables
|
87
|
$header = $day_cell = $row_form = $tree = $rows = array();
|
88
|
|
89
|
// First construct tree of suggestions for headers
|
90
|
foreach ($item['choices'] as $choice) {
|
91
|
$chdate = _makemeeting_date_timestamp($choice['chdate']);
|
92
|
$month = format_date($chdate, 'custom', 'F Y');
|
93
|
$day = format_date($chdate, 'custom', 'D. j');
|
94
|
$count = 0;
|
95
|
foreach ($choice['chsuggestions'] as $text) {
|
96
|
if (!$text && isset($tree[$month][$day]) && $count) {
|
97
|
continue;
|
98
|
}
|
99
|
elseif (!$text) {
|
100
|
$text = "-";
|
101
|
}
|
102
|
$tree[$month][$day][] = $text;
|
103
|
$count++;
|
104
|
}
|
105
|
}
|
106
|
|
107
|
// Now construct headers based on tree
|
108
|
$headers = $row_days = $row_suggestions = array('');
|
109
|
// Add month-related classes
|
110
|
$months_total = count($tree);
|
111
|
$months_count = 0;
|
112
|
foreach ($tree as $month => $days) {
|
113
|
$header['colspan'] = 0;
|
114
|
$header['data'] = $month;
|
115
|
|
116
|
$header['class'] = array('date-month');
|
117
|
_makemeeting_define_class_suffix($header, $months_count, $months_total, 'date-month');
|
118
|
$months_count++;
|
119
|
|
120
|
// Add day-related classes
|
121
|
$days_total = count($days);
|
122
|
$days_count = 0;
|
123
|
foreach ($days as $day => $suggestions) {
|
124
|
$day_cell['colspan'] = 0;
|
125
|
$day_cell['data'] = $day;
|
126
|
|
127
|
$day_cell['class'] = array('date');
|
128
|
_makemeeting_define_class_suffix($day_cell, $days_count, $days_total, 'date');
|
129
|
$days_count++;
|
130
|
|
131
|
// Add suggestion-related classes
|
132
|
$suggestions_total = count($suggestions);
|
133
|
$suggestion_count = 0;
|
134
|
foreach ($suggestions as $text) {
|
135
|
$suggestion = array('data' => $text, 'class' => array('suggestion'));
|
136
|
_makemeeting_define_class_suffix($suggestion, $suggestion_count, $suggestions_total, 'suggestion');
|
137
|
$suggestion_count++;
|
138
|
|
139
|
$row_suggestions[] = $suggestion;
|
140
|
|
141
|
// Set colspan
|
142
|
$header['colspan']++;
|
143
|
$day_cell['colspan']++;
|
144
|
}
|
145
|
$row_days[] = $day_cell;
|
146
|
}
|
147
|
$headers[] = $header;
|
148
|
}
|
149
|
array_push($rows, $row_days, $row_suggestions);
|
150
|
|
151
|
// Initialize totals labels
|
152
|
$totals = array();
|
153
|
$options = _makemeeting_options($item['yesnomaybe']);
|
154
|
foreach ($options as $key => $label) {
|
155
|
$totals[$key]['table'] = array(
|
156
|
array(
|
157
|
'data' => t('Totals ' . $label),
|
158
|
'class' => 'total-title'
|
159
|
)
|
160
|
);
|
161
|
foreach ($item['choices'] as $choice) {
|
162
|
$count = 0;
|
163
|
foreach ($choice['chsuggestions'] as $text) {
|
164
|
if ($text || (!$text && !$count)) {
|
165
|
// Initialize totals count
|
166
|
$totals[$key]['count'][] = 0;
|
167
|
}
|
168
|
$count++;
|
169
|
}
|
170
|
}
|
171
|
}
|
172
|
|
173
|
// Display already submitted answers
|
174
|
$select = db_select('makemeeting_answers', 'ma')
|
175
|
->fields('ma');
|
176
|
foreach (array(
|
177
|
'field_name',
|
178
|
'entity_type',
|
179
|
'deleted',
|
180
|
'entity_id',
|
181
|
'language',
|
182
|
'delta'
|
183
|
) as $info) {
|
184
|
$select->condition($info, $form[$info]['#value']);
|
185
|
}
|
186
|
// Filter out answer being edited
|
187
|
if (!empty($form['answer_edited'])) {
|
188
|
$select->condition('answer_id', $form['answer_edited']['#value']->answer_id, '!=');
|
189
|
}
|
190
|
$results = $select->execute()
|
191
|
->fetchAllAssoc('answer_id');
|
192
|
$uids = array();
|
193
|
foreach ($results as $result) {
|
194
|
$uids[] = $result->uid;
|
195
|
if (!$item['is_hidden']) {
|
196
|
$row = array();
|
197
|
// Display name of the person that has answered
|
198
|
$cell = _makemeeting_render_cell_name($result->uid, $result->name, $result->answer_id);
|
199
|
$row[] = drupal_render($cell);
|
200
|
|
201
|
// Display his/her answers
|
202
|
$answers = unserialize($result->value);
|
203
|
foreach (element_children($form['answers']) as $answer_key) {
|
204
|
$row_count = count($row);
|
205
|
|
206
|
// Determine choice based on choice type
|
207
|
if ($item['one_option']) {
|
208
|
$key = $answers == $answer_key ? MAKEMEETING_YES : MAKEMEETING_NO;
|
209
|
}
|
210
|
else {
|
211
|
$key = isset($answers[$answer_key]) ? intval($answers[$answer_key]) : FALSE;
|
212
|
}
|
213
|
$label = isset($options[$key]) ? $options[$key] : FALSE;
|
214
|
|
215
|
if ($key !== FALSE && $label !== FALSE) {
|
216
|
// Add corresponding classes for the answer
|
217
|
$classes = array('answer', 'answer-' . $key);
|
218
|
foreach (array(
|
219
|
'suggestion-first',
|
220
|
'suggestion-medium',
|
221
|
'suggestion-last'
|
222
|
) as $class) {
|
223
|
if (in_array($class, $row_suggestions[$row_count]['class'])) {
|
224
|
$classes[] = str_replace('suggestion', 'answer', $class);
|
225
|
}
|
226
|
}
|
227
|
|
228
|
// Store answer (will an background image according to class)
|
229
|
$row[] = array(
|
230
|
'data' => '<span>' . $label . '</span>',
|
231
|
'class' => $classes,
|
232
|
);
|
233
|
|
234
|
// Increment key answer counter
|
235
|
$totals[$key]['count'][$row_count - 1]++;
|
236
|
}
|
237
|
else {
|
238
|
$row[] = t('No answer');
|
239
|
}
|
240
|
}
|
241
|
$rows[] = array(
|
242
|
'data' => $row,
|
243
|
'id' => 'answer-' . $result->answer_id,
|
244
|
'class' => array('in' . (empty($cell['#editable']) ? '' : ' editable')),
|
245
|
);
|
246
|
}
|
247
|
}
|
248
|
|
249
|
if (!$item['is_hidden']) {
|
250
|
// Add participant count
|
251
|
$rows[1][0] = format_plural(count($results), '@count participant', '@count participants');
|
252
|
}
|
253
|
|
254
|
// Display answer form if ... not limited,
|
255
|
$limited = $item['limit'] > 0 && $item['limit'] * count($row_suggestions) - 1 <= count($results);
|
256
|
// ... not closed,
|
257
|
$closed = $item['closed'] || $limited;
|
258
|
$submitted = user_is_logged_in() && in_array($user->uid, array_values($uids));
|
259
|
// ... user has access and has not already submitted
|
260
|
$show_form = user_access(MAKEMEETING_ANSWER_PERM) && !$closed && !$submitted;
|
261
|
if ($show_form) {
|
262
|
$row_form[] = drupal_render($form['name']);
|
263
|
foreach (element_children($form['answers']) as $answer_key) {
|
264
|
$row_form[] = array(
|
265
|
'data' => drupal_render($form['answers'][$answer_key]),
|
266
|
'class' => $form['answers'][$answer_key]['#type'],
|
267
|
);
|
268
|
}
|
269
|
$rows[] = array(
|
270
|
'data' => $row_form,
|
271
|
'class' => array('answer-form-row'),
|
272
|
);
|
273
|
}
|
274
|
|
275
|
// Get total maxima
|
276
|
$totals_max = array();
|
277
|
foreach ($totals as $key => &$table) {
|
278
|
if (empty($table['count'])) {
|
279
|
$table['count'][] = 0;
|
280
|
}
|
281
|
$totals_max[$key] = max($table['count']);
|
282
|
}
|
283
|
// Display totals
|
284
|
foreach ($options as $key => $label) {
|
285
|
foreach ($totals[$key]['count'] as $choice => $count) {
|
286
|
$classes = array('total-count', 'total-' . $key);
|
287
|
if ($count) {
|
288
|
// Indicate first / last suggestion item
|
289
|
foreach (array(
|
290
|
'suggestion-first',
|
291
|
'suggestion-medium',
|
292
|
'suggestion-last'
|
293
|
) as $class) {
|
294
|
if (in_array($class, $row_suggestions[$choice + 1]['class'])) {
|
295
|
$classes[] = str_replace('suggestion', 'total', $class);
|
296
|
}
|
297
|
}
|
298
|
}
|
299
|
// Indicate max count
|
300
|
if (!empty($totals_max[$key]) && $count == $totals_max[$key]) {
|
301
|
$classes[] = 'total-max';
|
302
|
}
|
303
|
$totals[$key]['table'][] = array('data' => $count, 'class' => $classes);
|
304
|
}
|
305
|
$classes = array('total-row');
|
306
|
|
307
|
// Change labels for two choices
|
308
|
if (!$item['yesnomaybe']) {
|
309
|
$totals[$key]['table'][0]['data'] = t('Totals');
|
310
|
}
|
311
|
// Do not display other totals for two choices
|
312
|
if ($item['yesnomaybe'] || !$item['yesnomaybe'] && $key == MAKEMEETING_YES) {
|
313
|
$classes[] = 'total-row-' . ($key ? ($key == MAKEMEETING_YES ? 'last' : 'medium') : 'first');
|
314
|
$rows[] = array('data' => $totals[$key]['table'], 'class' => $classes);
|
315
|
}
|
316
|
}
|
317
|
|
318
|
// Apply classes to the two first rows
|
319
|
$rows[0] = array('data' => $rows[0], 'class' => array('dates'));
|
320
|
$rows[1] = array('data' => $rows[1], 'class' => array('suggestions'));
|
321
|
|
322
|
$suggestion = array(
|
323
|
'#theme' => 'table',
|
324
|
'#header' => $headers,
|
325
|
'#rows' => $rows,
|
326
|
'#attributes' => array('class' => array('makemeeting-table')),
|
327
|
);
|
328
|
if ($show_form) {
|
329
|
return drupal_render($suggestion) . drupal_render_children($form);
|
330
|
}
|
331
|
return drupal_render($suggestion);
|
332
|
}
|
333
|
|
334
|
/**
|
335
|
* Render the cell containing the submitter's name with
|
336
|
* a possible option to delete the answer
|
337
|
*/
|
338
|
function _makemeeting_render_cell_name($uid, $name, $answer_id) {
|
339
|
global $user;
|
340
|
if ($uid) {
|
341
|
$account = user_load($uid);
|
342
|
$username = theme('username', array('account' => user_load($account->uid)));
|
343
|
}
|
344
|
else {
|
345
|
$username = $name;
|
346
|
}
|
347
|
if (!user_access(MAKEMEETING_DELETE_PERM) && !user_access(MAKEMEETING_EDIT_PERM) && (user_is_anonymous() || $uid != $user->uid)) {
|
348
|
return array(
|
349
|
'#markup' => $username,
|
350
|
);
|
351
|
}
|
352
|
$images_path = drupal_get_path('module', 'makemeeting') . '/images/';
|
353
|
$cell[] = array(
|
354
|
'#prefix' => '<div class="answer-edit">',
|
355
|
'delete-link' => array(
|
356
|
'#type' => 'link',
|
357
|
'#title' => theme_image(array(
|
358
|
'path' => $images_path . 'trash.png',
|
359
|
'attributes' => array('title' => t('Delete answer'))
|
360
|
)),
|
361
|
'#href' => 'makemeeting/delete-answer/' . $answer_id,
|
362
|
'#options' => array(
|
363
|
'query' => drupal_get_destination(),
|
364
|
'html' => TRUE,
|
365
|
'attributes' => array('rel' => 'nofollow'),
|
366
|
),
|
367
|
'#access' => user_access(MAKEMEETING_DELETE_PERM) || $uid == $user->uid,
|
368
|
),
|
369
|
'edit-link' => array(
|
370
|
'#type' => 'link',
|
371
|
'#title' => theme_image(array(
|
372
|
'path' => $images_path . 'pen.png',
|
373
|
'attributes' => array('title' => t('Edit answer'))
|
374
|
)),
|
375
|
// Note the /nojs portion of the href - if javascript is enabled,
|
376
|
// this part will be stripped from the path before it is called.
|
377
|
'#href' => 'makemeeting/edit-answer/' . $answer_id . '/nojs/',
|
378
|
'#options' => array(
|
379
|
'query' => drupal_get_destination(),
|
380
|
'html' => TRUE,
|
381
|
'attributes' => array('rel' => 'nofollow'),
|
382
|
),
|
383
|
'#ajax' => array(
|
384
|
'wrapper' => 'answer-' . $answer_id,
|
385
|
'method' => 'html',
|
386
|
),
|
387
|
'#access' => user_access(MAKEMEETING_EDIT_PERM) || $uid == $user->uid,
|
388
|
),
|
389
|
'#suffix' => '</div>',
|
390
|
'#attached' => array(
|
391
|
'js' => array(
|
392
|
drupal_get_path('module', 'makemeeting') . '/makemeeting.js',
|
393
|
)
|
394
|
),
|
395
|
);
|
396
|
$cell[] = array('#markup' => $username);
|
397
|
return array(
|
398
|
'#markup' => '<div class="answer-editable">' . drupal_render($cell) . '</div>',
|
399
|
'#editable' => TRUE,
|
400
|
);
|
401
|
}
|
402
|
|
403
|
/**
|
404
|
* Helper function to define classes based on a count and a total
|
405
|
*
|
406
|
* @param $element
|
407
|
* @param $count
|
408
|
* @param $total
|
409
|
* @param string $prefix
|
410
|
*/
|
411
|
function _makemeeting_define_class_suffix(&$element, $count, $total, $prefix = '') {
|
412
|
if ($prefix) {
|
413
|
$prefix .= '-';
|
414
|
}
|
415
|
if ($count == 0) {
|
416
|
$element['class'][] = $prefix . 'first';
|
417
|
}
|
418
|
elseif ($count == ($total - 1)) {
|
419
|
$element['class'][] = $prefix . 'last';
|
420
|
}
|
421
|
else {
|
422
|
$element['class'][] = $prefix . 'medium';
|
423
|
}
|
424
|
}
|