You are here

function mailhandler_process_message in Mailhandler 5

Append default commands. Separate commands from body. Strip signature. Return a node object.

1 call to mailhandler_process_message()
mailhandler_retrieve in ./mailhandler.module
Retrieve all msgs from a given mailbox and process them.

File

./mailhandler.module, line 231

Code

function mailhandler_process_message($header, $body, $mailbox) {
  $node = new stdClass();

  // initialize params
  $sep = $mailbox['sigseparator'];

  // copy any name/value pairs from In-Reply-To or References e-mail headers to $node. Useful for maintaining threading info.
  if ($header->references) {

    // we want the final element in references header, watching out for white space
    $threading = substr(strrchr($header->references, '<'), 0);
  }
  else {
    if ($header->in_reply_to) {
      $threading = str_replace(strstr($header->in_reply_to, '>'), '>', $header->in_reply_to);

      // Some MUAs send more info in that header.
    }
  }
  if ($threading = rtrim(ltrim($threading, '<'), '>')) {

    //strip angle brackets
    if ($threading) {
      $node->threading = $threading;
    }
    parse_str($threading, $tmp);
    if ($tmp['host']) {
      $tmp['host'] = ltrim($tmp['host'], '@');

      // strip unnecessary @ from 'host' element
    }
    foreach ($tmp as $key => $value) {
      $node->{$key} = $value;
    }
  }

  // prepend the default commands for this mailbox
  if ($mailbox['commands']) {
    $body = trim($mailbox['commands']) . "\n" . $body;
  }

  // We set the type now, because we need it in the next block
  if (!$node->type) {
    $node->type = 'blog';
  }

  // Reset $node->taxonomy
  $node->taxonomy = array();

  // process the commands and the body
  $lines = explode("\n", $body);
  for ($i = 0; $i < count($lines); $i++) {
    $line = trim($lines[$i]);
    $words = explode(' ', $line);

    // look for a command line. if not present, note which line number is the boundary
    if (substr($words[0], -1) == ':' && is_null($endcommands)) {

      // Looks like a name: value pair
      $data = explode(': ', $line, 2);

      //TODO: allow for nested arrays in commands ... Possibly trim() values after explode().

      // if needed, turn this command value into an array
      if (substr($data[1], 0, 1) == '[' && substr($data[1], -1, 1) == ']') {
        $data[1] = rtrim(ltrim($data[1], '['), ']');

        //strip brackets
        $data[1] = explode(",", $data[1]);
      }
      $data[0] = strtolower(str_replace(' ', '_', $data[0]));

      // if needed, map term names into IDs. this should move to taxonomy_mailhandler()
      if ($data[0] == 'taxonomy' && !is_numeric($data[1][0])) {
        array_walk($data[1], 'mailhandler_term_map');
        $node->taxonomy = array_merge($node->taxonomy, $data[1]);
        unset($data[0]);
      }
      else {
        if (substr($data[0], 0, 9) == 'taxonomy[' && substr($data[0], -1, 1) == ']') {

          // make sure a valid vid is passed in:
          $vid = substr($data[0], 9, -1);
          $vocabulary = taxonomy_get_vocabulary($vid);

          // if the vocabulary is not activated for that node type, unset $data[0], so the command will be ommited from $node
          // TODO: add an error message
          if (!in_array($node->type, $vocabulary->nodes)) {
            unset($data[0]);
          }
          else {
            if (!$vocabulary->tags) {
              array_walk($data[1], 'mailhandler_term_map');
              $node->taxonomy = array_merge($node->taxonomy, $data[1]);
              unset($data[0]);
            }
            else {
              if ($vocabulary->tags) {

                // for freetagging vocabularies, we just pass the list of terms
                $node->taxonomy['tags'][$vid] = implode(',', $data[1]);
                unset($data[0]);

                // unset, so it won't be included when populating the node object
              }
            }
          }
        }
      }
      if (!empty($data[0])) {
        $node->{$data}[0] = $data[1];
      }
    }
    else {
      if (is_null($endcommands)) {
        $endcommands = $i;
      }
    }

    // stop when we encounter the sig. we'll discard all remaining text.
    $start = substr($line, 0, strlen($sep) + 3);
    if ($sep && strstr($start, $sep)) {

      // mail clients sometimes prefix replies with ' >'
      break;
    }
  }

  // isolate the body from the commands and the sig
  $tmp = array_slice($lines, $endcommands, $i - $endcommands);

  // flatten and assign the body to node object. note that filter() is called within node_save() [tested with blog post]
  $node->body = implode("\n", $tmp);
  if (!$node->teaser) {
    $node->teaser = node_teaser($node->body);
  }

  // decode encoded subject line
  $subjectarr = imap_mime_header_decode($header->subject);
  for ($i = 0; $i < count($subjectarr); $i++) {
    if ($subjectarr[$i]->charset != 'default') {
      $node->title .= drupal_convert_to_utf8($subjectarr[$i]->text, $subjectarr[$i]->charset);
    }
    else {
      $node->title .= $subjectarr[$i]->text;
    }
  }
  $node->date = format_date($header->udate, 'custom', 'Y-m-d H:i:s O');
  $node->format = $mailbox['format'];
  return $node;
}