You are here

function mailhandler_get_parts in Mailhandler 6

Same name and namespace in other branches
  1. 5 mailhandler.module \mailhandler_get_parts()
  2. 7 mailhandler.retrieve.inc \mailhandler_get_parts()

Returns an array of parts as file objects

Parameters

@param $structure: A message structure, usually used to recurse into specific parts

$max_depth: Maximum Depth to recurse into parts.

$depth: The current recursion depth.

$part_number: A message part number to track position in a message during recursion.

Return value

An array of file objects.

1 call to mailhandler_get_parts()
mailhandler_retrieve_message in ./mailhandler.retrieve.inc
Retrieve individual messages from an IMAP result

File

./mailhandler.retrieve.inc, line 77
Mailbox connection code.

Code

function mailhandler_get_parts($stream, $msg_number, $max_depth = 10, $depth = 0, $structure = FALSE, $part_number = FALSE) {
  $parts = array();

  // Load Structure.
  if (!$structure && !($structure = imap_fetchstructure($stream, $msg_number, FT_UID))) {
    mailhandler_watchdog_record('Could not fetch structure for message number %msg_number', array(
      '%msg_number' => $msg_number,
    ), WATCHDOG_ERROR);
    return $parts;
  }

  // Recurse into multipart messages.
  if ($structure->type == TYPEMULTIPART) {

    // Restrict recursion depth.
    if ($depth >= $max_depth) {
      mailhandler_watchdog_record('Maximum recursion depths met in mailhander_get_structure_part for message number %msg_number.', array(
        '%msg_number' => $msg_number,
      ), WATCHDOG_ERROR);
      return $parts;
    }
    $prefix = '';
    foreach ($structure->parts as $index => $sub_structure) {

      // If a part number was passed in and we are a multitype message, prefix the
      // the part number for the recursive call to match the imap4 dot seperated part indexing.
      if ($part_number) {
        $prefix = $part_number . '.';
      }
      $sub_parts = mailhandler_get_parts($stream, $msg_number, $max_depth, $depth + 1, $sub_structure, $prefix . ($index + 1));
      $parts = array_merge($parts, $sub_parts);
    }
    return $parts;
  }

  // Per Part Parsing.
  // Initalize file object like part structure.
  $part = new StdClass();
  $part->attributes = array();
  $part->filename = 'unnamed_attachment';
  if (!($part->filemime = mailhandler_get_mime_type($structure))) {
    mailhandler_watchdog_record('Could not fetch mime type for message part. Defaulting to application/octet-stream.', array(), WATCHDOG_NOTICE);
    $part->filemime = 'application/octet-stream';
  }
  if ($structure->ifparameters) {
    foreach ($structure->parameters as $parameter) {
      switch (strtoupper($parameter->attribute)) {
        case 'NAME':
        case 'FILENAME':
          $part->filename = $parameter->value;
          break;
        default:

          // put every thing else in the attributes array;
          $part->attributes[$parameter->attribute] = $parameter->value;
      }
    }
  }

  // Handle Content-Disposition parameters for non-text types.
  if ($structure->type != TYPETEXT && $structure->ifdparameters) {
    foreach ($structure->dparameters as $parameter) {
      switch (strtoupper($parameter->attribute)) {
        case 'NAME':
        case 'FILENAME':
          $part->filename = $parameter->value;
          break;

        // put every thing else in the attributes array;
        default:
          $part->attributes[$parameter->attribute] = $parameter->value;
      }
    }
  }

  // Retrieve part and convert MIME encoding to UTF-8
  if (!($part->data = imap_fetchbody($stream, $msg_number, $part_number, FT_UID))) {
    mailhandler_watchdog_record('Mail has No Data!!', array(), WATCHDOG_ERROR);
    return $parts;
  }

  // Decode as necessary.
  if ($structure->encoding == ENCBASE64) {
    $part->data = imap_base64($part->data);
  }
  elseif ($structure->encoding == ENCQUOTEDPRINTABLE) {
    $part->data = quoted_printable_decode($part->data);
  }
  elseif ($structure->type == TYPETEXT) {
    $part->data = imap_utf8($part->data);
  }

  //always return an array to satisfy array_merge in recursion catch, and array return value.
  $parts[] = $part;
  return $parts;
}