/[drupal]/contributions/modules/lovehate/lovehate.module
ViewVC logotype

Contents of /contributions/modules/lovehate/lovehate.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.24 - (show annotations) (download) (as text)
Thu Jul 20 16:25:34 2006 UTC (3 years, 4 months ago) by eaton
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-4-7
Changes since 1.23: +2 -2 lines
File MIME type: text/x-php
Fix for anonymous users viewing the lovehates of other users.
1 <?php
2 /* $Id: lovehate.module,v 1.23 2006/07/20 13:04:20 eaton Exp $ */
3
4 /**
5 * @file
6 * Lets users vote on vocabulary terms to announce their loves and hates.
7 */
8
9 // ************
10 // System hooks
11 // ************
12
13 function lovehate_help($section) {
14 switch ($section) {
15 case 'admin/modules#description':
16 return t('Lets users vote on vocabulary terms to announce their loves and hates.');
17 break;
18 }
19 }
20
21 /**
22 * hook_perm impelementation.
23 */
24 function lovehate_perm() {
25 return array('view loves and hates', 'choose loves and hates');
26 }
27
28 /**
29 * hook_menu impelementation.
30 */
31 function lovehate_menu($may_cache) {
32 global $user;
33 $items = array();
34
35 if ($may_cache) {
36 $items[] = array(
37 'path' => 'lovehate',
38 'title' => t('loves and hates'),
39 'callback' => 'lovehate_page',
40 'access' => user_access('view loves and hates'),
41 'type' => MENU_SUGGESTED_ITEM,
42 );
43 $items[] = array(
44 'path' => 'lovehate/vote',
45 'title' => t('lovehate vote'),
46 'callback' => 'lovehate_vote',
47 'access' => user_access('choose loves and hates'),
48 'type' => MENU_CALLBACK,
49 );
50 $items[] = array(
51 'path' => 'lovehate/ajaxvote',
52 'title' => t('lovehate ajax vote'),
53 'callback' => 'lovehate_ajax_vote',
54 'access' => user_access('choose loves and hates'),
55 'type' => MENU_CALLBACK,
56 );
57 }
58 else {
59 if (arg(0) == 'user' && is_numeric(arg(1))) {
60 $items[] = array(
61 'path' => 'user/'. arg(1) .'/lovehate',
62 'title' => t('loves and hates'),
63 'callback' => 'lovehate_user_page',
64 'access' => user_access('view loves and hates'),
65 'type' => MENU_IS_LOCAL_TASK
66 );
67 }
68 }
69
70 return $items;
71 }
72
73 // Intercept term deletion and remove old votes.
74 function lovehate_taxonomy($op, $type, $object = NULL) {
75 if ($op == 'delete' && $type == 'term') {
76 $votes = _votingapi_get_raw_votes('term', $object['tid']);
77 votingapi_delete_votes($votes);
78 votingapi_recalculate_results('term', $object['tid']);
79 }
80 }
81
82 function lovehate_term_path($term) {
83 return 'lovehate/' . $term->tid;
84 }
85
86 /**
87 * hook_settings impelementation.
88 */
89 function lovehate_settings() {
90 $form = array();
91
92 // preload variables for the form
93 $vid = variable_get('lovehate_vocabulary', 0);
94 $vocabularies = array();
95 $result = db_query("SELECT vid, name FROM {vocabulary} WHERE module = 'taxonomy' OR module = 'lovehate'");
96 while ($vocabulary = db_fetch_object($result)) {
97 $vocabularies[$vocabulary->vid] = $vocabulary->name;
98 }
99
100 db_query("UPDATE {vocabulary} SET module = 'taxonomy' WHERE module = 'lovehate'");
101 if ($vid && variable_get('lovehate_vocabulary_control', 0)) {
102 db_query("UPDATE {vocabulary} SET module = 'lovehate' WHERE vid = %d AND module = 'taxonomy'", $vid);
103 }
104
105 $form['lovehate_vocabulary'] = array(
106 '#type' => 'select',
107 '#title' => t('The vocabulary containing terms to love or hate'),
108 '#default_value' => $vid,
109 '#options' => $vocabularies,
110 '#description' => t('Users will be able to vote on whether they love or hate each term from this vocabulary.'),
111 );
112
113 $form['lovehate_vocabulary_control'] = array(
114 '#type' => 'checkbox',
115 '#title' => t('Take control of the selected vocabulary'),
116 '#description' => t('When selected, links to terms in the Love/Hate vocabulary will automatically be redirected to the Love/Hate page. Vocabularies already controlled by another module (like Forum or Image Gallery) cannot be changed.'),
117 '#return_value' => 1,
118 '#default_value' => variable_get('lovehate_vocabulary_control', 0),
119 );
120
121 $form['lovehate_item_count'] = array(
122 '#type' => 'select',
123 '#title' => t('User terms count'),
124 '#description' => t('The number of items to display for a given user\'s loves and hates.'),
125 '#default_value' => variable_get('lovehate_item_count', 50),
126 '#options' => drupal_map_assoc(array(5, 10, 15, 20, 25, 50, 75, 100, 200)),
127 );
128
129 $form['lovehate_user_count'] = array(
130 '#type' => 'select',
131 '#title' => t('Term users count'),
132 '#description' => t('The number of users to display for a given term\'s lovers/haters list.'),
133 '#default_value' => variable_get('lovehate_user_count', 50),
134 '#options' => drupal_map_assoc(array(5, 10, 15, 20, 25, 50, 75, 100, 200)),
135 );
136
137 return $form;
138 }
139
140 function lovehate_block($op = 'list', $delta = 0, $edit = array()) {
141 switch ($op) {
142 case 'configure': {
143 $form = array();
144 $form['lovehate_block_title'] = array(
145 '#type' => 'textfield',
146 '#default_value' => variable_get('lovehate_block_title', t('Popular topics')),
147 '#size' => 30,
148 '#maxlength' => 120,
149 '#description' => t('Enter the title for the Love/Hate block'),
150 '#title' => 'Block title',
151 );
152 $form['lovehate_block_count'] = array(
153 '#type' => 'select',
154 '#default_value' => variable_get('lovehate_block_count', 10),
155 '#options' => array(5=>5, 10=>10, 15=>15, 20=>20),
156 '#description' => t('Enter the number of loves and hates to list'),
157 '#title' => 'Block count',
158 );
159 return $form;
160 }
161 case 'save': {
162 variable_set('lovehate_block_title', $edit['lovehate_block_title']);
163 variable_set('lovehate_block_count', $edit['lovehate_block_count']);
164 break;
165 }
166 case 'list': {
167 $block[0]['info'] = "Love/Hate: ".variable_get('amazon_read_blocktitle', t('Popular topics'));
168 return $block;
169 }
170 case 'view': {
171 $terms = lovehate_get_top_terms(variable_get('lovehate_block_count', 10));
172 if (count($terms)) {
173 $block['subject'] = variable_get('amazon_read_blocktitle', t('Popular topics'));
174 $block['content'] = theme('lovehate_block_list', $terms);
175 return $block;
176 }
177 break;
178 }
179 }
180 }
181
182 /**
183 * Hunmonk's module dependency check: see http://drupal.org/node/54463
184 */
185 function lovehate_form_alter($form_id, &$form) {
186 if ($form_id == 'system_modules' && !$_POST) {
187 lovehate_system_module_validate($form);
188 }
189 }
190
191 /**
192 * Hunmonk's module dependency check: see http://drupal.org/node/54463
193 */
194 function lovehate_system_module_validate(&$form) {
195 $module = 'lovehate';
196 $dependencies = array('votingapi', 'taxonomy');
197 foreach ($dependencies as $dependency) {
198 if (!in_array($dependency, $form['status']['#default_value'])) {
199 $missing_dependency = TRUE;
200 $missing_dependency_list[] = $dependency;
201 }
202 }
203 if (in_array($module, $form['status']['#default_value']) && isset($missing_dependency)) {
204 db_query("UPDATE {system} SET status = 0 WHERE type = 'module' AND name = '%s'", $module);
205 $key = array_search($module, $form['status']['#default_value']);
206 unset($form['status']['#default_value'][$key]);
207 drupal_set_message(t('The module %module was deactivated--it requires the following disabled/non-existant modules to function properly: %dependencies', array('%module' => $module, '%dependencies' => implode(', ', $missing_dependency_list))), 'error');
208 }
209 }
210
211
212 // ************************************************
213 // Voting functions -- vote casting and calculation
214 // ************************************************
215
216 function lovehate_votingapi_calculate(&$cache, $votes, $content_type, $content_id) {
217 // Maintain an additional 'lovers' and 'haters' count for each term
218 if ($content_type == 'term' && count($votes)) {
219 $lovers = 0;
220 $haters = 0;
221
222 foreach($votes as $vote) {
223 if ($vote->value_type == 'points') {
224 if ($vote->value == 1) {
225 $lovers += 1;
226 }
227 else {
228 $haters += 1;
229 }
230 }
231 }
232
233 $cache['vote']['points']['haters'] = $haters;
234 $cache['vote']['points']['lovers'] = $lovers;
235 unset($cache['vote']['points']['count']);
236 unset($cache['vote']['points']['average']);
237 }
238 }
239
240 function _lovehate_cast_vote($tid, $score) {
241 global $user;
242
243 // bail out if the user doens't have access, if the args aren't numeric
244 if (!user_access('choose loves and hates')) {
245 return;
246 } if (!is_numeric($tid) || !is_numeric($score)) {
247 return;
248 }
249 if ($score > 1 || $score < -1) {
250 return;
251 }
252
253 if ($score == 0) {
254 votingapi_unset_vote('term', $tid);
255 }
256 else if ($score == -1 || $score == 1) {
257 // add the vote
258 $vote->value = $score;
259 $vote->value_type = 'points';
260 $vote->tag = 'vote';
261 votingapi_set_vote('term', $tid, $vote);
262 }
263 else {
264 // We only allow those three values. bail if it's anything else.
265 return;
266 }
267 }
268
269 function lovehate_vote($tid = NULL, $score = NULL) {
270 if ($tid === NULL) {
271 $tid = arg(2);
272 }
273 if ($score == NULL) {
274 $score = arg(3);
275 }
276
277 _lovehate_cast_vote($tid, $score);
278 drupal_goto();
279 }
280
281 function lovehate_ajax_vote($tid = NULL, $score = NULL) {
282 if ($tid === NULL) {
283 $tid = arg(2);
284 }
285 if ($score == NULL) {
286 $score = arg(3);
287 }
288
289 _lovehate_cast_vote($tid, $score);
290 $newscore = lovehate_get_term_score($tid);
291 print $newscore->lovers . ',' . $newscore->haters . ',' . $newscore->score;
292 exit();
293 }
294
295 // ********************************************
296 // Utility functions for handling lovehate data
297 // ********************************************
298
299 function lovehate_get_node_terms($nid, $precache = FALSE) {
300 $vid = variable_get('lovehate_vocabulary', 0);
301 if ($vid == 0) {
302 return array();
303 }
304 else {
305 $terms = taxonomy_node_get_terms_by_vocabulary($nid, $vid);
306 if ($precache) {
307 foreach ($terms as $tid => $term) {
308 $terms[$tid]->lovehate = lovehate_get_term_score($tid);
309 }
310 }
311 return $terms;
312 }
313 }
314
315 function lovehate_calculate_score_from_terms($terms) {
316 $score->user = 0;
317 $score->overall = 0;
318 foreach ($terms as $term) {
319 $score->user += $term->lovehate->current_user;
320 $score->overall += $term->lovehate->score;
321 }
322 return $score;
323 }
324
325 function lovehate_get_all_terms($uid = NULL, $precache = FALSE) {
326 $terms = array();
327 $vid = variable_get('lovehate_vocabulary', 0);
328 if ($vid != 0) {
329 $result = db_query('SELECT * FROM {term_data} WHERE vid = %d', $vid);
330 while ($term = db_fetch_object($result)) {
331 $term->lovehate = lovehate_get_term_score($term->tid, $uid);
332 $terms[$term->tid] = $term;
333 }
334 if ($precache) {
335 foreach ($terms as $tid => $term) {
336 $terms[$tid]->lovehate = lovehate_get_term_score($tid, $uid);
337 }
338 }
339 }
340 return $terms;
341 }
342
343 function lovehate_get_term_score($tid, $uid = NULL) {
344 $score->lovers = 0;
345 $score->haters = 0;
346 $score->score = 0;
347
348 $votes = votingapi_get_voting_results('term', $tid);
349 foreach ($votes as $vote) {
350 if ($vote->function == 'lovers') {
351 $score->lovers = $vote->value;
352 }
353 if ($vote->function == 'haters') {
354 $score->haters = $vote->value;
355 }
356 if ($vote->function == 'sum') {
357 $score->score = $vote->value;
358 }
359 }
360
361 if ($uid != NULL) {
362 $current_user_vote = votingapi_get_user_votes('term', $tid, $uid);
363 if (isset($current_user_vote[0])) {
364 $score->current_user = $current_user_vote[0]->value;
365 }
366 }
367 return $score;
368 }
369
370 function lovehate_get_term_users($tid) {
371 $users->lovers = array();
372 $users->haters = array();
373 $votes = votingapi_get_content_votes('term', $tid);
374
375 foreach ($votes as $uid=>$uid_votes) {
376 foreach ($uid_votes as $vote) {
377 if ($vote->value == 1) {
378 $users->lovers[] = $uid;
379 }
380 else if ($vote->value == -1) {
381 $users->haters[] = $uid;
382 }
383 }
384 }
385 return $users;
386 }
387
388 function lovehate_get_user_terms($uid = NULL) {
389 if ($uid == NULL) {
390 global $user;
391 $uid = $user->uid;
392 }
393
394 $terms->loves = array();
395 $terms->hates = array();
396 $terms->other = array();
397
398 $tmp = lovehate_get_all_terms($uid, TRUE);
399
400 foreach ($tmp as $term) {
401 if ($term->lovehate->current_user == 1) {
402 $terms->loves[$term->tid] = $term;
403 }
404 else if ($term->lovehate->current_user == -1) {
405 $terms->hates[$term->tid] = $term;
406 }
407 else {
408 $terms->other[$term->tid] = $term;
409 }
410 }
411
412 return $terms;
413 }
414
415 function lovehate_get_top_terms($count = 10) {
416 $ordered_terms = array();
417 $terms = lovehate_get_all_terms(NULL, TRUE);
418 foreach ($terms as $term) {
419 $ordered_terms[$term->lovehate->score] = $term;
420 }
421 krsort($ordered_terms, SORT_NUMERIC);
422 if ($count > count($ordered_terms)) {
423 $ordered_terms = array_slice($ordered_terms, 0, $count);
424 }
425 return $ordered_terms;
426 }
427
428
429 // *************************
430 // Page generation functions
431 // *************************
432
433 function lovehate_page($tid = 0) {
434 // we're in page-mode, not individual term mode.
435 if ($tid == 0) {
436 $terms = lovehate_get_all_terms();
437 return theme('lovehate_overview_page', $terms);
438 }
439 else {
440 $term = taxonomy_get_term($tid);
441 $term->lovehate = lovehate_get_term_score($tid);
442 $score = lovehate_get_term_score($tid);
443 $users = lovehate_get_term_users($tid);
444
445 return theme('lovehate_detail_page', $term, $score, $users->lovers, $users->haters);
446 }
447
448 return $output;
449 }
450
451 function lovehate_user_page() {
452 $uid = arg(1);
453 $user_data = lovehate_get_user_terms($uid);
454
455 $output = theme('lovehate_user_page', $uid, $user_data->loves, $user_data->hates, $user_data->other);
456
457 return $output;
458 }
459
460 // *****************
461 // Theming functions
462 // *****************
463
464 function theme_lovehate_overview_page($terms = array()) {
465 $output = "";
466 foreach ($terms as $term) {
467 $output .= theme('lovehate_term', $term, TRUE, TRUE);
468 }
469 return $output;
470 }
471
472 function theme_lovehate_detail_page($term, $score = NULL, $lovers = array(), $haters = array()) {
473 global $user;
474
475 drupal_set_title($term->name);
476 $breadcrumbs = drupal_get_breadcrumb();
477 $breadcrumbs[] = l(t('loves and hates'), 'lovehate');
478 drupal_set_breadcrumb($breadcrumbs);
479
480 $output .= '<p>' . $term->description . '</p>';
481
482 if ($user->uid && user_access('choose loves and hates')) {
483 if ($score->current_user == 1) {
484 $output .= '<p>You LOVE ' . $term->name . '! ' . theme('lovehate_vote_widget', $term) . '</p>';
485 }
486 else if ($score->current_user == -1) {
487 $output .= '<p>You HATE ' . $term->name . '! ' . theme('lovehate_vote_widget', $term) . '</p>';
488 }
489 else {
490 $output .= '<p>You don\'t care about ' . $term->name . '. ' . theme('lovehate_vote_widget', $term) . '</p>';
491 }
492 }
493
494 $output .= '<h4>Lovers</h4>';
495 $output .= theme('lovehate_users', $lovers);
496
497 $output .= '<h4>Haters</h4>';
498 $output .= theme('lovehate_users', $haters);
499
500 return $output;
501 }
502
503 function theme_lovehate_user_page($uid = 0, $loves = array(), $hates = array(), $other = array()) {
504 $output = '<div id="loves"><h2>Love it!</h2>';
505 foreach ($loves as $term) {
506 $output .= theme('lovehate_term', $term);
507 }
508 $output .= '</div>';
509
510 $output .= '<div id="hates"><h2>Hate it!</h2>';
511 foreach ($hates as $term) {
512 $output .= theme('lovehate_term', $term);
513 }
514 $output .= '</div>';
515
516 $output .= '<div id="other"><h2>Who cares?</h2>';
517 foreach ($other as $term) {
518 $output .= theme('lovehate_term', $term);
519 }
520 $output .= '</div>';
521 return $output;
522 }
523
524 function theme_lovehate_term($term, $show_description = FALSE, $show_count = FALSE) {
525 $output = '<div class="lovehate_term_detail">';
526 $output .= '<h3>' . l($term->name, 'lovehate/' . $term->tid);
527 if (user_access('choose loves and hates')) {
528 $output .= theme('lovehate_vote_widget', $term);
529 }
530 $output .= '</h3>';
531 if ($show_description) {
532 $output .= '<p>' . $term->description . '</p>';
533 }
534 if ($show_count) {
535 $output .= '<p>Lovers: ' . $term->lovehate->lovers . ' | Haters: ' . $term->lovehate->haters . '</p>';
536 }
537 $output .= '</div>';
538 return $output;
539 }
540
541 function theme_lovehate_users($users) {
542 $limit = variable_get('lovehate_user_count', 50);
543 $count = 0;
544 $names = array();
545 foreach ($users as $uid) {
546 $name = user_load(array('uid'=>$uid));
547 $names[] = theme('username', $name);
548 $count++;
549 if ($count > $limit) {
550 break;
551 }
552 }
553 $output .= '<p>' . implode(', ', $names) . '</p>';
554
555 return $output;
556 }
557
558 function theme_lovehate_vote_widget($term) {
559 $options = array();
560 if ($term->lovehate->current_user != 1) {
561 $options[] = '<span class="lovehate_love_widget">' . l('+', "lovehate/vote/$term->tid/1", array(), drupal_get_destination()) . '</span>';
562 }
563 if ($term->lovehate->current_user != 0) {
564 $options[] = '<span class="lovehate_neither_widget">' . l('x', "lovehate/vote/$term->tid/0", array(), drupal_get_destination()) . '</span>';
565 }
566 if ($term->lovehate->current_user != -1) {
567 $options[] = '<span class="lovehate_hate_widget">' . l('-', "lovehate/vote/$term->tid/-1", array(), drupal_get_destination()) . '</span>';
568 }
569 return ' (' . implode('/', $options) . ')';
570 }
571
572 function theme_lovehate_block_list($terms) {
573 foreach($terms as $term) {
574 $links[] = l($term->name, "lovehate/$term->tid", array('title' => 'Total score: '.$term->lovehate->score));
575 }
576 return theme('item_list', $links);
577 }

  ViewVC Help
Powered by ViewVC 1.1.2