Project

General

Profile

Paste
Download (13 KB) Statistics
| Branch: | Revision:

root / drupal7 / sites / all / modules / makemeeting / makemeeting.theme.inc @ b75b6b8b

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
}