/[drupal]/contributions/modules/tapatio/comms.module
ViewVC logotype

Contents of /contributions/modules/tapatio/comms.module

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


Revision 1.1 - (show annotations) (download) (as text)
Sat Dec 6 00:37:32 2008 UTC (11 months, 3 weeks ago) by evoltech
Branch: MAIN
CVS Tags: DRUPAL-5--1-0, HEAD
Branch point for: DRUPAL-5, DRUPAL-5--2
File MIME type: text/x-php
This is the initial check in of the files for the tapatio project
1 <?php
2 // $Id$
3
4 /**
5 * @file
6 * Enables the comms module wich creates a new content type that will hold
7 * communications data which can then be searched, moderated, and dispatched
8 * in a number of different fashions.
9 *
10 * This module is for Drupal 5.x only.
11 *
12 * Some notes on modifying this file:
13 * a) before checking into the repo make sure you do a checkout first and
14 * merge any changes
15 *
16 * b) make liberal use of the watchdog() function in your code
17 * (http://api.drupal.org/api/function/watchdog/5)
18 *
19 * c) When working with debug values, use this form:
20 * 0 - no messages
21 * 1 - function tracing w/ simple argument dump (no arrays, objects, or long texts)
22 * 2 - undefined
23 * 3 - function tracing w/ argument dump
24 * 4 - undefined
25 * 5 - undefined
26 *
27 * d) When making twitter api calls make sure that the twitter_api_calls
28 * table is updated with comms_add_twitter_api_call(). We use this so that
29 * we can monitor our rate usage.
30 *
31 * TODO: start integrating in simple test : http://drupal.org/project/simpletest
32 * TODO: write dispatch functionality
33 there are two ways we will dispatch something:
34 1) If the dispatch button is pressed - check!
35 2) If the dispatch level for a node is reached, after voting - check!
36 3) A user with points greater then comms_dispatchlevel submits a comms node - test
37 4) test without a net connection.
38 * TODO: theme any user interface that refers to the comms data type to use
39 the system wide configured name.
40 * TODO: groups should have free tagging keywords that specify the interests
41 of their groups
42 */
43
44 /*****************************/
45 /* HOOK_* AND CORE FUNCTIONS */
46 /*****************************/
47
48 function comms_init() {
49 // views_menu is executed
50 if (module_exists('views')) {
51 include_once('./'. drupal_get_path('module', 'comms') .'/comms_views.inc');
52 }
53 }
54
55
56 function comms_node_info() {
57 return array(
58 'comms' => array(
59 'name' => t('Comms'),
60 'module' => 'comms',
61 'description' => t("Create communications data."),
62 )
63 );
64 }
65
66 function comms_perm() {
67 return array(
68 "add comms data",
69 "edit comms data",
70 "edit own comms data",
71 "vote comms data",
72 "has operator view",
73 "has admin view");
74 }
75
76 //we can automatically add the users points to the node vote on submit here
77 //we can automatically dispatch here as well if the user has enough points
78 function comms_insert($node) {
79 if (variable_get('comms_debuglevel', 0) > 0) {
80 drupal_set_message('comms_insert()');
81 }
82
83 if (! ($result = db_query("INSERT INTO {comms_additions} (nid, sms_message) VALUES (%d, '%s')",
84 $node->nid, $node->sms_message))) {
85 watchdog('comms', t('Could not insert the sms message, source, or tmid into db for node->nid: @nid', array('@nid' => $node->nid)));
86 }
87
88 $vote->value = userpoints_get_current_points($node->uid);
89 //at this point there are no groups associated with the node
90 //so we can't dispatch the node yet
91
92 //if the user has 0 points there is no sence in casting a vote
93 if ($vote->value != 0) {
94 $vote->value_type = 'points';
95 $vote->tag = 'vote';
96 $result = votingapi_set_vote('comms', $node->nid, $vote, $node->uid);
97 }
98
99 }
100
101 //we need to update the sms message if it is set
102 function comms_update($node) {
103 if (variable_get('comms_debuglevel', 0) > 0) {
104 drupal_set_message('comms_update()');
105 }
106
107 //check to see if a row for this node has been added
108 $query = 'SELECT * from {comms_additions} WHERE nid=%d';
109 if (! ($result = db_query_range($query, $node->nid, 0, 1))) {
110 //Note that for mysql this will return a numeric value, pgsql a string
111 watchdog("comms_group", t("There was a problem selecting from comms_additions. Error: %db_error",
112 array('%db_error' => db_error())));
113 drupal_set_message(t("There is a database problem. Your sms message was not set for this data. Have one of the admins check the logs."));
114 return;
115 }
116
117 if (db_num_rows($result) < 1) {
118 comms_insert($node);
119 }
120 else {
121
122 //update the sms message
123 if (! db_query("UPDATE {comms_additions} set sms_message='%s' WHERE nid=%d",
124 $node->sms_message, $node->nid)) {
125 //Note that for mysql this will return a numeric value, pgsql a string
126 watchdog("comms", t("There was a problem updating the comms_additions table with nid=@nid. Error: %db_error",
127 array('@nid' => $node->nid, '%db_error' => db_error())));
128 }//if
129 }//else
130 }
131
132 //this does not delete votes associated with nodes, because they really belong
133 //to the users
134 function comms_delete($node) {
135 if (variable_get('comms_debuglevel', 0) > 0) {
136 drupal_set_message("comms_delete()");
137 }
138
139 if (! ($result = db_query('DELETE from {comms_additions} WHERE nid=%d', $node->nid ) ) ) {
140 //Note that for mysql this will return a numeric value, pgsql a string
141 watchdog("comms_group", t("There was a problem deleting a row from comms_additions with nid:@nid. Error: %db_error",
142 array('@nid' => $node->nid, '%db_error' => db_error())));
143 drupal_set_message(t("There is a database problem. Have one of the admins check the logs."));
144 return;
145 }
146
147 }
148
149 function comms_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
150 global $user;
151 if (variable_get('comms_debuglevel', 0) > 0) {
152 drupal_set_message("comms_nodeapi()");
153 }
154
155 if ($node->type == 'group') {
156 drupal_add_css(drupal_get_path('module', 'comms') .'/comms_group.css', 'module', 'all', TRUE);
157 }
158 else if ($node->type == 'comms') {
159 drupal_add_css(drupal_get_path('module', 'comms') .'/comms.css', 'module', 'all', TRUE);
160 }
161
162 //lets handle the validation for group nodes to make sure that all
163 //that twiiter shit is valid
164 if ($node->type == 'group' && $op == 'validate') {
165 comms_group_form_validate($node);
166 return;
167 }
168
169 //the associated twitter data validated and now we insert it into the db
170 if ($node->type == 'group' && $op == 'insert') {
171 comms_group_form_insert($node);
172 return;
173 }
174
175 //the associated twitter data validated and now we insert it into the db
176 if ($node->type == 'group' && $op == 'update') {
177 comms_group_form_update($node);
178 return;
179 }
180
181 //the associated twitter data validated and now we insert it into the db
182 if ($node->type == 'group' && $op == 'view') {
183 comms_group_view($node);
184 return;
185 }
186
187 //the associated twitter data validated and now we insert it into the db
188 if ($node->type == 'group' && $op == 'delete') {
189 comms_group_delete($node);
190 return;
191 }
192
193 }
194
195 //TODO: as far as I can tell this is the best place to add specific dispatching scenarios
196 //- when a node is added and a users points is already >= dispatchlevel
197 //- when a node has already been dispatched and new groups are added to the node (this is the
198 //same as a group being added to the node when vote is >= dispatchlevel)
199 function comms_load($node) {
200 if (variable_get('comms_debuglevel', 0) > 0) {
201 drupal_set_message('comms_load()');
202 }
203
204 $additions = db_fetch_object(
205 db_query('SELECT `sms_message` FROM {comms_additions} WHERE `nid` = %d', $node->nid));
206
207 return $additions;
208 }
209
210 function comms_help($section = NULL) {
211 switch ($section) {
212 case 'admin/help#comms':
213 $output = '<p>'. t('The comms module can be used to help organize data for a comunications team. Incoming data can be associated with different groups which members can subscribe to.') .'</p>';
214
215 $output = '<p>'. t('This module was developed by the !hbteam<p>', array(
216 '!hbteam' => l('hackbloc team', 'http://hackbloc.org') ));
217 return $output;
218 break;
219 }
220 }
221
222 //creates a block of all comms nodes
223 function comms_block($op = 'list', $delta = 0, $edit = array()) {
224 switch ($op) {
225 case 'list' :
226 $blocks[0]['info'] = t("Comms");
227 return $blocks;
228
229 case 'configure':
230
231 if ($delta == 0) {
232 $form['comms_block_count'] = array(
233 '#type' => 'textfield',
234 '#title' => 'Count',
235 '#size' => 4,
236 '#description' => 'Number of nodes to show, 0 will show all',
237 '#default_value' => variable_get('comms_block_count', '0'),
238 );
239 }
240 return $form;
241
242 case 'save':
243 if ($delta == 0) {
244 // Have Drupal save the string to the database.
245 variable_set('comms_block_count', $edit['comms_block_count']);
246 }
247 return;
248
249 case 'view': default:
250 $block['subject'] = t('Comms');
251 // The content of the block is typically generated by calling a custom
252 // function.
253 $block['content'] = comms_block_contents();
254 return $block;
255 }
256 }
257
258 //this supplies the contents of the comms block.
259 //Namely all of the comms nodes
260 function comms_block_contents() {
261 //2008-08-26, evoltech: this query makes sure that we do not pull
262 //anything that has already been dispatched, is not enabled, or is
263 //not a comms node
264 //2008-10-21, evoltech: verified that this is valid pgsql/mysql sql
265 $count = variable_get('comms_block_count', 0);
266 $sql = "SELECT * FROM {node} AS n WHERE (n.type = 'comms') AND (n.status = 1) AND (n.nid NOT IN (SELECT nid from {comms_group_dispatch})) ORDER BY nid DESC";
267 if ($count > 0) {
268 $result = db_query_range($sql, 0, $count);
269 }
270 else {
271 $result = db_query($sql);
272 }
273
274 while ($node = db_fetch_object($result)) {
275
276 $node->sms_message = comms_load($node);
277 $node = node_prepare($node);
278 $node = comms_view($node);
279 $build .= node_view($node);
280
281 }
282 return $build;
283 }
284
285 //responsible for overriding different forms in the
286 //drupal system
287 function comms_form_alter($form_id, &$form) {
288 if (variable_get('comms_debuglevel', 0) > 0) {
289 drupal_set_message("comms_form_alter()");
290 }
291
292 switch ($form_id) {
293 case 'group_node_form':
294 comms_group_form_alter($form);
295 break;
296 default:
297 }//switch
298
299 }//hook_form_alter
300
301 //responsible for responding to different submits on the site
302 function comms_submit($form_id, &$form = NULL) {
303 if (variable_get('comms_debuglevel', 0) > 0) {
304 drupal_set_message("comms_submit()");
305 }
306 }
307
308 function comms_form(&$node) {
309 if (variable_get('comms_debuglevel', 0) > 0) {
310 drupal_set_message("comms_form()");
311 }
312
313 $type = node_get_types('type', $node);
314
315 // We need to define form elements for the node's title and body.
316 $form['title'] = array(
317 '#type' => 'textfield',
318 '#title' => check_plain($type->title_label),
319 '#required' => TRUE,
320 '#default_value' => $node->title,
321 '#weight' => -5
322 );
323
324 $form['sms_message'] = array(
325 '#type' => 'textfield',
326 '#maxlength' => 140,
327 '#title' => t('SMS Message'),
328 '#default_value' => check_plain($node->sms_message),
329 '#required' => FALSE
330 );
331
332 // We want the body and filter elements to be adjacent. We could try doing
333 // this by setting their weights, but another module might add elements to the
334 // form with the same weights and end up between ours. By putting them into a
335 // sub-array together, we're able force them to be rendered together.
336 $form['body_filter']['body'] = array(
337 '#type' => 'textarea',
338 '#title' => check_plain($type->body_label),
339 '#default_value' => $node->body,
340 '#required' => FALSE
341 );
342
343 return $form;
344 }
345
346 function comms_access($op, $node) {
347 global $user;
348
349 if ($op == 'create') {
350 // Only users with permission to do so may create this node type.
351 return user_access('add comms data');
352 }
353
354 // Users who create a node may edit or delete it later, assuming they have the
355 // necessary permissions.
356 if ($op == 'update' || $op == 'delete') {
357 if (user_access('edit own comms data') && ($user->uid == $node->uid)) {
358 return TRUE;
359 }
360 else {
361 return user_access('edit comms data');
362 }//else
363 }//if
364
365 }//comms_access
366
367 /* this gives us a list of all comms nodes and their nids, shamefully stolen from og */
368 //2008-08-26, evoltech: implemented cacheing for this query ala:
369 //http://www.lullabot.com/articles/a_beginners_guide_to_caching_data
370 function comms_all_nodes_options($nid_omit=NULL, $reset=NULL) {
371 //2008-08-26, evoltech: this query makes sure that we do not pull
372 //anything that has already been dispatched, is not enabled, or is
373 //not a comms node
374 //2008-10-21, evoltech: verified this is valid pgsql/mysql sql
375 $sql = "SELECT n.title, n.nid FROM {node} n WHERE (n.type = 'comms') AND (n.status = 1) AND (n.nid NOT IN (SELECT nid from {comms_group_dispatch}))";
376 if (is_numeric($nid_omit)) {
377 $sql .= " AND (n.nid != $nid_omit)";
378 }
379 $sql .= " ORDER BY n.title ASC";
380 $result = db_query($sql);
381 while ($row = db_fetch_object($result)) {
382 $options[$row->nid] = $row->title;
383 }
384 return $options ? $options : array();
385 }
386
387 /* hook_user() : http://api.drupal.org/api/function/hook_user/5
388 * we use this to make sure all users have at least one point when
389 * they are created
390 */
391 function comms_user($op, $edit, $account, $category = NULL) {
392 if (variable_get('comms_debuglevel', 0) > 0) {
393 drupal_set_message("comms_user()");
394 }
395
396 switch ($op) {
397 //"insert": The user account is being added. The module should save
398 //its custom additions to the user object into the database and set
399 //the saved fields to NULL in $edit.
400 case 'insert':
401 $param = array(
402 'points' => 1,
403 'uid' => $account->uid
404 );
405 userpoints_userpointsapi($param);
406 break;
407 }//switch
408
409 }
410
411 /*****************************/
412 /* COMS DISPLAY FUNCTIONS */
413 /*****************************/
414
415 //this is where we should implement the following requirement: http://rnc08coms.hackbloc.org/node/45
416 //TODO: how do you use the theming functions here?
417 //TODO: also make sure that the use has permission to see the vote form
418 function comms_view($node, $teaser = FALSE, $page = FALSE) {
419 if (variable_get('comms_debuglevel', 0) > 0) {
420 drupal_set_message("comms_view()");
421 }
422
423 $node = node_prepare($node, $teaser);
424
425 $node->content['comms_sms_message'] = array(
426 '#value' => theme('comms_sms_message',
427 comms_get_sms_message($node->nid))
428 );
429
430 //include a node delete form button
431 $node->content['comms_delete'] = array(
432 '#weight' => 3,
433 '#value' => theme('comms_delete',
434 l('Delete', "node/$node->nid/delete", NULL, drupal_get_destination()))
435 );
436
437 //function that will generate the themed section that holds
438 //the Rating, Groups, Dispatch section of a comms node
439 //this shit should not even get displayed if the node has already been
440 //dispatched
441 $node->content['rgd_section'] = array(
442 '#value' => create_rgd_section($node)
443 );
444
445 return $node;
446
447 }
448
449 /*****************************/
450 /* COMS ADMIN FORM FUNCTIONS */
451 /*****************************/
452
453 function comms_admin_twitterAPI() {
454 $default_collection_method = '';
455 if (variable_get('comms_searchalltweets', 0)) {
456 $default_collection_method = 0;
457 }
458 else if (variable_get('comms_addfromgetfollowers', 0)) {
459 $default_collection_method = 1;
460 }
461
462 $form['comms_collection_method'] = array(
463 '#type' => 'radios',
464 '#title' => t('Comms collection method'),
465 '#options' => array(t('Search All Tweets'), t('Add From getFollowers()')),
466 '#default_value' => $default_collection_method,
467 '#description' => t("There are two main collection methods for twitter content. The first, <strong>search all tweets</strong>, uses the").
468 l(t("twitter search API"), 'http://search.twitter.com/api') .
469 t(" to collect data from followers of groups with assigned twitter accounts. The second is to collect posts from the status returned as we poll for new followers for each group. This may be usefull if the twitter search index is back logged."),
470 );
471
472 $form['comms_twitterAPI_path'] = array(
473 '#type' => 'textfield',
474 '#title' => t('Twitter API Path'),
475 '#default_value' => variable_get('comms_twitterAPI_path',
476 drupal_get_path('module', 'comms') .'/Arc90_Service_Twitter/lib/Arc90/Service'),
477 '#description' => t("The path to the Arc90 Twitter API library. For example: 'modules/comms/Arc90_Service_Twitter/lib/Arc90/Service'"),
478 '#after_build' => array('_audio_twitterAPI_settings_check_path'),
479 );
480
481 $form['audio_getid3_version'] = array(
482 '#type' => 'item',
483 '#title' => t('Include Check'),
484 );
485 if (comms_twitterAPI_isfound() &&
486 preg_match('/Arc90_Service_Twitter Object/',
487 print_r(_comms_twitterAPI_load(), 1))) {
488 $form['audio_getid3_version']['#value'] = 'Included';
489 $form['audio_getid3_version']['#description'] =
490 t("If you're seeing this it indicates that the Twitter API library was found.");
491 }//if
492 else {
493 $form['audio_getid3_version']['#value'] = 'NOT Included';
494 $form['audio_getid3_version']['#description'] =
495 t("The Twitter API library was not included.");
496 }
497
498 return system_settings_form($form);
499 }
500
501 function comms_admin() {
502
503
504 $form['comms_debuglevel'] = array(
505 '#type' => 'textfield',
506 '#title' => t('Comms module debug level'),
507 '#default_value' => variable_get('comms_debuglevel', 0),
508 '#size' => 2,
509 '#maxlength' => 2,
510 '#description' => t("Comms Debug Level")
511 );
512
513 $form['comms_dispatchlevel'] = array(
514 '#type' => 'textfield',
515 '#title' => t('Rating to dispatch info at'),
516 '#default_value' => variable_get('comms_dispatchlevel', 5),
517 '#size' => 2,
518 '#maxlength' => 2,
519 '#description' => t("The rating at which to dispatch a piece of info at")
520 );
521
522 $form['comms_actionname'] = array(
523 '#type' => 'textfield',
524 '#title' => t('Comms action name'),
525 '#default_value' => variable_get('comms_actionname', "comms"),
526 '#size' => 25,
527 '#maxlength' => 25,
528 '#description' => t("The name of the action")
529 );
530
531 return system_settings_form($form);
532 }
533
534 //this should be used to validate anything that can be changed in the
535 //comms_admin form. Drupal checks all input, but it is a good idea to
536 //provide additional checks, cause, ya know hackers and stuff
537 function comms_admin_validate($node, &$form) {
538 $dispatchlevel = $form['comms_dispatchlevel'];
539 if (!is_numeric($dispatchlevel)) {
540 form_set_error('comms_dispatchlevel', t('You must select a number for the dispatch level.'));
541 }
542 else if ($dispatchlevel < 1) {
543 form_set_error('comms_dispatchlevel', t('Minimum dispatch level must be positive.'));
544 }
545 else if ($dispatchlevel > 10) {
546 form_set_error('comms_dispatchlevel', t('Maximum dispatch level must be less then or equal to 10.'));
547 }
548
549 $actionname = $form['comms_actionname'];
550 if (!is_string($actionname)) {
551 form_set_error('comms_actionname', t('The action name must be a string.'));
552 }
553 else if (strlen($actionname) < 4) {
554 form_set_error('comms_actionname', t('The action name must be between 4 and 25 characters.'));
555 }
556 else if (strlen($actionname) > 25) {
557 form_set_error('comms_actionname', t('The action name must be between 4 and 25 characters.'));
558
559 }
560
561 $debuglevel = $form['comms_debuglevel'];
562 if (!is_numeric($debuglevel)) {
563 form_set_error('comms_debuglevel', t('You must select a number for the debug level.'));
564 }
565 else if ($debuglevel < 0) {
566 form_set_error('comms_debuglevel', t('Minimum debug level must at least zero.'));
567 }
568 else if ($debuglevel > 10) {
569 form_set_error('comms_debuglevel', t('Maximum debug level must be less then or equal to 10.'));
570 }
571
572 }
573
574 function comms_admin_submit($form_id, $node) {
575 if ($node['comms_collection_method']) {
576 variable_set('comms_searchalltweets', 0);
577 variable_set('comms_addfromgetfollowers', 1);
578 }
579 else {
580 variable_set('comms_searchalltweets', 1);
581 variable_set('comms_addfromgetfollowers', 0);
582 }
583 }//comms_admin_submit
584
585
586 //hook_forms
587 //this will act as a dispatcher for all comms_vote forms when they are displayed
588 //as a list. Niether of the forms validate or submit functions are getting called???
589 function comms_forms() {
590 $args = func_get_args();
591
592 if (variable_get('comms_debuglevel', 0) > 0) {
593 drupal_set_message("comms_forms()");
594 }
595
596 //handle the voteing forms
597 if (strpos($args[0][0], 'comms_vote') !== FALSE) {
598 if ($args[0][0] == 'comms_vote_'. $args[0][1] .'_'. $args[0][2]) {
599 $forms[$args[0][0]] = array('callback' => 'comms_vote');
600 return $forms;
601 }
602 }
603 //handle the dispatching forms
604 else if (strpos($args[0][0], 'comms_dispatch') !== FALSE) {
605 if ($args[0][0] == 'comms_dispatch_'. $args[0][1] .'_'. $args[0][2]) {
606 $forms[$args[0][0]] = array('callback' => 'comms_dispatch');
607 return $forms;
608 }
609 }
610 //handle the groups forms
611 else if (strpos($args[0][0], 'comms_groups') !== FALSE) {
612 if ($args[0][0] == 'comms_groups_'. $args[0][1] .'_'. $args[0][2]) {
613 $forms[$args[0][0]] = array('callback' => 'comms_groups');
614 return $forms;
615 }
616 }
617 //handle the deduplication forms
618 else if (strpos($args[0][0], 'comms_dedup') !== FALSE) {
619 if ($args[0][0] == 'comms_dedup_'. $args[0][1] .'_'. $args[0][2]) {
620 $forms[$args[0][0]] = array('callback' => 'comms_dedup');
621 return $forms;
622 }
623 }
624 //handle the priority forms
625 else if (strpos($args[0][0], 'comms_priority') !== FALSE) {
626 if ($args[0][0] == 'comms_priority_'. $args[0][1] .'_'. $args[0][2]) {
627 $forms[$args[0][0]] = array('callback' => 'comms_priority');
628 return $forms;
629 }
630 }
631 }
632
633 /********************************/
634 /* COMMS PRIORITY FORM FUNCTIONS */
635 /********************************/
636 function comms_priority($content_type, $content_id) {
637 if (variable_get('comms_debuglevel', 0) > 0) {
638 drupal_set_message("comms_priority()");
639 }
640
641 if (user_access('edit comms data')) {
642 $form['#base'] = 'comms_priority_'. $content_type .'_'. $content_id;
643 $form['#theme'] = 'comms_priority';
644
645 $default_value = array_keys(taxonomy_node_get_terms($content_id));
646 $form['comms_priority'] = taxonomy_form(1, $default_value[0]);
647
648 $form['comms_priority_submit'] = array(
649 '#id' => 'comms_priority_submit_'. $content_id,
650 '#type' => 'submit',
651 '#value' => 'Update Priority'
652 );
653
654 //this is some ninja shit here. For an explanation of why we need to
655 //use #submit see: http://tinyurl.com/472gcp
656 $form['#submit'] = array(
657 'comms_priority_submit' => array());
658
659 $form['#validate'] = array(
660 'comms_priority_validate' => array());
661 }//if
662 return $form;
663 }
664
665 function comms_priority_validate($form_id, $form_values=NULL, $form=NULL) {
666 //make sure we have form values
667 if (is_null($form_values)) {
668 form_set_error('comms_priority_submit', 'You have sumbitted invalid data');
669 }
670
671 if (!preg_match('/(\d+)$/', $form_id)) {
672 form_set_error('comms_priority_submit', 'You have sumbitted invalid data');
673 }
674 }
675
676 function comms_priority_submit($form_id, &$form) {
677 if (preg_match('/(\d+)$/', $form_id, $matches)) {
678 taxonomy_node_save($matches[1], array($form['comms_priority']));
679 }
680 }
681
682 /*****************************/
683 /* COMS VOTE FORM FUNCTIONS */
684 /*****************************/
685
686 //This will contain all the form data for casting a vote on a piece of
687 //information. These have to be of type 'submit' instead of 'button' so that
688 //the comms_vote_submit gets called when they are pressed
689 //drupal 5.x form api docs: http://api.drupal.org/api/file/developer/topics/forms_api_reference.html/5
690 //TODO: we could do some fancy stuff here like only displaying one of the
691 //buttons if a user already voted
692 function comms_vote($content_type, $content_id) {
693 global $user;
694 if (variable_get('comms_debuglevel', 0) > 0) {
695 drupal_set_message("comms_vote()");
696 }
697
698 static $js_added = FALSE;
699 if (!$js_added) {
700 drupal_add_js(drupal_get_path('module', 'comms') .'/js/comms.js');
701 $js_added = TRUE;
702 }//if
703
704 //get a list of all votes indexed by user that cast them
705 //for some reason $content_type here is always $node ???
706 $votes = votingapi_get_content_votes('comms', $content_id);
707
708 $form['#theme'] = 'comms_vote';
709
710 $form['content_type'] = array(
711 '#type' => 'hidden',
712 '#value' => $content_type,
713 '#id' => $content_id ? 'edit-content-type-'. $content_id : NULL,
714 '#prefix' => '<div id="comms_vote" class="comms-form-item">',
715 );
716
717 //2008-08-29, evoltech: it was decided that users should vote multiple times
718 //we do not list include the form for users who have already voted
719 //or who are not permitted to vote
720 if (
721 user_access('vote comms data')
722 ) {
723 $form['comms_vote_select'] = array(
724 '#type' => 'select',
725 '#options' => array(
726 '1' => '/'. drupal_get_path('module', 'comms') .'/plus1.jpg',
727 '-1' => '/'. drupal_get_path('module', 'comms') .'/minus1.jpg',
728 ),
729 '#id' => 'edit-comms-vote-'. $content_id,
730 );
731
732 $form['auto_submit_path'] = array(
733 '#type' => 'hidden',
734 '#value' => url('comms/vote/comms/'. $content_id),
735 '#id' => 'edit-auto-submit-path-'. $content_id,
736 '#attributes' => array('class' => 'comms-vote-path'),
737 );
738 }//if
739
740 $form['content_id'] = array(
741 '#type' => 'hidden',
742 '#value' => $content_id,
743 '#id' => $content_id ? 'edit-content-id-'. $content_id : NULL,
744 );
745
746 $result = votingapi_get_voting_results('comms', $content_id);
747 $vote_ct = $result[2]->value;
748 $point_ct = $result[1]->value;
749
750 if (is_array($votes) && count($votes) > 0) {
751 $total_vote = "<label>". t("Rating")
752 .":</label> <div class=\"value\">$point_ct</div>";
753 }
754 else {
755 $total_vote = "<label>". t("Rating")
756 .":</label> <div class=\"value\">0</div>";
757 }
758
759 //the #prefix here should really be done in a theming form,
760 //but I can't seem to get it working
761 $form['destination'] = array(
762 '#type' => 'hidden',
763 '#value' => $_GET['q'],
764 '#id' => isset($content_id) ? 'edit-destination-'. $content_id : NULL,
765 '#prefix' => '<div class="comms-vote-summary" id="comms-vote-summary-'. $content_id .'">'.
766 $total_vote .'</div>',
767 '#suffix' => '</div>'
768 );
769
770 return $form;
771 }
772
773 //This function will be called whenever one of the vote buttons from the
774 //comms_vote form are pressed. A vote is placed by a user of the system
775 //most likely an operator, it should not be confused with the initial
776 //vote value of a user contributing a piece of information, which can
777 //be added to another node if the two pieces are concatenated
778 function comms_vote_validate($node, &$form) {
779 //Votes are 1 or -1, but we recieve it from the form as a string, so we have
780 //to type cast it first
781 if (variable_get('comms_debuglevel', 0) > 0) {
782 drupal_set_message("comms_vote_validate()");
783 }
784
785 $vote = (int)$form['op'];
786 if ($vote != -1 && $vote != 1) {
787 form_set_error('comms_vote', t('There was a illegal vote cast. Votes are +1 or -1.'));
788 watchdog('comms_vote', t("There was a illegal vote cast. Votes are +1 or -1."));
789 }
790 }
791
792 //Not sure that this can be done like this
793 function comms_comms_vote($form) {
794 if (variable_get('comms_debuglevel', 0) > 0) {
795 drupal_set_message("comms_comms_vote()");
796 }
797 $output = '<div class="comms_vote_form">';
798 $output .= drupal_render($form);
799 $output .= '</div>';
800 return $output;
801 }
802
803 //this will return some xml for the client side js
804 function comms_vote_execute($type, $cid, $value, $tag = 'vote', $ignore_user=FALSE, $rval='xml') {
805 global $user;
806
807 $user_message = '';
808 $dont_query = 0;
809 $dont_vote = 0;
810
811 //make sure this is a comms node
812 $node = node_load($cid);
813 $type = $node->type;
814 if ($type != "comms") {
815 watchdog("comms_vote", t("attempting to execute comms vote for a non comms node type"));
816 $user_message .= t("You tried to vote for a invalid node type.") ."<br />";
817 $dont_query = 1;
818 }
819
820 //only logged in users can vote
821 if (!isset($uid)) {
822 if ($user->uid) {
823 $uid = $user->uid;
824 }
825 else {
826 watchdog("comms_vote", t("attempting to cast a vote for anonomous user"));
827 $user_message .= t('Only !userlink users can vote',
828 array('!userlink' => l('logged in', 'user')));
829 $dont_vote = 1;
830 }
831 }
832
833 if ($ignore_user)
834 $uid = NULL;
835
836 //if $value is passed in as a string we need to convert it
837 if (is_string($value)) {
838 $value = (int)$value;
839 }
840
841 if (!is_numeric($cid)) {
842 watchdog("comms_vote", t("attempting to cast a vote for a non-numeric cid"));
843 $user_message .= t('You tried to vote on an invalid node') .'.<br />';
844 $dont_query = 1;
845 }
846
847 if ($value != 1 && $value != -1 && !$ignore_user) {
848 watchdog("comms_vote", t("attempting to cast a vote for an invalid value: %value", array('%value' => $value)));
849 $user_message .= t('You tried to cast an invalid vote') .'.<br />';
850 $dont_vote = 1;
851 }
852
853 if (!$dont_vote && !$dont_query) {
854 $ballot->value = $value;
855 $ballot->value_type = 'points';
856 $ballot->tag = 'vote';
857
858 //2008-08-31, evoltech: we are now saying that multiple votes should be able
859 //to be cast. We are recieving the vote object cast here not the vote result
860 //we want to make sure that if this vote will put us over the dispatch level
861 //then we need to not increase the vote unless the dispatch succeeds
862 $vote = votingapi_get_voting_results($type, $cid);
863 if ($value + $vote[1]->value >= variable_get('comms_dispatchlevel', 5)) {
864 $message = comms_group_dispatch_validate($node);
865 if ($message != 1) {
866 $user_message .= $message;
867 }
868 else {
869 $message = comms_group_dispatch($node);
870 if ($message != 1) {
871 $user_message .= $message;
872 }
873 else {
874 $user_message .= t('Dispatched!') .'<br />';
875 $vote_cast = votingapi_add_vote($type, $cid, $value, 'points', 'vote', $uid);
876 $vote = votingapi_recalculate_results($type, $cid);
877 }//else
878 }//else
879 }
880 else {
881 $vote_cast = votingapi_add_vote($type, $cid, $value, 'points', 'vote', $uid);
882 $vote = votingapi_recalculate_results($type, $cid);
883 }
884
885 }//if
886 else {
887 watchdog("comms_vote", t("we could not vote"));
888 }
889
890 if (!$dont_query) {
891 $result = votingapi_get_voting_results($type, $cid);
892 $votes = votingapi_get_content_votes($type, $cid);
893
894 $sum = $result[1]->value;
895 $count = $result[2]->value;
896 }
897
898 if (count($result)) {
899 foreach ($result as $data) {
900 if ($data->tag == $tag) {
901 $output .= '<'. $data->function .'>'. $data->value .'</'. $data->function .'>';
902 $summary[$data->tag][$data->function] = $data->value;
903 }//if
904 }//foreach
905 }//if
906
907 $output = '';
908 $output .= '<?xml version="1.0" encoding="UTF-8"?>';
909 $output .= '<xml>';
910 if (!$dont_query) {
911 $output .= '<result><summary>';
912 $output .= '<count>'. $count . '</count>';
913
914 $output .= '<sum>'. $sum .'</sum>';
915
916 $output .= '<voters>';
917 foreach (array_keys($votes) as $voter) {
918 $output .= '<voter><path>'. url("user/$voter") .'</path>';
919 $output .= '<username>'. uid_to_username($voter) .
920 '('.
921 userpoints_get_current_points($voter) .
922 ')'.
923 '</username></voter>';
924 }
925 $output .= '</voters>';
926
927 $output .= '</summary>';
928 $output .= '</result>';
929 }//!$dont_query
930
931 //if (!$dont_vote) {
932 $output .= '<vote>';
933 $output .= '<value>'. $value .'</value>';
934 $output .= '<type>'. $type .'</type>';
935 $output .= '<id>'. $cid .'</id>';
936 $output .= '</vote>';
937 //}
938
939 if (variable_get('comms_debuglevel', 0) > 0) {
940 $output .= '<debug>'. print_r($votes, 1) .'</debug>';
941 }
942
943 $output .= '<debug_dont_vote>'. $dont_vote .'</debug_dont_vote>';
944 $output .= '<debug_dont_query>'. $dont_query .'</debug_dont_query>';
945 $output .= '<user_message>'. $user_message .'</user_message>';
946 $output .= '<params>'. 'rval: '. $rval .' user: '. $ignore_user .'</params>';
947 $output .= '</xml>';
948 if ($rval == 'xml') {
949 drupal_set_header("Content-Type: text/xml");
950 exit($output);
951 }
952 else {
953 return ( $user_message ." ". $value ." ". t("user") .": ". $uid );
954 }
955 }
956
957 /***************************************/
958 /* COMS DE-DUPLICATE FORM FUNCTIONS */
959 /***************************************/
960
961 // This contains all the logic for creating a form for users
962 // to report a duplicate node, the node is removed and then
963 // the points for that node are given to the node it is a duplicate of
964
965 function comms_dedup($content_type, $content_id) {
966 if (variable_get('comms_debuglevel', 0) > 0) {
967 drupal_set_message('comms_dedup()');
968 }
969
970
971 //we do not list include the form for those who are not
972 //able to edit comms data
973 if (user_access('edit comms data')) {
974 $form['#base'] = 'comms_dedup_'. $content_type .'_'. $content_id;
975 $form['#theme'] = 'comms_dedup';
976
977
978 $form['comms_dedup_duplicate_nodeid'] = array(
979 '#id' => 'comms_dedup_nodeid_'. $content_id,
980 '#type' => 'hidden',
981 '#value' => $content_id
982 );
983
984 $form['comms_dedup_good_nodeid'] = array(
985 '#id' => 'comms_dedup_good_nodeid_'. $content_id,
986 '#type' => 'select',
987 '#title' => t('This is a duplicate of:'),
988 '#multiple' => FALSE,
989 '#attributes' => array('class' => 'comms_dedup'),
990 '#default_value' => t('Select duplicate node...'),
991 '#options' => comms_all_nodes_options($content_id)
992 );
993
994 $form['comms_dedup_submit'] = array(
995 '#id' => 'comms_dedup_submit_'. $content_id,
996 '#type' => 'submit',
997 '#value' => t('Deduplicate node')
998 );
999
1000 //this is some ninja shit here. For an explanation of why we need to
1001 //use #submit see: http://tinyurl.com/472gcp
1002 $form['#submit'] = array(
1003 'comms_dedup_submit' => array());
1004
1005 $form['#validate'] = array(
1006 'comms_dedup_validate' => array());
1007 } //if
1008 return $form;
1009 } // end deduping form functions
1010
1011 function comms_dedup_validate($form_id, $form_values=NULL, $form=NULL) {
1012
1013
1014 //make sure we have form values
1015 if (is_null($form_values)) {
1016 form_set_error('comms_dedup_submit',
1017 t('You have sumbitted invalid data for deduplication form_values'));
1018 return;
1019 }
1020
1021 //make sure that the values are numeric and exist
1022 if (!isset($form_values['comms_dedup_duplicate_nodeid'])
1023 || !isset($form_values['comms_dedup_good_nodeid'])
1024 || !is_numeric($form_values['comms_dedup_duplicate_nodeid'])
1025 || !is_numeric($form_values['comms_dedup_good_nodeid']) ) {
1026 form_set_error('comms_dedup_submit',
1027 t('You have sumbitted invalid data for deduplication'));
1028 return;
1029 }
1030
1031 //at least they are real nodes so lets load the fuckers
1032 $dupe_node = node_load($form_values['comms_dedup_duplicate_nodeid']);
1033 $good_node = node_load($form_values['comms_dedup_good_nodeid']);
1034 if ($dupe_node->type != 'comms' || $good_node->type != 'comms') {
1035 form_set_error('comms_dedup_submit',
1036 t('You have sumbitted invalid data for deduplication. One of these things is not like the other.'));
1037 return;
1038 }
1039
1040 //lets also check that the node we hope to be jumping onto has a sms field
1041 //and an associated group if the combined vote will be > comms_dispatchlevel
1042 $dupe_node_rate = votingapi_get_voting_results('comms', $dupe_node->nid);
1043 $dupe_node_rate = $dupe_node_rate[1]->value;
1044
1045 $good_node_rate = votingapi_get_voting_results('comms', $good_node->nid);
1046 $good_node_rate = $good_node_rate[1]->value;
1047 if ($good_node_rate + $dupe_node_rate >=
1048 variable_get('comms_dispatchlevel', 0)) {
1049
1050 if (is_null($good_node->sms_message) || $good_node->sms_message == '') {
1051 form_set_error('comms_dedup_submit',
1052 t("This operation will cause the dispatching of")
1053 .'"<strong>'.
1054 $good_node->title
1055 .'</strong>"'.
1056 t("but it does not have a sms message to dispatch."));
1057 }
1058
1059 $asc_groups = module_invoke('og', 'get_node_groups', $good_node);
1060 if (!is_array($asc_groups) || count($asc_groups) == 0) {
1061 form_set_error('comms_dedup_submit',
1062 t("This operation will cause the dispatching of")
1063 ." \"<strong>".
1064 $good_node->title
1065 ."</strong>\"".
1066 t("but it does not have any groups to dispatch to."));
1067 }
1068 }//if
1069
1070 // if we hit here then we now definitely have a comms node that is good to go.
1071 return;
1072 }
1073
1074 function comms_dedup_submit($form_id, &$form) {
1075 $dupe_node = node_load($form['comms_dedup_duplicate_nodeid']);
1076 $good_node = node_load($form['comms_dedup_good_nodeid']);
1077
1078 //this next function returns an array matching votingapi_vote records for the nid we specify
1079 $dnode_votes = votingapi_get_content_votes('comms', $dupe_node->nid);
1080 $gnode_votes = votingapi_get_content_votes('comms', $dupe_node->nid);
1081 foreach ($dnode_votes as $dvuid) {
1082 $duid = $dvuid[0]->uid;
1083 $dvalue = $dvuid[0]->value;
1084
1085 //delete all votes for duplicate content
1086 if (isset($gnode_votes[$duid])) {
1087 votingapi_unset_vote("comms", $gnode_votes[$duid][0]->content_id, $duid);
1088 }
1089
1090 //add the old votes to the new node.
1091 $beep = votingapi_add_vote("comms", $good_node->nid, $dvalue, 'points', 'vote', $duid);
1092 }
1093
1094 // we have to do this to update the votingapi_cache table
1095 votingapi_recalculate_results("comms", $good_node->nid, TRUE);
1096
1097 //if we have enough votes to dispatch we should do it now
1098 //hyper on red jarito!
1099 $rate = votingapi_get_voting_results('comms', $good_node->nid);
1100 $rate = $rate[1]->value;
1101 if ($rate >= variable_get('comms_dispatchlevel', 0)) {
1102 $arg['comms_dispatch_nodeid'] = $good_node->nid;
1103 $message = comms_group_dispatch($good_node);
1104 drupal_set_message(
1105 t("Dispatched") ." \"<strong>".
1106 check_plain($good_node->title) ."</strong>\": ".
1107 $message);
1108 }//if
1109
1110 // now we take care of the groups
1111 $dupe_node_groups = module_invoke('og', 'get_node_groups', $dupe_node);
1112
1113 foreach ($dupe_node_groups as $gid => $v) {
1114 $good_node->og_groups[] = $gid;
1115 }
1116 // and save our changes
1117 og_save_ancestry($good_node);
1118
1119 $dupe_node->status = 0;
1120 node_save($dupe_node);
1121 }
1122
1123 /***************************************/
1124 /* COMS SEARCH FORM FUNCTIONS */
1125 /***************************************/
1126
1127 //then we want to see if we can check the search results and generate the view dynamically
1128 //check $form_values or $_POST['edit']
1129 //TODO: this is a total hack ... there has to be a correct way to do this
1130 function comms_search() {
1131 $return = drupal_get_form('comms_search_page');
1132
1133
1134 if ($_SESSION['comms']['submit'] == 1) {
1135 $timeframe = (isset($_SESSION['comms']['timeframe']) &&
1136 $_SESSION['comms']['timeframe'] != '') ?
1137 $_SESSION['comms']['timeframe'] : 'All';
1138
1139 $rating = (isset($_SESSION['comms']['rating']) &&
1140 $_SESSION['comms']['rating'] != '') ?
1141 $_SESSION['comms']['rating'] : 'All';
1142
1143 $dispatched = 'not';
1144 //we check to see if either they are both set or if they are not set, I know its funky
1145 //maybe there is a better way to do this
1146 if (
1147 (strcmp($_SESSION['comms']['dispatched']['dispatched'], 'dispatched') == 0 &&
1148 strcmp($_SESSION['comms']['dispatched']['notdispatched'], 'notdispatched') == 0) ||
1149
1150 ($_SESSION['comms']['dispatched']['notdispatched'] === 0 &&
1151 $_SESSION['comms']['dispatched']['dispatched'] === 0 )
1152 ) {
1153 $dispatched = 'All';
1154 }
1155 else if (strcmp($_SESSION['comms']['dispatched']['dispatched'], 'dispatched') == 0) {
1156 $dispatched = '1';
1157 }
1158
1159 $categorized = 'not';
1160 //we check to see if either they are both set or if they are not set, I know its funky
1161 //maybe there is a better way to do this
1162 //This is not working correctly
1163 if (
1164 (strcmp($_SESSION['comms']['categorized']['categorized'], 'categorized') == 0 &&