1<?php 2 3/** 4 * SquirrelMail Spam Buttons Plugin 5 * Copyright (c) 2005-2009 Paul Lesniewski <paul@squirrelmail.org>, 6 * Licensed under the GNU GPL. For full terms see the file COPYING. 7 * 8 * @package plugins 9 * @subpackage spam_buttons 10 * 11 */ 12 13 14 15/** 16 * Takes care of spam/ham button click 17 * 18 */ 19function sb_button_action_do($args) 20{ 21 22 include_once(SM_PATH . 'plugins/spam_buttons/functions.php'); 23 24 global $is_spam_shell_command, $is_spam_resend_destination, 25 $is_not_spam_shell_command, $is_not_spam_resend_destination, 26 $is_spam_subject_prefix, $is_not_spam_subject_prefix, 27 $sb_reselect_messages, $sb_delete_after_report, 28 $sb_reselect_messages_allow_override, $username, $data_dir, 29 $sb_delete_after_report_allow_override, 30 $sb_move_after_report_spam, $sb_move_after_report_spam_allow_override, 31 $sb_move_after_report_not_spam, $note, 32 $sb_move_after_report_not_spam_allow_override, 33 $sb_report_spam_by_move_to_folder, 34 $sb_report_not_spam_by_move_to_folder, 35 $sb_copy_after_report_spam_allow_override, $sb_copy_after_report_spam, 36 $sb_copy_after_report_not_spam_allow_override, 37 $sb_copy_after_report_not_spam, $sb_report_spam_by_copy_to_folder, 38 $sb_report_not_spam_by_copy_to_folder, 39 $reported_spam_text, $reported_not_spam_text, 40 $sb_move_to_other_message_after_report, $location, 41 $sb_move_to_other_message_after_report_allow_override, 42 $abort_message_view, $extra_buttons, $is_spam_keep_copy_in_sent, 43 $sb_report_spam_by_custom_function, $is_not_spam_keep_copy_in_sent, 44 $sb_report_not_spam_by_custom_function; 45 46 spam_buttons_init(); 47 48 49 if ($sb_reselect_messages_allow_override) 50 { 51 $sb_reselect_messages = getPref($data_dir, $username, 52 'sb_reselect_messages', $sb_reselect_messages); 53 } 54 if ($sb_delete_after_report_allow_override) 55 { 56 $sb_delete_after_report = getPref($data_dir, $username, 57 'sb_delete_after_report', $sb_delete_after_report); 58 } 59 if ($sb_move_after_report_spam_allow_override) 60 { 61 $sb_move_after_report_spam = getPref($data_dir, $username, 62 'sb_move_after_report_spam', 63 $sb_move_after_report_spam); 64 65 } 66 if ($sb_move_after_report_not_spam_allow_override) 67 { 68 $sb_move_after_report_not_spam = getPref($data_dir, $username, 69 'sb_move_after_report_not_spam', 70 $sb_move_after_report_not_spam); 71 } 72 if ($sb_copy_after_report_spam_allow_override) 73 { 74 $sb_copy_after_report_spam = getPref($data_dir, $username, 75 'sb_copy_after_report_spam', 76 $sb_copy_after_report_spam); 77 } 78 if ($sb_copy_after_report_not_spam_allow_override) 79 { 80 $sb_copy_after_report_not_spam = getPref($data_dir, $username, 81 'sb_copy_after_report_not_spam', 82 $sb_copy_after_report_not_spam); 83 } 84 if ($sb_move_to_other_message_after_report_allow_override) 85 { 86 $sb_move_to_other_message_after_report = getPref($data_dir, $username, 87 'sb_move_to_other_message_after_report', 88 $sb_move_to_other_message_after_report); 89 } 90 91 92//sm_print_r($_GET, $_POST, $_SERVER); 93//sm_print_r($_SESSION); 94//exit; 95 96 97 $passed_ent_id = 0; 98 sqGetGlobalVar('passed_ent_id', $passed_ent_id, SQ_FORM); 99 sqGetGlobalVar('REQUEST_METHOD', $method, SQ_SERVER); 100 101 if (sqGetGlobalVar('location', $location, SQ_POST)) 102 { /* $location = htmlspecialchars($location); */ } 103 else 104 $location = php_self(); 105 106 if (sqGetGlobalVar('passed_id', $passed_id, SQ_FORM)) 107 // fix for Dovecot UIDs can be bigger than normal integers 108 $passed_id = (preg_match('/^[0-9]+$/', $passed_id) ? $passed_id : '0'); 109 110 if (sqGetGlobalVar('msg', $msg, SQ_FORM)) 111 // fix for Dovecot UIDs can be bigger than normal integers 112 if (is_array($msg)) foreach ($msg as $i => $messageID) 113 $msg[$i] = (preg_match('/^[0-9]+$/', $messageID) ? $messageID : '0'); 114 else 115 $msg = (preg_match('/^[0-9]+$/', $msg) ? $msg : '0'); 116 117 118 // determine if the report was done from the message view screen 119 // 120 // the use of get_current_hook_name() means the Compatibility plugin is required 121 // 122 $hook_name = get_current_hook_name($args); 123 $move_to_message_after_report = -1; 124 if ($hook_name == 'read_body_header' || $hook_name == 'template_construct_read_headers.tpl') 125 { 126 $reporting_from_message_view = TRUE; 127 128 // get previous/next message UIDs before we possibly move/delete the current one 129 // 130 if (strtolower($sb_move_to_other_message_after_report) == 'next') 131 $move_to_message_after_report = spam_buttons_findNextMessage($passed_id); 132 else if (strtolower($sb_move_to_other_message_after_report) == 'previous') 133 $move_to_message_after_report = spam_buttons_findPreviousMessage($passed_id); 134 } 135 else 136 { 137 $reporting_from_message_view = FALSE; 138 } 139 140 141 // if in 1.4.x we need to print message 142 // to user after report, do that here 143 // 144 if (!check_sm_version(1, 5, 0) && sqGetGlobalVar('sb_note', $sb_note, SQ_SESSION)) 145 { 146 echo html_tag('div', '<b>' . $sb_note .'</b>', 'center') . "<br />\n"; 147 sqsession_unregister('sb_note'); 148 } 149 150 151 // pull button/link flags differently since during 152 // POST submissions, the $_GET array sticks around 153 // 154 $isSpam = NULL; 155 $notSpam = NULL; 156 $extraButton = NULL; 157 $callback = NULL; 158 $custom_button_success_singular = ''; 159 $custom_button_success_plural = ''; 160 $button_name = NULL; 161 if (strtoupper($method) == 'POST') 162 { 163 sqGetGlobalVar('isSpam', $isSpam, SQ_POST); 164 sqGetGlobalVar('notSpam', $notSpam, SQ_POST); 165 } 166 else 167 { 168 sqGetGlobalVar('isSpam', $isSpam, SQ_GET); 169 sqGetGlobalVar('notSpam', $notSpam, SQ_GET); 170 } 171 172 173 // detect if extra button was clicked 174 // 175 if (is_null($isSpam) && is_null($notSpam) && !empty($extra_buttons)) 176 { 177 foreach ($extra_buttons as $button => $button_info) 178 { 179 $button_name = preg_replace('/[^a-zA-Z0-9]/', '_', $button); 180 if ((strtoupper($method) == 'POST' 181 && sqGetGlobalVar($button_name, $extraButton, SQ_POST)) 182 || (strtoupper($method) == 'GET' 183 && sqGetGlobalVar($button_name, $extraButton, SQ_GET))) 184 { 185 if (!empty($button_info[3])) 186 $callback = $button_info[3]; 187 if (!empty($button_info[4])) 188 $custom_button_success_singular = $button_info[4]; 189 if (!empty($button_info[5])) 190 $custom_button_success_plural = $button_info[5]; 191 break; 192 } 193 } 194 } 195 196 197 // build message ID array if user came from one of the 198 // links on the message view page 199 // 200 if ($isSpam == 'yslnk' || $notSpam == 'yslnk' || $extraButton == 'yslnk') 201 $msg = array($passed_id); 202 203 204 // build list of checkboxes to be pre-selected when 205 // returning to message list 206 // 207 $prechecked = array(); 208 if ($sb_reselect_messages) 209// could add the following, but not absolutely necessary 210// && (empty($sb_report_spam_by_move_to_folder) 211// || empty($sb_report_not_spam_by_move_to_folder))) 212 { 213 if (is_array($msg)) foreach ($msg as $messageID) 214 $prechecked[$messageID] = TRUE; 215 } 216 217 218 219 // if no messages were selected or spam buttons were not clicked on 220 // this request, just return and let SM handle the error, if any 221 // 222 if (empty($msg) || (empty($isSpam) && empty($notSpam) && empty($extraButton))) 223 return; 224 225 226 sq_change_text_domain('spam_buttons'); 227 228 229 230 $note = ''; 231 $success = FALSE; 232 $abort_message_view = FALSE; 233 234 235 236//TODO: if we implement "dont_wait" functionality, we can fork a child process here; then the child uses the reporting code below and exits, but the parent needs to skip to the section a few hundred lines down where it redirects back to the message list or read-message page ("DONE, WHERE DO WE RETURN TO?"). See the TODO section of the README file for some issues regarding this kind of functioality 237 238 239 240 // ----------------------------------------------------------------- 241 // 242 // HANDLE EXTRA BUTTON CLICK 243 // 244 245 246 if (!empty($extraButton)) 247 { 248 list($result, $note) = sb_custom_button_action($button_name, $callback, $msg, $passed_ent_id); 249 250 251 // what note do we use? if we have success and there 252 // is a note configured in the config file, use it 253 // 254 if ($result) 255 { 256 if (!empty($custom_button_success_singular) 257 && !empty($custom_button_success_plural)) 258 $note = ngettext($custom_button_success_singular, $custom_button_success_plural, count($msg)); 259 else if (count($msg) < 2 && !empty($custom_button_success_singular)) 260 $note = _($custom_button_success_singular); 261 else if (count($msg) > 1 && !empty($custom_button_success_plural)) 262 $note = _($custom_button_success_plural); 263 else 264 $note = _($note); 265 } 266 267 268 // this should never actually be needed, but to be safe, let's 269 // make sure that none of the other action handlers below get 270 // kicked off... 271 // 272 $isSpam = NULL; 273 $notSpam = NULL; 274 275 } 276 277 278 279 // ----------------------------------------------------------------- 280 // 281 // SPAM 282 // 283 284 285 // mark as spam! 286 // 287 if (!empty($isSpam)) 288 { 289 290 // move-to-folder (only when target mailbox is not the same as source mailbox) 291 // 292 // note that we don't have to to check for $passed_ent_id because the report 293 // links/buttons are not shown when $passed_ent_id is non-zero, so we can never 294 // get here 295 // 296 global $mailbox; 297 if (!empty($sb_report_spam_by_move_to_folder) 298 && $mailbox != $sb_report_spam_by_move_to_folder 299 && is_array($msg)) 300 { 301 302 global $auto_expunge, $imapConnection, $username, $key, 303 $imapServerAddress, $imapPort; 304 if (check_sm_version(1, 5, 2)) $key = FALSE; 305 if (!is_resource($imapConnection)) 306 $imapConnection = sqimap_login($username, $key, $imapServerAddress, $imapPort, 0); 307 308 if (check_sm_version(1, 5, 2)) 309 { 310 global $aMailbox; 311 sqGetGlobalVar('lastTargetMailbox', $lastTargetMailbox, SQ_SESSION); 312 spam_buttons_auto_create_folder($imapConnection, $sb_report_spam_by_move_to_folder); 313 if ($sb_report_spam_by_copy_to_folder) 314 $note = handleMessageListForm($imapConnection, $aMailbox, 'copy', $msg, $sb_report_spam_by_move_to_folder); 315 else 316 $note = handleMessageListForm($imapConnection, $aMailbox, 'move', $msg, $sb_report_spam_by_move_to_folder); 317 sqsession_register($lastTargetMailbox,'lastTargetMailbox'); 318 } 319 else 320 { 321//TODO -- how to populate $note if an error occurs? sqimap_msgs_list_copy() doesn't have a return value... 322 if ($sb_report_spam_by_copy_to_folder) 323 spam_buttons_sqimap_msgs_list_copy($imapConnection, $msg, $sb_report_spam_by_move_to_folder); 324 else 325 spam_buttons_sqimap_msgs_list_move($imapConnection, $msg, $sb_report_spam_by_move_to_folder); 326 if ($auto_expunge) 327 $cnt = sqimap_mailbox_expunge($imapConnection, $mailbox, true); 328 else 329 $cnt = 0; 330 } 331 332 333 // done reporting-by-move, now redirect user as needed 334 // right away if javascript is available and reporting 335 // from message view, or just prepare redirect location 336 // otherwise 337 // 338 if (empty($note)) 339 { 340 $success = TRUE; 341 $note = _($reported_spam_text); 342//TODO? include something that identifies the message(s) that were reported(have to add it up in the loop above)? might take too much screen real estate....? 343 344 345 global $javascript_on, $username, $mbx_response, $mailbox, 346 $startMessage, $show_num, $sort, $imapConnection, 347 $key, $imapServerAddress, $imapPort, $account; 348 $uri_args = 'mailbox=' . urlencode($mailbox) 349 . (!empty($sort) ? "&sort=$sort" : '') 350 . (!empty($account) ? "&account=$account" : '') 351 . (!empty($startMessage) ? "&startMessage=$startMessage" : ''); 352 if (check_sm_version(1, 5, 2)) $key = FALSE; 353 if (empty($mbx_response)) 354 { 355 if (!is_resource($imapConnection)) 356 $imapConnection = sqimap_login($username, $key, $imapServerAddress, $imapPort, 0); 357 $mbx_response = sqimap_mailbox_select($imapConnection, $mailbox); 358 } 359 360 361 // when reading message itself, redirect back to 362 // message list after having moved it 363 // 364 if ($reporting_from_message_view && $javascript_on) 365 { 366 367//TODO: this may cause problems in 1.4.x, where output is probably already started 368 sqsession_register($note, 'sb_note'); 369 370 371 // do we want to move to next message or return to message list? 372 // 373 global $redirect_location; 374 if ($move_to_message_after_report < 0) 375 $redirect_location = sqm_baseuri() 376 . 'src/right_main.php?' . $uri_args; 377 else 378 $redirect_location = sqm_baseuri() 379 . 'src/read_body.php?passed_id=' 380 . $move_to_message_after_report . '&' . $uri_args; 381 382 383 // when viewing a message in the preview pane, 384 // need to clear pane (or go to next message) 385 // after delete as well as refresh message list 386 // 387 global $data_dir, $PHP_SELF; 388 if (is_plugin_enabled('preview_pane') 389 && getPref($data_dir, $username, 'use_previewPane', 0) == 1) 390 { 391 392 global $request_refresh_message_list; 393 $request_refresh_message_list = 1; 394 395 // if not going to next message, go to empty preview pane 396 // 397 if ($move_to_message_after_report < 0) 398 $redirect_location = sqm_baseuri() . 'plugins/preview_pane/empty_frame.php'; 399 400 401 // refresh message list & close 402 // 403 if (check_sm_version(1, 5, 2)) 404 { 405 global $oTemplate; 406 $oTemplate->assign('redirect_location', $redirect_location, FALSE); 407 $oTemplate->assign('request_refresh_message_list', $request_refresh_message_list); 408 $output = $oTemplate->fetch('plugins/spam_buttons/redirect_preview_pane.tpl'); 409 return array('read_body_header' => $output); 410 } 411 else 412 { 413 global $t; 414 $t = array(); // no need to put config vars herein, they are already globalized 415 include(SM_PATH . 'plugins/spam_buttons/templates/default/redirect_preview_pane.tpl'); 416 } 417 418 } 419 420 421 // otherwise, just redirect with javascript 422 // 423 else 424 { 425 if (check_sm_version(1, 5, 2)) 426 { 427 global $oTemplate; 428 $oTemplate->assign('redirect_location', $redirect_location, FALSE); 429 $output = $oTemplate->fetch('plugins/spam_buttons/redirect_standard.tpl'); 430 return array('read_body_header' => $output); 431 } 432 else 433 { 434 global $t; 435 $t = array(); // no need to put config vars herein, they are already globalized 436 include(SM_PATH . 'plugins/spam_buttons/templates/default/redirect_standard.tpl'); 437 } 438 439 } 440 441 } 442 443 444 // otherwise (reporting from message list or no javascript support), 445 // make sure we didn't move ourselves off the last page or anything 446 // like that (code copied from 1.4.11 src/move_messages.php) 447 // 448 else if (!$reporting_from_message_view) 449 { 450 if (($startMessage + $cnt - 1) >= $mbx_response['EXISTS']) 451 { 452 if ($startMessage > $show_num) 453 $location = set_url_var($location,'startMessage',$startMessage-$show_num, false); 454 else 455 $location = set_url_var($location,'startMessage',1, false); 456 } 457 } 458 459 460 // finally, if we don't have JavaScript and we moved the message 461 // out from under the message view, so we need to indicate that 462 // the current message view needs to be aborted 463 // 464 else if ($reporting_from_message_view && !$javascript_on) 465 { 466 $abort_message_view = TRUE; 467 } 468 469 } 470 471 } 472 473 474 // shell command 475 // 476 else if (!empty($is_spam_shell_command)) 477 { 478 479 $note = report_by_shell_command($is_spam_shell_command, $msg, $passed_ent_id); 480 481 if (empty($note)) 482 { 483 $success = TRUE; 484 $note = _($reported_spam_text); 485//TODO? include something that identifies the message(s) that were reported(have to add it up in the loop above)? might take too much screen real estate....? 486 } 487 488 } 489 490 491 // re-send elsewhere via email 492 // 493 else if (!empty($is_spam_resend_destination)) 494 { 495 496 $note = report_by_email($is_spam_resend_destination, $msg, $passed_ent_id, $is_spam_keep_copy_in_sent, $is_spam_subject_prefix); 497 498 if (empty($note)) 499 { 500 $success = TRUE; 501 $note = _($reported_spam_text); 502//TODO? include something that identifies the message(s) that were reported(have to add it up in the loop above)? might take too much screen real estate....? 503 } 504 505 } 506 507 508 // custom function callout 509 // 510 else if (!empty($sb_report_spam_by_custom_function)) 511 { 512 513 $note = $sb_report_spam_by_custom_function($msg, $passed_ent_id); 514 515 if (empty($note)) 516 { 517 $success = TRUE; 518 $note = _($reported_spam_text); 519//TODO? include something that identifies the message(s) that were reported(have to add it up in the loop above)? might take too much screen real estate....? 520 } 521 522 } 523 524 525 else 526//TODO: we could put a warning here for the sysadmin... (but note that it is possible to get here when report-by-move-to-folder is correctly configured but no messages were selected by the user before pressing the report button) 527 $note = ''; 528 529 } 530 531 532 533 // ----------------------------------------------------------------- 534 // 535 // HAM 536 // 537 538 539 // mark as ham! 540 // 541 else if (!empty($notSpam)) 542 { 543 544 // move-to-folder (only when target mailbox is not the same as source mailbox) 545 // 546 // note that we don't have to to check for $passed_ent_id because the report 547 // links/buttons are not shown when $passed_ent_id is non-zero, so we can never 548 // get here 549 // 550 global $mailbox; 551 if (!empty($sb_report_not_spam_by_move_to_folder) 552 && $mailbox != $sb_report_not_spam_by_move_to_folder 553 && is_array($msg)) 554 { 555 556 global $auto_expunge, $imapConnection, $username, $key, 557 $imapServerAddress, $imapPort; 558 if (check_sm_version(1, 5, 2)) $key = FALSE; 559 if (!is_resource($imapConnection)) 560 $imapConnection = sqimap_login($username, $key, $imapServerAddress, $imapPort, 0); 561 562 if (check_sm_version(1, 5, 2)) 563 { 564 global $aMailbox; 565 sqGetGlobalVar('lastTargetMailbox', $lastTargetMailbox, SQ_SESSION); 566 spam_buttons_auto_create_folder($imapConnection, $sb_report_not_spam_by_move_to_folder); 567 if ($sb_report_not_spam_by_copy_to_folder) 568 $note = handleMessageListForm($imapConnection, $aMailbox, 'copy', $msg, $sb_report_not_spam_by_move_to_folder); 569 else 570 $note = handleMessageListForm($imapConnection, $aMailbox, 'move', $msg, $sb_report_not_spam_by_move_to_folder); 571 sqsession_register($lastTargetMailbox,'lastTargetMailbox'); 572 } 573 else 574 { 575//TODO -- how to populate $note if an error occurs? sqimap_msgs_list_copy() doesn't have a return value... 576 if ($sb_report_not_spam_by_copy_to_folder) 577 spam_buttons_sqimap_msgs_list_copy($imapConnection, $msg, $sb_report_not_spam_by_move_to_folder); 578 else 579 spam_buttons_sqimap_msgs_list_move($imapConnection, $msg, $sb_report_not_spam_by_move_to_folder); 580 if ($auto_expunge) 581 $cnt = sqimap_mailbox_expunge($imapConnection, $mailbox, true); 582 else 583 $cnt = 0; 584 } 585 586 587 // done reporting-by-move, now redirect user as needed 588 // right away if javascript is available and reporting 589 // from message view, or just prepare redirect location 590 // otherwise 591 // 592 if (empty($note)) 593 { 594 $success = TRUE; 595 $note = _($reported_not_spam_text); 596//TODO? include something that identifies the message(s) that were reported(have to add it up in the loop above)? might take too much screen real estate....? 597 598 599 global $javascript_on, $username, $mbx_response, $mailbox, 600 $startMessage, $show_num, $sort, $imapConnection, 601 $key, $imapServerAddress, $imapPort, $account; 602 $uri_args = 'mailbox=' . urlencode($mailbox) 603 . (!empty($sort) ? "&sort=$sort" : '') 604 . (!empty($account) ? "&account=$account" : '') 605 . (!empty($startMessage) ? "&startMessage=$startMessage" : ''); 606 if (check_sm_version(1, 5, 2)) $key = FALSE; 607 if (empty($mbx_response)) 608 { 609 if (!is_resource($imapConnection)) 610 $imapConnection = sqimap_login($username, $key, $imapServerAddress, $imapPort, 0); 611 $mbx_response = sqimap_mailbox_select($imapConnection, $mailbox); 612 } 613 614 615 // when reading message itself, redirect back to 616 // message list after having moved it 617 // 618 if ($reporting_from_message_view && $javascript_on) 619 { 620 621//TODO: this may cause problems in 1.4.x, where output is probably already started 622 sqsession_register($note, 'sb_note'); 623 624 625 // do we want to move to next message or return to message list? 626 // 627 global $redirect_location; 628 if ($move_to_message_after_report < 0) 629 $redirect_location = sqm_baseuri() 630 . 'src/right_main.php?' . $uri_args; 631 else 632 $redirect_location = sqm_baseuri() 633 . 'src/read_body.php?passed_id=' 634 . $move_to_message_after_report . '&' . $uri_args; 635 636 637 // when viewing a message in the preview pane, 638 // need to clear pane (or go to next message) 639 // after delete as well as refresh message list 640 // 641 global $data_dir, $PHP_SELF; 642 if (is_plugin_enabled('preview_pane') 643 && getPref($data_dir, $username, 'use_previewPane', 0) == 1) 644 { 645 646 global $request_refresh_message_list; 647 $request_refresh_message_list = 1; 648 649 // if not going to next message, go to empty preview pane 650 // 651 if ($move_to_message_after_report < 0) 652 $redirect_location = sqm_baseuri() . 'plugins/preview_pane/empty_frame.php'; 653 654 655 // refresh message list & close 656 // 657 if (check_sm_version(1, 5, 2)) 658 { 659 global $oTemplate; 660 $oTemplate->assign('redirect_location', $redirect_location, FALSE); 661 $oTemplate->assign('request_refresh_message_list', $request_refresh_message_list); 662 $output = $oTemplate->fetch('plugins/spam_buttons/redirect_preview_pane.tpl'); 663 return array('read_body_header' => $output); 664 } 665 else 666 { 667 global $t; 668 $t = array(); // no need to put config vars herein, they are already globalized 669 include(SM_PATH . 'plugins/spam_buttons/templates/default/redirect_preview_pane.tpl'); 670 } 671 672 } 673 674 675 // otherwise, just redirect with javascript 676 // 677 else 678 { 679 if (check_sm_version(1, 5, 2)) 680 { 681 global $oTemplate; 682 $oTemplate->assign('redirect_location', $redirect_location, FALSE); 683 $output = $oTemplate->fetch('plugins/spam_buttons/redirect_standard.tpl'); 684 return array('read_body_header' => $output); 685 } 686 else 687 { 688 global $t; 689 $t = array(); // no need to put config vars herein, they are already globalized 690 include(SM_PATH . 'plugins/spam_buttons/templates/default/redirect_standard.tpl'); 691 } 692 693 } 694 695 } 696 697 698 // otherwise (reporting from message list or no javascript support), 699 // make sure we didn't move ourselves off the last page or anything 700 // like that (code copied from 1.4.11 src/move_messages.php) 701 // 702 else if (!$reporting_from_message_view) 703 { 704 if (($startMessage + $cnt - 1) >= $mbx_response['EXISTS']) 705 { 706 if ($startMessage > $show_num) 707 $location = set_url_var($location,'startMessage',$startMessage-$show_num, false); 708 else 709 $location = set_url_var($location,'startMessage',1, false); 710 } 711 } 712 713 714 // finally, if we don't have JavaScript and we moved the message 715 // out from under the message view, so we need to indicate that 716 // the current message view needs to be aborted 717 // 718 else if ($reporting_from_message_view && !$javascript_on) 719 { 720 $abort_message_view = TRUE; 721 } 722 723 } 724 725 } 726 727 728 // shell command 729 // 730 else if (!empty($is_not_spam_shell_command)) 731 { 732 733 $note = report_by_shell_command($is_not_spam_shell_command, $msg, $passed_ent_id); 734 735 736 if (empty($note)) 737 { 738 $success = TRUE; 739 $note = _($reported_not_spam_text); 740//TODO? include something that identifies the message(s) that were reported(have to add it up in the loop above)? might take too much screen real estate....? 741 } 742 743 } 744 745 746 // re-send elsewhere via email 747 // 748 else if (!empty($is_not_spam_resend_destination)) 749 { 750 751 $note = report_by_email($is_not_spam_resend_destination, $msg, $passed_ent_id, $is_not_spam_keep_copy_in_sent, $is_not_spam_subject_prefix); 752 753 if (empty($note)) 754 { 755 $success = TRUE; 756 $note = _($reported_not_spam_text); 757//TODO? include something that identifies the message(s) that were reported(have to add it up in the loop above)? might take too much screen real estate....? 758 } 759 760 } 761 762 763 // custom function callout 764 // 765 else if (!empty($sb_report_not_spam_by_custom_function)) 766 { 767 768 $note = $sb_report_not_spam_by_custom_function($msg, $passed_ent_id); 769 770 if (empty($note)) 771 { 772 $success = TRUE; 773 $note = _($reported_not_spam_text); 774//TODO? include something that identifies the message(s) that were reported(have to add it up in the loop above)? might take too much screen real estate....? 775 } 776 777 } 778 779 780 else 781//TODO: we could put a warning here for the sysadmin... (but note that it is possible to get here when report-by-move-to-folder is correctly configured but no messages were selected by the user before pressing the report button) 782 $note = ''; 783 784 } 785 786 787 sq_change_text_domain('squirrelmail'); 788 789 790 791 // ----------------------------------------------------------------- 792 // 793 // REPORTED... NOW MOVE? 794 // 795 796 797 // move spam 798 // 799 if ($success && !empty($isSpam) && $sb_move_after_report_spam 800 && (empty($sb_report_spam_by_move_to_folder) // not if already moved! 801 || $sb_report_spam_by_copy_to_folder) 802 && empty($passed_ent_id) // not if reporting an attachment! 803 && is_array($msg)) 804 { 805 806 global $auto_expunge, $imapConnection, $username, $key, $show_num, 807 $mbx_response, $imapServerAddress, $imapPort, $mailbox, 808 $startMessage, $sort, $account, $javascript_on; 809 $uri_args = 'mailbox=' . urlencode($mailbox) 810 . (!empty($sort) ? "&sort=$sort" : '') 811 . (!empty($account) ? "&account=$account" : '') 812 . (!empty($startMessage) ? "&startMessage=$startMessage" : ''); 813 if (check_sm_version(1, 5, 2)) $key = FALSE; 814 if (!is_resource($imapConnection)) 815 $imapConnection = sqimap_login($username, $key, $imapServerAddress, $imapPort, 0); 816 if (empty($mbx_response)) 817 $mbx_response = sqimap_mailbox_select($imapConnection, $mailbox); 818 819 // move messages only when target mailbox is not the same as source mailbox 820 // 821 if ($mailbox != $sb_move_after_report_spam) 822 { 823 824 if (check_sm_version(1, 5, 2)) 825 { 826 global $aMailbox; 827 sqGetGlobalVar('lastTargetMailbox', $lastTargetMailbox, SQ_SESSION); 828 spam_buttons_auto_create_folder($imapConnection, $sb_move_after_report_spam); 829 if ($sb_copy_after_report_spam) 830 $move_result = handleMessageListForm($imapConnection, $aMailbox, 'copy', $msg, $sb_move_after_report_spam); 831 else 832 $move_result = handleMessageListForm($imapConnection, $aMailbox, 'move', $msg, $sb_move_after_report_spam); 833 sqsession_register($lastTargetMailbox,'lastTargetMailbox'); 834 } 835 else 836 { 837 if ($sb_copy_after_report_spam) 838 spam_buttons_sqimap_msgs_list_copy($imapConnection, $msg, $sb_move_after_report_spam); 839 else 840 spam_buttons_sqimap_msgs_list_move($imapConnection, $msg, $sb_move_after_report_spam); 841 if ($auto_expunge) 842 $cnt = sqimap_mailbox_expunge($imapConnection, $mailbox, true); 843 else 844 $cnt = 0; 845 } 846 847 848 // when reading message itself, redirect back to 849 // message list after having moved it 850 // 851 if ($reporting_from_message_view && $javascript_on) 852 { 853 854//TODO: this may cause problems in 1.4.x, where output is probably already started 855 sqsession_register($note, 'sb_note'); 856 857 858 // do we want to move to next message or return to message list? 859 // 860 global $redirect_location; 861 if ($move_to_message_after_report < 0) 862 $redirect_location = sqm_baseuri() 863 . 'src/right_main.php?' . $uri_args; 864 else 865 $redirect_location = sqm_baseuri() 866 . 'src/read_body.php?passed_id=' 867 . $move_to_message_after_report . '&' . $uri_args; 868 869 870 // when viewing a message in the preview pane, 871 // need to clear pane (or go to next message) 872 // after delete as well as refresh message list 873 // 874 global $data_dir, $PHP_SELF; 875 if (is_plugin_enabled('preview_pane') 876 && getPref($data_dir, $username, 'use_previewPane', 0) == 1) 877 { 878 879 global $request_refresh_message_list; 880 $request_refresh_message_list = 1; 881 882 // if not going to next message, go to empty preview pane 883 // 884 if ($move_to_message_after_report < 0) 885 $redirect_location = sqm_baseuri() . 'plugins/preview_pane/empty_frame.php'; 886 887 888 // refresh message list & close 889 // 890 if (check_sm_version(1, 5, 2)) 891 { 892 global $oTemplate; 893 $oTemplate->assign('redirect_location', $redirect_location, FALSE); 894 $oTemplate->assign('request_refresh_message_list', $request_refresh_message_list); 895 $output = $oTemplate->fetch('plugins/spam_buttons/redirect_preview_pane.tpl'); 896 return array('read_body_header' => $output); 897 } 898 else 899 { 900 global $t; 901 $t = array(); // no need to put config vars herein, they are already globalized 902 include(SM_PATH . 'plugins/spam_buttons/templates/default/redirect_preview_pane.tpl'); 903 } 904 905 } 906 907 908 // otherwise, just redirect with javascript 909 // 910 else 911 { 912 if (check_sm_version(1, 5, 2)) 913 { 914 global $oTemplate; 915 $oTemplate->assign('redirect_location', $redirect_location, FALSE); 916 $output = $oTemplate->fetch('plugins/spam_buttons/redirect_standard.tpl'); 917 return array('read_body_header' => $output); 918 } 919 else 920 { 921 global $t; 922 $t = array(); // no need to put config vars herein, they are already globalized 923 include(SM_PATH . 'plugins/spam_buttons/templates/default/redirect_standard.tpl'); 924 } 925 926 } 927 928 } 929 930 931 // otherwise (reporting from message list or no javascript support), 932 // make sure we didn't move ourselves off the last page or anything 933 // like that (code copied from 1.4.11 src/move_messages.php) 934 // 935 else if (!$reporting_from_message_view) 936 { 937 if (($startMessage + $cnt - 1) >= $mbx_response['EXISTS']) 938 { 939 if ($startMessage > $show_num) 940 $location = set_url_var($location,'startMessage',$startMessage-$show_num, false); 941 else 942 $location = set_url_var($location,'startMessage',1, false); 943 } 944 } 945 946 947 // finally, if we don't have JavaScript and we moved the message 948 // out from under the message view, so we need to indicate that 949 // the current message view needs to be aborted 950 // 951 else if ($reporting_from_message_view && !$javascript_on) 952 { 953 $abort_message_view = TRUE; 954 } 955 956 } 957 958 } 959 960 961 // move ham 962 // 963 if ($success && !empty($notSpam) && $sb_move_after_report_not_spam 964 && (empty($sb_report_not_spam_by_move_to_folder) // not if already moved! 965 || $sb_report_not_spam_by_copy_to_folder) 966 && empty($passed_ent_id) // not if reporting an attachment! 967 && is_array($msg)) 968 { 969 970 global $auto_expunge, $imapConnection, $username, $key, $show_num, 971 $mbx_response, $imapServerAddress, $imapPort, $mailbox, 972 $startMessage, $sort, $account, $javascript_on; 973 $uri_args = 'mailbox=' . urlencode($mailbox) 974 . (!empty($sort) ? "&sort=$sort" : '') 975 . (!empty($account) ? "&account=$account" : '') 976 . (!empty($startMessage) ? "&startMessage=$startMessage" : ''); 977 if (check_sm_version(1, 5, 2)) $key = FALSE; 978 if (!is_resource($imapConnection)) 979 $imapConnection = sqimap_login($username, $key, $imapServerAddress, $imapPort, 0); 980 if (empty($mbx_response)) 981 $mbx_response = sqimap_mailbox_select($imapConnection, $mailbox); 982 983 // move messages only when target mailbox is not the same as source mailbox 984 // 985 if ($mailbox != $sb_move_after_report_not_spam) 986 { 987 988 if (check_sm_version(1, 5, 2)) 989 { 990 global $aMailbox; 991 sqGetGlobalVar('lastTargetMailbox', $lastTargetMailbox, SQ_SESSION); 992 spam_buttons_auto_create_folder($imapConnection, $sb_move_after_report_not_spam); 993 if ($sb_copy_after_report_not_spam) 994 $move_result = handleMessageListForm($imapConnection, $aMailbox, 'copy', $msg, $sb_move_after_report_not_spam); 995 else 996 $move_result = handleMessageListForm($imapConnection, $aMailbox, 'move', $msg, $sb_move_after_report_not_spam); 997 sqsession_register($lastTargetMailbox,'lastTargetMailbox'); 998 } 999 else 1000 { 1001 if ($sb_copy_after_report_not_spam) 1002 spam_buttons_sqimap_msgs_list_copy($imapConnection, $msg, $sb_move_after_report_not_spam); 1003 else 1004 spam_buttons_sqimap_msgs_list_move($imapConnection, $msg, $sb_move_after_report_not_spam); 1005 if ($auto_expunge) 1006 $cnt = sqimap_mailbox_expunge($imapConnection, $mailbox, true); 1007 else 1008 $cnt = 0; 1009 } 1010 1011 1012 // when reading message itself, redirect back to 1013 // message list after having moved it 1014 // 1015 if ($reporting_from_message_view && $javascript_on) 1016 { 1017 1018//TODO: this may cause problems in 1.4.x, where output is probably already started 1019 sqsession_register($note, 'sb_note'); 1020 1021 1022 // do we want to move to next message or return to message list? 1023 // 1024 global $redirect_location; 1025 if ($move_to_message_after_report < 0) 1026 $redirect_location = sqm_baseuri() 1027 . 'src/right_main.php?' . $uri_args; 1028 else 1029 $redirect_location = sqm_baseuri() 1030 . 'src/read_body.php?passed_id=' 1031 . $move_to_message_after_report . '&' . $uri_args; 1032 1033 1034 // when viewing a message in the preview pane, 1035 // need to clear pane (or go to next message) 1036 // after delete as well as refresh message list 1037 // 1038 global $data_dir, $PHP_SELF; 1039 if (is_plugin_enabled('preview_pane') 1040 && getPref($data_dir, $username, 'use_previewPane', 0) == 1) 1041 { 1042 1043 global $request_refresh_message_list; 1044 $request_refresh_message_list = 1; 1045 1046 // if not going to next message, go to empty preview pane 1047 // 1048 if ($move_to_message_after_report < 0) 1049 $redirect_location = sqm_baseuri() . 'plugins/preview_pane/empty_frame.php'; 1050 1051 1052 // refresh message list & close 1053 // 1054 if (check_sm_version(1, 5, 2)) 1055 { 1056 global $oTemplate; 1057 $oTemplate->assign('redirect_location', $redirect_location, FALSE); 1058 $oTemplate->assign('request_refresh_message_list', $request_refresh_message_list); 1059 $output = $oTemplate->fetch('plugins/spam_buttons/redirect_preview_pane.tpl'); 1060 return array('read_body_header' => $output); 1061 } 1062 else 1063 { 1064 global $t; 1065 $t = array(); // no need to put config vars herein, they are already globalized 1066 include(SM_PATH . 'plugins/spam_buttons/templates/default/redirect_preview_pane.tpl'); 1067 } 1068 1069 } 1070 1071 1072 // otherwise, just redirect with javascript 1073 // 1074 else 1075 { 1076 if (check_sm_version(1, 5, 2)) 1077 { 1078 global $oTemplate; 1079 $oTemplate->assign('redirect_location', $redirect_location, FALSE); 1080 $output = $oTemplate->fetch('plugins/spam_buttons/redirect_standard.tpl'); 1081 return array('read_body_header' => $output); 1082 } 1083 else 1084 { 1085 global $t; 1086 $t = array(); // no need to put config vars herein, they are already globalized 1087 include(SM_PATH . 'plugins/spam_buttons/templates/default/redirect_standard.tpl'); 1088 } 1089 1090 } 1091 1092 } 1093 1094 1095 // otherwise (reporting from message list or no javascript support), 1096 // make sure we didn't move ourselves off the last page or anything 1097 // like that (code copied from 1.4.11 src/move_messages.php) 1098 // 1099 else if (!$reporting_from_message_view) 1100 { 1101 if (($startMessage + $cnt - 1) >= $mbx_response['EXISTS']) 1102 { 1103 if ($startMessage > $show_num) 1104 $location = set_url_var($location,'startMessage',$startMessage-$show_num, false); 1105 else 1106 $location = set_url_var($location,'startMessage',1, false); 1107 } 1108 } 1109 1110 1111 // finally, if we don't have JavaScript and we moved the message 1112 // out from under the message view, so we need to indicate that 1113 // the current message view needs to be aborted 1114 // 1115 else if ($reporting_from_message_view && !$javascript_on) 1116 { 1117 $abort_message_view = TRUE; 1118 } 1119 1120 } 1121 1122 } 1123 1124 1125 1126 // ----------------------------------------------------------------- 1127 // 1128 // OR DELETE? 1129 // 1130 1131 1132 // delete spam if needed (but not if already moved) 1133 // 1134 if ($success && $sb_delete_after_report && !empty($isSpam) 1135 && !$sb_move_after_report_spam // not if already moved! 1136 && empty($passed_ent_id) // not if reporting an attachment! 1137 && empty($sb_report_spam_by_move_to_folder)) // not if already moved! 1138 { 1139 1140 if (is_array($msg)) 1141 { 1142 global $auto_expunge, $imapConnection, $username, $key, $show_num, 1143 $mbx_response, $imapServerAddress, $imapPort, $mailbox, 1144 $startMessage, $sort, $account, $javascript_on; 1145 $uri_args = 'mailbox=' . urlencode($mailbox) 1146 . (!empty($sort) ? "&sort=$sort" : '') 1147 . (!empty($account) ? "&account=$account" : '') 1148 . (!empty($startMessage) ? "&startMessage=$startMessage" : ''); 1149 if (check_sm_version(1, 5, 2)) $key = FALSE; 1150//LEFT OFF HERE -- debugging UW 1151//sm_print_r('$imapConnection contains:', $imapConnection); 1152//sqimap_logout($imapConnection); 1153 if (!is_resource($imapConnection)) 1154 $imapConnection = sqimap_login($username, $key, $imapServerAddress, $imapPort, 0); 1155//echo '$mbx_response now contains:<br />'; 1156//sm_print_r($mbx_response); 1157 if (empty($mbx_response)) 1158//{ 1159 $mbx_response = sqimap_mailbox_select($imapConnection, $mailbox); 1160//echo 'And now $mbx_response contains:<br />'; 1161//sm_print_r($mbx_response); 1162//} 1163 1164 if (check_sm_version(1, 5, 2)) 1165 { 1166 global $aMailbox; 1167 handleMessageListForm($imapConnection, $aMailbox, 'setDeleted', $msg); 1168 } 1169 else 1170 { 1171 sqimap_msgs_list_delete($imapConnection, $mailbox, $msg); 1172//echo "Finished deleting; now expunge if necessary...<br />"; 1173 if ($auto_expunge) 1174 { 1175//echo "Expunging...<br />"; 1176 $cnt = sqimap_mailbox_expunge($imapConnection, $mailbox, true); 1177 } 1178//echo "Finished<br />"; 1179//exit; 1180 } 1181 1182 1183 // when reading message itself, redirect back to 1184 // message list after deletion 1185 // 1186 if ($reporting_from_message_view && $javascript_on) 1187 { 1188 1189//TODO: this may cause problems in 1.4.x, where output is probably already started 1190 sqsession_register($note, 'sb_note'); 1191 1192 1193 // do we want to move to next message or return to message list? 1194 // 1195 global $redirect_location; 1196 if ($move_to_message_after_report < 0) 1197 $redirect_location = sqm_baseuri() 1198 . 'src/right_main.php?' . $uri_args; 1199 else 1200 $redirect_location = sqm_baseuri() 1201 . 'src/read_body.php?passed_id=' 1202 . $move_to_message_after_report . '&' . $uri_args; 1203 1204 1205 // when viewing a message in the preview pane, 1206 // need to clear pane (or go to next message) 1207 // after delete as well as refresh message list 1208 // 1209 global $data_dir, $PHP_SELF; 1210 if (is_plugin_enabled('preview_pane') 1211 && getPref($data_dir, $username, 'use_previewPane', 0) == 1) 1212 { 1213 1214 global $request_refresh_message_list; 1215 $request_refresh_message_list = 1; 1216 1217 // if not going to next message, go to empty preview pane 1218 // 1219 if ($move_to_message_after_report < 0) 1220 $redirect_location = sqm_baseuri() . 'plugins/preview_pane/empty_frame.php'; 1221 1222 1223 // refresh message list & close 1224 // 1225 if (check_sm_version(1, 5, 2)) 1226 { 1227 global $oTemplate; 1228 $oTemplate->assign('redirect_location', $redirect_location, FALSE); 1229 $oTemplate->assign('request_refresh_message_list', $request_refresh_message_list); 1230 $output = $oTemplate->fetch('plugins/spam_buttons/redirect_preview_pane.tpl'); 1231 return array('read_body_header' => $output); 1232 } 1233 else 1234 { 1235 global $t; 1236 $t = array(); // no need to put config vars herein, they are already globalized 1237 include(SM_PATH . 'plugins/spam_buttons/templates/default/redirect_preview_pane.tpl'); 1238 } 1239 1240 } 1241 1242 1243 // otherwise, just redirect with javascript 1244 // 1245 else 1246 { 1247 if (check_sm_version(1, 5, 2)) 1248 { 1249 global $oTemplate; 1250 $oTemplate->assign('redirect_location', $redirect_location, FALSE); 1251 $output = $oTemplate->fetch('plugins/spam_buttons/redirect_standard.tpl'); 1252 return array('read_body_header' => $output); 1253 } 1254 else 1255 { 1256 global $t; 1257 $t = array(); // no need to put config vars herein, they are already globalized 1258 include(SM_PATH . 'plugins/spam_buttons/templates/default/redirect_standard.tpl'); 1259 } 1260 1261 } 1262 1263 } 1264 1265 1266 // otherwise (reporting from message list or no javascript support), 1267 // make sure we didn't move ourselves off the last page or anything 1268 // like that (code copied from 1.4.11 src/move_messages.php) 1269 // 1270 else if (!$reporting_from_message_view) 1271 { 1272 if (($startMessage + $cnt - 1) >= $mbx_response['EXISTS']) 1273 { 1274 if ($startMessage > $show_num) 1275 $location = set_url_var($location,'startMessage',$startMessage-$show_num, false); 1276 else 1277 $location = set_url_var($location,'startMessage',1, false); 1278 } 1279 } 1280 1281 1282 // finally, if we don't have JavaScript and we moved the message 1283 // out from under the message view, so we need to indicate that 1284 // the current message view needs to be aborted 1285 // 1286 else if ($reporting_from_message_view && !$javascript_on) 1287 { 1288 $abort_message_view = TRUE; 1289 } 1290 1291 } 1292 1293 } 1294 1295 1296 1297 // ----------------------------------------------------------------- 1298 // 1299 // DONE, WHERE DO WE RETURN TO? 1300 // 1301 1302 1303 // if no note, then we shouldn't do anything at all 1304 // 1305 if (empty($note)) 1306 { 1307 if (check_sm_version(1, 5, 0)) 1308 return; 1309 else 1310 { 1311 header('Location: ' . $location); 1312 exit; 1313 } 1314 } 1315 1316 1317 // when reading message itself, print message 1318 // in header and continue (unless message has been deleted) 1319 // 1320 if ($reporting_from_message_view) 1321 { 1322 if (check_sm_version(1, 5, 2)) 1323 global $br; 1324 else 1325 $br = '<br />'; 1326 1327 if ($abort_message_view) 1328 $note .= $br . _("The reported message is no longer available in this folder"); 1329 1330 if (check_sm_version(1, 5, 2)) 1331 { 1332 global $oTemplate; 1333 $oTemplate->assign('note', $note, FALSE); // FALSE because of use of $br 1334 $output = $oTemplate->fetch('plugins/spam_buttons/confirmation_note.tpl'); 1335 return array('read_body_header' => $output); 1336 // note that message view will be aborted in next executed 1337 // template hook: template_construct_read_message_body.tpl 1338 // using the global $abort_message_view variable 1339 } 1340 else 1341 { 1342 echo html_tag('tr', html_tag('td', "<strong>$note</strong>", 'center', '', ' colspan="2"')); 1343 1344 // if we need to abort, do that now 1345 // 1346 if ($abort_message_view) 1347 { 1348 echo '</table></td></tr></table></body></html>'; 1349 exit; 1350 } 1351 1352 return; 1353 } 1354 } 1355 1356 1357 1358 // 1359 // behavior is different when button on message list was clicked 1360 // 1361 1362 1363 // SM 1.5.2+: $note will be displayed automatically, so 1364 // all we need to do is return 1365 // 1366 if (check_sm_version(1, 5, 2)) 1367 { 1368 global $preselected; 1369 $preselected = array_keys($prechecked); 1370 return; 1371 } 1372 1373 1374 // SM 1.5: just display note and let go 1375 // 1376 else if (check_sm_version(1, 5, 0)) 1377 { 1378 global $preselected; 1379 $preselected = array_keys($prechecked); 1380 echo html_tag('div', '<b>' . $note .'</b>', 'center') . "<br />\n"; 1381 return; 1382 } 1383 1384 1385 // For SM 1.4.x, redirect to message list so SM 1386 // doesn't try to do something else funny (1.4.x 1387 // assumes it has to delete messages... yikes) 1388 // 1389 else 1390 { 1391 // put note in session so we can display it when back in 1392 // message list, without putting $note in the location, since 1393 // it is hard to remove from there, even on subsequent requests 1394 // 1395 sqsession_register($note, 'sb_note'); 1396 1397 // compress prechecked array and pass it along 1398 // 1399 $query = ''; 1400 foreach ($prechecked as $msgid => $ignore) 1401 $query .= '&preselected[' . $msgid . ']=1'; 1402 if (strpos($location, '?') === FALSE) 1403 $query{0} = '?'; 1404 1405 //header('Location: ' . $location . $query . '¬e=' . urlencode($note)); 1406 header('Location: ' . $location . $query); 1407 exit; 1408 } 1409 1410 1411} 1412 1413 1414 1415/** 1416 * Reports one or more spam/non-spam using email redirection. 1417 * 1418 * @param string $destination The email address to which the 1419 * message should be redirected. 1420 * @param array $msg An array of message IDs to be reported. 1421 * @param string $passed_ent_id The message entity being reported 1422 * (zero if the message itself is being 1423 * reported (only applicable when there 1424 * is just one element in the $msg array)) 1425 * @param boolean $keep_copy_in_sent When sending as an attachment, 1426 * should a copy of the spam report 1427 * being sent out get stored in the 1428 * user's sent folder? 1429 * @param string $subjectPrefix Any extra subject info for 1430 * redirected mail's subject. 1431 * (optional; default is empty 1432 * string, nothing is done to subject) 1433 * 1434 * @return string An error message if an error occurred, 1435 * empty string otherwise 1436 * 1437 */ 1438function report_by_email($destination, $msg, $passed_ent_id, 1439 $keep_copy_in_sent, $subjectPrefix='') 1440{ 1441 1442 global $spam_report_email_method, $spam_report_smtpServerAddress, 1443 $spam_report_smtpPort, $spam_report_useSendmail, 1444 $spam_report_smtp_auth_mech, $spam_report_use_smtp_tls, 1445 $smtpServerAddress, $smtpPort, $useSendmail, $smtp_auth_mech, 1446 $use_smtp_tls, $sb_debug, $data_dir, $username, $domain; 1447 $at_sign = '@'; 1448 1449 spam_buttons_init(); 1450 1451 1452 // do replacements on destination 1453 // 1454 if (strpos($username, $at_sign) !== FALSE) 1455 list($user, $dom) = explode($at_sign, $username); 1456 else 1457 { 1458 $user = $username; 1459 $dom = $domain; 1460 } 1461 $email_address = getPref($data_dir, $username, 'email_address'); 1462 $destination = str_replace(array('###EMAIL_PREF###', '###EMAIL_ADDRESS###', '###USERNAME###', '###DOMAIN###'), 1463 array($email_address, $user . $at_sign . $dom, $user, $dom), 1464 $destination); 1465 1466 1467 // take care of overrides for SMTP server 1468 // 1469 if (!empty($spam_report_smtpServerAddress)) 1470 $smtpServerAddress = $spam_report_smtpServerAddress; 1471 if (!empty($spam_report_smtpPort)) 1472 $smtpPort = $spam_report_smtpPort; 1473 if ($spam_report_useSendmail !== '') 1474 if (strtolower($spam_report_useSendmail) === 'false') 1475 $useSendmail = FALSE; 1476 else 1477 $useSendmail = $spam_report_useSendmail; 1478 if (!empty($spam_report_smtp_auth_mech)) 1479 $smtp_auth_mech = $spam_report_smtp_auth_mech; 1480 if (!empty($spam_report_use_smtp_tls)) 1481 $use_smtp_tls = $spam_report_use_smtp_tls; 1482 1483 1484 $note = ''; 1485 1486 1487 // redirect by bouncing message and preserving headers 1488 // 1489 if ($spam_report_email_method == 'bounce') 1490 { 1491 1492 global $imapServerAddress, $imapPort, $useSendmail; 1493 1494 1495 // we will be manually manipulating $_GET, so... 1496 // 1497 global $_GET; 1498 if (!check_php_version(4,1)) 1499 { 1500 global $HTTP_GET_VARS; 1501 $_GET = $HTTP_GET_VARS; 1502 } 1503 1504 1505 if (is_array($msg)) foreach ($msg as $messageID) 1506 { 1507 $_GET['bounce_send_to'] = $destination; 1508 $_GET['passed_id'] = $messageID; 1509 $_GET['passed_ent_id'] = $passed_ent_id; 1510 require(SM_PATH . 'plugins/spam_buttons/bounce_send.php'); 1511 } 1512 1513 } 1514 1515 1516 // redirect by including message as an attachment 1517 // 1518 else 1519 { 1520 1521 // some versions of SM need this when using some compose functions 1522 // 1523 if (!function_exists('addressbook_init')) 1524 include_once(SM_PATH . 'functions/addressbook.php'); 1525 1526 sqGetGlobalVar('mailbox', $mailbox); 1527 if (check_sm_version(1, 5, 2)) 1528 include_once(SM_PATH . 'plugins/spam_buttons/compose_functions-1.5.2.php'); 1529 else if (check_sm_version(1, 4, 14)) 1530 include_once(SM_PATH . 'plugins/spam_buttons/compose_functions-1.4.14.php'); 1531 else if (check_sm_version(1, 4, 11)) 1532 include_once(SM_PATH . 'plugins/spam_buttons/compose_functions-1.4.11.php'); 1533 else 1534 include_once(SM_PATH . 'plugins/spam_buttons/compose_functions-1.4.10.php'); 1535 1536 1537 if (is_array($msg)) foreach ($msg as $messageID) 1538 { 1539 1540 global $composeMessage, $send_to, $subject, $sb_keep_copy_in_sent; 1541 1542 $sb_keep_copy_in_sent = $keep_copy_in_sent; 1543 1544 $composeMessage = new Message(); 1545 $rfc822_header = new Rfc822Header(); 1546 $composeMessage->rfc822_header = $rfc822_header; 1547 $composeMessage->reply_rfc822_header = ''; 1548 1549 $message = newMail($mailbox, $messageID, $passed_ent_id, 'forward_as_attachment', ''); 1550 $subject = $message['subject']; 1551 if (!empty($subjectPrefix)) 1552 $subject = preg_replace('/fwd/i', $subjectPrefix, $subject); 1553 1554 $send_to = $destination; 1555 1556 $Result = deliverMessage($composeMessage); 1557 if (! $Result) 1558 { 1559 sq_change_text_domain('spam_buttons'); 1560 $note = _("ERROR: Report could not be delivered"); 1561 sq_change_text_domain('squirrelmail'); 1562 break; 1563 } 1564 1565 // dump stuff out if debugging 1566 // 1567 if ($sb_debug) 1568 { 1569 echo '<hr /><strong>EMAIL ADDRESS USED TO REPORT:</strong> ' . $destination . '<br /><br />'; 1570 echo '<hr /><strong>MESSAGE BODY AS REPORTED:</strong> (note that this is a parsed representation thereof)'; 1571 sm_print_r($composeMessage); 1572 echo '<br /><br />'; 1573 exit; 1574 } 1575 1576 } 1577 1578 } 1579 1580 1581 return $note; 1582 1583} 1584 1585 1586 1587/** 1588 * Reports one or more spam/non-spam using the shell 1589 * command provided. 1590 * 1591 * @param string $command The shell command to be used. 1592 * @param array $msg An array of message IDs to be reported. 1593 * @param string $passed_ent_id The message entity being reported 1594 * (zero if the message itself is being 1595 * reported (only applicable when there 1596 * is just one element in the $msg array)) 1597 * 1598 * @return string An error message if an error occurred, 1599 * empty string otherwise 1600 * 1601 */ 1602function report_by_shell_command($command, $msg, $passed_ent_id) 1603{ 1604 1605 global $attachment_dir, $data_dir, $username, $domain, $sb_debug; 1606 $at_sign = '@'; 1607 1608 spam_buttons_init(); 1609 1610 1611 $passed_ent_id = 0; 1612 sqGetGlobalVar('passed_ent_id', $passed_ent_id, SQ_FORM); 1613 sqGetGlobalVar('mailbox', $mailbox); 1614 1615 1616 // do replacements on command 1617 // 1618 if (strpos($username, $at_sign) !== FALSE) 1619 list($user, $dom) = explode($at_sign, $username); 1620 else 1621 { 1622 $user = $username; 1623 $dom = $domain; 1624 } 1625 $email_address = getPref($data_dir, $username, 'email_address'); 1626 $command = str_replace(array('###EMAIL_PREF###', '###EMAIL_ADDRESS###', '###USERNAME###', '###DOMAIN###'), 1627 array($email_address, $user . $at_sign . $dom, $user, $dom), 1628 $command); 1629 1630 1631 $note = ''; 1632 $timestamp = time(); 1633 1634 1635 if (is_array($msg)) foreach ($msg as $messageID) 1636 { 1637 1638 // get message body, correctly formatted 1639 // 1640 global $uid_support, $imapConnection, $username, $key, 1641 $mbx_response, $imapServerAddress, $imapPort, $mailbox; 1642 if (check_sm_version(1, 5, 2)) { $key = FALSE; $uid_support = TRUE; } 1643 1644 if (!is_resource($imapConnection)) 1645 $imapConnection = sqimap_login($username, $key, $imapServerAddress, $imapPort, 0); 1646 if (empty($mbx_response)) 1647 $mbx_response = sqimap_mailbox_select($imapConnection, $mailbox); 1648 $response = ''; 1649 $message = ''; 1650 1651 if (empty($passed_ent_id)) 1652 $raw_message = sqimap_run_command($imapConnection, "FETCH $messageID BODY.PEEK[]", true, $response, $message, $uid_support); 1653 else 1654 $raw_message = sqimap_run_command($imapConnection, "FETCH $messageID BODY.PEEK[$passed_ent_id]", true, $response, $message, $uid_support); 1655 1656 if ($response != 'OK') 1657 { 1658 global $color; 1659 sq_change_text_domain('spam_buttons'); 1660 $msg = sprintf(_("Could not find requested message: %s"), $message); 1661 sq_change_text_domain('squirrelmail'); 1662 $ret = plain_error_message($msg, $color); 1663 if (check_sm_version (1, 5, 2)) 1664 { 1665 echo $ret; 1666 global $oTemplate; 1667 $oTemplate->display('footer.tpl'); 1668 } 1669 exit; 1670 } 1671 1672 // rebuild the message exactly as it comes from the IMAP server 1673 // (except first and last array entries are command wrappers, so skip them) 1674 // 1675 array_shift($raw_message); 1676 array_pop($raw_message); 1677 $raw_message = implode('', $raw_message); 1678 1679 1680 // store message in attachments directory in temp file 1681 // 1682 $tempFile = $attachment_dir . '/sb_tmp_' . $messageID . '_' . $timestamp; 1683 $tempFileOK = FALSE; 1684 if ($FILE = @fopen($tempFile, 'w')) 1685 { 1686 1687 fwrite($FILE, $raw_message); 1688 fclose($FILE); 1689 $tempFileOK = TRUE; 1690 1691 1692 // run command 1693 // 1694 $cmd = $command . ' < ' . $tempFile; 1695//sm_print_r($cmd, $raw_message);exit; 1696 $lastLineOfOutput = exec($cmd, $allOutput, $retValue); 1697//sm_print_r($allOutput);exit; 1698 1699 1700 // remove temp file 1701 // 1702 unlink($tempFile); 1703 1704 1705 // dump stuff out if debugging 1706 // 1707 if ($sb_debug) 1708 { 1709 echo '<hr /><strong>COMMAND USED TO REPORT:</strong> ' . $cmd . '<br /><br />'; 1710 echo '<hr /><strong>MESSAGE BODY AS REPORTED:</strong> '; 1711 sm_print_r($raw_message); 1712 echo '<br /><br />'; 1713 echo '<hr /><strong>RESULTS FROM REPORT:</strong> (' . $retValue . ')'; 1714 sm_print_r($allOutput); 1715 echo '<br /><br />'; 1716 exit; 1717 } 1718 1719 } 1720 1721 1722 // couldn't open temp file 1723 // 1724 if (!$tempFileOK) 1725 { 1726 $note = _("ERROR: Could not open temp file; check attachments directory permissions"); 1727 break; 1728 } 1729 1730 1731 // oops, command failed 1732 // 1733 else if ($retValue !== 0) 1734 { 1735 if (empty($passed_ent_id)) 1736 $note = str_replace(array('%1', '%2', '%3'), 1737 array($retValue, $messageID, $lastLineOfOutput), 1738 _("ERROR %1: Problem reporting message ID %2: %3")); 1739 else 1740 $note = str_replace(array('%1', '%2', '%3', '%4'), 1741 array($retValue, $messageID, $lastLineOfOutput, $passed_ent_id), 1742 _("ERROR %1: Problem reporting message ID %2 (entity %4): %3")); 1743 break; 1744 } 1745 1746 } 1747 1748 return $note; 1749 1750} 1751 1752 1753 1754/** 1755 * Abort message view when message is moved/deleted 1756 * out from under current message view (SM 1.5.2+ only) 1757 * 1758 */ 1759function sb_abort_message_view_do() 1760{ 1761 1762 global $abort_message_view; 1763 1764 if ($abort_message_view) 1765 { 1766 global $oTemplate; 1767 $oTemplate->display('footer.tpl'); 1768 exit; 1769 } 1770 1771} 1772 1773 1774 1775// 1776// ripped from functions/auth.php (merged both STABLE and DEVEL; 1777// the only difference being how the hook is handled) 1778// 1779 1780/** 1781 * Fillin user and password based on SMTP auth settings. 1782 * 1783 * @param string $user Reference to SMTP username 1784 * @param string $pass Reference to SMTP password (unencrypted) 1785 */ 1786if (!function_exists('get_smtp_user')) 1787{ 1788function get_smtp_user(&$user, &$pass) { 1789 global $username, $smtp_auth_mech, 1790 $smtp_sitewide_user, $smtp_sitewide_pass; 1791 1792 if ($smtp_auth_mech == 'none') { 1793 $user = ''; 1794 $pass = ''; 1795 } elseif ( isset($smtp_sitewide_user) && isset($smtp_sitewide_pass) && 1796 !empty($smtp_sitewide_user)) { 1797 $user = $smtp_sitewide_user; 1798 $pass = $smtp_sitewide_pass; 1799 } else { 1800 $user = $username; 1801 $pass = sqauth_read_password(); 1802 } 1803 1804 if (check_sm_version(1, 5, 2)) { 1805 $temp = array(&$user, &$pass); 1806 do_hook('smtp_auth', $temp); 1807 } else { 1808 $ret = do_hook_function('smtp_auth', array($user, $pass)); 1809 if (!empty($ret[0])) 1810 $user = $ret[0]; 1811 if (!empty($ret[1])) 1812 $pass = $ret[1]; 1813 } 1814} 1815} 1816 1817 1818 1819// findPreviousMessage()'s prototype changed as of 1.5.1 1820// 1821function spam_buttons_findPreviousMessage($passed_id) 1822{ 1823 if (check_sm_version(1, 5, 1)) 1824 { 1825 if (!sqGetGlobalVar('what', $what, SQ_GET)) $what = 0; 1826 global $aMailbox; 1827 return findPreviousMessage($aMailbox['UIDSET'][$what], $passed_id); 1828 } 1829 else 1830 { 1831 global $mbx_response; 1832 if (empty($mbx_response)) 1833 { 1834 global $imapConnection, $mailbox, $key, $username, 1835 $imapServerAddress, $imapPort; 1836 if (!is_resource($imapConnection)) 1837 $imapConnection = sqimap_login($username, $key, $imapServerAddress, $imapPort, 0); 1838 $mbx_response = sqimap_mailbox_select($imapConnection, $mailbox); 1839 } 1840 return findPreviousMessage($mbx_response['EXISTS'], $passed_id); 1841 } 1842} 1843 1844 1845 1846// findNextMessage()'s prototype changed as of 1.5.1 1847// 1848function spam_buttons_findNextMessage($passed_id) 1849{ 1850 if (check_sm_version(1, 5, 1)) 1851 { 1852 if (!sqGetGlobalVar('what', $what, SQ_GET)) $what = 0; 1853 global $aMailbox; 1854 return findNextMessage($aMailbox['UIDSET'][$what], $passed_id); 1855 } 1856 else 1857 return findNextMessage($passed_id); 1858} 1859 1860 1861 1862// The move and copy function names change as of 1.4.18 to be what 1863// they say they are, so use those if we are at the right version. 1864// 1865// For versions less than 1.4.18, there is no copy function, so we 1866// use a modified version of the move function from 1.4.11 (which, 1867// ironically is mis-labelled "copy") 1868// 1869// Also, if configured to do so, the target folder will be created 1870// first if it does not exist. 1871// 1872function spam_buttons_sqimap_msgs_list_copy($imap_stream, $id, $mailbox) { 1873 1874 spam_buttons_auto_create_folder($imap_stream, $mailbox); 1875 1876 1877 if (check_sm_version(1, 4, 18)) 1878 return sqimap_msgs_list_copy($imap_stream, $id, $mailbox); 1879 1880 1881 // here is our own modified version of 1.4.11's move ("copy") function... 1882 // 1883 global $uid_support; 1884 $msgs_id = sqimap_message_list_squisher($id); 1885 $read = sqimap_run_command ($imap_stream, "COPY $msgs_id \"$mailbox\"", true, $response, $message, $uid_support); 1886 if ($response == 'OK') 1887 return true; 1888 else 1889 return false; 1890 1891} 1892 1893 1894 1895// the move and copy function names change as of 1.4.18 to be what they say they are 1896// 1897// Also, if configured to do so, the target folder will be created 1898// first if it does not exist. 1899// 1900function spam_buttons_sqimap_msgs_list_move($imap_stream, $id, $mailbox) { 1901 1902 spam_buttons_auto_create_folder($imap_stream, $mailbox); 1903 1904 1905 if (check_sm_version(1, 4, 18)) 1906 return sqimap_msgs_list_move($imap_stream, $id, $mailbox); 1907 1908 1909 // mis-labelled function name in versions less than 1.4.18 1910 // 1911 return sqimap_msgs_list_copy($imap_stream, $id, $mailbox); 1912 1913} 1914 1915 1916 1917// create a folder if it does not exist if necessary 1918// 1919function spam_buttons_auto_create_folder($imap_stream, $mailbox) 1920{ 1921 1922 // auto-create non-existing folder? 1923 // 1924 global $sb_auto_create_destination_folder; // assume config file already globally included 1925 if ($sb_auto_create_destination_folder 1926 && !sqimap_mailbox_exists($imap_stream, $mailbox)) 1927 sqimap_mailbox_create($imap_stream, $mailbox, ''); 1928 1929} 1930 1931 1932 1933/** 1934 * Execute action for custom button click. 1935 * 1936 * @param string $button_name The name of the button or link 1937 * (with non-alphanumerics having 1938 * been replaced with underscores). 1939 * @param string $callback The name of the function that 1940 * will handle the button action. 1941 * @param array $messages A list of message IDs. 1942 * @param string $passed_ent_id Entity ID when message is an 1943 * attachment (might be empty). 1944 * 1945 * @return array A two-element array, the first element being 1946 * a boolean value that is TRUE if all message(s) 1947 * were processed normally and FALSE if some error 1948 * occured. The second element is a string containing 1949 * a note (untranslated) that will be displayed to 1950 * the user upon completion (may be blank, in which 1951 * case, any message from the user configuration will 1952 * be used if available). 1953 * 1954 */ 1955function sb_custom_button_action($button_name, $callback, $messages, $passed_ent_id) 1956{ 1957 1958 global $username; 1959 $result = array(FALSE, 'ERROR: Unknown error'); 1960 1961 1962 // first, make sure the callback is correctly configured 1963 // 1964 if (empty($callback) || !function_exists($callback)) 1965 { 1966 global $color; 1967 1968 // if users complain of seeing a message "Function not found in 1969 // Spam Buttons plugin", it means they don't have a action callback 1970 // defined at all 1971 // 1972 sq_change_text_domain('spam_buttons'); 1973 $msg = sprintf(_("Function %s not found in Spam Buttons plugin"), $callback); 1974 sq_change_text_domain('squirrelmail'); 1975 $ret = plain_error_message($msg, $color); 1976 if (check_sm_version (1, 5, 2)) 1977 { 1978 echo $ret; 1979 global $oTemplate; 1980 $oTemplate->display('footer.tpl'); 1981 } 1982 exit; 1983 } 1984 1985 1986 // loop through each message (even if there is just one) 1987 // 1988 foreach ($messages as $message_id) 1989 { 1990 1991 // this retrieves the message's From header in the format 1992 // array(0 => 'From:', 1 => '"Jose" <jose@example.org>') 1993 // 1994 $from = sb_get_message_header($message_id, $passed_ent_id, 'From'); 1995 1996 1997 // this parses out just the email address portion of the From header 1998 // 1999 if (function_exists('parseRFC822Address')) 2000 { 2001 $from = parseRFC822Address($from[1], 1); 2002 $from = $from[0][2] . '@' . $from[0][3]; 2003 } 2004 else 2005 { 2006 $from = parseAddress($from[1], 1); 2007 $from = $from[0][0]; 2008 } 2009 2010 2011 // execute the callback 2012 // 2013 $result = $callback($button_name, $username, $from, $message_id, $passed_ent_id); 2014 2015 if (!is_array($result)) $result = array($result, ''); 2016 2017 if (!$result[0]) 2018 return array(FALSE, 'ERROR: ' . $result[1]); 2019 2020 } 2021 2022 2023 // finished, just return success (which will be the last known 2024 // value of $result... any note therein will also be used) 2025 // 2026 return $result; 2027 2028} 2029 2030 2031 2032