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

Contents of /contributions/modules/listhandler/listhandler.module

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


Revision 1.88 - (show annotations) (download) (as text)
Sun Oct 25 16:16:51 2009 UTC (4 weeks, 5 days ago) by philipnet
Branch: MAIN
CVS Tags: HEAD
Changes since 1.87: +2 -2 lines
File MIME type: text/x-php
Grammar cleanup.
1 <?php
2 // $Id: listhandler.module,v 1.87 2009/10/25 16:15:02 philipnet Exp $
3
4 /**
5 * @file
6 * Listhandler main module.
7 */
8
9 /**
10 * To do:
11 * Does attachment handling screw up druapl_html_to_text or vise-versa?
12 * listhandler_update_5000 needs testing with the new db_drop_index code
13 * 5.x to 6.x migration needs testing
14 * Descriptions for database schema
15 * Check attachment handling after admin screen UI improvement.
16 */
17
18 /**
19 * Implementation of hook_help().
20 */
21 function listhandler_help($path, $arg) {
22 $output = '';
23 switch ($path) {
24 case 'admin/help#listhandler':
25 $output = '<p>'. t('The listhandler module allows you to connect mailing lists to forums and vice versa. It works in conjunction with the mailhandler module. Mailhandler receives an email and then asks listhandler if the received email is part of a list. If the email is from a mailing list associated with a forum on your site, then listhandler adds the recieved email to the forum.') .'</p>';
26 $output .= '<p>'. t('Listhandler administration allows you to set the email address of the list administrator. The email address is used as the From: field to check the address of messages sent by anonymous users. You can also enable and disable the listhandler for a list.') .'</p>';
27 $output .= t('<p>You can:</p>
28 <ul>
29 <li>administer listhandler <a href="!admin-listhandler">administer &gt;&gt; listhandler</a>.</li>
30 <li>administer mailhandler <a href="!admin-mailhandler">administer &gt;&gt; mailhandler</a> to create a mailbox which list handler can work with.</li>
31 <li>administer forum <a href="!admin-forum">administer &gt;&gt; forum</a>.</li>
32 ', array('!admin-listhandler' => url('admin/content/listhandler'), '!admin-mailhandler' =>
33 url('admin/content/mailhandler'), '!admin-forum' => url('admin/content/forum'))) .'</ul>';
34 $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="!listhandler">Listhandler page</a>.', array('!listhandler' => 'http://www.drupal.org/handbook/modules/listhandler/')) .'</p>';
35 return $output;
36 case 'admin/build/modules#description':
37 $output = t('Connect your mailing lists to your drupal site and your drupal site to your mailing lists.');
38 break;
39 case 'admin/content/listhandler':
40 $output = t("First go to the <a href='!url'>mailhandler configuration screen</a> and add some mailboxes. A mailbox becomes recognised as a mailing list if the 'Second E-mail address' is set.", array('!url' => url('admin/content/mailhandler')));
41 break;
42 }
43 return $output;
44 }
45
46 /**
47 * Implementation of hook_perm().
48 * Permissions for this module
49 */
50 function listhandler_perm() {
51 return array('administer listhandler');
52 }
53
54 /**
55 * Implementation of hook_menu().
56 */
57 function listhandler_menu() {
58 $items = array();
59 $items['admin/content/listhandler'] = array(
60 'title' => 'Listhandler',
61 'description' => 'Manage mailing-lists subscriptions.',
62 'page callback' => 'drupal_get_form',
63 'page arguments' => array('listhandler_admin_settings'),
64 'access callback' => 'user_access',
65 'access arguments' => array('administer listhandler')
66 );
67
68 return $items;
69 }
70
71 /**
72 * Implementation of hook_theme().
73 */
74 function listhandler_theme() {
75 return array(
76 'listhandler_admin_settings' => array(
77 'arguments' => array('form' => NULL)
78 )
79 );
80 }
81
82 /**
83 * Configuration options for this module
84 */
85 function listhandler_admin_settings() {
86 // This is the first chance we get to identify any new Mailhandler mailboxes.
87 // We need to check for:
88 // * new mailboxes
89 // * removed mailboxes
90
91
92
93 $form = array();
94 $form['listhandler_from'] = array(
95 '#type' => 'textfield',
96 '#title' => t("'Anonymous user' email address"),
97 '#default_value' => variable_get('listhandler_from', ''),
98 '#size' => 50,
99 '#maxlength' => 100,
100 '#description' => t('Used as the From address of messages sent by anonymous users; this is usually the mailing list administrator. However, if it is not then please ensure this email address can post to the list otherwise a bounce message will be generated'));
101 $form['listhandler_strip_title'] = array(
102 '#type' => 'textfield',
103 '#title' => t('Strip title'),
104 '#default_value' => variable_get('listhandler_strip_title', 'Re: , AW:,[my list]'),
105 '#size' => 50,
106 '#maxlength' => 1024,
107 '#description' => t("A comma delimited sequence of strings that should be stripped from the titles of topics and comments posted to the forums. You can use it to remove certain tags like 'Re: ' or '[My Mailinglist]'."));
108 $form['listhandler_attachments_as_link'] = array(
109 '#type' => 'radios',
110 '#title' => t('Attachment handling'),
111 '#options' => array(0 => t('Links at the bottom of emails'), 1 => t('Attachments in emails')),
112 '#default_value' => variable_get('listhandler_attachments_as_link', 0),
113 '#description' => t('Send attachments as links or MIME attachments. It only affects mails generated by forum posts.'));
114 $form['listhandler_accountstatus'] = array(
115 '#type' => 'radios',
116 '#title' => t('Account status'),
117 '#default_value' => variable_get('listhandler_accountstatus', 0),
118 '#options' => array(0 => t('blocked'), 1 => t('active')),
119 '#description' => t('The status of accounts created by Listhandler.'));
120 $form['listhandler_htmltotext'] = array(
121 '#type' => 'radios',
122 '#title' => t('HTML to text converter'),
123 '#default_value' => variable_get('listhandler_htmltotext', 0),
124 '#options' => array(0 => t('Fancy'), 1 => t('Standard')),
125 '#description' => t('If forums posts will be made using a WYSIWYG editor (i.e. TinyMCE) then the Fancy converter offers a more accurate convertion.'));
126 $form['listhandler_alwaysnewthread'] = array(
127 '#type' => 'radios',
128 '#title' => t('Email Replies'),
129 '#default_value' => variable_get('listhandler_alwaysnewthread', 0),
130 '#options' => array(0 => t('Replies as comments to original thread'), 1 => t('Replies as new threads')),
131 '#description' => t('Whether incoming email replies will be treated as comments or new threads.'));
132
133 $form['listhandler_list'] = array(
134 '#tree' => TRUE,
135 );
136
137 $form['listhandler_prefix'] = array(
138 '#tree' => TRUE,
139 );
140
141 $result = db_query("
142 SELECT {mailhandler}.mid AS mid, {listhandler_prefix}.prefix AS prefix, {mailhandler}.mailto AS mailto FROM {mailhandler}
143 LEFT OUTER JOIN {listhandler_prefix}
144 ON {mailhandler}.mid = {listhandler_prefix}.mid
145 ORDER BY mailto");
146
147 while ($mailbox = db_fetch_object($result)) {
148 $form['listhandler_list'][$mailbox->mid] = array(
149 '#value' => '<div><a href="mailto:'. $mailbox->mailto .'">'. $mailbox->mailto .'</a></div>');
150 $form['listhandler_prefix'][$mailbox->mid] = array(
151 '#type' => 'textfield',
152 '#default_value' => $mailbox->prefix,
153 '#size' => 50,
154 '#maxlength' => 100);
155 }
156
157 $form=system_settings_form($form);
158
159 $form['#submit'][] = 'listhandler_admin_settings_submit';
160 $form['#theme'] = 'listhandler_admin_settings';
161 return $form;
162 }
163
164 /**
165 * Theme call to render the tabular form of mailing lists and prefixes
166 */
167 function theme_listhandler_admin_settings($form) {
168 $output = '';
169 $output .= drupal_render($form['listhandler_from']);
170 $output .= drupal_render($form['listhandler_strip_title']);
171 $output .= drupal_render($form['listhandler_accountstatus']);
172 $output .= drupal_render($form['listhandler_attachments_as_link']);
173 $output .= drupal_render($form['listhandler_htmltotext']);
174 $output .= drupal_render($form['listhandler_alwaysnewthread']);
175 if (count($form['listhandler_list'])) {
176 $rows = array();
177 foreach (element_children($form['listhandler_list']) as $mid) {
178 $row = array();
179 $row[] = drupal_render($form['listhandler_list'][$mid]);
180 $row[] = drupal_render($form['listhandler_prefix'][$mid]);
181 $rows[] = $row;
182 }
183 $header = array(t('Mailing list'), t('Prefix'));
184 $output .= theme('table', $header, $rows);
185 $output .= '<div>'. t("The prefix will be prepended to all outgoing mail subjects for the specified list. It is a good idea to put the prefix in the 'strip title' field.") .'</div>';
186 }
187 else {
188 $output .= '<div>'. t("No mailing lists have been defined. Please go to the <a href='!url'>mailhandler configuration screen</a> and add one or more mailboxes. A mailbox becomes recognised as a mailing list if the 'Second E-mail address' is set.", array('!url' => 'admin/content/mailhandler')) .'</div>';
189 }
190 $output .= drupal_render($form);
191 return $output;
192 }
193
194 /**
195 * Writes configuration settings as Drupal variables and entries in
196 * the listhandler and mailhandler tables
197 */
198 function listhandler_admin_settings_submit($form, &$form_state) {
199 // Drupal can save the standard options, it's just the table it can't:
200 if (isset($form_state['values']['listhandler_prefix'])) {
201 foreach ($form_state['values']['listhandler_prefix'] as $key => $value) {
202 $result = db_query("SELECT {listhandler_prefix}.mid FROM {listhandler_prefix} WHERE mid = %d", $key);
203 if (!db_fetch_array($result)) {
204 db_query("INSERT INTO {listhandler_prefix} (prefix,mid) VALUES ('%s', '%d')", $value, $key);
205 }
206 else {
207 db_query("UPDATE {listhandler_prefix} SET prefix = '%s' WHERE mid = %d", $value, $key);
208 }
209 }
210 }
211 }
212
213 /**
214 * Implementation of hook_nodeapi().
215 */
216 function listhandler_nodeapi(&$node, $op, $arg = 0) {
217 switch ($op) {
218 case 'update': // what to do with updates?
219 break;
220 case 'insert': // mail new forum topics to mailing list.
221 if ($node->type == 'forum') {
222 if ($node->sentbylisthandler) { // avoid running an infinite loop.
223 // save ids in listhandler table.
224 db_query("INSERT INTO {listhandler} (msgid, nid, cid, pid, uid, mid, tid) VALUES ('%s','%s','%s','%s','%s','%s','%s')", $node->message_id, $node->nid, 0, 0, $node->uid, $node->mid, $node->tid);
225 // call watchdog
226 watchdog('listhandler', "Forum '%s' inserted.", array("%s" => $node->title), WATCHDOG_NOTICE);
227 }
228 else {
229 $node->subject = $node->title;
230 $node->comment = $node->body;
231 listhandler_send_mail((array) $node);
232 }
233 }
234 break;
235 }
236 }
237
238 /**
239 * Called by comment.module after submitting a comment.
240 * Sends comments to specified addresses.
241 *
242 * $type: type of call, here insert is expected.
243 *
244 * $edit: Array containing the comment.
245 * Important fields:
246 * $edit["subject"]: Oh well.
247 * $edit["comment"]: The text
248 * $edit["nid"]: commented node id
249 * $edit["cid"]: comment id
250 * $edit["pid"]: cid of parent
251 * $edit["uid"]: user id
252 * $edit["mid"]: id of mailbox
253 * $edit["tid"]: taxo id of the forum
254 */
255 function listhandler_comment($edit = array(), $type) {
256 if ($type == "insert") { // only accept calls by the comment insert hook.
257 if ($edit["sentbylisthandler"]) { // avoid running an infinite loop.
258 // save comment ids in listhandler table.
259 db_query("INSERT INTO {listhandler} (msgid, nid, cid, pid, uid, mid, tid) VALUES ('%s','%s','%s','%s','%s','%s','%s')", $edit["message_id"], $edit["nid"], $edit["cid"], $edit["pid"], $edit["uid"], $edit["mid"], $edit["tid"]);
260 // call watchdog
261 watchdog('listhandler', "Comment '%s' inserted.", array("%s" => $edit["subject"]), WATCHDOG_NOTICE);
262 }
263 else {
264 if (filter_access($edit['format']) && $edit['subject'] == truncate_utf8(decode_entities(strip_tags(check_markup($edit['comment'], $edit['format']))), 29, TRUE)) {
265 // subject was autogenerated, get it from parent instead
266 if ($edit['pid']) {
267 $parent = db_fetch_object(db_query('SELECT * FROM {comments} WHERE cid = %d', $edit['pid']));
268 $edit['subject'] = truncate_utf8(decode_entities(check_plain(t('Re: ') . $parent->subject)), 29, TRUE);
269 }
270 // no parent, get node title
271 else {
272 $parent = db_fetch_object(db_query('SELECT title FROM {node} WHERE nid = %d', $edit['nid']));
273 $parent->subject = truncate_utf8(decode_entities(strip_tags(check_markup($parent->title, $edit['format']))), 29, TRUE);
274 $edit['subject'] = t('Re: ') . $parent->subject;
275 }
276 db_query("UPDATE {comments} SET subject = '%s' WHERE cid = %d", $parent->subject, $edit['cid']);
277 }
278
279 listhandler_send_mail($edit);
280 }
281 }
282 }
283
284 /**
285 * Send email to mailing list.
286 * Includes a References/In_reply-To header if possible.
287 */
288 function listhandler_send_mail($edit) {
289 global $user, $base_url, $language;
290
291 if (!$user->uid) {
292 $edit['name'] = variable_get('anonymous', 'Anonymous');
293 $edit['mail'] = variable_get('listhandler_from', '');
294 }
295 else {
296 $edit["name"] = $user->name;
297 $edit["mail"] = $user->mail;
298 }
299 // Find the list to send to.
300 $mboxen = array();
301
302 // taxo terms of the node.
303 if (count($edit['taxonomy'])) {
304 foreach ($edit['taxonomy'] as $taxoterm) {
305 // Now for the mailbox.
306 switch ($GLOBALS['db_type']) {
307 case 'mysql':
308 case 'mysqli':
309 $result2 = db_query("SELECT * FROM {mailhandler} m WHERE m.commands REGEXP '%s'", 'tid:[[:blank:]]*'. $taxoterm .'[[:>:]]');
310 break;
311 case 'pgsql':
312 $result2 = db_query("SELECT * FROM {mailhandler} m WHERE m.commands ~ '%s'", 'tid:[[:blank:]]*'. $taxoterm .'[[:>:]]');
313 }
314 while ($mbox = db_fetch_object($result2)) {
315 $mboxen[] = array($mbox->mid, $mbox->mailto, $taxoarr->tid);
316 }
317 }
318 }
319 else {
320 $result = db_query("SELECT t.tid FROM {term_node} t WHERE t.nid = %d", $edit["nid"]);
321 while ($taxoarr = db_fetch_object($result)) {
322 // Now for the mailbox.
323 switch ($GLOBALS['db_type']) {
324 case 'mysql':
325 case 'mysqli':
326 $result2 = db_query("SELECT * FROM {mailhandler} m WHERE m.commands REGEXP '%s'", 'tid:[[:blank:]]*'. $taxoarr->tid .'[[:>:]]');
327 break;
328 case 'pgsql':
329 $result2 = db_query("SELECT * FROM {mailhandler} m WHERE m.commands ~ '%s'", 'tid:[[:blank:]]*'. $taxoarr->tid .'[[:>:]]');
330 }
331 while ($mbox = db_fetch_object($result2)) {
332 $mboxen[] = array($mbox->mid, $mbox->mailto, $taxoarr->tid);
333 }
334 }
335 }
336 // Find parent's MsgID if received by listhandler.
337 if ($edit["pid"]) {
338 // We should get only one or no result.
339 $result = db_fetch_object(db_query("SELECT * FROM {listhandler} WHERE cid = %d", $edit['pid']));
340 }
341 else {
342 $result = db_fetch_object(db_query("SELECT * FROM {listhandler} WHERE nid = %d", $edit['nid']));
343 $edit['pid']=0;
344 }
345 $mid=array();
346 if ($result) {// Parent was sent or received by listhandler
347 $mid['References'] = $result->msgid;
348 $mid['In-Reply-To'] = $result->msgid;
349 }
350 //common headers
351 $dir = str_replace("/", ".", substr(strchr(str_replace("http://", "", $base_url), "/"), 1));
352 foreach ($mboxen as $mbox) {
353 $edit["mid"] = $mbox[0];
354 $to = $mbox[1];
355 $edit["tid"] = $mbox[2];
356
357 // The below is required for EZMLM
358 // It sets the Return Path to the Listhandler subscribed email address (rather than the webserver)
359 // so that EZMLM (and everybody else) knows that we sent it
360 $mid['Return-Path'] = $edit['mail'];
361
362 // We add tokens to the MID. Replies to comments sent by listhandler can thus be classified easier.
363 $msgid = "<listhandler=". $edit["mid"] ."&site=". $dir . $_SERVER["SERVER_NAME"] ."&nid=". $edit["nid"] ."&pid=". $edit["pid"] ."&cid=". $edit["cid"] ."&uid=". $user->uid ."&tid=". $edit["tid"] ."&". md5($edit["nid"] . $edit["cid"]) ."@". $dir . strtolower($_SERVER["SERVER_NAME"]) .">";
364 $mid['Message-Id'] = $msgid;
365
366 // Ensure emails are treated as mailing list posts, not junk
367 $mid['Precedence'] = "list";
368
369 if (variable_get('listhandler_htmltotext', 0)) {
370 $subject = decode_entities(strip_tags($edit['subject']));
371 $body = decode_entities(strip_tags($edit['comment'])); }
372 else {
373 $subject = drupal_html_to_text($edit['subject']);
374 $body = drupal_html_to_text($edit['comment']);
375 }
376
377 // Add attachments
378 $fragment = NULL;
379 $lfiles = FALSE;
380 if ($edit['cid']) {
381 $fragment = "comment-" . $edit['cid'];
382 //attachment comments are already created
383 if (function_exists('comment_upload_load_files')) {
384 $lfiles = comment_upload_load_files($edit['cid']);
385 }
386 }
387 else {
388 $lfiles = $edit['files'];
389 }
390 if ($lfiles) {
391 // add $fragment to arguments: needed to build proper URL back
392 // to comments, which can contain attachments too
393 if (variable_get('listhandler_attachments_as_link', 0)) {
394 $body .= _listhandler_mail_links($lfiles, $edit['nid'], $fragment);
395 }
396 else {
397 $body = _listhandler_mail_attachments($body, $lfiles, $mid, $fragment);
398 }
399 }
400
401 // send email
402 $params = array(
403 'body' => $body,
404 'subject' => $subject,
405 'mid' => $mid
406 );
407 $ok = drupal_mail('listhandler', 'mail', $to, $language, $params, $edit["mail"] /* from */);
408
409 // sanitize cid and tid values for SQL mode STRICT_TRANS_TABLES
410 if (!$edit["cid"]) {
411 $edit["cid"]=0;
412 }
413 if (!$edit["tid"]) {
414 $edit["tid"]=0;
415 }
416
417 // save comment ids in listhandler table.
418 // Not strictly needed, the same info is stored in the msgid.
419 db_query("INSERT INTO {listhandler} (msgid, nid, cid, pid, uid, mid, tid) VALUES ('%s','%s','%s','%s','%s','%s','%s')", $msgid, $edit["nid"], $edit["cid"], $edit["pid"], $user->uid, $edit["mid"], $edit["tid"]);
420
421 // Call watchdog
422 if ($ok) {
423 watchdog('listhandler', "'!s' sent to '!a'.", array("!s" => $edit["subject"], "!a" => $to), WATCHDOG_NOTICE);
424 }
425 else {
426 watchdog('listhandler', "Error sending '!s' to '!a'.", array("!s" => $edit["subject"], "!a" => $to), WATCHDOG_WARNING);
427 }
428 }
429 }
430
431 /**
432 * Implements hook_mail.
433 */
434 function listhandler_mail($key, &$message, $params) {
435 $message['subject'] = $params['subject'];
436 $message['body'][] = $params['body'];
437 $message['headers'] = array_merge($message['headers'], $params['mid']);
438 }
439
440 /**
441 * Called by mailhandler after a new mail has been received.
442 *
443 * Only the first and last argument are used.
444 *
445 * $node: The new node or comment
446 * $stream: The number of the opened imap stream.
447 * $msg_number: The number of the current message in the mailbox.
448 * $mailbox: Array containing info about the mailbox the message is from.
449 * $header: Some, but not all headers (From, To, message_id, ...) of the current message.
450 */
451 function listhandler_mailhandler($node, $result, $msg_number, $header, $mailbox) {
452 global $base_url;
453
454 if ($node->tid) { // If no tid is assigned, then the mail is not comming through a mailhandler enabled list. Do nothing.
455 $node->cid = 0; // Might have a cid from the msg id. This will confuse comment_post. Updating comments via mail does not make sense anyway. GK
456 // Override value from msgid. Might be crossposted.
457 $node->mid = $mailbox['mid'];
458 // We need to ensure that no messages that have been sent by listhandler on this site (!)
459 // get processed. We would get an infinite loop on a mailing list.
460 $dir = str_replace("/", ".", substr(strchr(str_replace("http://", "", $base_url), "/"), 1));
461 $regex = "<listhandler=[[:print:]]+@". $dir . strtolower($_SERVER["SERVER_NAME"]) .">";
462 if (ereg($regex, $header->message_id)) {
463 // Sent by listhandler on this site. Destroy the node.
464 watchdog('listhandler', "Discarded message '!s' to avoid loop.", array("!s" => $node->title), WATCHDOG_NOTICE);
465 unset($node);
466 return;
467 }
468 else {
469 // Debug
470 //if($node->site != $dir . $_SERVER["SERVER_NAME"]) { // parent (!) not sent by listhandler on this site.
471 if ($node->uid == 0) { // mailhandler did not find the author, create a new account
472 $node = listhandler_create_author($node, $header);
473 }
474 //}
475 // Strip stuff from title
476 $replace = explode(',', variable_get('listhandler_strip_title', ''));
477 //print_r($replace);
478 $replacements = array();
479 //print_r($replacements);
480 foreach ($replace as $v) {
481 $replacements[trim($v)] = '';
482 }
483 //print_r($replacements);
484 unset($replacements['']);
485 //print_r($node->title);
486 if (count($replacements)) {
487 $node->title = trim(strtr($node->title, $replacements));
488 }
489 //print_r($node->title);
490 if (trim($node->title) == '') {
491 $node->title = truncate_utf8(decode_entities(strip_tags(check_markup($node->body, 1))), 29, TRUE);
492 }
493 $node = listhandler_find_parent($node, $header);
494
495 $node->message_id = $header->message_id;
496 $node->sentbylisthandler = TRUE;
497
498 return $node;
499 }
500 }
501 else { // allow other modules to have that node unaltered.
502 return $node;
503 }
504 }
505
506 /**
507 * Create account for unknown authors of a new mailsubmitted node or comment.
508 * Admin is able to choose if it will be
509 * a real account or a blocked one (see conf).
510 * if no account can be created (email or name already taken) the name and address
511 * are prepended to the node body and posted as anonymous.
512 */
513 function listhandler_create_author($node, $header) {
514 $from = $header->from;
515 $from_address = strtolower(sprintf("%s@%s", $from[0]->mailbox, $from[0]->host));
516 // decode encoded author name
517 $from_name = '';
518 $from_arr = imap_mime_header_decode($header->from[0]->personal);
519 for ($i = 0; $i < count($from_arr); $i++) {
520 if ($from_arr[$i]->charset != 'default') {
521 $from_name .= drupal_convert_to_utf8($from_arr[$i]->text, $from_arr[$i]->charset);
522 }
523 else {
524 $from_name .= $from_arr[$i]->text;
525 }
526 }
527 $from_name = trim($from_name, '"');
528 if ($from_name == '') {
529 $from_name = $from_address;
530 }
531 // check if name is available
532 if (db_result(db_query("SELECT COUNT(name) FROM {users} WHERE LOWER(name) = LOWER('%s')", $from_name)) > 0) {
533 $node->body = t('Message from !n !a', array('!n' => $from_name, '!a' => $from_address)) ."\n\n". $node->body;
534 watchdog('listhandler', "Cannot create account: The name '!s' is already taken.", array("!s" => $from_name), WATCHDOG_WARNING);
535 }
536 // check if address is valid
537 elseif (!valid_email_address($from_address)) {
538 $node->body = t('Message from !n !a', array('!n' => $from_name, '!a' => $from_address)) ."\n\n". $node->body;
539 watchdog('listhandler', "Cannot create account: The email address '!s' is not valid.", array("!s" => $from_address), WATCHDOG_WARNING);
540 }
541 // create account
542 else {
543 $empty_account = new stdClass();
544 $from_user = user_save($empty_account, array('name' => $from_name, 'pass' => user_password(), 'init' => $from_address, 'mail' => $from_address, 'roles' => array(DRUPAL_AUTHENTICATED_RID), 'status' => variable_get('listhandler_accountstatus', 0)), 'account');
545 watchdog('listhandler', 'Created account for !fa, with roles !rid', array('!fa' => $from_address, '!rid' => implode(', ', $from_user->roles)), WATCHDOG_NOTICE);
546 mailhandler_switch_user($from_user->uid);
547 }
548 $node->uid = $from_user->uid;
549 $node->name = $from_user->name;
550
551 return $node;
552 }
553
554 /**
555 * Find the parent of a new mailsubmitted comment. First use some heuristics
556 * and assumptions about Message-ID, References, and In-Reply-To headers.
557 * Then try to find a parent based on Subject line.
558 * If all else fails, start a new forum topic.
559 */
560 function listhandler_find_parent($node, $header) {
561 // create new thread no matter what?
562 if (variable_get('listhandler_alwaysnewthread', 0)) {
563 return listhandler_new_thread($node);
564 }
565
566 if ($node->threading) {
567 $parent = db_fetch_object(db_query("SELECT * FROM {listhandler} WHERE msgid = '<%s>'", $node->threading));
568 // Debug
569 // watchdog('listhandler', "Parent seek '". $node->threading ."\np.nid:".$parent->nid."\n p.cid".$parent->cid."\nSubject: ".$header->subject."'", array(), WATCHDOG_DEBUG);
570 if ($parent) { // parent (!) seen by listhandler on this site.
571 return listhandler_parent_thread($node, $parent);
572 }
573 }
574
575 // Still no parent.
576 // Now find the most recent matching subject in the current forum
577 $title = trim(substr($node->title, (strrpos($node->title, ':'))));
578 // watchdog ('listhandler', 'Now searching for title "'.$title.'"', array(), WATCHDOG_DEBUG);
579 $parent = db_fetch_object(db_query("SELECT * FROM {listhandler} l INNER JOIN {node} n ON l.nid = n.nid WHERE n.title LIKE '%%%s' AND mid = %d ORDER by n.nid DESC", $title, $node->mid));
580 if ($parent) {
581 return listhandler_parent_thread($node, $parent);
582 }
583 else {
584 // Could be a comment to a comment.
585 // watchdog ('listhandler', 'Could be a comment to a comment', array(), WATCHDOG_DEBUG);
586 $parent = db_fetch_object(db_query("SELECT * FROM {comments} c WHERE c.subject = '%s' ORDER BY cid DESC", $title));
587 if ($parent) {
588 return listhandler_parent_thread($node, $parent);
589 }
590 else {
591 // No parent found so new thread.
592 return listhandler_new_thread($node);
593 }
594 }
595 }
596
597 /**
598 * Convert upload files into links.
599 * Optional argument $fragment is used in supporting comments
600 */
601 function _listhandler_mail_links($lfiles, $nid, $fragment=NULL) {
602 $body = '';
603 $attachments = '';
604 foreach ($lfiles as $key => $ufile) {
605 $ufile = (object) $ufile;
606 $href = file_create_url((strpos($ufile->fid, 'upload') === FALSE ? $ufile->filepath : file_create_filename($ufile->filename, file_create_path())));
607 $href = str_replace(' ', '%20', $href);
608 $text = $ufile->description ? $ufile->description : $ufile->filename ;
609 $attachments .= "\n\n"." [". $text ."]:\n". $href;
610 }
611 if (!empty($attachments)) {
612 // change set up for call to url() function. Drupal 6 wants it to have
613 // options array as second argument.
614 if ($fragment) {
615 $my_url_options = array('fragment' => $fragment, 'absolute' => TRUE);
616 }
617 else {
618 $my_url_options = array('absolute' => TRUE);
619 }
620 $url = url('node/'. $nid, $my_url_options);
621
622 $body .= "\n\n". t('File attachments') .":";
623 $body .= $attachments;
624 $body .= "\n----------\n". t("Original attachments can be found at:\n!u", array('!u' => $url));
625 }
626 return $body;
627 }
628
629 /**
630 * Convert upload files into mail attachments.
631 */
632 function _listhandler_mail_attachments($body, $files, &$mid, $fragment=NULL) {
633 $trenner = md5(uniqid(time()));
634 $mid['Content-Type'] = "multipart/mixed; boundary=$trenner";
635 $message = "\n--$trenner\n";
636 $message .= "Content-Type: text/plain; charset=UTF-8; format=flowed;"."\n\n"; // sets the mime type
637
638 $message .= $body ."\n";
639 $message .= "\n\n";
640 foreach ($files as $key => $file) {
641 $file = (object) $file;
642 if ($file->filename) {
643 $file->filepath = str_replace("\\", "\\\\", $file->filepath);
644 $message .= "--". $trenner ."\n";
645 $message .= "Content-Type:". $file->filemime .";\n\tname=\"". $file->filename ."\"\n";
646 $message .= "Content-Transfer-Encoding: base64\n";
647 $message .= "Content-Disposition: attachment;\n\tfilename=\"". $file->filename ."\"\n\n";
648 $filedata = fread(fopen($file->filepath, "rb"), $file->filesize);
649 $message .= chunk_split(base64_encode($filedata));
650 $message .= "\n\n";
651 }
652 }
653 $message .= "--". $trenner ."--";
654 return $message;
655 }
656
657 /**
658 * Sets $node-> attributes to that of the parent thread.
659 */
660 function listhandler_parent_thread($node, $parent) {
661 // Debug
662 // watchdog('listhandler', "Parent found '". $node->threading ."\np.nid:".$parent->nid."\np.cid".$parent->cid."\nSubject:".$node->title."'", array(), WATCHDOG_DEBUG);
663 $node->pid = $parent->cid;
664 if ($node->cid) unset($node->cid);
665 $node->nid = $parent->nid;
666 $node->type = 'comment';
667
668 // use perms to set publish status for comments
669 $node->status = user_access('post comments without approval') ? 0 : 1;
670
671 return $node;
672 }
673
674 /**
675 * Sets $node-> attributes to create a new thread.
676 */
677 function listhandler_new_thread($node) {
678 $node->type = 'forum';
679 $node->nid = 0;
680 $node->taxonomy[] = $node->tid;
681 $node->pid = 0;
682 $node->comment = 2;
683
684 return $node;
685 }
686
687 /**
688 * Implementation of hook_simpletest().
689 */
690 function listhandler_simpletest() {
691 $dir = drupal_get_path('module', 'listhandler') .'/tests';
692 $tests = file_scan_directory($dir, '\.test$');
693 return array_keys($tests);
694 }

  ViewVC Help
Powered by ViewVC 1.1.2