| 1 |
<?php
|
| 2 |
// $Id: simple_review.module,v 1.10 2008/01/23 10:59:45 smk Exp $
|
| 3 |
|
| 4 |
/**
|
| 5 |
* @file
|
| 6 |
* Allows users to review nodes using standard comments with an attached
|
| 7 |
* Fivestar widget.
|
| 8 |
*/
|
| 9 |
|
| 10 |
/**
|
| 11 |
* Theme function override.
|
| 12 |
*
|
| 13 |
* Stub function needs to be copied along with comment.tpl.php to your theme.
|
| 14 |
*
|
| 15 |
* @see theme_comment(), comment.module
|
| 16 |
* @ingroup themable
|
| 17 |
*/
|
| 18 |
function yourtheme_comment($comment, $links = array()) {
|
| 19 |
// Remove reply link
|
| 20 |
if (isset($comment->rating) && !empty($links)) {
|
| 21 |
unset($links['comment_reply']);
|
| 22 |
}
|
| 23 |
// Remove 'new' marker on preview
|
| 24 |
if ($comment->op == $comment->preview) {
|
| 25 |
$comment->new = 0;
|
| 26 |
}
|
| 27 |
|
| 28 |
return _phptemplate_callback('comment', array(
|
| 29 |
'author' => theme('username', $comment),
|
| 30 |
'comment' => $comment,
|
| 31 |
'content' => $comment->comment,
|
| 32 |
'date' => format_date($comment->timestamp),
|
| 33 |
'links' => isset($links) ? theme('links', $links) : '',
|
| 34 |
'new' => $comment->new ? t('new') : '',
|
| 35 |
'picture' => theme_get_setting('toggle_comment_user_picture') ? theme('user_picture', $comment) : '',
|
| 36 |
'submitted' => t('Submitted by !a on @b.',
|
| 37 |
array('!a' => theme('username', $comment),
|
| 38 |
'@b' => format_date($comment->timestamp))),
|
| 39 |
'title' => l($comment->subject, $_GET['q'], NULL, NULL, "comment-$comment->cid"),
|
| 40 |
'rating' => isset($comment->rating) ? theme('fivestar_static', $comment->rating) : '',
|
| 41 |
));
|
| 42 |
}
|
| 43 |
|
| 44 |
/**
|
| 45 |
* Implementation of hook_form_alter().
|
| 46 |
*
|
| 47 |
* Hint: To alter or remove the default name for anonymous users in the comment
|
| 48 |
* form, go to admin/settings/site-information and configure the displayed
|
| 49 |
* name for non-authenticated users.
|
| 50 |
*/
|
| 51 |
function simple_review_form_alter($form_id, &$form) {
|
| 52 |
if ($form_id == 'node_type_form' && isset($form['identity']['type'])) {
|
| 53 |
// Allow reviews on a per-node type basis
|
| 54 |
if (!isset($form['workflow']['comment']['#weight'])) {
|
| 55 |
$form['workflow']['comment']['#weight'] = 1;
|
| 56 |
}
|
| 57 |
$form['workflow']['simple_review'] = array(
|
| 58 |
'#type' => 'checkbox',
|
| 59 |
'#title' => t('Enable simple review functionality'),
|
| 60 |
'#default_value' => variable_get('simple_review_'. $form['#node_type']->type, 0),
|
| 61 |
'#description' => t("Check to turn the comment form into a simple review form. Be sure to follow the installation instructions in the module's README.txt."),
|
| 62 |
'#weight' => $form['workflow']['comment']['#weight'],
|
| 63 |
);
|
| 64 |
}
|
| 65 |
else if ($form_id == 'comment_form') {
|
| 66 |
$node = node_load($form['nid']['#value']);
|
| 67 |
if (variable_get('simple_review_'. $node->type, 0)) {
|
| 68 |
// Check whether the user has already reviewed this node (except admins)
|
| 69 |
if (simple_review_already_reviewed($form['nid']['#value']) && !user_access('administer comments')) {
|
| 70 |
drupal_goto("node/{$form['nid']['#value']}");
|
| 71 |
}
|
| 72 |
|
| 73 |
// Make room for Fivestar widget
|
| 74 |
$form['comment_filter']['#weight'] = 2;
|
| 75 |
|
| 76 |
if ($form['cid']['#value']) {
|
| 77 |
// Editing a comment: load current vote
|
| 78 |
$current_vote = simple_review_get_vote($form['cid']['#value']);
|
| 79 |
}
|
| 80 |
$form['rating'] = array(
|
| 81 |
'#type' => 'fivestar',
|
| 82 |
'#title' => t('Your rating'),
|
| 83 |
'#default_value' => (isset($current_vote) ? $current_vote->value : 0),
|
| 84 |
'#weight' => 1,
|
| 85 |
);
|
| 86 |
}
|
| 87 |
}
|
| 88 |
}
|
| 89 |
|
| 90 |
/**
|
| 91 |
* Implementation of hook_link_alter().
|
| 92 |
*/
|
| 93 |
function simple_review_link_alter($node, &$links) {
|
| 94 |
if (variable_get('simple_review_'. $node->type, 0)) {
|
| 95 |
if (isset($links['comment_add'])) {
|
| 96 |
if (!simple_review_already_reviewed($node->nid)) {
|
| 97 |
// Change wording
|
| 98 |
$links['comment_add']['title'] = t('Review this article');
|
| 99 |
$links['comment_add']['attributes']['title'] = t('Share your thoughts and opinions and rate this article.');
|
| 100 |
}
|
| 101 |
else {
|
| 102 |
// Remove link when already reviewed
|
| 103 |
unset($links['comment_add']);
|
| 104 |
}
|
| 105 |
}
|
| 106 |
}
|
| 107 |
}
|
| 108 |
|
| 109 |
/**
|
| 110 |
* Implementation of hook_comment().
|
| 111 |
*/
|
| 112 |
function simple_review_comment(&$comment, $op) {
|
| 113 |
switch ($op) {
|
| 114 |
case 'view':
|
| 115 |
if (!empty($comment->cid)) {
|
| 116 |
$node = node_load($comment->nid);
|
| 117 |
if (variable_get('simple_review_'. $node->type, 0)) {
|
| 118 |
$vote = simple_review_get_vote($comment->cid);
|
| 119 |
$comment->rating = $vote->value;
|
| 120 |
}
|
| 121 |
}
|
| 122 |
break;
|
| 123 |
|
| 124 |
case 'insert':
|
| 125 |
case 'update':
|
| 126 |
$node = node_load($comment['nid']);
|
| 127 |
if (variable_get('simple_review_'. $node->type, 0)) {
|
| 128 |
$vote = simple_review_cast_vote($comment['cid'], $comment['nid'], $comment['uid'], $comment['rating']);
|
| 129 |
if ($op == 'insert' && $vote) {
|
| 130 |
db_query("INSERT INTO {simple_review} (vid, cid) VALUES (%d, %d)", $vote->vote_id, $comment['cid']);
|
| 131 |
}
|
| 132 |
else if (!$vote) {
|
| 133 |
simple_review_delete_vote($comment['cid']);
|
| 134 |
}
|
| 135 |
}
|
| 136 |
break;
|
| 137 |
|
| 138 |
case 'delete':
|
| 139 |
$node = node_load($comment->nid);
|
| 140 |
if (variable_get('simple_review_'. $node->type, 0)) {
|
| 141 |
simple_review_delete_vote($comment->cid);
|
| 142 |
}
|
| 143 |
break;
|
| 144 |
}
|
| 145 |
}
|
| 146 |
|
| 147 |
/**
|
| 148 |
* Return the vote record for a comment.
|
| 149 |
*
|
| 150 |
* @param $cid
|
| 151 |
* A comment id.
|
| 152 |
* @return object
|
| 153 |
* A vote record.
|
| 154 |
*/
|
| 155 |
function simple_review_get_vote($cid) {
|
| 156 |
$vid = db_result(db_query("SELECT vid FROM {simple_review} WHERE cid = %d", $cid));
|
| 157 |
return votingapi_get_vote_by_id($vid);
|
| 158 |
}
|
| 159 |
|
| 160 |
/**
|
| 161 |
* Deletes the association between a comment and a vote.
|
| 162 |
*
|
| 163 |
* @param $cid
|
| 164 |
* A comment id.
|
| 165 |
*/
|
| 166 |
function simple_review_delete_vote($cid) {
|
| 167 |
if ($vote = simple_review_get_vote($cid)) {
|
| 168 |
votingapi_delete_vote($vote);
|
| 169 |
votingapi_recalculate_results('node', $vote->content_id);
|
| 170 |
}
|
| 171 |
db_query("DELETE FROM {simple_review} WHERE cid = %d", $cid);
|
| 172 |
}
|
| 173 |
|
| 174 |
/**
|
| 175 |
* Save the comment rating and trigger a voting API update.
|
| 176 |
*
|
| 177 |
* @param $cid
|
| 178 |
* A comment id.
|
| 179 |
* @param $nid
|
| 180 |
* The node id the comment is for.
|
| 181 |
* @param $uid
|
| 182 |
* The user id casting the vote.
|
| 183 |
* @param $value
|
| 184 |
* The rating value.
|
| 185 |
* @return object
|
| 186 |
* The created or updated vote record, or FALSE
|
| 187 |
* if the vote has been cancelled.
|
| 188 |
*/
|
| 189 |
function simple_review_cast_vote($cid, $nid, $uid, $value) {
|
| 190 |
if (is_numeric($cid) && is_numeric($nid) && is_numeric($value)) {
|
| 191 |
if ($value > 100) {
|
| 192 |
$value = 100;
|
| 193 |
}
|
| 194 |
|
| 195 |
// Try to lookup an existing vote record.
|
| 196 |
$old_vote = simple_review_get_vote($cid);
|
| 197 |
|
| 198 |
// If the old vote exists, either delete it (if the new one is zero)
|
| 199 |
// or change it. If it doesn't exist, cast it and recalculate.
|
| 200 |
if ($old_vote) {
|
| 201 |
if ($value == 0) {
|
| 202 |
votingapi_delete_vote($old_vote);
|
| 203 |
// Set return value
|
| 204 |
$vote = FALSE;
|
| 205 |
}
|
| 206 |
else {
|
| 207 |
$vote = votingapi_change_vote($old_vote, $value);
|
| 208 |
}
|
| 209 |
}
|
| 210 |
else {
|
| 211 |
$vote = votingapi_add_vote('node', $nid, $value, 'percent', 'vote', $uid);
|
| 212 |
}
|
| 213 |
|
| 214 |
votingapi_recalculate_results('node', $nid);
|
| 215 |
|
| 216 |
return $vote;
|
| 217 |
}
|
| 218 |
else {
|
| 219 |
return FALSE;
|
| 220 |
}
|
| 221 |
}
|
| 222 |
|
| 223 |
/**
|
| 224 |
* Determine if a user is allowed to post another comment.
|
| 225 |
*
|
| 226 |
* @param $nid
|
| 227 |
* A node id.
|
| 228 |
* @return boolean
|
| 229 |
* TRUE, if a user isn't allowed to post another comment.
|
| 230 |
*/
|
| 231 |
function simple_review_already_reviewed($nid) {
|
| 232 |
global $user;
|
| 233 |
|
| 234 |
if ($user->uid) {
|
| 235 |
$num_comments = db_result(db_query("SELECT COUNT(*) FROM {comments} WHERE nid = %d AND uid = %d", $nid, $user->uid));
|
| 236 |
}
|
| 237 |
else {
|
| 238 |
// For anonyous user all we can do is to set a time limit on their IP
|
| 239 |
// @todo Additionally setting/checking for a cookie might be better
|
| 240 |
$num_comments = db_result(db_query("SELECT COUNT(*) FROM {comments} WHERE nid = %d AND uid = 0 AND hostname = '%s' AND timestamp > %d", $nid, $_SERVER['REMOTE_ADDR'], time() - (24*60*60)));
|
| 241 |
}
|
| 242 |
|
| 243 |
return $num_comments > 0;
|
| 244 |
}
|
| 245 |
|