Index: i18n_poll/i18n_poll.info =================================================================== --- i18n_poll/i18n_poll.info (revision 0) +++ i18n_poll/i18n_poll.info (revision 3626) @@ -0,0 +1,6 @@ +name = Poll aggregate +description = Aggregates poll results for all translations. +dependencies[] = translation +dependencies[] = poll +package = Multilingual - Internationalization +core = 7.x \ No newline at end of file Index: i18n_poll/i18n_poll.module =================================================================== --- i18n_poll/i18n_poll.module (revision 0) +++ i18n_poll/i18n_poll.module (revision 3626) @@ -0,0 +1,191 @@ +tnid) && ($vote = i18n_poll_get_vote($node->tnid))) { + $form['#i18ntnid'] = $node->tnid; + $form['#nid'] = $vote->nid; + } + } + } +} + +/** + * Implements hook_node_view(). + * + * Replaces poll results with aggregated translations. + * + * We don't add all language results on loading to avoid the data being trashed + * when editing and saving nodes again. + */ +function i18n_poll_node_view($node, $view_mode, $langcode) { + if ($node->type == 'poll' && !empty($node->tnid)) { + // Replace results for node view + if (!empty($node->allowvotes) && empty($node->show_results)) { + $node->content['poll_view_voting'] = drupal_get_form('poll_view_voting', $node); + } + else { + $node->content['poll_view_results'] = array('#markup' => i18n_poll_view_results($node, $view_mode, FALSE)); + } + } +} + +/** + * Implements hook_node_load(). + * + * We don't add all language results on loading to avoid the data being trashed + * when editing and saving nodes again. + */ +function i18n_poll_node_load($nodes, $types) { + // Check again whether or not this user is allowed to vote. + // User may have voted for any of the translations + foreach ($nodes as $node) { + if ($node->type == 'poll' && !empty($node->tnid)) { + if ($node->allowvotes) { + $result = i18n_poll_get_vote($node->tnid); + if (isset($result->chid)) { + $node->vote = $result->chid; + $node->allowvotes = FALSE; + } + } + } + } +} + +/** + * Implements hook_block_info(). + * + * Generates a block containing the latest poll with aggregated results. + */ +function i18n_poll_block_info() { + $blocks['most_recent'] = array( + 'info' => t('Most recent poll (Aggregated translations)'), + 'cache' => DRUPAL_NO_CACHE, + ); + return $blocks; +} + +/** + * Implements hook_block_view(). + */ +function i18n_poll_block_view($delta = '') { + if (user_access('access content')) { + // Retrieve the latest poll. + $select = db_select('node', 'n'); + $select->join('poll', 'p', 'p.nid = n.nid'); + $select->fields('n', array('nid')) + ->condition('n.status', 1) + ->condition('p.active', 1) + ->orderBy('n.created', 'DESC') + ->range(0, 1) + ->addTag('node_access'); + + $record = $select->execute()->fetchObject(); + if ($record) { + $poll = node_load($record->nid); + if ($poll->nid) { + $poll = i18n_poll_block_latest_poll_view($poll, 'full', TRUE); + $block['subject'] = t('Poll'); + $block['content'] = $poll->content; + return $block; + } + } + } +} + +/** + * Implements hook_view(). + * + * @param $block + * An extra parameter that adapts the hook to display a block-ready + * rendering of the poll. + */ +function i18n_poll_block_latest_poll_view($node, $view_mode, $block = FALSE) { + global $user; + $output = ''; + + // This is necessary for shared objects because PHP doesn't copy objects, but + // passes them by reference. So when the objects are cached it can result in + // the wrong output being displayed on subsequent calls. The cloning and + // unsetting of $node->content prevents the block output from being the same + // as the node output. + $node = clone $node; + unset($node->content); + + // No 'read more' link. + $node->readmore = FALSE; + $node->teaser = ''; + + $links = array(); + $links[] = array('title' => t('Older polls'), 'href' => 'poll', 'attributes' => array('title' => t('View the list of polls on this site.'))); + if ($node->allowvotes) { + $links[] = array('title' => t('Results'), 'href' => 'node/' . $node->nid . '/results', 'attributes' => array('title' => t('View the current poll results.'))); + } + + $node->links = $links; + + if (!empty($node->allowvotes)) { + $node->content['poll_view_voting'] = drupal_get_form('poll_view_voting', $node, TRUE); + $node->content['links'] = array( + '#theme' => 'links', + '#links' => $node->links, + '#weight' => 5, + ); + } + else { + $node->content['poll_view_results'] = array('#markup' => i18n_poll_view_results($node, TRUE, TRUE)); + } + + return $node; +} + +/** + * Generates a graphical representation of the results of a poll. + */ +function i18n_poll_view_results(&$node, $view_mode, $block) { + // Load the appropriate choices into the $poll object. + $result = db_query("SELECT c.chid, SUM(c.chvotes) AS votes FROM {poll_choice} c INNER JOIN {node} n ON c.nid = n.nid WHERE n.tnid = :tnid AND n.nid != :nid GROUP BY c.chid", array('tnid' => $node->tnid, 'nid' => $node->nid)); + $choices = array_values($node->choice); + foreach ($result as $i => $choice) { + // If this option not set for the source node, do not show. + if (!empty($choices[$i])) { + $choices[$i]['chvotes'] += $choice->votes; + } + } + $node->choice = $choices; + return poll_view_results($node, $view_mode, $block); +} + +/** + * Get user vote for this node or its translations. + * + * Returns object with nid, chid. Has static caching as this will typically be called twice. + */ +function i18n_poll_get_vote($tnid) { + global $user; + static $vote = array(); + if (!array_key_exists($tnid, $vote)) { + if ($user->uid) { + $vote[$tnid] = db_query('SELECT v.nid, v.chid FROM {poll_vote} v INNER JOIN {node} n ON n.nid = v.nid WHERE n.tnid = :tnid AND v.uid = :uid', array('tnid' => $tnid, 'uid' => $user->uid))->fetchObject(); + } + else { + $vote[$tnid] = db_query("SELECT v.nid, v.chid FROM {poll_vote} v INNER JOIN {node} n ON n.nid = v.nid WHERE n.tnid = :tnid AND v.hostname = :hostname", array('tnid' => $tnid, 'hostname' => ip_address()))->fetchObject(); + } + } + return $vote[$tnid]; +} +