Projet

Général

Profil

Paste
Télécharger (44,1 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / pollfield / pollfield.module @ 62f5c69e

1 85ad3d82 Assos Assos
<?php
2 62f5c69e Assos Assos
3
/**
4
 * @file
5
 * Pollfield module
6
 */
7
8
/**
9
 * Implements hook_init().
10
 *
11
 * Executed at the begining of page requests to add custom css.
12
 */
13
function pollfield_init() {
14
  $css_file = drupal_get_path('module', 'pollfield') . '/pollfield.css';
15
  drupal_add_css($css_file, 'module');
16
}
17
18
/**
19
 * Implements hook_menu().
20
 *
21
 * Provides a simple user interface that tells the developer where to go.
22
 */
23
function pollfield_menu() {
24
  $items = array();
25
  $items['pollfield/add_choice'] = array(
26
    'title' => 'Add choice',
27
    'page callback' => 'pollfield_add_choice',
28
    'access arguments' => array('access content'),
29
    'type' => MENU_CALLBACK,
30
  );
31
  return $items;
32
}
33
34 85ad3d82 Assos Assos
/**
35
 * Implements hook_field_info().
36
 *
37
 * Provides the description of the field.
38
 */
39
function pollfield_field_info() {
40
  return array(
41
    // We name our field as the associative name of the array.
42 62f5c69e Assos Assos
    // This is name of field that evetrhing else is connected.
43
    'pollfield_poll' => array(
44 85ad3d82 Assos Assos
      'label' => t('Pollfield module'),
45
      'description' => t('This is to store poll as a field and not as a node.'),
46 62f5c69e Assos Assos
      'default_widget' => 'pollfield_main', // Each field can have many widget.
47 85ad3d82 Assos Assos
      'default_formatter' => 'pollfield_default',
48
    ),
49
  );
50
}
51 62f5c69e Assos Assos
52
/**
53 85ad3d82 Assos Assos
 * Implements hook_field_validate().
54
 *
55
 * This hook gives us a chance to validate content that's in our
56
 * field. We're really only interested in the $items parameter, since
57
 * it holds arrays representing content in the field we've defined.
58
 * We want to verify that the items only contain RGB hex values like
59
 * this: #RRGGBB. If the item validates, we do nothing. If it doesn't
60
 * validate, we add our own error notification to the $errors parameter.
61
 *
62
 * @see field_example_field_widget_error()
63
 */
64
function pollfield_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
65
  foreach ($items as $delta => $item) {
66 62f5c69e Assos Assos
67 85ad3d82 Assos Assos
  }
68
}
69
70
/**
71
 * Implements hook_field_is_empty().
72
 *
73
 * hook_field_is_emtpy() is where Drupal asks us if this field is empty.
74
 * Return TRUE if it does not contain data, FALSE if it does. This lets
75
 * the form API flag an error when required fields are empty.
76
 */
77
function pollfield_field_is_empty($item, $field) {
78 62f5c69e Assos Assos
  // For now field are always full.
79 85ad3d82 Assos Assos
  return FALSE;
80
}
81
82
/**
83
 * Implements hook_field_formatter_info().
84
 *
85
 * We need to tell Drupal that we have two different types of formatters
86
 * for this field. One will change the text color, and the other will
87
 * change the background color.
88
 *
89
 * @see field_example_field_formatter_view()
90
 */
91
function pollfield_field_formatter_info() {
92
  return array(
93
    // This formatter just displays the hex value in the color indicated.
94
    'pollfield_default' => array(
95
      'label' => t('Default'),
96
      'field types' => array('pollfield_poll'),
97
    ),
98
    // This formatter changes the background color of the content region.
99
    'pollfield_choice' => array(
100
      'label' => t('Only choices'),
101
      'field types' => array('pollfield_poll'),
102
    ),
103
    // This formatter changes the background color of the content region.
104
    'pollfield_question' => array(
105
      'label' => t('Only questions'),
106
      'field types' => array('pollfield_poll'),
107
    ),
108
    'pollfield_results' => array(
109
      'label' => t('Only results'),
110
      'field types' => array('pollfield_poll'),
111
    ),
112
    'pollfield_runtime' => array(
113
      'label' => t('Only runtime'),
114
      'field types' => array('pollfield_poll'),
115
    ),
116
  );
117
}
118
119
/**
120 62f5c69e Assos Assos
 * Implements hook_field_presave().
121
 *
122
 * Used to serialize some pollfield settings.
123 85ad3d82 Assos Assos
 */
124 62f5c69e Assos Assos
function pollfield_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
125
  foreach ($items as $delta => $item) {
126
    // Poll settings.
127
    $poll_settings = array(
128
      'poll_type' => $item['poll_type'],
129
      'cancelvote_allow' => $item['cancelvote_allow'],
130
      'result_allow' => $item['result_allow'],
131
    );
132
    $items[$delta]['poll_features'] = serialize($poll_settings);
133
134
    // Delete all votes.
135
    if ($item['delete_votes'] && !empty($entity->nid)) {
136
      db_delete('pollfield_votes')
137
        ->condition('nid', $entity->nid)
138
        ->execute();
139
    }
140
141
    // Delete empty choices.
142
    $choices_items = array();
143
    foreach ($item['group'] as $key => $value) {
144
      $choice = trim($value['choice']);
145
      if (!empty($choice)) {
146
        $choices_items[$key] = $value;
147
      }
148
    }
149
    $items[$delta]['choice'] = serialize($choices_items);
150
  }
151
}
152
153 85ad3d82 Assos Assos
/**
154
 * Implements hook_field_formatter_view().
155
 *
156
 * Two formatters are implemented.
157
 * - field_example_simple_text just outputs markup indicating the color that
158
 *   was entered and uses an inline style to set the text color to that value.
159
 * - field_example_color_background does the same but also changes the
160
 *   background color of div.region-content.
161
 *
162
 * @see field_example_field_formatter_info()
163
 */
164
function pollfield_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
165
  $element = array();
166 62f5c69e Assos Assos
167 85ad3d82 Assos Assos
  switch ($display['type']) {
168
    // This formatter simply outputs the field as text and with a color.
169
    case 'pollfield_default':
170
      foreach ($items as $delta => $item) {
171 62f5c69e Assos Assos
        $elements = array(
172
          'item'   => $item,
173
          'entity' => $entity,
174
          'delta'  => $delta,
175
          'field'  => $field,
176
        );
177 85ad3d82 Assos Assos
        $element[$delta] = array(
178 62f5c69e Assos Assos
          '#markup' => theme('pollfield_default_formatter', array('elements' => $elements)),
179 85ad3d82 Assos Assos
        );
180
      }
181
      break;
182
183
    // This formatter adds css to the page changing the '.region-content' area's
184
    // background color. If there are many fields, the last one will win.
185
    case 'pollfield_choices':
186
      foreach ($items as $delta => $item) {
187 62f5c69e Assos Assos
        // We create a render array to produce the desired markup,
188
        // "<p style="color: #hexcolor">The color code ... #hexcolor</p>".
189
        // See theme_html_tag().
190
        $element[$delta] = array(
191 85ad3d82 Assos Assos
          '#type' => 'html_tag',
192
          '#tag' => 'p',
193
          '#value' => t('This is choices formater'),
194
        );
195
      }
196
      break;
197 62f5c69e Assos Assos
198
    case 'pollfield_question':
199 85ad3d82 Assos Assos
      foreach ($items as $delta => $item) {
200 62f5c69e Assos Assos
        // We create a render array to produce the desired markup,
201
        // "<p style="color: #hexcolor">The color code ... #hexcolor</p>".
202
        // See theme_html_tag().
203
        $element[$delta] = array(
204 85ad3d82 Assos Assos
          '#type' => 'html_tag',
205
          '#tag' => 'p',
206
          '#value' => t('This is defualt formater'),
207
        );
208
      }
209
      break;
210 62f5c69e Assos Assos
211
    case 'pollfield_results':
212 85ad3d82 Assos Assos
      foreach ($items as $delta => $item) {
213 62f5c69e Assos Assos
        // We create a render array to produce the desired markup,
214
        // "<p style="color: #hexcolor">The color code ... #hexcolor</p>".
215
        // See theme_html_tag().
216
        $element[$delta] = array(
217 85ad3d82 Assos Assos
          '#type' => 'html_tag',
218
          '#tag' => 'p',
219
          '#value' => t('This is results formater'),
220
        );
221
      }
222
      break;
223 62f5c69e Assos Assos
224
    case 'pollfield_runtime':
225 85ad3d82 Assos Assos
      foreach ($items as $delta => $item) {
226 62f5c69e Assos Assos
        // We create a render array to produce the desired markup,
227
        // "<p style="color: #hexcolor">The color code ... #hexcolor</p>".
228
        // See theme_html_tag().
229
        $element[$delta] = array(
230 85ad3d82 Assos Assos
          '#type' => 'html_tag',
231
          '#tag' => 'p',
232
          '#value' => t('This is runtime formater'),
233
        );
234
      }
235
      break;
236
  }
237
238
  return $element;
239
}
240 62f5c69e Assos Assos
241 85ad3d82 Assos Assos
/**
242
 * Implements hook_field_widget_info().
243
 *
244
 * Three widgets are provided.
245
 * - A simple text-only widget where the user enters the '#ffffff'.
246
 * - A 3-textfield widget that gathers the red, green, and blue values
247
 *   separately.
248
 * - A farbtastic colorpicker widget that chooses the value graphically.
249
 *
250
 * These widget types will eventually show up in hook_field_widget_form,
251
 * where we will have to flesh them out.
252
 *
253
 * @see field_example_field_widget_form()
254
 */
255
function pollfield_field_widget_info() {
256
  return array(
257
    'pollfield_main' => array(
258
      'label' => t('Pollfield'),
259
      'field types' => array('pollfield_poll'),
260
    ),
261
  );
262
}
263 62f5c69e Assos Assos
264 85ad3d82 Assos Assos
/**
265
 * Implements hook_field_widget_form().
266
 *
267
 * hook_widget_form() is where Drupal tells us to create form elements for
268
 * our field's widget.
269
 *
270
 * We provide one of three different forms, depending on the widget type of
271
 * the Form API item provided.
272
 */
273
function pollfield_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
274
  $value = isset($items[$delta]['question']) ? $items[$delta]['question'] : '';
275 62f5c69e Assos Assos
276 85ad3d82 Assos Assos
  $widget = $element;
277
  $widget['#delta'] = $delta;
278 62f5c69e Assos Assos
  
279
  if (isset($form['#node'])) {
280
  $node = $form['#node'];
281
  }
282
  //dpr($form);
283
  if (!empty($items[$delta]['poll_features'])) {
284
    if (is_array($items[$delta]['poll_features'])) {
285
      $poll_features = $items[$delta]['poll_features'];
286
    }
287
    else {
288
      $poll_features = unserialize($items[$delta]['poll_features']);
289
    }
290
  }
291 85ad3d82 Assos Assos
292
  switch ($instance['widget']['type']) {
293
    case 'pollfield_main':
294 62f5c69e Assos Assos
      // Question.
295 85ad3d82 Assos Assos
      $widget['question'] = array(
296
        '#type' => 'textfield',
297
        '#title' => t('Question'),
298 62f5c69e Assos Assos
        '#default_value' => $value,
299
      );
300
      // Status.
301
      $admin_pollfield = TRUE;
302
      $_active = array(
303
        t('Closed'),
304
        t('Active'),
305
      );
306
      $widget['active'] = array(
307
        '#type' => 'radios',
308
        '#access' => $admin_pollfield,
309
        '#title' => t('Status'),
310
        // If no value exists, always default to active (1).
311
        '#default_value' => isset($items[$delta]['active']) ? $items[$delta]['active'] : 1,
312
        '#options' => $_active,
313
        '#description' => t('When a pollfield is closed, visitors can no longer vote for it.'),
314
      );
315
      // Runtime - duration.
316
      $widget['runtime'] = array(
317
        '#type' => 'select',
318
        '#access' => $admin_pollfield,
319
        '#title' => t('Duration'),
320
        // If no value exists, always default to Unlimited (0).
321
        '#default_value' => isset($items[$delta]['runtime']) ? $items[$delta]['runtime'] : 0,
322
        '#options' => pollfield_duration_options(),
323
        '#description' => t('After this period, the pollfield will be closed automatically.'),
324
      );
325
      // Anonymous voting.
326
      $widget['anonymous'] = array(
327
        '#type' => 'select',
328
        '#access' => $admin_pollfield,
329
        '#title' => t('Anonymous voting'),
330
        // If no value exists, always default to Not allowed (anon_non).
331
        '#default_value' => isset($items[$delta]['anonymous']) ? $items[$delta]['anonymous'] : 'anon_non',
332
        '#options' => array(
333
          'anon_non' => t('Not allowed'),
334
          'anon_by_ip' => t('Allowed, filtered by user IP'),
335
          'anon_by_cookie' => t('Allowed, filtered by user cookie'),
336
          'anon_all' => t('Allowed'),
337
        ),
338
        '#description' => t('Allow or disallow anonymous users to vote on this poll. Filtering by user IP or cookie ensures only one vote is allowed per user IP.'),
339
      );
340
      // Cancel permission.
341
      $options_allow = array(
342
        t('Disallow'),
343
        t('Allow'),
344
      );
345
      $widget['cancelvote_allow'] = array(
346
        '#type' => 'radios',
347
        '#access' => $admin_pollfield,
348
        '#title' => t('Cancel Vote'),
349
        '#default_value' => isset($poll_features['cancelvote_allow']) ? $poll_features['cancelvote_allow'] : 1,
350
        '#options' => $options_allow,
351
        '#description' => t('Allow or disallow "Cancel vote" button. "Cancel vote" button allows voters to cancel their vote and choose a different one if they want.'),
352
      );
353
      // Show result befor a voting.
354
      $widget['result_allow'] = array(
355
        '#type' => 'radios',
356
        '#access' => $admin_pollfield,
357
        '#title' => t('Show results before voting'),
358
        '#default_value' => isset($poll_features['result_allow']) ? $poll_features['result_allow'] : 0,
359
        '#options' => $options_allow,
360
        '#description' => t('Allow or disallow users to see current poll results before voting on this poll. If set to disallow, anonymous users can never see the results. Permissions under pollfield module override this setting.'),
361 85ad3d82 Assos Assos
      );
362 62f5c69e Assos Assos
363
      // Poll type
364
      // Can users vote on multiple choices or just one?
365
      $_poll_type = array(
366
        'single' => t('Single choice'),
367
        'multiple' => t('Multiple choice'),
368
      );
369
      $widget['poll_type'] = array(
370
        '#type' => 'radios',
371
        '#title' => t('Poll type'),
372
        '#default_value' => isset($poll_features['poll_type']) ? $poll_features['poll_type'] : 'multiple',
373
        '#options' => $_poll_type,
374
        '#description' => t('In a Single choice poll only one of the responses can be voted for while in a Multiple choice poll it is possible to choose more than one at the same time.'),
375
      );
376
377
      // Delete votes from this poll.
378
      $widget['delete_votes'] = array(
379
        '#type' => 'checkbox',
380
        '#title' => t('Delete all votes'),
381
        '#description' => t('Delete all votes on this poll. <strong>This action can not be undone!</strong>'),
382
        '#default_value' => FALSE,
383
        '#access' => $admin_pollfield,
384
      );
385
386
      $widget['poll_features'] = array(
387
        '#type' => 'value',
388
        '#value' => isset($poll_features) ? $poll_features : NULL,
389
      );
390
      $widget['choice'] = array(
391
        '#type' => 'value',
392
        '#value' => isset($items[$delta]['choice']) ? $items[$delta]['choice'] : array(),
393
      );
394
395
      // Choices.
396
      $choices = !empty($items[$delta]['choice']) ? unserialize($items[$delta]['choice']) : array();
397
      $number_in_data_base = $number_of_choices = count($choices);
398
      // Ajax wrapper.
399
      $wrapper = 'pollfield-ajax-wrapper-' . $delta;
400
      $field_name = $field['field_name'];
401
      if (isset($form_state['count_choices'])) {
402
        $number_of_choices = $form_state['count_choices'];
403
      }
404
      else {
405
        $form_state['count_choices'] = $number_of_choices;
406
      }
407
      // Forming field definition for form return in ajax.
408
      $form_state['field_name'] = $field_name;
409
410
      if (isset($node->$field_name)) {
411
        global $language;
412
        if (isset($node->{$field_name}[$language->language])) {
413
          $field_lang = $node->{$field_name}[$language->language];
414
        }
415
        else {
416
          $field_lang = LANGUAGE_NONE;
417
        }
418
      }
419
      else {
420
        $field_lang = LANGUAGE_NONE;
421
      }
422
      $form_state['field_lang'] = $field_lang;
423
      $form_state['field_delta'] = $delta;
424
425
      $widget['group'] = array(
426
        '#prefix' => '<div id="' . $wrapper . '">',
427
        '#suffix' => '</div>',
428
      );
429
430
      for ($i = 1; $i <= ($number_of_choices + 1); $i++) {
431
        $widget['group'][$i] = array(
432
          '#type' => 'fieldset',
433
          '#title' => t('Choice #%delta', array('%delta' => $i)),
434
          '#collapsible' => TRUE,
435
          '#collapsed' => FALSE,
436
          '#weight' => $i,
437
        );
438
        $widget['group'][$i]['choice'] = array(
439
          '#title' => t('Response'),
440
          '#type' => 'textfield',
441
          '#default_value' => isset($choices[$i]['choice']) ? $choices[$i]['choice'] : '',
442
          '#rows' => 2,
443
          '#description' => t('If you want to delete this choice leave the field empty.'),
444
        );
445
        $widget['group'][$i]['votes'] = array(
446
          '#title' => t('Starting votes count (optional)'),
447
          '#access' => $admin_pollfield,
448
          '#type' => 'textfield',
449
          '#default_value' => isset($choices[$i]['votes']) ? $choices[$i]['votes'] : '',
450
          '#element_validate' => array('_pollfield_is_digits_validate'),
451
          '#size' => 10,
452
        );
453
      }
454
455
      $widget['add-more'] = array(
456
        '#type' => 'submit',
457
        '#value' => t('More choices'),
458
        '#description' => t("If the amount of boxes above isn't enough, click here to add more choices."),
459
        '#submit' => array('pollfield_more_choice_callback_submit'),
460
        '#ajax' => array(
461
          'callback' => 'pollfield_more_choice_callback_js',
462
          'wrapper' => $wrapper,
463
        ),
464
      );
465
      break;
466 85ad3d82 Assos Assos
  }
467 62f5c69e Assos Assos
468
  // Question is name of field in field database.
469 85ad3d82 Assos Assos
  $element['question'] = $widget['question'];
470 62f5c69e Assos Assos
  $element['active'] = $widget['active'];
471
  $element['anonymous'] = $widget['anonymous'];
472
  $element['runtime'] = $widget['runtime'];
473
  $element['poll_type'] = $widget['poll_type'];
474
  $element['cancelvote_allow'] = $widget['cancelvote_allow'];
475
  $element['result_allow'] = $widget['result_allow'];
476
  $element['delete_votes'] = $widget['delete_votes'];
477
  $element['group'] = $widget['group'];
478
  $element['add-more'] = $widget['add-more'];
479
  // Hidden elements for serialized fields.
480
  $element['poll_features'] = $widget['poll_features'];
481
  $element['choice'] = $widget['choice'];
482
483
  return $element;
484 85ad3d82 Assos Assos
}
485
486
/**
487
 * ajax more choice callback
488
 */
489 62f5c69e Assos Assos
function pollfield_more_choice_callback_js($form, $form_state) {
490
  $field = $form[$form_state['field_name']];
491
  $lang = $form_state['field_lang'];
492
  if (!isset($field[$lang])) {
493
    $lang = LANGUAGE_NONE;
494
  }
495
  $delta = $form_state['field_delta'];
496
  return $field[$lang][$delta]['group'];
497 85ad3d82 Assos Assos
}
498 62f5c69e Assos Assos
499 85ad3d82 Assos Assos
/**
500
 * submit more choice callback
501
 */
502 62f5c69e Assos Assos
function pollfield_more_choice_callback_submit($form, &$form_state) {
503
  $form_state['count_choices'] += 1;
504
  $form_state['rebuild'] = TRUE;
505 85ad3d82 Assos Assos
}
506
507
/**
508
 * Implements hook_field_widget_error().
509
 *
510
 * hook_field_widget_error() lets us figure out what to do with errors
511
 * we might have generated in hook_field_validate(). Generally, we'll just
512
 * call form_error().
513
 *
514
 * @see field_example_field_validate()
515
 * @see form_error()
516
 */
517
function pollfield_field_widget_error($element, $error, $form, &$form_state) {
518
  switch ($error['error']) {
519
    case 'field_example_invalid':
520
      form_error($element, $error['message']);
521
      break;
522
  }
523
}
524
525
/**
526 62f5c69e Assos Assos
 * Save vote information.
527 85ad3d82 Assos Assos
 */
528
function pollfield_save_choice($vote, $node) {
529 62f5c69e Assos Assos
  // Get total votes.
530
  $field = field_get_items('node', $node, $vote->field_name);
531
  $total_votes = isset($field[0]['votes']) ? $field[0]['votes'] : 0;
532 85ad3d82 Assos Assos
533 62f5c69e Assos Assos
  $vote->table = 'field_revision_' . $vote->field_name;
534 85ad3d82 Assos Assos
  // Make sure the voter filled out the poll form correctly.
535
  $vote_error = FALSE;
536 62f5c69e Assos Assos
537 85ad3d82 Assos Assos
  if ($vote->type == 'single' && !isset($vote->choice)) {
538
    $vote_error = TRUE;
539
  }
540
  else {
541 62f5c69e Assos Assos
    if (!isset($vote->choice) || !count($vote->choice)) {
542 85ad3d82 Assos Assos
      $vote_error = TRUE;
543
    }
544
  }
545
  if ($vote_error) {
546 62f5c69e Assos Assos
    drupal_set_message(t('Choice is not selected. Select your answer and vote.'), 'warning');
547
    return FALSE;
548 85ad3d82 Assos Assos
  }
549 62f5c69e Assos Assos
550
  // Check if the user has already voted on this pollfield.
551
  $elements['entity'] = $node;
552
  $elements['field']['field_name'] = $vote->field_name;
553
  $elements['delta'] = $vote->field_name_delta;
554
  $elements['item'] = $vote->item;
555
556
  if (!pollfield_user_voted($elements)) {
557
    // Save votes.
558
    foreach ($vote->choice as $choice) {
559
      pollfield_save_vote_record($vote, $choice);
560 85ad3d82 Assos Assos
    }
561
562 62f5c69e Assos Assos
    // Increment total votes for this pollfield.
563 85ad3d82 Assos Assos
    $total_votes++;
564 62f5c69e Assos Assos
    $node->{$vote->field_name}[LANGUAGE_NONE][0]['votes'] = $total_votes;
565
    field_attach_update('node', $node);
566
567
    // Any time a vote is recorded, clear the CCK cache
568
    // so the votes can be updated.
569 85ad3d82 Assos Assos
    pollfield_clear($node);
570
571
    drupal_set_message(t('Your vote was recorded.'));
572
  }
573
  else {
574
    drupal_set_message(t('You already voted or you are not allowed to vote'), 'error');
575 62f5c69e Assos Assos
    return FALSE;
576 85ad3d82 Assos Assos
  }
577 62f5c69e Assos Assos
  return TRUE;
578 85ad3d82 Assos Assos
}
579
580
/**
581 62f5c69e Assos Assos
 * Write a vote to the database.
582 85ad3d82 Assos Assos
 */
583
function pollfield_save_vote_record($vote, $choice) {
584 62f5c69e Assos Assos
  // Store user id if the user is logged in.
585 85ad3d82 Assos Assos
  if ($vote->uid > 0) {
586 62f5c69e Assos Assos
    db_insert('pollfield_votes')
587
      ->fields(array(
588
        'nid' => $vote->nid,
589
        'field_table' => $vote->table,
590
        'field_name' => $vote->field_name,
591
        'uid' => $vote->uid,
592
        'delta' => $choice,
593
        'field_name_delta' => $vote->field_name_delta,
594
      ))
595
      ->execute();
596 85ad3d82 Assos Assos
  }
597 62f5c69e Assos Assos
  // Store IP or cookie if the user is anonymous.
598 85ad3d82 Assos Assos
  else {
599 62f5c69e Assos Assos
    db_insert('pollfield_votes')
600
      ->fields(array(
601
        'nid' => $vote->nid,
602
        'field_table' => $vote->table,
603
        'field_name' => $vote->field_name,
604
        'uid' => $vote->uid,
605
        'delta' => $choice,
606
        'hostname' => $vote->hostname,
607
        'field_name_delta' => $vote->field_name_delta,
608
        'cookie' => $vote->cookie,
609
      ))
610
      ->execute();
611 85ad3d82 Assos Assos
  }
612
}
613
614
/**
615 62f5c69e Assos Assos
 * Cancel a user's vote on a poll.
616 85ad3d82 Assos Assos
 */
617 62f5c69e Assos Assos
function pollfield_cancel_choice($vote, $node) {
618
  // Get total votes.
619
  $field = field_get_items('node', $node, $vote->field_name);
620
  $total_votes = isset($field[0]['votes']) ? $field[0]['votes'] : 0;
621 85ad3d82 Assos Assos
622 62f5c69e Assos Assos
  // Cancel all the votes by this user on this poll.
623
  pollfield_cancel_vote_record($vote);
624 85ad3d82 Assos Assos
625 62f5c69e Assos Assos
  // Decrement total votes for this pollfield.
626 85ad3d82 Assos Assos
  $total_votes--;
627 62f5c69e Assos Assos
  $total_votes = ($total_votes < 0) ? 0 : $total_votes;
628
  $node->{$vote->field_name}[LANGUAGE_NONE][0]['votes'] = $total_votes;
629
  field_attach_update('node', $node);
630
631
  return TRUE;
632 85ad3d82 Assos Assos
}
633
634
/**
635 62f5c69e Assos Assos
 * Delete votes from the database.
636 85ad3d82 Assos Assos
 *
637 62f5c69e Assos Assos
 * Delete votes made by a specific user on a specific pollfield.
638 85ad3d82 Assos Assos
 */
639
function pollfield_cancel_vote_record($vote) {
640 62f5c69e Assos Assos
  $query = db_delete('pollfield_votes')
641
    ->condition('nid', $vote->nid)
642
    ->condition('field_table', $vote->field_table)
643
    ->condition('field_name', $vote->field_name)
644
    ->condition('field_name_delta', $vote->field_name_delta);
645 85ad3d82 Assos Assos
646
  if ($vote->uid) {
647 62f5c69e Assos Assos
    $query->condition('uid', $vote->uid);
648
    $query->execute();
649 85ad3d82 Assos Assos
  }
650
  else {
651
    if ($vote->anonymous == 'anon_by_ip') {
652 62f5c69e Assos Assos
      $query->condition('hostname', $vote->hostname);
653
      $query->execute();
654 85ad3d82 Assos Assos
    }
655 62f5c69e Assos Assos
    elseif ($vote->anonymous == 'anon_by_cookie') {
656
      $query->condition('cookie', $vote->cookie);
657
      $query->execute();
658 85ad3d82 Assos Assos
    }
659
  }
660
}
661 62f5c69e Assos Assos
662 85ad3d82 Assos Assos
/**
663
 * Saving or canceling user poll vote.
664
 */
665 62f5c69e Assos Assos
function pollfield_vote($form, &$form_state) {
666
667
$vote = new stdClass();
668
  $values = $form_state['input'];
669
  // Build vote object.
670
  $vote->nid = $values['nid'];
671
  $vote->field_name = $values['field_name'];
672
  $vote->field_name_delta = $values['field_name_delta'];
673
  $vote->field_table = $values['table'];
674
  $vote->cancel = $values['cancel'];
675
  if (isset($values['choice'])) {
676
    if (is_array($values['choice'])) {
677
      $choices = array_filter($values['choice']);
678
      $vote->choice = array_keys($choices);
679
    }
680
    else {
681
      $vote->choice = array($values['choice']);
682
    }
683
  }
684
  $item = unserialize($values['item']);
685
  $vote->item = $item;
686
687
  // Information about the voter.
688 85ad3d82 Assos Assos
  global $user;
689
  $vote->uid = $user->uid;
690 62f5c69e Assos Assos
  $vote->hostname = ip_address();
691 85ad3d82 Assos Assos
692 62f5c69e Assos Assos
  // If we need a cookie add it here.
693
  $cookie = pollfield_cookie_id_generator($values);
694
  $vote->cookie = ($cookie) ? serialize($cookie) : $cookie;
695 85ad3d82 Assos Assos
696
  $node = node_load($vote->nid);
697
698 62f5c69e Assos Assos
  // Get poll features.
699 85ad3d82 Assos Assos
  $poll_features = unserialize($item['poll_features']);
700
  $vote->anonymous = $item['anonymous'];
701
702 62f5c69e Assos Assos
  if ($vote->nid) {
703
    // Cancel vote.
704
    if ($vote->cancel) {
705
      pollfield_cancel_choice($vote, $node);
706 85ad3d82 Assos Assos
    }
707 62f5c69e Assos Assos
    // Vote.
708
    else {
709
      $vote->type = $poll_features['poll_type'];
710
      pollfield_save_choice($vote, $node);
711 85ad3d82 Assos Assos
    }
712
  }
713 62f5c69e Assos Assos
  // Clear the cache.
714 85ad3d82 Assos Assos
  pollfield_clear($node);
715
}
716
717
/**
718
 * Cookie generator for anonymous voting.
719
 */
720 62f5c69e Assos Assos
function pollfield_cookie_id_generator($values) {
721 85ad3d82 Assos Assos
  global $user;
722 62f5c69e Assos Assos
723
  $item = unserialize($values['item']);
724
  if ($item['anonymous'] != 'anon_by_cookie') {
725
    return FALSE;
726
  }
727
728
  $nid = $values['nid'];
729
  $field_name = $values['field_name'];
730
  $field_name_delta = $values['field_name_delta'];
731
  $field_table = $values['table'];
732 85ad3d82 Assos Assos
  $node = node_load($nid);
733 62f5c69e Assos Assos
  $user_id_cookie = rand(0, 100000) + time();
734
  $user_id_cookie = 'id' . $user_id_cookie;
735 85ad3d82 Assos Assos
  // /cookie add***************************************
736 62f5c69e Assos Assos
  $cookie_name = $field_table . '_' . $field_name . '_' . $field_name_delta;
737 85ad3d82 Assos Assos
  $cookie_value = $user_id_cookie;
738
  $field = $node->$field_name;
739
  $duration = $item['runtime'];
740
741
  if (!isset($_COOKIE[$cookie_name])) {
742 62f5c69e Assos Assos
    if ($duration == 0) {
743
      // If poll is unlimited set expire one month.
744
      $expire = time() + 60 * 60 * 24 * 30;
745 85ad3d82 Assos Assos
    }
746
    else {
747 62f5c69e Assos Assos
      $expire = time() + $duration;
748 85ad3d82 Assos Assos
    }
749
    setcookie($cookie_name, $cookie_value, $expire, '/');
750 62f5c69e Assos Assos
    $cookie = array(
751
      'cookie_name' => $cookie_name,
752
      'cookie_value' => $cookie_value,
753
    );
754 85ad3d82 Assos Assos
  }
755
  else {
756 62f5c69e Assos Assos
    $cookie = array(
757
      'cookie_name' => $cookie_name,
758
      'cookie_value' => $_COOKIE[$cookie_name],
759
    );
760 85ad3d82 Assos Assos
  }
761
762
  return $cookie;
763
}
764
765
/**
766
 * Check if user has voted on a specific pollfield.
767
 *
768 62f5c69e Assos Assos
 * @return int
769 85ad3d82 Assos Assos
 *   Integer of the number of votes.
770
 *   0 if they haven't voted.
771
 */
772
function pollfield_user_voted($elements) {
773
  global $user;
774 62f5c69e Assos Assos
775
  $node = $elements['entity'];
776
777
  $field_name = $elements['field']['field_name'];
778
  $field_table = 'field_revision_' . $field_name;
779
  $field_name_delta = $elements['delta'];
780
781 85ad3d82 Assos Assos
  $nid = $node->nid;
782
  $uid = $user->uid;
783 62f5c69e Assos Assos
  $hostname = ip_address();
784 85ad3d82 Assos Assos
  $voted = FALSE;
785 62f5c69e Assos Assos
  $is_voted = 0;
786
787
  // There is no translation.
788
  if ($node->tnid == 0) {
789
    $t_nodes_results = array($nid);
790 85ad3d82 Assos Assos
  }
791 62f5c69e Assos Assos
  // There is translation.
792
  else {
793
    $t_nodes_results = db_select('node', 'n')
794
      ->fields('n', array('nid'))
795
      ->condition('tnid', $node->tnid)
796
      ->execute()
797
      ->fetchAllAssoc('nid');
798
    $t_nodes_results = array_keys($t_nodes_results);
799 85ad3d82 Assos Assos
  }
800
801 62f5c69e Assos Assos
  // Check all translations.
802
  foreach ($t_nodes_results as $t_nid) {
803
    // Get anonymous vote settings.
804 85ad3d82 Assos Assos
    $field = $elements['item'];
805
    $anonymous = $field['anonymous'];
806
807 62f5c69e Assos Assos
    // Check if user has voted.
808 85ad3d82 Assos Assos
    if ($user->uid) {
809 62f5c69e Assos Assos
      $voted = (int) db_select('pollfield_votes', 'pfv')
810
        ->condition('pfv.nid', $t_nid)
811
        ->condition('pfv.field_table', $field_table)
812
        ->condition('pfv.field_name', $field_name)
813
        ->condition('pfv.uid', $user->uid)
814
        ->condition('pfv.field_name_delta', $field_name_delta)
815
        ->countQuery()->execute()->fetchField();
816 85ad3d82 Assos Assos
    }
817 62f5c69e Assos Assos
    // User is anonymous.
818
    else {
819 85ad3d82 Assos Assos
      if ($anonymous == 'anon_by_ip') {
820 62f5c69e Assos Assos
        $voted = (int) db_select('pollfield_votes', 'pfv')
821
          ->condition('pfv.nid', $t_nid)
822
          ->condition('pfv.field_table', $field_table)
823
          ->condition('pfv.field_name', $field_name)
824
          ->condition('pfv.hostname', $hostname)
825
          ->condition('pfv.field_name_delta', $field_name_delta)
826
          ->countQuery()->execute()->fetchField();
827 85ad3d82 Assos Assos
      }
828 62f5c69e Assos Assos
      elseif ($anonymous == 'anon_by_cookie') {
829
        // Add cookie.
830
        $cookie_name = $field_table . '_' . $field_name . '_' . $field_name_delta;
831
        $cookie_collected_value = isset($_COOKIE[$cookie_name]) ? $_COOKIE[$cookie_name] : '';
832
833
        $cookie_compare = array(
834
          'cookie_name' => $cookie_name,
835
          'cookie_value' => $cookie_collected_value,
836
        );
837 85ad3d82 Assos Assos
838
        $cookie_compare_db = serialize($cookie_compare);
839
840 62f5c69e Assos Assos
        $voted = (int) db_select('pollfield_votes', 'pfv')
841
          ->condition('pfv.nid', $t_nid)
842
          ->condition('pfv.field_table', $field_table)
843
          ->condition('pfv.field_name', $field_name)
844
          ->condition('pfv.cookie', $cookie_compare_db)
845
          ->condition('pfv.field_name_delta', $field_name_delta)
846
          ->countQuery()->execute()->fetchField();
847 85ad3d82 Assos Assos
      }
848
    }
849 62f5c69e Assos Assos
850
    $is_voted += $voted;
851 85ad3d82 Assos Assos
  }
852
853
  return $is_voted;
854
}
855
856
/**
857
 * Get user votes.
858
 *
859 62f5c69e Assos Assos
 * @return array Returns an array of votes for theme functions.
860 85ad3d82 Assos Assos
 */
861
function pollfield_user_votes($elements) {
862
  global $user;
863 62f5c69e Assos Assos
  $node = $elements['entity'];
864
  $hostname = ip_address();
865
866
  $field_name = $elements['field']['field_name'];
867
  $field_table = 'field_revision_' . $field_name;
868
  $field_name_delta = $elements['delta'];
869
870
  // There is no translation.
871
  if ($node->tnid == 0) {
872
    $t_nodes_results = array($node->nid);
873 85ad3d82 Assos Assos
  }
874 62f5c69e Assos Assos
  // There is translation.
875
  else {
876
    $t_nodes_results = db_select('node', 'n')
877
      ->fields('n', array('nid'))
878
      ->condition('tnid', $node->tnid)
879
      ->execute()
880
      ->fetchAllAssoc('nid');
881
    $t_nodes_results = array_keys($t_nodes_results);
882 85ad3d82 Assos Assos
  }
883
884 62f5c69e Assos Assos
  $votes = array();
885
  // Check all translations.
886
  foreach ($t_nodes_results as $t_nid) {
887
    $query = db_select('pollfield_votes', 'pfv')
888
      ->fields('pfv', array('delta'))
889
      ->condition('nid', $t_nid)
890
      ->condition('field_table', $field_table)
891
      ->condition('field_name', $field_name)
892
      ->condition('field_name_delta', $field_name_delta);
893
894
    // Get user votes.
895 85ad3d82 Assos Assos
    if ($user->uid) {
896 62f5c69e Assos Assos
      // Delta is number of choice.
897
      $result = $query->condition('uid', $user->uid)
898
        ->execute()->fetchAllAssoc('delta');
899
      $votes = array_merge($votes, array_keys($result));
900 85ad3d82 Assos Assos
    }
901 62f5c69e Assos Assos
    // User is anonymous.
902 85ad3d82 Assos Assos
    else {
903 62f5c69e Assos Assos
      $anonymous = $elements['item']['anonymous'];
904 85ad3d82 Assos Assos
      if ($anonymous == 'anon_by_ip') {
905 62f5c69e Assos Assos
        // Delta is number of choice.
906
        $result = $query->condition('hostname', $hostname)
907
          ->execute()->fetchAllAssoc('delta');
908
        $votes = array_merge($votes, array_keys($result));
909 85ad3d82 Assos Assos
      }
910 62f5c69e Assos Assos
      elseif ($anonymous == 'anon_by_cookie') {
911
        // Generate cookie.
912
        $cookie_name = $field_table . '_' . $field_name . '_' . $field_name_delta;
913
        $cookie_collected_value = isset($_COOKIE[$cookie_name]) ? $_COOKIE[$cookie_name] : '';
914
        $cookie_compare = array(
915
          'cookie_name' => $cookie_name,
916
          'cookie_value' => $cookie_collected_value,
917
        );
918 85ad3d82 Assos Assos
919 62f5c69e Assos Assos
        $result = $query->condition('cookie', serialize($cookie_compare))
920
          ->execute()->fetchAllAssoc('delta');
921
        $votes = array_merge($votes, array_keys($result));
922 85ad3d82 Assos Assos
      }
923
    }
924
  }
925 62f5c69e Assos Assos
926 85ad3d82 Assos Assos
  return $votes;
927
}
928
929
/**
930
 * Build array of duration options
931
 *
932
 * The times in seconds that a pollfield can run for.
933
 */
934
function pollfield_duration_options() {
935 62f5c69e Assos Assos
  $options = array(86400, 172800, 345600, 604800, 1209600, 2419200, 4838400, 9676800, 31536000);
936
  $duration_options = array(0 => t('Unlimited')) + drupal_map_assoc($options, "format_interval");
937 85ad3d82 Assos Assos
  return $duration_options;
938
}
939 62f5c69e Assos Assos
940 85ad3d82 Assos Assos
/**
941
 * Internal callback to validate starting vote totals.
942
 *
943
 * Check that this value is an integer.
944
 */
945
function _pollfield_is_digits_validate($element, &$form_state) {
946
  if ($element['#value'] != NULL) {
947
    if (!ctype_digit($element['#value'])) {
948
      form_error($element, t('The starting votes count must be a whole number.'));
949
    }
950
  }
951
}
952
953
/**
954 62f5c69e Assos Assos
 * Default field formatter function.
955 85ad3d82 Assos Assos
 */
956 62f5c69e Assos Assos
function theme_pollfield_default_formatter($elements) {
957
  // Node object.
958 85ad3d82 Assos Assos
  $node = $elements['elements']['entity'];
959 62f5c69e Assos Assos
  $delta = $elements['elements']['delta'];
960
  // Get the available choices for this poll.
961 85ad3d82 Assos Assos
  $choices = unserialize($elements['elements']['item']['choice']);
962 62f5c69e Assos Assos
  $item = $elements['elements']['item'];
963 85ad3d82 Assos Assos
964
  $output = '';
965
  if (!empty($choices)) {
966
    $pollfield_title = check_plain($elements['elements']['item']['question']);
967
    $poll_result = pollfield_build_results($elements['elements']);
968 62f5c69e Assos Assos
969
    // Build voting form.
970 85ad3d82 Assos Assos
    $form = drupal_get_form('pollfield_voting_form', $elements['elements']);
971 62f5c69e Assos Assos
972
    $output  = '<div class="pollfield">';
973
    $output .= '<div id="pollfield-' . $node->nid . '-' . $delta . '" class="pollfield-form">';
974
    $output .= '<div class="pollfield-title">' . $pollfield_title . '</div>';
975 85ad3d82 Assos Assos
    $output .= $poll_result;
976
    $output .= render($form);
977
    $output .= '</div>';
978
    $output .= '</div>';
979
  }
980 62f5c69e Assos Assos
981 85ad3d82 Assos Assos
  return $output;
982
}
983
984
/**
985
 * Build voting form
986
 *
987
 * Checks all the various rules associate with the current
988
 * pollfield and builds a form that lets you vote on
989
 * or cancel a pollfield.
990
 */
991 62f5c69e Assos Assos
function pollfield_voting_form($form, $form_state, $elements) {
992
  if (empty($elements['item']['active'])) {
993
    return NULL;
994
  }
995
996 85ad3d82 Assos Assos
  global $user;
997 62f5c69e Assos Assos
  $table = 'field_revision_' . $elements['field']['field_name'];
998 85ad3d82 Assos Assos
  $field_name = $elements['field']['field_name'];
999
  $field_name_delta = $elements['delta'];
1000
  $items = $elements['item'];
1001
  $node = $elements['entity'];
1002
1003 62f5c69e Assos Assos
  // Get poll features.
1004
  if (is_array($elements['item']['poll_features'])) {
1005
    $poll_features = $elements['item']['poll_features'];
1006
  }
1007
  else {
1008
    $poll_features = unserialize($elements['item']['poll_features']);
1009
  }
1010
1011
  // Get anonymous vote settings.
1012
  $anonymous = $elements['item']['anonymous'];
1013
1014
  // If the user has voted, build the cancel vote form.
1015
  if (pollfield_user_voted($elements)) {
1016
    if ($user->uid) {
1017
      // Allow cancel vote.
1018
      if ($poll_features['cancelvote_allow']) {
1019
        $cancel = 1;
1020
        pollfield_voting_form_data($form, $field_name_delta, $field_name, $node->nid, $table, $cancel, $items);
1021
      }
1022 85ad3d82 Assos Assos
    }
1023
    else {
1024 62f5c69e Assos Assos
      if ($anonymous == 'anon_non') {
1025
        return NULL;
1026 85ad3d82 Assos Assos
      }
1027
      else {
1028 62f5c69e Assos Assos
        if ($poll_features['cancelvote_allow']) {
1029
          $cancel = 1;
1030
          pollfield_voting_form_data($form, $field_name_delta, $field_name, $node->nid, $table, $cancel, $items);
1031 85ad3d82 Assos Assos
        }
1032
      }
1033
    }
1034 62f5c69e Assos Assos
  }
1035 85ad3d82 Assos Assos
1036 62f5c69e Assos Assos
  // If the user hasn't voted, build the vote form.
1037
  else {
1038
    if ($user->uid == 0) {
1039
      if ($anonymous == 'anon_non') {
1040
        return NULL;
1041 85ad3d82 Assos Assos
      }
1042 62f5c69e Assos Assos
    }
1043
    if ($items) {
1044
      $list = array();
1045
      $choices = unserialize($items['choice']);
1046
      if (!empty($choices)) {
1047
        // Build choices array.
1048
        foreach ($choices as $delta => $choice) {
1049
          if (!empty($choice['choice'])) {
1050
            $list[$delta] = check_plain($choice['choice']);
1051 85ad3d82 Assos Assos
          }
1052
        }
1053 62f5c69e Assos Assos
        // Build single choice poll.
1054
        if ($poll_features['poll_type'] == 'single') {
1055
          $form['choice'] = array(
1056
            '#type' => 'radios',
1057
            '#title' => check_plain($items['question']),
1058
            '#title_display' => 'invisible',
1059
            '#options' => $list,
1060
          );
1061
        }
1062
        // Build multiple choice poll.
1063
        else {
1064
          $form['choice'] = array(
1065
            '#type' => 'checkboxes',
1066
            '#title' => check_plain($items['question']),
1067
            '#title_display' => 'invisible',
1068
            '#options' => $list,
1069
          );
1070
        }
1071 85ad3d82 Assos Assos
      }
1072
    }
1073 62f5c69e Assos Assos
    $cancel = 0;
1074
    pollfield_voting_form_data($form, $field_name_delta, $field_name, $node->nid, $table, $cancel, $items);
1075 85ad3d82 Assos Assos
  }
1076
1077
  return $form;
1078
}
1079
1080 62f5c69e Assos Assos
/**
1081
 * Voting form data.
1082
 */
1083
function pollfield_voting_form_data(&$form, $field_name_delta, $field_name, $nid, $table, $cancel, $items) {
1084
  $form['field_name_delta'] = array(
1085
    '#type' => 'hidden',
1086
    '#value' => $field_name_delta,
1087
  );
1088
  $form['field_name'] = array(
1089
    '#type' => 'hidden',
1090
    '#value' => $field_name,
1091
  );
1092
  $form['nid'] = array(
1093
    '#type' => 'hidden',
1094
    '#value' => $nid,
1095
  );
1096
  $form['item'] = array(
1097
    '#type' => 'hidden',
1098
    '#value' => serialize($items),
1099
  );
1100
  $form['table'] = array(
1101
    '#type' => 'hidden',
1102
    '#value' => $table,
1103
  );
1104
  $form['cancel'] = array(
1105
    '#type' => 'hidden',
1106
    '#value' => $cancel,
1107
  );
1108
  $form['vote'] = array(
1109
    '#type' => 'submit',
1110
    '#value' => $cancel ? t('Cancel Vote') : t('Vote'),
1111
    '#submit' => array('pollfield_vote'),
1112
  );
1113
}
1114
1115 85ad3d82 Assos Assos
/**
1116
 * Build the results display
1117
 *
1118 62f5c69e Assos Assos
 * @param array $elements Elements
1119 85ad3d82 Assos Assos
 *
1120
 * @return pollfield_result
1121
 *   A formatted HTML string of the appropriate pollfield
1122
 *   result display. Will output empty HTML structure if
1123
 *   the user can't view results b/c of permissions.
1124
 */
1125
function pollfield_build_results($elements) {
1126 62f5c69e Assos Assos
  $poll_result = '';
1127 85ad3d82 Assos Assos
1128 62f5c69e Assos Assos
  $active = $elements['item']['active'];
1129
  $display_before = pollfield_display_results_before_vote($elements['item']);
1130 85ad3d82 Assos Assos
1131 62f5c69e Assos Assos
  // Get the available choices for this poll.
1132 85ad3d82 Assos Assos
  $choices = unserialize($elements['item']['choice']);
1133
1134
  // Determine if the user voted on this node.
1135
  $user_voted = pollfield_user_voted($elements);
1136
  $user_votes = pollfield_user_votes($elements);
1137
1138
  // Array of vote totals for each choice.
1139 62f5c69e Assos Assos
  $votes = pollfield_sum_all_votes($elements['entity'], $choices, $elements);
1140 85ad3d82 Assos Assos
  // Total of all votes.
1141
  $sum = array_sum($votes);
1142
1143 62f5c69e Assos Assos
  // If the user has permission to view results and
1144
  // this node allows results viewing, show them.
1145
  if (user_access('view pollfield results ' . $elements['field']['field_name'])) {
1146
    if ($user_voted || $display_before || !$active) {
1147
      foreach ($choices as $delta => $choice) {
1148
        if (!empty($choice['choice'])) {
1149
          $percent = ($sum == 0) ? 0 : round(floatval(($votes[$delta] * 100.0) / $sum), 1);
1150
          $percent_string = $percent . '% (' . format_plural($votes[$delta], '1 vote', '@count votes') . ')';
1151
          $user_choice = (is_array($user_votes) && in_array($delta, $user_votes)) ? TRUE : FALSE;
1152
1153
          $variables = array(
1154
            'choice' => $choice['choice'],
1155
            'percent' => $percent,
1156
            'percent_string' => $percent_string,
1157
            'user_choice' => $user_choice,
1158
          );
1159 85ad3d82 Assos Assos
          $poll_result .= theme('pollfield_row', $variables);
1160
        }
1161
      }
1162
    }
1163
  }
1164 62f5c69e Assos Assos
1165 85ad3d82 Assos Assos
  return $poll_result;
1166
}
1167
1168
/**
1169
 * Return an array of vote totals for each choice in a pollfield.
1170
 */
1171
function pollfield_sum_all_votes($node, $choices, $elements) {
1172 62f5c69e Assos Assos
  $field_name = $elements['field']['field_name'];
1173 85ad3d82 Assos Assos
  $field_name_delta = $elements['delta'];
1174 62f5c69e Assos Assos
  $table = 'field_revision_' . $field_name;
1175 85ad3d82 Assos Assos
  // This check is required until we can stop empty pollfields from
1176
  // requesting a vote count, which would be more efficient.
1177
  $choice_count = array();
1178
  if (is_array($choices)) {
1179
    foreach ($choices as $delta => $group) {
1180 62f5c69e Assos Assos
      // Count user submitted votes.
1181
      $count = (int) db_select('pollfield_votes', 'pfv')
1182
        ->condition('nid', $node->nid)
1183
        ->condition('delta', $delta)
1184
        ->condition('field_table', $table)
1185
        ->condition('field_name', $field_name)
1186
        ->condition('field_name_delta', $field_name_delta)
1187
        ->countQuery()->execute()->fetchField();
1188
      $choice_count[$delta] = $choices[$delta]['votes'] + $count;
1189 85ad3d82 Assos Assos
    }
1190
  }
1191
  return $choice_count;
1192
}
1193
1194
/**
1195
 * Return a sum of the total votes on a pollfield.
1196 62f5c69e Assos Assos
 *
1197
 * TODO: dead code?
1198 85ad3d82 Assos Assos
 */
1199
function pollfield_sum_starting_votes($choices) {
1200
  // This check is required until we can stop empty pollfields from
1201
  // requesting a vote count, which would be more efficient.
1202
  if (is_array($choices)) {
1203
    foreach ($choices as $delta => $group) {
1204
      // Count starting votes.
1205
      $total_votes = $total_votes + $choices[$delta]['votes'];
1206
    }
1207
    return $total_votes;
1208
  }
1209
}
1210 62f5c69e Assos Assos
1211 85ad3d82 Assos Assos
/**
1212
 * Does this node allow the user to view results?
1213
 *
1214 62f5c69e Assos Assos
 * @param $item Array of the pollfield information
1215 85ad3d82 Assos Assos
 *
1216 62f5c69e Assos Assos
 * @return boolean
1217 85ad3d82 Assos Assos
 *   Boolean value. Defaults to FALSE, meaning you can't view the results
1218
 *   before you vote on the pollfield.
1219
 */
1220
function pollfield_display_results_before_vote($item) {
1221
  $poll_features = unserialize($item['poll_features']);
1222
  if ($poll_features['result_allow']) {
1223
    return TRUE;
1224
  }
1225
  return FALSE;
1226
}
1227 62f5c69e Assos Assos
1228 85ad3d82 Assos Assos
/**
1229
 * choices field formatter function
1230
 */
1231 62f5c69e Assos Assos
function theme_pollfield_choices_formatter($item, $entity) {
1232
  // Node object.
1233 85ad3d82 Assos Assos
  $node = $elements['elements']['entity'];
1234 62f5c69e Assos Assos
  $delta = $elements['elements']['delta'];
1235
  // Get the available choices for this poll.
1236 85ad3d82 Assos Assos
  $choices = unserialize($elements['elements']['item']['choice']);
1237 62f5c69e Assos Assos
1238 85ad3d82 Assos Assos
  $output = '';
1239
  if (!empty($choices)) {
1240
    $pollfield_title = check_plain($elements['elements']['item']['question']);
1241
    $poll_result = pollfield_build_results($elements['elements']);
1242 62f5c69e Assos Assos
1243
    // Build voting form.
1244 85ad3d82 Assos Assos
    $form = drupal_get_form('pollfield_voting_form', $elements['elements']);
1245 62f5c69e Assos Assos
1246
    $output  = '<div class="pollfield">';
1247
    $output .= '<div id="pollfield-' . $node->nid . '-' . $delta . '" class="pollfield-form">';
1248
    $output .= '<div class="pollfield-title">' . $pollfield_title . '</div>';
1249 85ad3d82 Assos Assos
    $output .= '</div>';
1250
    $output .= '</div>';
1251
  }
1252 62f5c69e Assos Assos
1253 85ad3d82 Assos Assos
  return $output;
1254
}
1255
/**
1256 62f5c69e Assos Assos
 * Results field formatter function.
1257 85ad3d82 Assos Assos
 */
1258 62f5c69e Assos Assos
function theme_pollfield_results_formatter($item, $entity) {
1259
  // Node object.
1260 85ad3d82 Assos Assos
  $node = $elements['elements']['entity'];
1261 62f5c69e Assos Assos
  $delta = $elements['elements']['delta'];
1262
  // Get the available choices for this poll.
1263 85ad3d82 Assos Assos
  $choices = unserialize($elements['elements']['item']['choice']);
1264 62f5c69e Assos Assos
1265 85ad3d82 Assos Assos
  $output = '';
1266
  if (!empty($choices)) {
1267
    $pollfield_title = check_plain($elements['elements']['item']['question']);
1268
    $poll_result = pollfield_build_results($elements['elements']);
1269 62f5c69e Assos Assos
1270
    // Build voting form.
1271 85ad3d82 Assos Assos
    $form = drupal_get_form('pollfield_voting_form', $elements['elements']);
1272 62f5c69e Assos Assos
1273
    $output  = '<div class="pollfield">';
1274
    $output .= '<div id="pollfield-' . $node->nid . '-' . $delta . '" class="pollfield-form">';
1275
    $output .= '<div class="pollfield-title">' . $pollfield_title . '</div>';
1276 85ad3d82 Assos Assos
    $output .= $poll_result;
1277
    $output .= '</div>';
1278
    $output .= '</div>';
1279
  }
1280
  return $output;
1281
}
1282
/**
1283 62f5c69e Assos Assos
 * Runtime field formatter function.
1284 85ad3d82 Assos Assos
 */
1285 62f5c69e Assos Assos
function theme_pollfield_runtime_formatter($item, $entity) {
1286
  $node = $elements['elements']['entity'];
1287
  $delta = $elements['elements']['delta'];
1288
  // Get the available choices for this poll.
1289 85ad3d82 Assos Assos
  $choices = unserialize($elements['elements']['item']['choice']);
1290 62f5c69e Assos Assos
1291 85ad3d82 Assos Assos
  $output = '';
1292
  if (!empty($choices)) {
1293
1294 62f5c69e Assos Assos
    if ($elements['elements']['item']['runtime'] > 0) {
1295 85ad3d82 Assos Assos
      $runtime = t('!duration duration of poll in seconds', array('!duration' => $elements['elements']['item']['runtime']));
1296
    }
1297 62f5c69e Assos Assos
    else {
1298 85ad3d82 Assos Assos
      $runtime = t('Unlimited poll duration.');
1299
    }
1300 62f5c69e Assos Assos
    $out = '<div class="pollfield-runtime">' . check_plain($runtime) . '</div>';
1301 85ad3d82 Assos Assos
    return $out;
1302
  }
1303
  return $output;
1304
}
1305 62f5c69e Assos Assos
1306 85ad3d82 Assos Assos
/**
1307 62f5c69e Assos Assos
 * Question field formatter function.
1308 85ad3d82 Assos Assos
 */
1309 62f5c69e Assos Assos
function theme_pollfield_question_formatter($item, $entity) {
1310
  // TODO: fix.
1311
  $node = $elements['elements']['entity'];
1312
  $delta = $elements['elements']['delta'];
1313
  // Get the available choices for this poll.
1314 85ad3d82 Assos Assos
  $choices = unserialize($elements['elements']['item']['choice']);
1315 62f5c69e Assos Assos
1316 85ad3d82 Assos Assos
  $output = '';
1317
  if (!empty($choices)) {
1318
    $output = '<div class="pollfield-questions">';
1319
1320 62f5c69e Assos Assos
    if ($elements['elements']['item']['question'] != "' '") {
1321
      $output .= '<div class="pollfield-row">' . check_plain($elements['elements']['item']['question']) . '</div>';
1322 85ad3d82 Assos Assos
    }
1323
    $output .= '</div>';
1324
  }
1325
  return $output;
1326
}
1327 62f5c69e Assos Assos
1328 85ad3d82 Assos Assos
/**
1329 62f5c69e Assos Assos
 * Implements hook_theme().
1330 85ad3d82 Assos Assos
 *
1331
 * Define the theme hooks for pollfield.
1332
 *
1333
 * These setup the various display styles you can choose
1334
 * in the CCK display settings for this field.
1335
 */
1336
function pollfield_theme() {
1337 62f5c69e Assos Assos
  return array(
1338 85ad3d82 Assos Assos
    'pollfield_default_formatter' => array(
1339
      'variables' => array('elements'),
1340
    ),
1341
    'pollfield_row' => array(
1342 62f5c69e Assos Assos
      'variables' => array(
1343
        'choice' => NULL,
1344
        'user_choice' => FALSE,
1345
        'percent' => NULL,
1346
        'percent_string' => NULL,
1347
      ),
1348 85ad3d82 Assos Assos
    ),
1349
    'pollfield_results_formatter' => array(
1350
      'variables' => array('elements'),
1351
    ),
1352
    'pollfield_question_formatter' => array(
1353
      'variables' => array('elements'),
1354
    ),
1355
    'pollfield_runtimeformatter_' => array(
1356
      'variables' => array('elements'),
1357
    ),
1358
    'pollfield_choices_formatter' => array(
1359
      'variables' => array('elements'),
1360
    ),
1361
  );
1362
}
1363 62f5c69e Assos Assos
1364 85ad3d82 Assos Assos
/**
1365
 * Theme function for an single results row.
1366
 */
1367
function theme_pollfield_row($variables) {
1368 62f5c69e Assos Assos
  // Mark the user's vote.
1369
  $row_class = '';
1370 85ad3d82 Assos Assos
  if ($variables['user_choice']) {
1371
    $row_class = ' pollfield-chosen';
1372
  }
1373 62f5c69e Assos Assos
  $output  = '<div class="pollfield-row' . $row_class . '">';
1374
  $output .= '<div class="text">' . check_plain($variables['choice']) . '</div>';
1375
  $output .= '<div class="barcell">';
1376
  $output .= '<div class="bar"><div class="pollfield-foreground" style="width: ' . $variables['percent'] . '%;"></div></div>';
1377
  $output .= '</div>';
1378
  $output .= '<div class="pollfield-percent">' . $variables['percent_string'] . '</div>';
1379 85ad3d82 Assos Assos
  $output .= '</div>';
1380
  return $output;
1381
}
1382 62f5c69e Assos Assos
1383 85ad3d82 Assos Assos
/**
1384 62f5c69e Assos Assos
 * Implements hook_permission().
1385 85ad3d82 Assos Assos
 *
1386
 * Defines the permission options for pollfields.
1387
 */
1388
function pollfield_permission() {
1389 62f5c69e Assos Assos
  $permissions = array();
1390
  $fields = field_read_fields(array('type' => 'pollfield_poll'));
1391
  // Build a permission for each pollfield enabled content type.
1392
  foreach ($fields as $field_name => $field) {
1393
    $permissions['view pollfield results ' . $field_name] = array(
1394
      'title' => t('%field_name: View pollfield results', array('%field_name' => $field_name)),
1395
    );
1396
    $permissions['admin pollfield ' . $field_name] = array(
1397
      'title' => t('%field_name: Full admin access to pollfield edit options', array('%field_name' => $field_name)),
1398
    );
1399
  }
1400
  return $permissions;
1401 85ad3d82 Assos Assos
}
1402
1403
/**
1404
 * Clear the Drupal cache
1405
 *
1406
 * The cache is generally cleared after a vote is recorded
1407
 *
1408
 * TODO - really? clear the entire cache every time a vote is recorded?
1409
 */
1410
function pollfield_clear($node) {
1411 62f5c69e Assos Assos
  $cid = 'field:node:' . $node->nid;
1412 85ad3d82 Assos Assos
  cache_clear_all($cid, db_table_exists('cache_field') ? 'cache_field' : 'cache', TRUE);
1413
  cache_clear_all();
1414
}
1415
1416 62f5c69e Assos Assos
/**
1417
 * Implements hook_node_delete().
1418
 */
1419
function pollfield_node_delete($node) {
1420
  db_delete('pollfield_votes')
1421
    ->condition('nid', $node->nid)
1422
    ->execute();
1423
}
1424 85ad3d82 Assos Assos
1425
/**
1426
 * Implementation of hook_cron().
1427
 * Closes pollfields that have exceeded their allowed runtime.
1428
 */
1429
function pollfield_cron() {
1430
  $time = time();
1431
	$fields_query = db_query("SELECT field_name FROM {field_config} WHERE type='pollfield_poll'");
1432
	while ($field_name=$fields_query->fetchField()){
1433
		$query="SELECT p.* FROM {field_revision_".$field_name."} p LEFT JOIN {node} n ON n.nid=p.entity_id WHERE (n.created + p.".$field_name."_runtime)<".$time;
1434
		$polls_query = db_query($query);
1435
		while ($polls=$polls_query->fetchObject()){
1436
			$query_update = "UPDATE {field_revision_".$field_name."} SET ".$field_name."_active = 0 WHERE entity_id=".$polls->entity_id." AND delta = ".$polls->delta;
1437
			db_query($query_update);
1438
			$query_update = "UPDATE {field_data_".$field_name."} SET ".$field_name."_active = 0 WHERE entity_id=".$polls->entity_id." AND delta = ".$polls->delta;
1439
			db_query($query_update);
1440
		}
1441
	}
1442
  
1443
}