| 38 |
* Implementation of hook_settings() |
* Implementation of hook_settings() |
| 39 |
*/ |
*/ |
| 40 |
function voting_settings() { |
function voting_settings() { |
| 41 |
|
// form group: Colors |
| 42 |
$group = form_textfield(t('Background color for voting control'), 'voting_bgcolor', |
$group = form_textfield(t('Background color for voting control'), 'voting_bgcolor', |
| 43 |
variable_get('voting_bgcolor', '0xffffff'), 8, 8); |
variable_get('voting_bgcolor', '0xffffff'), 8, 8); |
| 44 |
$group .= form_textfield(t("Star 'on' fill color"), 'voting_on_fill', |
$group .= form_textfield(t("Star 'on' fill color"), 'voting_on_fill', |
| 53 |
variable_get('voting_txt_color', '0x000000'), 8, 8); |
variable_get('voting_txt_color', '0x000000'), 8, 8); |
| 54 |
$output .= form_group(t('Colors (0xffffff for white, 0x000000 for black, etc.)'), $group); |
$output .= form_group(t('Colors (0xffffff for white, 0x000000 for black, etc.)'), $group); |
| 55 |
|
|
| 56 |
|
// form group: Text Strings |
| 57 |
$group = form_textfield(t('Star 1'), 'voting_txt_vote1', |
$group = form_textfield(t('Star 1'), 'voting_txt_vote1', |
| 58 |
variable_get('voting_txt_vote1', 'Awful'), 20, 20); |
variable_get('voting_txt_vote1', 'Awful'), 20, 20); |
| 59 |
$group .= form_textfield(t('Star 2'), 'voting_txt_vote2', |
$group .= form_textfield(t('Star 2'), 'voting_txt_vote2', |
| 72 |
variable_get('voting_txt_login', 'Please login or register to vote.'), 40, 40); |
variable_get('voting_txt_login', 'Please login or register to vote.'), 40, 40); |
| 73 |
$output .= form_group(t('Text Messages (Leave blank for defaults)'), $group); |
$output .= form_group(t('Text Messages (Leave blank for defaults)'), $group); |
| 74 |
|
|
| 75 |
|
// form group: Other |
| 76 |
|
$group = form_radios(t('Voting controls on nodes'), 'voting_location', |
| 77 |
|
variable_get('voting_location', 1), array(t('Display above the node'), t('Display below the node'), t('Do not display')), |
| 78 |
|
t('Position of the voting control. Select "Do not display" if you are calling the voting module function directly from your theme and/or module code.')); |
| 79 |
|
$group .= form_textfield(t("Voting IP timeout (in seconds)"), 'voting_ip_timeout', |
| 80 |
|
variable_get('voting_ip_timeout', 3600), 8, 8, |
| 81 |
|
t('Controls if and how often users with the same IP address can vote for the same thing. Set it to 0 to disable this feature.')); |
| 82 |
|
|
| 83 |
|
$output .= form_group(t('Other'), $group); |
| 84 |
|
|
| 85 |
return $output; |
return $output; |
| 86 |
} |
} |
| 87 |
|
|
| 88 |
/** |
/** |
| 89 |
* Return a vote object (containing the user's vote, plus other relevant information) |
* Return a vote object (containing the user's vote, average vote, and number of votes) |
| 90 |
*/ |
*/ |
| 91 |
function voting_get_vote($content_type, $content_id) { |
function voting_get_vote($content_type, $content_id) { |
| 92 |
global $user; |
global $user; |
| 93 |
|
|
| 94 |
if ($_COOKIE["vote_{$content_type}_{$content_id}"]) { |
// my vote |
| 95 |
|
if ($_COOKIE["vote_{$content_type}_{$content_id}"]) { // get user's vote from a cookie on their computer |
| 96 |
$voting_id = $_COOKIE["vote_{$content_type}_{$content_id}"]; |
$voting_id = $_COOKIE["vote_{$content_type}_{$content_id}"]; |
| 97 |
$result = db_query("SELECT * FROM {votes} WHERE voting_id=%d", $voting_id); |
$result = db_query("SELECT * FROM {votes} WHERE voting_id=%d", $voting_id); |
| 98 |
$vote = db_fetch_object($result); |
$vote = db_fetch_object($result); |
| 99 |
} elseif ($user->uid) { |
} elseif ($user->uid) { // get the user's vote by using their user_id |
| 100 |
$result = db_query("SELECT * FROM {votes} WHERE content_type='%s' AND content_id=%d AND uid=%d", $content_type, $content_id, $user->uid); |
$result = db_query("SELECT * FROM {votes} WHERE content_type='%s' AND content_id=%d AND uid=%d", $content_type, $content_id, $user->uid); |
| 101 |
$vote = db_fetch_object($result); |
$vote = db_fetch_object($result); |
| 102 |
} else { |
} else { // get the user's vote from their IP address (only within one hour, or whatever the voting_ip_timeout variable is set to) |
| 103 |
$result = db_query("SELECT * FROM {votes} WHERE content_type='%s' AND content_id=%d AND hostname='%s' AND timestamp > %d", $content_type, $content_id, $_SERVER['REMOTE_ADDR'], time() - variable_get("voting_ip_timeout", 60 * 60)); |
$result = db_query("SELECT * FROM {votes} WHERE content_type='%s' AND content_id=%d AND hostname='%s' AND timestamp > %d", $content_type, $content_id, $_SERVER['REMOTE_ADDR'], time() - variable_get("voting_ip_timeout", 60 * 60)); |
| 104 |
$vote = db_fetch_object($result); |
$vote = db_fetch_object($result); |
| 105 |
} |
} |
| 106 |
|
|
| 107 |
if ($vote->vote) { |
// average vote |
| 108 |
// my vote |
$result = db_query("SELECT SUM(vote)/COUNT(vote) AS avg_vote FROM {votes} WHERE content_type='%s' AND content_id=%d", $content_type, $content_id); |
| 109 |
$vote->vote = round($vote->vote / 0.5) * 0.5; // rounds to nearest half |
$vote->avg_vote = $result ? db_result($result, "avg_vote") : 0; |
| 110 |
$vote->vote = number_format($vote->vote, 1); // fixes to 1 decimal place |
$vote->avg_vote = round($vote->avg_vote / 0.5) * 0.5; // rounds to nearest half |
| 111 |
|
$vote->avg_vote = number_format($vote->avg_vote, 1); // fixes to 1 decimal place |
| 112 |
// average vote |
|
| 113 |
$result = db_query("SELECT SUM(vote)/COUNT(vote) AS avg_vote FROM {votes} WHERE content_type='%s' AND content_id=%d", $content_type, $content_id); |
// number of votes |
| 114 |
$vote->avg_vote = $result ? db_result($result, "avg_vote") : 0; |
$result = db_query("SELECT COUNT(vote) FROM {votes} WHERE content_type='%s' AND content_id=%d", $content_type, $content_id); |
| 115 |
$vote->avg_vote = round($vote->avg_vote / 0.5) * 0.5; // rounds to nearest half |
$vote->num_votes = $result ? db_result($result, 0) : 0; |
| 116 |
$vote->avg_vote = number_format($vote->avg_vote, 1); // fixes to 1 decimal place |
|
| 117 |
|
return $vote; |
|
// number of votes |
|
|
$result = db_query("SELECT COUNT(vote) FROM {votes} WHERE content_type='%s' AND content_id=%d", $content_type, $content_id); |
|
|
$vote->num_votes = $result ? db_result($result, 0) : 0; |
|
|
|
|
|
return $vote; |
|
|
} else { |
|
|
return false; |
|
|
} |
|
| 118 |
} |
} |
| 119 |
|
|
| 120 |
/** |
/** |
| 121 |
* This function is used with a Macromedia Flash based voting control to send and receive data in |
* This function is used with a Macromedia Flash based voting control to send and receive data in |
| 122 |
* one step. First, Flash is passed the content_type and content_id from the page where it is used. |
* one step. First, Flash is passed the content_type and content_id from the page where it is used. |
| 123 |
* Then, Flash calls /voting/flash and sends the content_type and content_id using POST. A vote is |
* Then, Flash calls /voting/flash and sends the content_type and content_id using POST. A vote is |
| 124 |
* not passed, so this function will not insert a vote, but it was returns the current voting information. |
* not passed, so this function will not insert a vote, but it will return the current voting information. |
| 125 |
* If a user votes (or changes their vote), this function is called again from Flash, this time with |
* If a user votes (or changes their vote), this function is called again from Flash, this time with |
| 126 |
* a vote. |
* a vote. |
| 127 |
* |
* |
| 131 |
|
|
| 132 |
$content_type = $_POST['content_type']; |
$content_type = $_POST['content_type']; |
| 133 |
$content_id = $_POST['content_id']; |
$content_id = $_POST['content_id']; |
| 134 |
$vote = $_POST['vote']; |
$new_vote = $_POST['vote']; |
| 135 |
|
$vote = voting_get_vote($content_type, $content_id); // get average vote, number of votes, and user's current vote (if any) |
| 136 |
if (($vote) && user_access('vote on content')) { // if a vote is sent |
|
| 137 |
if ($prev_vote = voting_get_vote($content_type, $content_id)) { |
if ($new_vote) { // if a new vote is sent... |
| 138 |
db_query("UPDATE {votes} SET vote=%d, timestamp=%d, hostname='%s' WHERE voting_id=%d", $vote, time(), $_SERVER['REMOTE_ADDR'], $prev_vote->voting_id); |
if ($vote->voting_id) { // ...and the user has already voted |
| 139 |
// I don't know why the cookie name needs to be in {} but it doesn't work otherwise |
db_query("UPDATE {votes} SET vote=%d, timestamp=%d, hostname='%s' WHERE voting_id=%d", $new_vote, time(), $_SERVER['REMOTE_ADDR'], $vote->voting_id); |
| 140 |
setcookie ("vote_{$content_type}_{$content_id}", $prev_vote->voting_id, time()+60*60*24*30); // expire in 30 days |
setcookie ("vote_{$content_type}_{$content_id}", $prev_vote->voting_id, time()+60*60*24*30); // expire in 30 days |
| 141 |
} else { // and this hasn't already been voted on |
} else { // ...and the user has NOT voted yet |
| 142 |
$result = db_query("SELECT MAX(voting_id) FROM {votes}"); |
$result = db_query("SELECT MAX(voting_id) FROM {votes}"); |
| 143 |
$voting_id = $result ? db_result($result, 0) : 0; |
$voting_id = $result ? db_result($result, 0) : 0; |
| 144 |
$voting_id++; |
$voting_id++; |
|
|
|
| 145 |
db_query("INSERT INTO {votes} (voting_id, content_type, content_id, vote, uid, timestamp, hostname) VALUES (%d, '%s', %d, %d, %d, %d, '%s')", |
db_query("INSERT INTO {votes} (voting_id, content_type, content_id, vote, uid, timestamp, hostname) VALUES (%d, '%s', %d, %d, %d, %d, '%s')", |
| 146 |
$voting_id, $content_type, $content_id, $vote, $user->uid, time(), $_SERVER['REMOTE_ADDR']); |
$voting_id, $content_type, $content_id, $new_vote, $user->uid, time(), $_SERVER['REMOTE_ADDR']); |
|
|
|
| 147 |
setcookie ("vote_{$content_type}_{$content_id}", $voting_id, time()+60*60*24*30); // expire in 30 days |
setcookie ("vote_{$content_type}_{$content_id}", $voting_id, time()+60*60*24*30); // expire in 30 days |
| 148 |
} |
} |
| 149 |
|
$vote = voting_get_vote($content_type, $content_id); // get new updated average vote and number of votes |
| 150 |
} |
} |
| 151 |
// return to flash the current vote info |
|
| 152 |
$vote = voting_get_vote($content_type, $content_id); |
// return the current vote info to flash |
| 153 |
$vote->vote = ($vote->vote) ? $vote->vote : 0; |
$vote->vote = ($vote->vote) ? $vote->vote : 0; |
| 154 |
$vote->avg_vote = ($vote->avg_vote) ? $vote->avg_vote : 0; |
$vote->avg_vote = ($vote->avg_vote) ? $vote->avg_vote : 0; |
| 155 |
$vote->num_votes = ($vote->num_votes) ? $vote->num_votes : 0; |
$vote->num_votes = ($vote->num_votes) ? $vote->num_votes : 0; |
|
|
|
| 156 |
echo "vote=$vote->vote&avg_vote=$vote->avg_vote&num_votes=$vote->num_votes"; |
echo "vote=$vote->vote&avg_vote=$vote->avg_vote&num_votes=$vote->num_votes"; |
| 157 |
} |
} |
| 158 |
|
|
| 183 |
global $user; |
global $user; |
| 184 |
|
|
| 185 |
// required variables |
// required variables |
| 186 |
$url = urlencode('voting/flash'); |
$url = urlencode('voting/flash'); // callback URL that retrieves voting info and process votes |
| 187 |
// optional variables |
|
| 188 |
|
// optional: user_access() dependent variables |
| 189 |
if (user_access('vote on content') && user_access('show average without voting')) { |
if (user_access('vote on content') && user_access('show average without voting')) { |
| 190 |
$mode = 'show_avg_first'; |
$mode = 'show_avg_first'; |
| 191 |
} elseif (user_access('show average without voting')) { |
} elseif (user_access('show average without voting')) { |
| 192 |
$mode = 'show_avg_only'; |
$mode = 'show_avg_only'; |
| 193 |
} |
} |
| 194 |
$bgcolor = variable_get('voting_bgcolor', '0xffffff'); |
|
| 195 |
|
// optional: variables set from administer/settings/voting |
| 196 |
$star_on_fill = variable_get('voting_on_fill', '0x990000'); |
$star_on_fill = variable_get('voting_on_fill', '0x990000'); |
| 197 |
$star_on_border = variable_get('voting_on_border', '0x330000'); |
$star_on_border = variable_get('voting_on_border', '0x330000'); |
| 198 |
$star_off_fill = variable_get('voting_off_fill', '0xcccccc'); |
$star_off_fill = variable_get('voting_off_fill', '0xcccccc'); |
| 204 |
$txt_vote4 = variable_get('voting_txt_vote4', 'Good'); |
$txt_vote4 = variable_get('voting_txt_vote4', 'Good'); |
| 205 |
$txt_vote5 = variable_get('voting_txt_vote5', 'Excellent'); |
$txt_vote5 = variable_get('voting_txt_vote5', 'Excellent'); |
| 206 |
$txt_login = urlencode(variable_get('voting_txt_login', 'Please login or register to vote.')); |
$txt_login = urlencode(variable_get('voting_txt_login', 'Please login or register to vote.')); |
| 207 |
|
|
| 208 |
|
// optional: certain variables can be overridden on individual voting controls |
| 209 |
|
// ex: $output .= voting_control_generic('pagevote', $node->nid, array('prompt' => 'Do you like it?', 'confirmation' => 'Vote saved!', 'bgcolor' => '0xffffff')); |
| 210 |
$txt_before_vote = urlencode(($attributes['prompt']) ? $attributes['prompt'] : variable_get('voting_txt_before_vote', 'Rate This:')); |
$txt_before_vote = urlencode(($attributes['prompt']) ? $attributes['prompt'] : variable_get('voting_txt_before_vote', 'Rate This:')); |
| 211 |
$txt_after_vote = urlencode(($attributes['confirmation']) ? $attributes['confirmation'] : variable_get('voting_txt_after_vote', 'My Vote:')); |
$txt_after_vote = urlencode(($attributes['confirmation']) ? $attributes['confirmation'] : variable_get('voting_txt_after_vote', 'My Vote:')); |
| 212 |
|
$bgcolor = ($attributes['bgcolor']) ? $attributes['bgcolor'] : variable_get('voting_bgcolor', '0xffffff'); |
| 213 |
|
|
| 214 |
// make optional variables into a really long querystring |
// make optional variables into a really long querystring |
| 215 |
$optional_vars = "&mode=$mode&bgcolor=$bgcolor&star_on_fill=$star_on_fill&star_on_border=$star_on_border"; |
$optional_vars = "&mode=$mode&bgcolor=$bgcolor&star_on_fill=$star_on_fill&star_on_border=$star_on_border"; |
| 216 |
$optional_vars .= "&star_off_fill=$star_off_fill&star_off_border=$star_off_border&txt_color=$txt_color"; |
$optional_vars .= "&star_off_fill=$star_off_fill&star_off_border=$star_off_border&txt_color=$txt_color"; |
| 217 |
$optional_vars .= "&txt_vote1=$txt_vote1&txt_vote2=$txt_vote2&txt_vote3=$txt_vote3&txt_vote4=$txt_vote4&txt_vote5=$txt_vote5"; |
$optional_vars .= "&txt_vote1=$txt_vote1&txt_vote2=$txt_vote2&txt_vote3=$txt_vote3&txt_vote4=$txt_vote4&txt_vote5=$txt_vote5"; |
| 218 |
$optional_vars .= "&txt_login=$txt_login&txt_before_vote=$txt_before_vote&txt_after_vote=$txt_after_vote"; |
$optional_vars .= "&txt_login=$txt_login&txt_before_vote=$txt_before_vote&txt_after_vote=$txt_after_vote"; |
| 219 |
|
|
| 220 |
|
// create the Flash filename, including the required variables and optional querystring |
| 221 |
$filename = drupal_get_path('module', 'voting') . "/voting.swf?content_type=$content_type&content_id=$content_id&url=$url" . $optional_vars; |
$filename = drupal_get_path('module', 'voting') . "/voting.swf?content_type=$content_type&content_id=$content_id&url=$url" . $optional_vars; |
| 222 |
|
|
| 223 |
|
// create the HTML to put the Flash object on the page |
| 224 |
|
// |
| 225 |
|
// NOTE: The object is nested in a table for CSS styling. It does |
| 226 |
|
// not seem to work correctly in Firefox when a DIV is used instead. |
| 227 |
$output .= "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" class=\"voting\"><tr><td>\n"; |
$output .= "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" class=\"voting\"><tr><td>\n"; |
| 228 |
$output .= '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" |
$output .= '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" |
| 229 |
codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" |
codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" |
| 246 |
switch ($op) { |
switch ($op) { |
| 247 |
case 'view': |
case 'view': |
| 248 |
if (!$teaser) { |
if (!$teaser) { |
| 249 |
$node->body .= voting_control_node($node, $teaser, $page); |
switch (variable_get('voting_location', 1)) { |
| 250 |
|
case 0: // display above the node |
| 251 |
|
$node->body = voting_control_node($node, $teaser, $page) . $node->body; |
| 252 |
|
break; |
| 253 |
|
case 1: // display below the node |
| 254 |
|
$node->body .= voting_control_node($node, $teaser, $page); |
| 255 |
|
break; |
| 256 |
|
case 2: // do not display |
| 257 |
|
} |
| 258 |
} |
} |
| 259 |
break; |
break; |
| 260 |
case 'settings': // default workflow settings (administer/content/configure/content types) |
case 'settings': // default workflow settings (administer/content/configure/content types) |
| 261 |
return form_radios(t('Voting'), 'voting_'. $node->type, variable_get('voting_'. $node->type, 0), array(t('Disabled'), t('Enabled'))); |
return form_radios(t('Voting'), 'voting_'. $node->type, variable_get('voting_'. $node->type, 0), array(t('Disabled'), t('Enabled'))); |
| 262 |
case 'form admin': // editing a node |
case 'form admin': // editing a node |
| 263 |
if (user_access('administer nodes')) { |
if (user_access('administer nodes')) { |
| 264 |
$selected = isset($node->voting) ? $node->voting : variable_get("voting_$node->type", 1); |
$selected = isset($node->voting) ? $node->voting : variable_get('voting_' . $node->type, 0); |
| 265 |
$output = form_radios('', 'voting', $selected, array(t('Disabled'), t('Enabled'))); |
$output = form_radios('', 'voting', $selected, array(t('Disabled'), t('Enabled'))); |
| 266 |
return form_group(t('User voting'), $output); |
//return form_group_collapsible(t('Voting options'), $output, TRUE); // for Drupal 4.7+ |
| 267 |
|
return form_group(t('Voting options'), $output); // for Drupal 4.6 and before |
| 268 |
} |
} |
| 269 |
break; |
break; |
| 270 |
case 'load': |
case 'load': |
| 280 |
break; |
break; |
| 281 |
case 'validate': |
case 'validate': |
| 282 |
if (!user_access('administer nodes')) { |
if (!user_access('administer nodes')) { |
| 283 |
// Force default for normal users: |
// Force default (for this content type) for normal users: |
| 284 |
$node->voting = variable_get("voting_$node->type", 0); // default is off |
$node->voting = variable_get('voting_' . $node->type, 0); |
| 285 |
} |
} |
| 286 |
voting_filter_validate($node); |
voting_filter_validate($node); |
| 287 |
break; |
break; |