| 10 |
/********************************************************************\ |
/********************************************************************\ |
| 11 |
** this section contains all the themable functions in this module ** |
** this section contains all the themable functions in this module ** |
| 12 |
\********************************************************************/ |
\********************************************************************/ |
| 13 |
function theme_mail_archive_content(&$node, $main = 0, $page = 0) { |
function theme_mail_archive_content($node, $teaser = FALSE) { |
| 14 |
$output = "<div class=\"mailarchive\" id=\"mailarchive-$node->lid\">\n"; |
$output = "<div class=\"mailarchive\" id=\"mailarchive-$node->lid\">\n"; |
| 15 |
$output .= $node->body; |
$output .= $node->body; |
| 16 |
if ($node->messages) { |
if ($node->messages) { |
| 22 |
$output .= "</div>\n"; |
$output .= "</div>\n"; |
| 23 |
|
|
| 24 |
$node->body = $output; |
$node->body = $output; |
| 25 |
$node = node_prepare($node, $main); |
$node = node_prepare($node, $teaser); |
| 26 |
} |
} |
| 27 |
|
|
| 28 |
function theme_mail_archive_message_list_thread($lid) { |
function theme_mail_archive_message_list_thread($lid) { |
| 249 |
return $output; |
return $output; |
| 250 |
} |
} |
| 251 |
|
|
| 252 |
|
function theme_mail_archive_display($categories, $subscriptions, $parents, $tid, $subscriptions_per_page) { |
| 253 |
|
global $user; |
| 254 |
|
|
| 255 |
|
$vocabulary = module_invoke('taxonomy', 'get_vocabulary', variable_get('mail_archive_vocabulary', '')); |
| 256 |
|
$title = $vocabulary->name; |
| 257 |
|
|
| 258 |
|
$breadcrumb = array(); |
| 259 |
|
if ($tid) { |
| 260 |
|
$breadcrumb[] = array('path' => 'mailarchive', 'title' => $title); |
| 261 |
|
} |
| 262 |
|
|
| 263 |
|
if ($parents) { |
| 264 |
|
$parents = array_reverse($parents); |
| 265 |
|
foreach ($parents as $parent) { |
| 266 |
|
if ($parent->tid == $tid) { |
| 267 |
|
$title = $parent->name; |
| 268 |
|
$output .= theme('box', '', $parent->description); |
| 269 |
|
} |
| 270 |
|
else { |
| 271 |
|
$breadcrumb[] = array('path' => 'mailarchive/'. $parent->tid, 'title' => $parent->name); |
| 272 |
|
} |
| 273 |
|
} |
| 274 |
|
} |
| 275 |
|
$breadcrumb[] = array('path' => $_GET['q']); |
| 276 |
|
menu_set_location($breadcrumb); |
| 277 |
|
|
| 278 |
|
if (count($categories) || count($parents)) { |
| 279 |
|
$output .= '<div id="mail_archive">'; |
| 280 |
|
} |
| 281 |
|
$output .= theme('mail_archive_list', $categories, $parents, $tid); |
| 282 |
|
|
| 283 |
|
if ($tid) { |
| 284 |
|
$output .= theme('mail_archive_subscription_list', $tid, $subscriptions, $subscriptions_per_page); |
| 285 |
|
} |
| 286 |
|
|
| 287 |
|
print theme('page', $output, $title); |
| 288 |
|
} |
| 289 |
|
|
| 290 |
|
function theme_mail_archive_list($categories, $parents, $tid) { |
| 291 |
|
if ($categories) { |
| 292 |
|
$header = array(t('Categories'), t('Mailing lists')); |
| 293 |
|
foreach ($categories as $category) { |
| 294 |
|
$description = '<div style="margin-left: '. ($category->depth * 15) ."px;\">\n"; |
| 295 |
|
$description .= ' <div class="name">'. l($category->name, "mailarchive/$category->tid") ."</div>\n"; |
| 296 |
|
|
| 297 |
|
if ($category->description) { |
| 298 |
|
$description .= " <div class='description'>$category->description</div>\n"; |
| 299 |
|
} |
| 300 |
|
$description .= "</div>\n"; |
| 301 |
|
|
| 302 |
|
$rows[] = array( |
| 303 |
|
array('data' => $description, 'class' => 'mail_archive'), |
| 304 |
|
array('data' => ($category->num_subscriptions ? $category->num_subscriptions : ''), 'class' => 'subscriptions') |
| 305 |
|
); |
| 306 |
|
} |
| 307 |
|
return theme('table', $header, $rows); |
| 308 |
|
} |
| 309 |
|
} |
| 310 |
|
|
| 311 |
|
function theme_mail_archive_subscription_list($tid, $subscriptions, $subscriptions_per_page) { |
| 312 |
|
global $subscription_list_header; |
| 313 |
|
|
| 314 |
|
if ($subscriptions) { |
| 315 |
|
foreach ($subscriptions as $subscription) { |
| 316 |
|
$display = 1; |
| 317 |
|
$rows[] = array( |
| 318 |
|
array('data' => ''), |
| 319 |
|
array('data' => l($subscription->title, "mailarchive/$subscription->lid/overview/thread"), 'class' => 'title'), |
| 320 |
|
array('data' => $subscription->messages, 'class' => 'messages'), |
| 321 |
|
array('data' => t('%time ago', array('%time' => format_interval(time() - $subscription->last))), 'class' => 'last') |
| 322 |
|
); |
| 323 |
|
} |
| 324 |
|
if ($pager = theme('pager', NULL, $subscriptions_per_page, 0, tablesort_pager())) { |
| 325 |
|
$rows[] = array(array('data' => $pager, 'colspan' => '4', 'class' => 'pager')); |
| 326 |
|
} |
| 327 |
|
} |
| 328 |
|
|
| 329 |
|
if ($display) { |
| 330 |
|
return theme('table', $subscription_list_header, $rows); |
| 331 |
|
} |
| 332 |
|
} |
| 333 |
|
|
| 334 |
function theme_mail_archive_subscription_overview($subscription) { |
function theme_mail_archive_subscription_overview($subscription) { |
| 335 |
$output = '<p>'. $subscription->body .'</p>'; |
$output = '<p>'. $subscription->body .'</p>'; |
| 336 |
if ($subscription->messages) { |
if ($subscription->messages) { |
| 394 |
$output = form_textfield(t('Mail archive path'), 'mail_archive_path', variable_get('mail_archive_path', 'mail_archive'), 45, 255, t('Subdirectory in the directory "%dir" where raw and filtered mail messages will be stored.', array('%dir' => variable_get('file_directory_path', 'files') . '/')) . $error); |
$output = form_textfield(t('Mail archive path'), 'mail_archive_path', variable_get('mail_archive_path', 'mail_archive'), 45, 255, t('Subdirectory in the directory "%dir" where raw and filtered mail messages will be stored.', array('%dir' => variable_get('file_directory_path', 'files') . '/')) . $error); |
| 395 |
$output .= form_select(t('Maximum message download'), 'mail_archive_max_download', variable_get('mail_archive_max_download', 1000), array(0 => t('unlimited'), 1 => 1, 25 => 25, 50 => 50, 100 => 100, 500 => 500, 1000 => 1000, 1500 => 1500, 2000 => 2000, 2500 => 2500, 5000 => 5000, 10000 => 10000), t('Select the maximum number of messages that should be downloaded at one time. This should be kept low enough that your browser doesn\'t timeout during the message download process.')); |
$output .= form_select(t('Maximum message download'), 'mail_archive_max_download', variable_get('mail_archive_max_download', 1000), array(0 => t('unlimited'), 1 => 1, 25 => 25, 50 => 50, 100 => 100, 500 => 500, 1000 => 1000, 1500 => 1500, 2000 => 2000, 2500 => 2500, 5000 => 5000, 10000 => 10000), t('Select the maximum number of messages that should be downloaded at one time. This should be kept low enough that your browser doesn\'t timeout during the message download process.')); |
| 396 |
|
|
| 397 |
|
if (module_exist('taxonomy')) { |
| 398 |
|
$vocabularies[0] = '<'. t('none') .'>'; |
| 399 |
|
foreach (taxonomy_get_vocabularies('mail_archive') as $vid => $vocabulary) { |
| 400 |
|
$vocabularies[$vid] = $vocabulary->name; |
| 401 |
|
} |
| 402 |
|
if ($vocabulary) { |
| 403 |
|
$output .= form_select(t('Mail archive vocabulary'), 'mail_archive_vocabulary', variable_get('mail_archive_vocabulary', ''), $vocabularies, t("The taxonomy vocabulary that will be used to define the mail archive page layout. This vocabulary's terms will be used to display your mailing lists to your users in an organized manner. Mailing lists that are not contained in this vocabulary will not be displayed.")); |
| 404 |
|
} |
| 405 |
|
} |
| 406 |
|
|
| 407 |
|
|
| 408 |
return $output; |
return $output; |
| 409 |
} |
} |
| 410 |
|
|
| 413 |
if ($may_cache) { |
if ($may_cache) { |
| 414 |
$items[] = array('path' => 'mailarchive', |
$items[] = array('path' => 'mailarchive', |
| 415 |
'title' => t('mail archives'), |
'title' => t('mail archives'), |
| 416 |
'callback' => 'mail_archive_overview', |
'callback' => 'mail_archive_page', |
| 417 |
'access' => user_access('access mail archive'), |
'access' => user_access('access mail archive'), |
| 418 |
'weight' => 5); |
'weight' => 5); |
| 419 |
$items[] = array('path' => 'admin/mailarchive', |
$items[] = array('path' => 'admin/mailarchive', |
| 616 |
return $output; |
return $output; |
| 617 |
} |
} |
| 618 |
|
|
| 619 |
function mail_archive_view(&$node, $main = 0, $page = 0) { |
function mail_archive_view(&$node, $teaser = FALSE, $page = FALSE) { |
| 620 |
global $theme; |
global $theme; |
| 621 |
|
|
| 622 |
|
// format mail archive based on taxonomy "mail_archive_vocabulary" |
| 623 |
|
if ($page && $vocabulary = module_invoke('taxonomy', 'get_vocabulary', variable_get('mail_archive_vocabulary', ''))) { |
| 624 |
|
$breadcrumb = array(); |
| 625 |
|
$breadcrumb[] = array('path' => 'mailarchive', 'title' => $vocabulary->name); |
| 626 |
|
if ($parents = module_invoke('taxonomy', 'get_parents_all', $node->tid)) { |
| 627 |
|
$parents = array_reverse($parents); |
| 628 |
|
foreach ($parents as $parent) { |
| 629 |
|
$breadcrumb[] = array('path' => 'mailarchive/'. $parent->tid, 'title' => $parent->name); |
| 630 |
|
} |
| 631 |
|
} |
| 632 |
|
$breadcrumb[] = array('path' => 'node/'. $node->nid); |
| 633 |
|
menu_set_location($breadcrumb); |
| 634 |
|
} |
| 635 |
$themefunction = "{$theme}_mail_archive_content"; |
$themefunction = "{$theme}_mail_archive_content"; |
| 636 |
if (!function_exists($themefunction)) { |
if (!function_exists($themefunction)) { |
| 637 |
$themefunction = 'theme_mail_archive_content'; |
$themefunction = 'theme_mail_archive_content'; |
| 638 |
} |
} |
| 639 |
$themefunction($node, $main, $page); |
|
| 640 |
|
$themefunction($node, $teaser); |
| 641 |
|
} |
| 642 |
|
|
| 643 |
|
function mail_archive_taxonomy($op, $type, $object) { |
| 644 |
|
if ($type == 'vocabulary' && ($op == 'insert' || $op == 'update')) { |
| 645 |
|
if (variable_get('mail_archive_vocabulary', '') == '' && in_array('mail_archive', $object['nodes'])) { |
| 646 |
|
variable_set('mail_archive_vocabulary', $object['vid']); |
| 647 |
|
} |
| 648 |
|
} |
| 649 |
} |
} |
| 650 |
|
|
| 651 |
/* |
/* |
| 681 |
/**************\ |
/**************\ |
| 682 |
** user pages ** |
** user pages ** |
| 683 |
\**************/ |
\**************/ |
| 684 |
|
function mail_archive_page($tid = 0, $display = 'all') { |
| 685 |
|
global $user; |
| 686 |
|
|
| 687 |
|
if (module_exist('taxonomy')) { |
| 688 |
|
$subscriptions_per_page = variable_get('subscriptions_per_page', 25); |
| 689 |
|
|
| 690 |
|
$categories = mail_archive_get_categories($tid); |
| 691 |
|
$parents = module_invoke('taxonomy', 'get_parents_all', $tid); |
| 692 |
|
$subscriptions = mail_archive_get_subscriptions($tid, $subscriptions_per_page); |
| 693 |
|
|
| 694 |
|
print theme('mail_archive_display', $categories, $subscriptions, $parents, $tid, $subscriptions_per_page); |
| 695 |
|
} |
| 696 |
|
else { |
| 697 |
|
$subscriptions = mail_archive_load_subscription(NULL, 'object'); |
| 698 |
|
foreach ($subscriptions as $subscription) { |
| 699 |
|
$output .= theme('mail_archive_subscription_overview', $subscription); |
| 700 |
|
} |
| 701 |
|
drupal_set_breadcrumb(array(l(t('Home'), NULL))); |
| 702 |
|
} |
| 703 |
|
} |
| 704 |
|
|
| 705 |
|
function mail_archive_get_subscriptions($tid, $subscriptions_per_page) { |
| 706 |
|
global $user, $subscription_list_header; |
| 707 |
|
$subscriptions = array(); |
| 708 |
|
|
| 709 |
|
$subscription_list_header = array( |
| 710 |
|
array('data' => ' '), |
| 711 |
|
array('data' => t('Mailing list'), 'field' => 'n.title'), |
| 712 |
|
array('data' => t('Messages'), 'field' => 's.messages'), |
| 713 |
|
array('data' => t('Last message'), 'field' => 's.last') |
| 714 |
|
); |
| 715 |
|
|
| 716 |
|
$term = module_invoke('taxonomy', 'get_term', $tid); |
| 717 |
|
$check_tid = $tid ? "'". check_query($tid) ."'" : 'NULL'; |
| 718 |
|
|
| 719 |
|
$sql = 'SELECT s.messages, s.last, s.lid, n.title, n.nid, n.sticky FROM {mail_archive_subscriptions} s INNER JOIN {node} n ON s.nid = n.nid INNER JOIN {term_node} r ON n.nid = r.nid '. node_access_join_sql() ." WHERE r.tid = $check_tid"; |
| 720 |
|
$sql .= tablesort_sql($subscription_list_header, 'n.sticky DESC,'); |
| 721 |
|
|
| 722 |
|
$sql_count = 'SELECT COUNT(n.nid) FROM {node} n '. node_access_join_sql() ." INNER JOIN {term_node} r ON n.nid = r.nid AND r.tid = $check_tid WHERE n.status = 1 AND n.type = 'mail_archive'"; |
| 723 |
|
|
| 724 |
|
$result = pager_query($sql, $subscriptions_per_page, 0, $sql_count); |
| 725 |
|
|
| 726 |
|
while ($subscription = db_fetch_object($result)) { |
| 727 |
|
$subscriptions[] = $subscription; |
| 728 |
|
} |
| 729 |
|
return $subscriptions; |
| 730 |
|
} |
| 731 |
|
|
| 732 |
|
function mail_archive_get_categories($tid = 0) { |
| 733 |
|
$tid = (int)$tid; |
| 734 |
|
|
| 735 |
|
$categories = array(); |
| 736 |
|
$_categories = module_invoke('taxonomy', 'get_tree', variable_get('mail_archive_vocabulary', ''), $tid); |
| 737 |
|
|
| 738 |
|
if (count($_categories)) { |
| 739 |
|
$counts = array(); |
| 740 |
|
|
| 741 |
|
$_counts = db_query("SELECT r.tid, COUNT(n.nid) AS subscriptions FROM {node} n INNER JOIN {term_node} r ON n.nid = r.nid " . node_access_join_sql() . " WHERE n.status = 1 AND n.type = 'mail_archive' AND " . node_access_where_sql(). " GROUP BY r.tid", $tid); |
| 742 |
|
while ($count = db_fetch_object($_counts)) { |
| 743 |
|
$counts[$count->tid] = $count; |
| 744 |
|
} |
| 745 |
|
} |
| 746 |
|
|
| 747 |
|
foreach ($_categories as $category) { |
| 748 |
|
$category->num_subscriptions = (int)$counts[$category->tid]->subscriptions; |
| 749 |
|
$categories[$category->tid] = $category; |
| 750 |
|
} |
| 751 |
|
|
| 752 |
|
return $categories; |
| 753 |
|
} |
| 754 |
|
|
| 755 |
function mail_archive_overview() { |
function mail_archive_overview() { |
| 756 |
$output = ""; |
$output = ""; |
| 757 |
$lid = arg(1); |
$lid = arg(1); |
| 880 |
mail_archive_display_message_raw($lid, $id); |
mail_archive_display_message_raw($lid, $id); |
| 881 |
break; |
break; |
| 882 |
case 'thread': |
case 'thread': |
|
// TODO: Use the pager to display only n messages from the thread at a time |
|
|
// load first message |
|
| 883 |
$output = "<div class=\"message\">\n"; |
$output = "<div class=\"message\">\n"; |
| 884 |
|
|
| 885 |
|
$messages_per_page = $_GET['messages_per_page']; |
| 886 |
|
if (!(int)$messages_per_page) { |
| 887 |
|
$messages_per_page = 10; |
| 888 |
|
} |
| 889 |
|
|
| 890 |
|
// load first message to get thread details |
| 891 |
$first_message = mail_archive_load_message($lid, $id); |
$first_message = mail_archive_load_message($lid, $id); |
| 892 |
|
$thread_id = $first_message->thread_id; |
| 893 |
|
$sub_thread_id = rtrim($first_message->sub_thread_id, '/'); |
| 894 |
|
|
| 895 |
drupal_set_title(htmlspecialchars($first_message->subject_short)); |
drupal_set_title(htmlspecialchars($first_message->subject_short)); |
| 896 |
|
|
| 897 |
|
/* it's possible that what we consider the first message is not the first |
| 898 |
|
** message in the thread. We check for this, and adjust our spacing so |
| 899 |
|
** our first message is flush left. In lengthy threads this can be |
| 900 |
|
** important to keep from indenting too far off the right side of the |
| 901 |
|
** screen. |
| 902 |
|
*/ |
| 903 |
|
$offset = 0; |
| 904 |
|
$depth = count(explode('.', $sub_thread_id)) - 1; |
| 905 |
|
if ($depth) { |
| 906 |
|
$offset = $depth; |
| 907 |
|
} |
| 908 |
|
|
| 909 |
|
// invoke 'thread_top' hook |
| 910 |
if ($updated = mail_archive_invoke_api($first_message, 'thread_top', $output)) { |
if ($updated = mail_archive_invoke_api($first_message, 'thread_top', $output)) { |
| 911 |
foreach ($updated as $key => $value) { |
foreach ($updated as $key => $value) { |
| 912 |
${$key} = $value; |
${$key} = $value; |
| 913 |
} |
} |
| 914 |
} |
} |
| 915 |
|
|
| 916 |
|
// now load and display the full thread |
| 917 |
|
$sql = "SELECT mid FROM {mail_archive_message_index} WHERE lid = $lid AND thread_id = $thread_id AND (sub_thread_id LIKE '$sub_thread_id.%%' OR mid = $id) GROUP BY mid, thread_id, subject_short, received, sub_thread_id ORDER BY thread_id DESC, sub_thread_id DESC"; |
| 918 |
|
$result = pager_query($sql, $messages_per_page, 0, "SELECT COUNT(thread_id) FROM {mail_archive_message_index} WHERE lid = $lid AND thread_id = $thread_id AND (sub_thread_id LIKE '$sub_thread_id.%%' OR mid = $id)"); |
| 919 |
|
|
| 920 |
// display first message |
if ($pager = theme('pager', NULL, $messages_per_page, 0, array('messages_per_page' => $messages_per_page))) { |
| 921 |
$offset = 0; |
$output .= $pager; |
| 922 |
$depth = count(explode('.', $first_message->sub_thread_id)) - 1; |
$output .= '<hr /><br />'; |
|
if ($depth) { |
|
|
// this isn't the first message, provide link to earlier message |
|
|
$output .= theme('mail_archive_message_replyto', $first_message->reply_to, 'thread'); |
|
|
// when displaying, the first message of this subthread needs a depth of 0 |
|
|
$offset = $depth; |
|
| 923 |
} |
} |
| 924 |
|
|
| 925 |
$output .= theme('mail_archive_message_thread', $first_message, $depth - $offset); |
// display thread |
|
|
|
|
// find rest of thread |
|
|
$selected = db_fetch_object(db_query('SELECT thread_id, sub_thread_id FROM {mail_archive_message_index} WHERE lid = %d AND mid = %d', $lid, $id)); |
|
|
$selected->sub_thread_id = rtrim($selected->sub_thread_id, '/'); |
|
|
$result = db_query('SELECT mid FROM {mail_archive_message_index} WHERE lid = %d AND thread_id = %d AND sub_thread_id LIKE "%s.%%" GROUP BY mid, thread_id, subject_short, received, sub_thread_id ORDER BY thread_id DESC, sub_thread_id DESC', $lid, $selected->thread_id, $selected->sub_thread_id); |
|
|
|
|
|
// display rest of thread |
|
| 926 |
while ($message = db_fetch_object($result)) { |
while ($message = db_fetch_object($result)) { |
| 927 |
$message = mail_archive_load_message($lid, $message->mid); |
// see if we've already loaded this message |
| 928 |
|
if ($message->mid == $first_message->mid) { |
| 929 |
|
if ($offset) { |
| 930 |
|
/* the fact that there is an offset tells us that what we are |
| 931 |
|
** calling the first message is not the first message in the |
| 932 |
|
** current thread. Thus, we provide a link to whatever message |
| 933 |
|
** this is a reply to. |
| 934 |
|
*/ |
| 935 |
|
$output .= theme('mail_archive_message_replyto', $first_message->reply_to, 'thread'); |
| 936 |
|
} |
| 937 |
|
$message = $first_message; |
| 938 |
|
} |
| 939 |
|
else { |
| 940 |
|
$message = mail_archive_load_message($lid, $message->mid); |
| 941 |
|
} |
| 942 |
$depth = count(explode('.', $message->sub_thread_id)) - 1; |
$depth = count(explode('.', $message->sub_thread_id)) - 1; |
| 943 |
|
// TODO: only display n characters from each message (ie groups.google) |
| 944 |
$output .= theme('mail_archive_message_thread', $message, $depth - $offset); |
$output .= theme('mail_archive_message_thread', $message, $depth - $offset); |
| 945 |
} |
} |
| 946 |
|
|
| 947 |
|
if ($pager = theme('pager', NULL, $messages_per_page, 0, array('messages_per_page' => $messages_per_page))) { |
| 948 |
|
$output .= '<hr />'; |
| 949 |
|
$output .= $pager; |
| 950 |
|
} |
| 951 |
|
|
| 952 |
|
// invoke 'thread_bottom' hook |
| 953 |
if ($updated = mail_archive_invoke_api($first_message, 'thread_bottom', $output)) { |
if ($updated = mail_archive_invoke_api($first_message, 'thread_bottom', $output)) { |
| 954 |
foreach ($updated as $key => $value) { |
foreach ($updated as $key => $value) { |
| 955 |
${$key} = $value; |
${$key} = $value; |
| 957 |
} |
} |
| 958 |
|
|
| 959 |
$output .= "</div>\n"; |
$output .= "</div>\n"; |
|
|
|
| 960 |
break; |
break; |
| 961 |
case 'rethread': |
case 'rethread': |
| 962 |
$message = db_fetch_object(db_query('SELECT thread_id FROM {mail_archive_message_index} WHERE lid = %d AND mid = %d', $lid, $id)); |
$message = db_fetch_object(db_query('SELECT thread_id FROM {mail_archive_message_index} WHERE lid = %d AND mid = %d', $lid, $id)); |