Projet

Général

Profil

Paste
Télécharger (49,7 ko) Statistiques
| Branche: | Révision:

root / htmltest / sites / all / modules / pollfield / pollfield.module @ a5572547

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