Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Branch: 7.x-1.x
Fetching contributors…

Cannot retrieve contributors at this time

441 lines (401 sloc) 14.135 kB
<?php
/**
* @file smackdown.module
*
* Pit two nodes against one another and vote for the winner.
* Choose what content type to reference in the smackdown content type's
* nodereference settings. (admin/content/node-type/smackdown/fields)
*/
/**
* Implementation of hook_init().
*/
function smackdown_init() {
if (isset($_GET['smackdown_vote']) && module_exists('context')) {
context_set_by_condition('smackdown', TRUE);
}
}
/**
* Implementation of hook_context_conditions().
*/
function smackdown_context_conditions() {
return array(
'smackdown' => array(
'#title' => t('Just Voted on a Smackdown'),
'#description' => t('Set this context when a user has just voted on a smackdown on the previous page'),
'#options' => array(
0 => t('Off'),
1 => t('On'),
),
'#type' => 'radios',
),
);
}
/**
* Implementation of hook_permission().
*/
function smackdown_permission() {
return array(
'vote on smackdowns' => array(
'title' => t('Vote on Smackdowns'),
),
);
}
/**
* Implementation of hook_menu().
*/
function smackdown_menu() {
$items = array();
$items['smackdown/vote'] = array(
'title' => 'Vote',
'page callback' => 'smackdown_vote',
'page arguments' => array(2, 3),
'access callback' => 'smackdown_access',
'access arguments' => array(4, 2),
'type' => MENU_CALLBACK,
);
$items['node/%smackdown/voting-results'] = array(
'title' => 'Results',
'page callback' => 'smackdown_results',
'page arguments' => array('page', 1),
'access callback' => 'node_access',
'access arguments' => array('view', 1),
'type' => MENU_LOCAL_TASK,
);
return $items;
}
/**
* Menu access callback.
*/
function smackdown_access($token, $sid) {
if (user_access('vote on smackdowns')) {
return drupal_valid_token($token, $sid, TRUE);
}
return FALSE;
}
/**
* Menu load function to verify a node is a smackdown.
*/
function smackdown_load($nid){
$node = node_load($nid);
if (in_array($node->type, variable_get('smackdown_types', array()))) {
return $node;
}
return FALSE;
}
/**
* Voting mechanism.
*
* @param $cid
* Content id that was voted for.
*
* @param $sid
* Smackdown node id.
*/
function smackdown_vote($sid = NULL, $cid = NULL) {
if (!$cid) {
$cid = $_GET['cid'];
}
if (!$sid) {
$sid = $_GET['sid'];
}
$return = is_numeric($cid);
if (is_numeric($cid) && is_numeric($sid)) {
// contruct our $vote array
$vote = array(
'entity_type' => 'node',
'entity_id' => $sid,
'value_type' => 'option',
'value' => $cid,
'tag' => 'smackdown',
);
drupal_alter('smackdown_vote', $vote);
$location = url('node/' . $sid . '/voting-results', array('absolute' => TRUE));
// Save voting results.
$results = votingapi_set_votes($vote);
drupal_json_output(array('results' => $results, 'location' => $location));
}
else {
drupal_json_output(array('return' => $return));
}
}
/**
* Implements hook_node_view().
*/
function smackdown_node_view($node, $build_mode = 'full') {
// make sure to only compare to the smackdown you are looking at in the URL
if (in_array($node->type, variable_get('smackdown_types', array()))) {
static $added = FALSE;
drupal_add_js(drupal_get_path('module', 'smackdown') .'/smackdown.js');
if (!$added) {
if (user_access('vote on smackdowns')) {
drupal_add_js(array('smackdownPerm' => 1), 'setting');
}
$field_names = smackdown_get_nodereference_fields($node->type);
$field_value_one = field_fetch_field_values('node', $node, $field_names[0]);
$field_value_two = field_fetch_field_values('node', $node, $field_names[1]);
// setings for js
$settings = array(
'smackdown' => array(
'sid' => $node->nid,
'field1' => array(
'name' => $field_names[0],
'nid' => $field_value_one->nid,
),
'field2' => array(
'name' => $field_names[1],
'nid' => $field_value_two->nid,
),
'location' => 'node/'. $node->nid .'/voting-results',
'token' => drupal_get_token($node->nid),
),
);
drupal_add_js($settings,'setting');
// a log of previous votes are stored in $_GET
if (isset($_GET['smackdown_vote'])) {
$prev_results = smackdown_results('short', node_load($_GET['smackdown_vote']));
// append the results of the previous smackdown to $node->content
$node->content['prev_results'] = array('#value' => $prev_results, '#weight' => $node->content['body']['#weight']--);
}
$added = TRUE;
}
}
}
/**
*Implements hook_form_FORM_ID_alter().
*/
function smackdown_form_node_type_form_alter(&$form, &$form_state,$form_id = 'node_type') {
// Add in a checkbox to designate a content type as a smackdown node.
// @todo: link for doc about the makeup of a smackdown node in #description
$form['smackdown_type_'. $form['#node_type']->type] = array(
'#type' => 'checkbox',
'#title' => t('Smackdown node'),
'#description' => t('Use this node as a smackdown node. Please see <a href="!requirements_url">requirements</a>.', array('!requirements_url' => url(drupal_get_path('module', 'smackdown') .'/INSTALL.txt'))),
'#default_value' => in_array($form['#node_type']->type, variable_get('smackdown_types', array())),
'#weight' => 10,
);
$form['#submit'][] = 'smackdown_form_node_type_form_submit';
}
/**
* Submit handler for our implementation of hook_form_FORM_ID_alter().
*/
function smackdown_form_node_type_form_submit($form, $form_state) {
$current_types = variable_get('smackdown_types', array());
if (!empty($current_types) && in_array($form['#node_type']->type, $current_types)) {
if ($form_state['values']['smackdown_type_'. $form['#node_type']->type] === 0) {
unset($current_types[$form['#node_type']->type]);
variable_set('smackdown_types', $current_types);
}
}
else {
if ($form_state['values']['smackdown_type_'. $form['#node_type']->type] === 1) {
// format: type => type
$new_types = array_merge($current_types, array($form['#node_type']->type => $form['#node_type']->type));
variable_set('smackdown_types', $new_types);
}
}
}
/**
* Function to get the results of the previously voted upon node.
*
* @param $node
* The node object of the smackdown we want results for.
*/
function smackdown_results($view, $node) {
$results = array();
foreach (smackdown_get_nodereference_fields($node->type) as $field_name) {
$ref = field_fetch_field_values('node',$node, $field_name);
$criteria = array(
'entity_type' => 'node',
'entity_id' => $node->nid,
'value_type' => 'option',
'tag' => 'smackdown',
'function' => 'option-'. $ref->nid,
);
$results[$ref->nid] = votingapi_select_results($criteria);
$results[$ref->nid]['title'] = node_load($ref->nid)->title;
}
$variables = array('node' => $node, 'results' => $results);
if ($view == 'short') {
return theme('smackdown_results_short', $variables);
}
else {
return theme('smackdown_results', $variables);
}
}
/**
* Helper function to get the nodereference fields of a content type.
* @param string $content_type
* @return array of field names that are nodereference fields
*/
function smackdown_get_nodereference_fields($content_type) {
$fields = array();
foreach (field_info_instances('node', $content_type) as $field_name => $field) {
$field_info = field_info_field($field_name);
$type = $field_info['type'];
if($type == 'node_reference'){
$fields[] = $field['field_name'];
}
}
return $fields;
}
/**
* Implementation of hook_theme().
*/
function smackdown_theme() {
return array(
'smackdown_results' => array(
'arguments' => array(
'node' => NULL,
'prev_node' => NULL,
),
),
'smackdown_results_short' => array(
'arguments' => array(
'node' => NULL,
'prev_node' => NULL,
),
),
'smackdown_formatter_smackdown' => array(
'arguments' => array('element' => NULL),
),
);
}
/**
* Theme the results of the votes.
*/
function theme_smackdown_results($variables) {
$node = $variables['node'];
$results = $variables['results'];
$field_names = smackdown_get_nodereference_fields($node->type);
$field_value_one = field_fetch_field_values('node', $node, $field_names[0]);
$field_value_two = field_fetch_field_values('node', $node, $field_names[1]);
$field_values = array($field_value_one, $field_value_two);
$node_ref1 = $field_value_one->nid;
$node_ref2 = $field_value_two->nid;
// Turn the results into a percentage.
// Note that there might be an empty result in case of no votes.
$first_result_val = (empty($results[$node_ref1][0]) ? 0 : $results[$node_ref1][0]['value']);
$second_result_val = (empty($results[$node_ref2][0]) ? 0 : $results[$node_ref2][0]['value']);
$votes = $first_result_val + $second_result_val;
$output = '<div class="poll">';
if (isset($_GET['last'])) {
$type_name = node_get_types('name', $node);
$text = 'There are no more @type_name to vote on. The results from the previous one are below. !link';
$message = t($text, array('@type_name' => $type_name, '!link' => l(t('Click here to create your own @type_name', array('@type_name' => $type_name)), 'node/add/' . $node->type)));
$output .= '<br><div class="messages notice"><div>'. $message . '</div></div>';
}
foreach ($results as $nid => $node) {
$node_val = (empty($node[0]) ? 0 : $node[0]['value']);
$percentage = $node_val ? round(($node_val / $votes) * 100) : 0;
$output .= '
<div class="text">'. l($node['title'], 'node/'. $nid) .'</div>
<div class="bar">
<div style="width: '. $percentage .'%;" class="foreground"></div>
</div>
<div class="percent">
'. $percentage .'% ('. format_plural($votes, '1 vote', '@count votes') .')
</div>';
}
$output .= '</div>';
return $output;
}
function theme_smackdown_results_short($variables) {
$node = $variables['node'];
$results = $variables['results'];
$field_names = smackdown_get_nodereference_fields($node->type);
$field_value_one = field_fetch_field_values('node', $node, $field_names[0]);
$field_value_two = field_fetch_field_values('node', $node, $field_names[1]);
$node_ref1 = $field_value_one->nid;
$node_ref2 = $field_value_two->nid;
// turn the results into a percentage
$votes = 0;
$votes = $results[$node_ref1][0]['value'] + $results[$node_ref2][0]['value'];
$count = 0;
$output .= "<span class='smackdown_results_title'>Previous results: ". l($node->title, 'node/'. $node->nid .'/voting-results') ." </span>";
foreach ($results as $nid => $node_ref) {
$count++;
$percentage = $votes ? round(($node_ref[0]['value'] / $votes) * 100) : 0;
$output .= "<span class='smackdown_result'>". $node_ref['title'] .' '. $percentage ."%</span>";
if ($count == 1) {
$output .= " | ";
}
}
return "<div class='smackdown-results-wrapper'>". $output ."</div>";
}
/**
* Implementation of hook_views_api().
*/
function smackdown_views_api() {
return array(
'api' => 2.0,
'path' => drupal_get_path('module', 'Smackdown'),
);
}
/**
* Implementation of hook_votingapi_results_alter().
*/
function smackdown_votingapi_results_alter(&$cache, $content_type, $content_id) {
// count the number of votes on this smackdown
// no need to check type as no other node.type will have a tag of smackdown
// so if $cache['smackdown'] doesn't exists, it doesn't do anything
// NOTE: http://drupal.org/node/435782
if (isset($cache[$content_type])) {
foreach ($cache[$content_type]['option'] as $option_id => $score) {
$count += $score;
}
$cache[$content_type]['option']['count'] = $count;
}
}
/**
* Implementation of hook_field_formatter_info().
*/
function smackdown_field_formatter_info() {
return array(
'smackdown' => array(
'label' => t('Smackdown reference'),
'field types' => array('node_reference'),
'description' => t('Display the referenced node according to the smackdown settings.'),
),
);
}
/**
* Theme function for 'smackdown' nodereference field formatter.
* Copied from nodereference's theme_nodereference_formatter_full_teaser().
*/
function theme_smackdown_formatter_smackdown($element) {
static $recursion_queue = array();
$output = '';
if (!empty($element['#item']['nid']) && is_numeric($element['#item']['nid'])) {
$node = $element['#node'];
$field = content_fields($element['#field_name'], $element['#type_name']);
// If no 'referencing node' is set, we are starting a new 'reference thread'
if (!isset($node->referencing_node)) {
$recursion_queue = array();
}
$recursion_queue[] = $node->nid;
if (in_array($element['#item']['nid'], $recursion_queue)) {
// Prevent infinite recursion caused by reference cycles:
// if the node has already been rendered earlier in this 'thread',
// we fall back to 'default' (node title) formatter.
return theme('node_reference_default', $element);
}
if ($referenced_node = node_load($element['#item']['nid'])) {
$referenced_node->referencing_node = $node;
$referenced_node->referencing_field = $field;
_nodereference_titles($element['#item']['nid'], $referenced_node->title);
$output = node_view($referenced_node, $element['#formatter'] == 'teaser');
}
}
return $output;
}
/**
* Returns field values as actual entities where possible,
* also allows selection of individual items to be returned
*/
function field_fetch_field_values($entity_type, $entity, $field_name) {
//$field_node1 = $entity->field_nodereference1['und'][0]['nid'];
$value = field_get_items($entity_type, $entity, $field_name);
$node = $value[0]['nid'];
$node_load = node_load($node);
return $node_load;
}
Jump to Line
Something went wrong with that request. Please try again.