View source
<?php
module_load_include('inc', 'advpoll', 'includes/advpoll_voteapi');
module_load_include('inc', 'advpoll', 'includes/advpoll_helper');
function advpoll_menu() {
$menu['node/%node/advpoll/votes'] = array(
'title' => 'Votes',
'page callback' => 'advpoll_votes_page',
'page arguments' => array(
1,
),
'access callback' => '_advpoll_votes_access',
'access arguments' => array(
1,
),
'weight' => 3,
'type' => MENU_LOCAL_TASK,
'file' => 'advpoll.pages.inc',
'file path' => drupal_get_path('module', 'advpoll') . '/includes',
);
$menu['node/%node/electoral-list'] = array(
'title' => 'Electoral list',
'page callback' => 'advpoll_electoral_list_page',
'page arguments' => array(
1,
),
'access callback' => '_advpoll_electoral_list_access',
'access arguments' => array(
1,
),
'weight' => 3,
'type' => MENU_LOCAL_TASK,
'file' => 'advpoll.pages.inc',
'file path' => drupal_get_path('module', 'advpoll') . '/includes',
);
$menu['node/%node/remove'] = array(
'page callback' => 'advpoll_remove_voter',
'page arguments' => array(
1,
),
'access arguments' => array(
'administer polls',
),
'weight' => 3,
'type' => MENU_CALLBACK,
'file' => 'advpoll.pages.inc',
'file path' => drupal_get_path('module', 'advpoll') . '/includes',
);
$menu['node/%node/advpoll/votes/clear'] = array(
'page callback' => 'advpoll_clear_votes_page',
'page arguments' => array(
1,
),
'access callback' => '_advpoll_clear_votes_access',
'access arguments' => array(
1,
),
'weight' => 3,
'type' => MENU_LOCAL_TASK,
'file' => 'advpoll.pages.inc',
'file path' => drupal_get_path('module', 'advpoll') . '/includes',
);
$menu['node/%node/write-ins'] = array(
'title' => 'Write-ins',
'page callback' => 'advpoll_writeins_page',
'page arguments' => array(
1,
),
'access callback' => '_advpoll_writeins_access',
'access arguments' => array(
1,
),
'weight' => 3,
'type' => MENU_LOCAL_TASK,
'file' => 'advpoll.pages.inc',
'file path' => drupal_get_path('module', 'advpoll') . '/includes',
);
$menu['node/%node/results'] = array(
'title' => 'Results',
'page callback' => 'advpoll_results_page',
'page arguments' => array(
1,
),
'access callback' => '_advpoll_results_access',
'access arguments' => array(
1,
),
'weight' => 3,
'type' => MENU_LOCAL_TASK,
'file' => 'advpoll.pages.inc',
'file path' => drupal_get_path('module', 'advpoll') . '/includes',
);
$menu['node/%node/advpoll/votes/clear'] = array(
'page callback' => 'advpoll_clear_votes_page',
'page arguments' => array(
1,
),
'access callback' => '_advpoll_clear_votes_access',
'access arguments' => array(
1,
),
'weight' => 3,
'type' => MENU_LOCAL_TASK,
'file path' => drupal_get_path('module', 'advpoll') . '/includes',
'file' => 'advpoll.pages.inc',
);
return $menu;
}
function advpoll_permission() {
return array(
'vote on polls' => array(
'title' => t('Vote on polls'),
'description' => t('User may vote on polls.'),
),
'cancel own vote' => array(
'title' => t('Cancel own vote'),
'description' => t('User may cancel their vote in cases where individual user votes are being tracked.'),
),
'administer polls' => array(
'title' => t('Administer polls'),
'description' => t('User may use poll administration pages.'),
'restrict access' => TRUE,
),
'inspect all votes' => array(
'title' => t('Inspect all votes'),
'description' => t('User may use votes administration page.'),
'restrict access' => TRUE,
),
'show vote results' => array(
'title' => t('Show vote results'),
'description' => t('User may view poll results in cases where access to results is generally restricted.'),
),
'access electoral list' => array(
'title' => t('Access electoral list'),
'description' => t('User may see electoral lists associated with each poll.'),
),
'add write-ins' => array(
'title' => t('Add write-in votes'),
'description' => t('User may add write-ins for polls that allow them.'),
'restrict access' => TRUE,
),
);
}
function advpoll_node_view($node, $view_mode) {
if ($node->type == 'advpoll') {
$data = advpoll_get_data($node);
if ($data->behavior == 'approval' || $data->behavior == 'pool') {
drupal_add_css(drupal_get_path('module', 'advpoll') . '/css/advpoll.css', array(
'group' => CSS_DEFAULT,
'every_page' => TRUE,
));
unset($node->content['advpoll_choice']);
if (advpoll_user_eligibility($node)) {
$voteform = drupal_get_form('advpoll_choice_form', $node);
$node->content['advpoll_choice'] = array(
0 => $voteform,
'#weight' => 1,
);
}
else {
$votes = array();
if ($data->mode == 'normal') {
$votes = advpoll_get_user_votes($node->nid);
}
if ($data->state == 'close' && $data->show_results != 'afterclose' || ($data->start_date > time() || $data->end_date < time())) {
$results = theme('advpoll_closed', array(
'data' => $data,
));
}
else {
if ($data->electoral && $data->show_results != 'aftervote') {
$results = theme('advpoll_ineligible', array(
'data' => $data,
));
}
else {
$results = advpoll_display_results($node->nid, $data);
}
}
$node->content['advpoll_choice'] = array(
'#markup' => $results,
'#weight' => 1,
);
}
}
}
}
function advpoll_block_info() {
$blocks['advpoll_recent'] = array(
'info' => t('Advanced Poll: Most Recent'),
);
$blocks = advpoll_get_poll_info_blocks($blocks);
return $blocks;
}
function advpoll_block_view($delta = '') {
$block = array();
switch ($delta) {
case 'advpoll_recent':
$block['subject'] = t('Most Recent Poll');
$block['content'] = array(
'#markup' => advpoll_get_recent(),
);
break;
default:
$block = advpoll_generate_block_view($block, $delta);
break;
}
return $block;
}
function advpoll_theme($existing, $type, $theme, $path) {
return array(
'advpoll_bar' => array(
'variables' => array(
'percentage' => 0,
'votes' => 0,
'voted' => 0,
),
'path' => drupal_get_path('module', 'advpoll') . '/templates',
'template' => 'advpoll-bar',
),
'advpoll_closed' => array(
'variables' => array(
'data' => null,
),
'path' => drupal_get_path('module', 'advpoll') . '/templates',
'template' => 'advpoll-closed',
),
'advpoll_noresults' => array(
'variables' => array(
'available_date' => null,
'votes' => null,
'nid' => null,
'cancel_form' => null,
),
'path' => drupal_get_path('module', 'advpoll') . '/templates',
'template' => 'advpoll-noresults',
),
'advpoll_results' => array(
'variables' => array(
'bars' => null,
'total' => 0,
'voted' => null,
'nid' => null,
'cancel_form' => null,
),
'path' => drupal_get_path('module', 'advpoll') . '/templates',
'template' => 'advpoll-results',
),
'advpoll_ineligible' => array(
'variables' => array(
'data' => null,
),
'path' => drupal_get_path('module', 'advpoll') . '/templates',
'template' => 'advpoll-ineligible',
),
);
}
function advpoll_node_presave($node) {
if ($node->type === 'advpoll') {
if (isset($node->nid)) {
$criteria = array();
$criteria['entity_id'] = $node->nid;
$criteria['entity_type'] = 'advpoll';
$results = votingapi_select_votes($criteria);
if ($results) {
$choices = $node->advpoll_choice[$node->language];
foreach ($choices as $choice) {
$ids[] = $choice['choice_id'];
}
$noMatch = array();
foreach ($results as $vote) {
if (!in_array($vote['tag'], $ids)) {
$noMatch[] = $vote;
}
}
votingapi_delete_votes($noMatch);
}
}
}
}
function advpoll_node_delete($node) {
db_delete('votingapi_vote')
->condition('entity_id', $node->nid)
->execute();
}
function advpoll_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'advpoll_node_form') {
$lang = $form['language']['#value'];
$form['advpoll_max_choices'][$lang][0]['value']['#element_validate'][] = 'advpoll_validate_max_choices';
}
}
function advpoll_validate_max_choices($element, &$form_state, $form) {
$input_choices = array();
$lang = $form_state['build_info']['args'][0]->language;
$choices = $form_state['input']['advpoll_choice'][$lang];
foreach ($choices as $choice) {
if ($choice['choice']) {
$input_choices[] = $choice['choice'];
}
}
$max = (int) $element['#value'];
if ($max > count($input_choices)) {
form_error($element, t('The max number of choices is @max.', array(
'@max' => $max,
)));
}
if (count($input_choices) < 2) {
form_set_error('advpoll_choice', t('Please enter at least two choices.'));
}
}
function advpoll_display_results($nid, $data) {
$output = '';
$form = null;
if (user_access('cancel own vote')) {
$form = drupal_render(drupal_get_form('advpoll_cancel_vote_form', $nid));
}
$votes = array();
if ($data->mode == 'normal') {
$votes = advpoll_get_user_votes($nid);
}
if ($data->show_results == 'never' || $data->show_results == 'afterclose' && $data->end_date > time()) {
$output .= theme('advpoll_noresults', array(
'data' => $data,
'votes' => $votes,
'nid' => $nid,
'cancel_form' => $form,
));
}
else {
$results = advpoll_get_votes($nid, $data->behavior);
$bars = '';
$final = advpoll_update_choices($data->choices, $results['choices']);
foreach ($final as $item) {
$voted = false;
if (in_array($item['tag'], $votes)) {
$voted = true;
}
$bars .= theme('advpoll_bar', array(
'title' => $item['title'],
'percentage' => $item['percentage'],
'votes' => $item['votes'],
'voted' => $voted,
));
}
$output .= theme('advpoll_results', array(
'bars' => $bars,
'total' => $results['total'],
'voted' => $votes,
'nid' => $nid,
'cancel_form' => $form,
));
}
return $output;
}
function advpoll_update_choices($choices, $results) {
$choiceSet = array();
foreach ($choices as $choice) {
$choiceSet[$choice['choice_id']] = $choice['choice'];
}
$final = array();
foreach ($results as $result) {
$final[] = array(
'title' => $choiceSet[$result['index']],
'percentage' => $result['percentage'],
'votes' => $result['votes'],
'tag' => $result['index'],
);
unset($choiceSet[$result['index']]);
}
if (count($choiceSet) > 0) {
foreach ($choiceSet as $key => $choice) {
$final[] = array(
'title' => $choice,
'percentage' => 0,
'votes' => 0,
'tag' => $key,
);
}
}
return $final;
}
function advpoll_choice_form($form, &$form_state, $values) {
$data = advpoll_get_data($values);
$count = count($data->choices);
$options = array();
$form['#id'] = 'advpoll-form-' . $values->nid;
for ($i = 0; $i < $count; $i++) {
if (!$data->choices[$i]['write_in']) {
$options[] = strip_tags($data->choices[$i]['choice']);
}
}
$options = drupal_map_assoc($options);
$input_type = 'radios';
if ($data->max_choices > 1) {
$input_type = 'checkboxes';
}
if ($data->write_in && $data->mode != 'unlimited') {
$options['write-in'] = t('(Write-in)');
$form['choice_' + $count] = array(
'#type' => $input_type,
'#title' => '',
'#options' => $options,
'#ajax' => array(
'callback' => 'advpoll_writein_callback',
'wrapper' => 'advpoll-form-' . $values->nid,
'effect' => 'fade',
),
);
if (isset($form_state['values'])) {
foreach ($form_state['values'] as $key => $item) {
if (is_numeric($key)) {
break;
}
}
$selected = false;
if ($input_type == 'radios') {
if ($item === 'write-in') {
$selected = true;
}
}
else {
if ($item['write-in']) {
$selected = true;
}
}
if ($selected) {
$form['write_in'] = array(
'#type' => 'textfield',
'#element_validate' => array(
'advpoll_writein_validate',
),
'#prefix' => '<div class="advpoll-write-in">',
'#suffix' => '</div>',
'#size' => '30',
);
}
}
}
else {
$form['choice_' + $count] = array(
'#type' => $input_type,
'#title' => '',
'#options' => drupal_map_assoc($options),
);
}
$form['submit'] = array(
'#type' => 'submit',
'#ajax' => array(
'callback' => 'advpoll_form_submit',
'wrapper' => 'advpoll-form-' . $values->nid,
'name' => 'submit1',
),
'#value' => t('Vote'),
);
return $form;
}
function advpoll_writein_validate($element, &$form_state, $form) {
if (empty($element['#value'])) {
form_error($element, t('Please type in your write-in choice or select a different option.'));
}
}
function advpoll_writein_callback($form, $form_state) {
return $form;
}
function advpoll_form_submit($form, &$form_state) {
$data = advpoll_get_form_data($form_state);
$count = count($data->choices);
$votes = $form[$count]['#value'];
$nid = $form_state['build_info']['args'][0]->nid;
$writein = '';
$message = advpoll_form_submit_check($data, $nid);
if ($message) {
$form['message'] = array(
'#type' => 'markup',
'#prefix' => '<div id="message">',
'#suffix' => '</div>',
'#markup' => $message,
);
return $form;
}
if ($data->write_in) {
if (isset($form_state['values']['write_in'])) {
$writein = trim($form_state['values']['write_in']);
$writein = filter_xss($writein);
$writein = check_plain($writein);
if ($writein) {
$data->choices[] = advpoll_process_writein($nid, $writein, $data);
}
else {
$form['message'] = array(
'#type' => 'markup',
'#prefix' => '<div id="message">',
'#suffix' => '</div>',
'#markup' => t('Please type in a valid write-in choice or select a different option.'),
);
return $form;
}
}
}
if ($data->max_choices > 1) {
if ($writein) {
unset($votes['write-in']);
$votes[$writein] = $writein;
}
$selected = advpoll_checkbox_selected($data->choices, $votes);
}
else {
if ($writein) {
$votes = $writein;
}
$selected = advpoll_radio_selected($data->choices, $votes);
}
if (count($selected) > 0 && count($selected) <= $data->max_choices) {
foreach ($selected as $item) {
$vote = array();
$vote['type'] = 'advpoll';
$vote['tag'] = $item;
$vote['nid'] = $nid;
$vote['value'] = 1;
$vote['mode'] = $data->mode;
$vote['duration'] = $data->cookie_duration;
advpoll_add_votes($vote);
}
$element['#markup'] = advpoll_display_results($nid, $data);
return $element;
}
else {
$form['message'] = array(
'#type' => 'markup',
'#prefix' => '<div id="message">',
'#suffix' => '</div>',
'#markup' => t('Select up to @quantity @votes.', array(
'@quantity' => $data->max_choices,
'@votes' => format_plural($data->max_choices, 'vote', 'votes'),
)),
);
return $form;
}
}
function advpoll_form_submit_check($data, $nid) {
if ($data->mode === 'cookie' && isset($_COOKIE['advpoll' . $nid])) {
return t('You have already voted on this poll.');
}
if ($data->mode === 'normal') {
global $user;
$criteria = array();
$criteria['entity_id'] = $nid;
$criteria['entity_type'] = 'advpoll';
$criteria['uid'] = $user->uid;
$results = votingapi_select_votes($criteria);
if ($results) {
return t('You have already voted on this poll.');
}
}
return;
}
function advpoll_cancel_vote_form($form, &$form_state, $nid) {
$form['#nid'] = $nid;
$form['submit'] = array(
'#type' => 'submit',
'#ajax' => array(
'callback' => 'advpoll_cancel_vote_submit',
'wrapper' => 'advpoll-' . $nid,
'name' => 'submit1',
),
'#value' => t('Cancel your vote'),
);
return $form;
}
function advpoll_cancel_vote_submit($form, &$form_state) {
global $user;
if ($user) {
$nid = $form['#nid'];
$criteria = array();
$criteria['entity_id'] = $nid;
$criteria['entity_type'] = 'advpoll';
$criteria['uid'] = $user->uid;
votingapi_delete_votes(votingapi_select_votes($criteria));
$node = node_load($nid);
if (advpoll_user_eligibility($node)) {
return drupal_get_form('advpoll_choice_form', $node);
}
}
}
function advpoll_process_writein($nid, $writein, $data) {
$node = node_load($nid);
$id = dechex(time() * rand(5, 50));
$writein_choice = array();
if ($node) {
$nodeChoices = $node->advpoll_choice[$node->language];
$writein_choice = array(
'choice' => $writein,
'write_in' => 1,
'choice_id' => $id,
);
$nodeChoices[] = $writein_choice;
$node->advpoll_choice[$node->language] = $nodeChoices;
node_save($node);
}
return $writein_choice;
}
function advpoll_get_recent() {
$node = null;
$result = db_query("SELECT n.nid FROM {node} n\n LEFT JOIN {field_data_advpoll_dates} d \n ON d.entity_id = n.nid \n LEFT JOIN {field_data_advpoll_closed} c\n ON c.entity_id = n.nid\n LEFT JOIN {field_data_advpoll_options} o\n ON o.entity_id = n.nid\n WHERE \n n.type LIKE '%advpoll%' AND\n o.advpoll_options_value <> 'electoral' AND\n n.status = 1 AND\n c.advpoll_closed_value = 'open' AND\n d.advpoll_dates_value < NOW() AND \n d.advpoll_dates_value2 > NOW() \n GROUP BY n.nid ORDER BY n.created DESC \n LIMIT 1");
if ($result) {
foreach ($result as $record) {
$node = node_load($record->nid);
break;
}
return drupal_render(node_view($node));
}
}
function advpoll_get_poll_info_blocks($blocks) {
$result = db_query("SELECT n.title, n.nid FROM node n\n LEFT JOIN field_data_advpoll_dates d \n ON d.entity_id = n.nid \n LEFT JOIN field_data_advpoll_closed c\n ON c.entity_id = n.nid\n LEFT JOIN field_data_advpoll_options o\n ON o.entity_id = n.nid\n WHERE \n n.type LIKE '%advpoll%' AND\n o.advpoll_options_value <> 'electoral' AND\n o.advpoll_options_value = 'block' AND\n n.status = 1 AND\n c.advpoll_closed_value = 'open' AND\n d.advpoll_dates_value < NOW() AND d.advpoll_dates_value2 > NOW() \n GROUP BY n.nid \n ORDER BY n.created DESC");
if ($result) {
foreach ($result as $record) {
$blocks['advpoll_block_' . $record->nid] = array(
'info' => t('Advanced Poll: @title', array(
'@title' => $record->title,
)),
);
}
}
return $blocks;
}
function advpoll_generate_block_view($block, $delta) {
$parts = explode('_', $delta);
$nid = $parts[count($parts) - 1];
$isBlock = false;
$node = node_load($nid);
$options = $node->advpoll_options[$node->language];
foreach ($options as $option) {
if ($option['value'] == 'block') {
$isBlock = true;
}
}
if ($isBlock) {
$block['subject'] = t('Poll');
$block['content'] = array(
'#markup' => drupal_render(node_view($node)),
);
}
return $block;
}
function _advpoll_results_access($node) {
if ($node->type == 'advpoll') {
$data = advpoll_get_data($node);
$votes = advpoll_get_votes($node->nid);
return $data->show_results && $votes['total'] > 0 && (user_access("show vote results") || user_access('administer polls'));
}
}
function _advpoll_electoral_list_access($node) {
if ($node->type == 'advpoll') {
$data = advpoll_get_data($node);
return (user_access('access electoral list') || user_access('administer polls')) && $data->electoral;
}
}
function _advpoll_votes_access($node) {
if ($node->type == 'advpoll') {
$data = advpoll_get_data($node);
$votes = advpoll_get_votes($node->nid);
return $votes['total'] > 0 && (user_access('inspect all votes') && $data->show_votes || user_access('administer polls'));
}
}
function _advpoll_clear_votes_access($node) {
if ($node->type == 'advpoll') {
$votes = advpoll_get_votes($node->nid);
return $votes['total'] > 0 && user_access('administer polls');
}
}
function _advpoll_writeins_access($node) {
if ($node->type == 'advpoll') {
$data = advpoll_get_data($node);
return user_access('administer polls') && $data->write_in;
}
}