mediumvote * 4) Node-specific voting options * * Development funded by addictedtotravel.com */ // ability to show voting on nodes & comments define ('MEDIUMVOTE_DENY', 0); define ('MEDIUMVOTE_ALLOW', 1); define ('MEDIUMVOTE_NODE', 2); // ability to vote on nodes and comments define ('VOTINGAPI_VALUE_NODE_CONTENT_TYPE', 'node'); define ('VOTINGAPI_VALUE_COMMENT_CONTENT_TYPE', 'comment'); // define the tags used for multi-criteria voting define ('VOTINGAPI_COMMENT_TAG_TAG1', '1'); define ('VOTINGAPI_COMMENT_TAG_TAG2', '2'); // number of allowed voting criteria define ('NUM_VOTING_CRITERIA', 5); function mediumvote_menu($may_cache) { drupal_set_html_head(theme('stylesheet_import', theme('mediumvote_css_path'))); $items = array(); if ($may_cache) { $items[] = array( 'path' => 'vote', 'title' => t('vote on content'), 'callback' => 'mediumvote_vote', 'access' => TRUE, 'type' => MENU_CALLBACK ); $items[] = array( 'path' => 'ajax_mediumvote', 'title' => t('vote on content (ajax)'), 'callback' => 'ajax_mediumvote_handler', 'access' => TRUE, 'type' => MENU_CALLBACK ); $items[] = array( 'path' => 'admin/settings/mediumvote', 'title' => t('mediumvote'), 'callback' => 'mediumvote_configure' ); } return $items; } function mediumvote_help($section) { switch ($section) { case 'admin/modules#description': return t('Adds a vote widget to every node and comment.'); break; case 'admin/settings/mediumvote': return t('

Configure mediumvote:

'); break; } } /** * Return an array of voting modes. * Three standard types defined by votingapi: * VOTINGAPI_VALUE_TYPE_PERCENT -- 'Value' is a number from 0-100. The API will cache an average for all votes. * VOTINGAPI_VALUE_TYPE_TOKEN -- 'Value' is a positive or negative int. The API will cache the sum of all votes. * VOTINGAPI_VALUE_TYPE_KEY -- 'Value' is a foreign key. The API will cache a vote-count for each discrete value. */ function _mediumvote_get_modes_array() { return array( VOTINGAPI_VALUE_TYPE_PERCENT => t('Percentage (0-100)'), VOTINGAPI_VALUE_TYPE_TOKEN => t('Score (positive or negative)') // Not yet implemented: //VOTINGAPI_VALUE_TYPE_KEY => t('Foreign Key') ); } /** * Return voting mode for a node or comment * * @param $id * Element (node, comment) id. * @param $type * node or comment * @return * Voting mode for element */ function _mediumvote_get_mode($id, $type) { $allow_override = variable_get('allow_override_'.$type, FALSE); if ($allow_override) { if ($type == VOTINGAPI_VALUE_NODE_CONTENT_TYPE) { $node = node_load(array('nid' => $id)); $mode = variable_get($type.'_mode_'.$node->type, VOTINGAPI_VALUE_TYPE_PERCENT); } elseif ($type == VOTINGAPI_VALUE_COMMENT_CONTENT_TYPE) { $comment_result = _comment_load($id); $comment_nid = $comment_result->nid; $node = node_load(array('nid' => $comment_nid)); $mode = variable_get($type.'_mode_'.$node->type, VOTINGAPI_VALUE_TYPE_PERCENT); } else { $mode = variable_get($type.'_mode_all', VOTINGAPI_VALUE_TYPE_PERCENT); } } else { $mode = variable_get($type.'_mode_all', VOTINGAPI_VALUE_TYPE_PERCENT); } return $mode; } /** * Return voting tag for a node or comment * * @param $index * Tag number * @param $id * Element (node, comment) id. * @param $type * node or comment * @param $node * Either node, or node comment belongs to * @return * Voting tag for element at index */ function _mediumvote_get_tag($index, $type, &$node) { $allow_override = variable_get('allow_override_'.$type, FALSE); if ($allow_override) { if ($type == VOTINGAPI_VALUE_NODE_CONTENT_TYPE) { $tag = variable_get($type.'_tag_'.$node->type.'_'.$index, ''); } elseif ($type == VOTINGAPI_VALUE_COMMENT_CONTENT_TYPE) { $tag = variable_get($type.'_tag_'.$node->type.'_'.$index, ''); } else { $tag = variable_get($type.'_tag_'.$index, ''); } } else { $tag = variable_get($type.'_tag_'.$index, ''); } return $tag; } /** * Return an array of allow modes. */ function _mediumvote_get_allow($type, $node_type) { $allow = array( MEDIUMVOTE_ALLOW => t('Allow %type voting for %nodetype', array('%type' => ($type?$type.' ':''), '%nodetype' => $node_type)), MEDIUMVOTE_DENY => t('Deny %type voting for %nodetype', array('%type' => ($type?$type.' ':''), '%nodetype' => $node_type)), ); return $allow; } function mediumvote_configure_settings() { } /** * mediumvote settings page. */ function mediumvote_configure() { // default settings $form['default_settings'] = array( '#type' => 'fieldset', '#title' => t('Default settings'), ); // nodes defaults $form['default_settings']['node'] = array( '#type' => 'fieldset', '#title' => t('Nodes'), ); $form['default_settings']['node']['allow_node_all'] = array( '#type' => 'radios', '#title' => t('Allow/Deny'), '#default_value' => variable_get('allow_node_all', MEDIUMVOTE_ALLOW), '#options' => _mediumvote_get_allow('', t('all nodes')) ); $form['default_settings']['node']['node_mode_all'] = array( '#type' => 'radios', '#title' => t('Default Voting Mode'), '#default_value' => variable_get('node_mode_all', VOTINGAPI_VALUE_TYPE_PERCENT), '#options' => _mediumvote_get_modes_array(), '#description' => t('The default voting mode: Percentages or Raw Scores.'), ); $form['default_settings']['node']['criteria'] = array( '#type' => 'fieldset', '#title' => t('Voting Criteria'), ); for ($tag_count = 1; $tag_count <= NUM_VOTING_CRITERIA; $tag_count++) { $form['default_settings']['node']['criteria']['node_tag_'.$tag_count] = array( '#type' => 'textfield', '#title' => t('Tag').' '.$tag_count, '#default_value' => variable_get('node_tag_'.$tag_count, ''), '#size' => 25, '#maxlength' => 25 ); } $form['default_settings']['node']['allow_override_node'] = array( '#type' => 'checkbox', '#title' => t('Allow node-specific override'), '#return_value' => 1, '#default_value' => variable_get('allow_override_node', FALSE), '#description' => t('If checked, node-specific settings below will override default values.') ); // comments defaults $form['default_settings']['comment'] = array( '#type' => 'fieldset', '#title' => t('Comments'), ); $form['default_settings']['comment']['allow_comment_all'] = array( '#type' => 'radios', '#title' => t('Allow/Deny'), '#default_value' => variable_get('allow_comment_all', MEDIUMVOTE_ALLOW), '#options' => _mediumvote_get_allow('', t('all comments')) ); $form['default_settings']['comment']['comment_mode_all'] = array( '#type' => 'radios', '#title' => t('Default Voting Mode'), '#default_value' => variable_get('comment_mode_all', VOTINGAPI_VALUE_TYPE_PERCENT), '#options' => _mediumvote_get_modes_array(), '#description' => t('The default voting mode: Percentages or Raw Scores.'), ); for ($tag_count = 1; $tag_count <= NUM_VOTING_CRITERIA; $tag_count++) { $form['default_settings']['comment']['criteria']['comment_tag_'.$tag_count] = array( '#type' => 'textfield', '#title' => t('Tag').' '.$tag_count, '#default_value' => variable_get('comment_tag_'.$tag_count, ''), '#size' => 25, '#maxlength' => 25 ); } $form['default_settings']['comment']['allow_override_comment'] = array( '#type' => 'checkbox', '#title' => t('Allow node-specific override for comments'), '#return_value' => 1, '#default_value' => variable_get('allow_override_comment', FALSE), '#description' => t('If checked, node-specific settings below will override default values.') ); // if override of node or comments is allowed // show node-specific settings if (variable_get('allow_override_node', FALSE) OR variable_get('allow_override_comment', FALSE)) { // node-specific settings $form['allow_votes'] = array( '#type' => 'fieldset', '#title' => t('Node-specific settings'), ); foreach(node_get_types() as $type => $name) { $form['allow_votes'][$type] = array( '#type' => 'fieldset', '#title' => $name, '#collapsible' => TRUE, '#collapsed' => TRUE, ); if (variable_get('allow_override_node', FALSE)) { // node $form['allow_votes'][$type]['node'] = array( '#type' => 'fieldset', '#title' => t('Node'), ); $form['allow_votes'][$type]['node']['allow_node_'.$type] = array( '#type' => 'radios', '#title' => t('Allow/Deny'), '#default_value' => variable_get('allow_node_'.$type, MEDIUMVOTE_ALLOW), '#options' => _mediumvote_get_allow(t('node'), $name) ); $form['allow_votes'][$type]['node']['node_mode_'.$type] = array( '#type' => 'radios', '#title' => t('Voting Mode'), '#default_value' => variable_get('node_mode_'.$type, VOTINGAPI_VALUE_TYPE_PERCENT), '#options' => _mediumvote_get_modes_array(), '#description' => t('The default voting mode: Percentages or Raw Scores.'), ); for ($tag_count = 1; $tag_count <= NUM_VOTING_CRITERIA; $tag_count++) { $form['allow_votes'][$type]['node']['criteria']['node_tag_'.$type.'_'.$tag_count] = array( '#type' => 'textfield', '#title' => t('Tag').' '.$tag_count, '#default_value' => variable_get('node_tag_'.$type.'_'.$tag_count, ''), '#size' => 25, '#maxlength' => 25 ); } } else { // clear variables variable_set('allow_node_'.$type, MEDIUMVOTE_DENY); variable_set('node_mode_'.$type, VOTINGAPI_VALUE_TYPE_PERCENT); for ($tag_count = 1; $tag_count <= NUM_VOTING_CRITERIA; $tag_count++) { variable_set('node_tag_'.$type.'_'.$tag_count, ''); } } // end if node override if (variable_get('allow_override_comment', FALSE)) { // comments $form['allow_votes'][$type]['comment'] = array( '#type' => 'fieldset', '#title' => t('Comments'), ); $form['allow_votes'][$type]['comment']['allow_comment_'.$type] = array( '#type' => 'radios', '#title' => t('Allow/Deny'), '#default_value' => variable_get('allow_comment_'.$type, MEDIUMVOTE_ALLOW), '#options' => _mediumvote_get_allow(t('comment'), $name) ); $form['allow_votes'][$type]['comment']['comment_mode_'.$type] = array( '#type' => 'radios', '#title' => t('Voting Mode'), '#default_value' => variable_get('comment_mode_'.$type, VOTINGAPI_VALUE_TYPE_PERCENT), '#options' => _mediumvote_get_modes_array(), '#description' => t('The default voting mode: Percentages or Raw Scores.'), ); for ($tag_count = 1; $tag_count <= NUM_VOTING_CRITERIA; $tag_count++) { $form['allow_votes'][$type]['comment']['criteria']['comment_tag_'.$type.'_'.$tag_count] = array( '#type' => 'textfield', '#title' => t('Tag').' '.$tag_count, '#default_value' => variable_get('comment_tag_'.$type.'_'.$tag_count, ''), '#size' => 25, '#maxlength' => 25 ); } } else { // clear variables variable_set('allow_comment_'.$type, MEDIUMVOTE_DENY); variable_set('comment_mode_'.$type, VOTINGAPI_VALUE_TYPE_PERCENT); for ($tag_count = 1; $tag_count <= NUM_VOTING_CRITERIA; $tag_count++) { variable_set('comment_tag_'.$type.'_'.$tag_count, ''); } } // end if comment override } // end foreach node type } else { // clear variables foreach(node_get_types() as $type => $name) { variable_set('allow_node_'.$type, MEDIUMVOTE_DENY); variable_set('node_mode_'.$type, VOTINGAPI_VALUE_TYPE_PERCENT); variable_set('allow_comment_'.$type, MEDIUMVOTE_DENY); variable_set('comment_mode_'.$type, VOTINGAPI_VALUE_TYPE_PERCENT); for ($tag_count = 1; $tag_count <= NUM_VOTING_CRITERIA; $tag_count++) { variable_set('node_tag_'.$type.'_'.$tag_count, ''); variable_set('comment_tag_'.$type.'_'.$tag_count, ''); } } } // end if override return system_settings_form('mediumvote_configure_settings', $form); } function mediumvote_vote($type, $tag = VOTINGAPI_VALUE_DEFAULT_TAG, $cid, $value) { $mode = _mediumvote_get_mode($cid, $type); if ($mode == VOTINGAPI_VALUE_TYPE_PERCENT) { // sanity-check the incoming values. if (is_numeric($cid) && is_numeric($value)) { if ($value > 100) { $value = 100; } } } $vote->value = $value; $vote->value_type = $mode; $vote->tag = $tag; votingapi_set_vote($type, $cid, $vote); drupal_goto(drupal_get_destination()); } /** * An ajax voting get handler * * Params passed by url: * @param $content_type * A string identifying the type of content whose votes are being retrieved. Node, comment, aggregator item, etc. * @param $tag * Tag defining vote criteria. * @param $id * Element (node, comment) id. * @param $score * Score of the vote cast. * @return * String containing an Updated score (via print) */ function ajax_mediumvote_handler() { // get vote paramaters from get $content_type = arg(1); $tag = arg(2); $id = arg(3); $score = arg(4); $mode = _mediumvote_get_mode($id, $content_type); if ($mode == VOTINGAPI_VALUE_TYPE_PERCENT) { $function = 'average'; } else { $function = 'sum'; } // add the vote $vote->value = $score; $vote->value_type = $mode; $vote->tag = $tag; votingapi_set_vote($content_type, $id, $vote); // get updated results $vote = votingapi_get_voting_result($content_type, $id, $mode, $tag, $function); // send the results back print $tag.' (' . $vote->value . ')'; exit(); } function theme_mediumvote_widget($cid, $type, $tag = VOTINGAPI_VALUE_DEFAULT_TAG) { global $user; $mode = _mediumvote_get_mode($cid, $type); // if user is logged in, get votes already cast $user_vote = ''; if ($user->uid != 0) { $user_vote = votingapi_get_vote($type, $cid, $mode, $tag, $user->uid); } if ($mode == VOTINGAPI_VALUE_TYPE_PERCENT) { // Get the current vote. It should come in as a percentage, $vote = votingapi_get_voting_result($type, $cid, $mode, $tag, 'average'); if ($vote) { $stars = round($vote->value); } else { $stars = 0; } $output = '
'; switch ($type) { case VOTINGAPI_VALUE_NODE_CONTENT_TYPE: $output .= '' . $tag . ' (' . $stars . ')'; break; case VOTINGAPI_VALUE_COMMENT_CONTENT_TYPE: default: $output .= '' . $tag . ' (' . $stars . ')'; break; } for ($i = 20; $i <= 100; $i += 20) { $output .= theme('mediumvote_icon', $type, $cid, $i, $stars >= $i, $tag, $mode, $user_vote); } $output .= ''; $output .= '
'; } else { // Get the current vote. It should come in as a score $vote = votingapi_get_voting_result($type, $cid, $mode, $tag, 'sum'); if ($vote) { $score = $vote->value; } else { $score = 0; } $output = '
'; switch ($type) { case VOTINGAPI_VALUE_NODE_CONTENT_TYPE: $output .= '' . $tag . ' (' . $score . ')'; break; case VOTINGAPI_VALUE_COMMENT_CONTENT_TYPE: default: $output .= '' . $tag . ' (' . $score . ')'; break; } // add positive vote $output .= theme('mediumvote_icon', $type, $cid, 1, FALSE, $tag, $mode, $user_vote); // add negative vote $output .= theme('mediumvote_icon', $type, $cid, -1, FALSE, $tag, $mode, $user_vote); $output .= ''; $output .= '
'; } return $output; } function theme_mediumvote_icon($type, $cid, $value, $filled, $tag = VOTINGAPI_VALUE_DEFAULT_TAG, $mode = VOTINGAPI_VALUE_TYPE_PERCENT, $user_vote = '') { global $user; $url = 'vote/' . $type . '/' . $tag . '/' . $cid . '/' . $value; $ajax_url = 'ajax_mediumvote/' . $type . '/' . $tag . '/' . $cid . '/' . $value; if ($mode == VOTINGAPI_VALUE_TYPE_PERCENT) { if ($filled) { $class = 'vote-on'; } else { $class = 'vote-off'; } // If the user isn't logged in, or has voted already, show the vote but don't let them change it. // We do this by writing out a span with the same classes, rather than an tag. if ($user->uid == 0 OR $user_vote) { return ''; } else { $attributes = array( 'class' => $class, 'title' => 'Rate' ); $link = ''; } } else { // If the user isn't logged in, or has voted already, show the vote but don't let them change it. // We do this by writing out a span with the same classes, rather than an tag. if ($user->uid == 0 OR $user_vote) { return ''; } else { // add either positive or negative vote link if ($value == 1) { $attributes = array( 'class' => 'link_pos', 'title' => 'Like' ); $class = 'vote_pos'; $link = '[+]'; } else { $attributes = array( 'class' => 'link_neg', 'title' => 'Dislike' ); $class = 'vote_neg'; $link = '[-]'; } } } return '' . l($link, $url, $attributes, drupal_get_destination(), NULL, FALSE, TRUE) . ''; } function theme_mediumvote_css_path() { // depending on installation this path may require a preceding / // return '/' . drupal_get_path('module', 'mediumvote') . '/theme/mediumvote.css'; return drupal_get_path('module', 'mediumvote') . '/theme/mediumvote.css'; } function mediumvote_nodeapi(&$node, $op, $teaser, $page) { $path = drupal_get_path('module', 'mediumvote'); drupal_add_js($path . '/theme/ajax_mediumvote.js'); $allow_all = variable_get('allow_node_all', FALSE); $allow_override = variable_get('allow_override_node', FALSE); $allow_node_type = variable_get('allow_node_'.$node->type, FALSE); if ($allow_all OR ($allow_override AND $allow_node_type)) { switch ($op) { case 'view': if ($teaser == FALSE) { for ($tag_count = 1; $tag_count <= NUM_VOTING_CRITERIA; $tag_count++) { $tag = _mediumvote_get_tag($tag_count, VOTINGAPI_VALUE_NODE_CONTENT_TYPE, $node); if ($tag) { $node->body = theme('mediumvote_widget', $node->nid, VOTINGAPI_VALUE_NODE_CONTENT_TYPE, $tag) . $node->body; } } } break; } } } function mediumvote_comment(&$comment, $op) { $path = drupal_get_path('module', 'mediumvote'); drupal_add_js($path . '/theme/ajax_mediumvote.js'); // get comment's node to see if comment voting // is allowed for node type $node = node_load(array('nid' => $comment->nid)); $allow_all = variable_get('allow_comment_all', FALSE); $allow_override = variable_get('allow_override_comment', FALSE); $allow_node_type = variable_get('allow_comment_'.$node->type, FALSE); if ($allow_all OR ($allow_override AND $allow_node_type)) { switch ($op) { case 'view': for ($tag_count = 1; $tag_count <= NUM_VOTING_CRITERIA; $tag_count++) { $tag = _mediumvote_get_tag($tag_count, VOTINGAPI_VALUE_COMMENT_CONTENT_TYPE, $node); if ($tag) { $comment->comment = theme('mediumvote_widget', $node->nid, VOTINGAPI_VALUE_COMMENT_CONTENT_TYPE, $tag) . $comment->comment; } } break; } } // end if voting allowed }