/**
* Obtain an ActiveSync message from the backend.
*
* @param string $folderid The server's folder id this message is from
* @param string $id The server's message id
* @param array $collection The colletion data. May contain things like:
* - mimesupport: (integer) Indicates if the device has MIME support.
* DEFAULT: 0 (No MIME support)
* - truncation: (integer) Non-MIME truncation limit. Anything larger
* than this amount of bytes will be truncated.
* DEFAULT: 0 (No truncation)
* - mimetruncation: (integer) MIME truncation limit. Anything larger
* than this amount of bytes will be
* truncated.
* DEFAULT: 0 (No truncation)
* - bodyprefs: (array) The bodypref array from the device.
*
* @return Horde_ActiveSync_Message_Base The message data
* @throws Horde_ActiveSync_Exception, Horde_Exception_NotFound
*/
public function getMessage($folderid, $id, array $collection)
{
$this->_logger->info(sprintf("[%s] Horde_Core_ActiveSync_Driver::getMessage(%s, %s)", $this->_pid, $folderid, $id));
ob_start();
$message = false;
$folder_split = $this->_parseFolderId($folderid);
if (is_array($folder_split)) {
$folder_class = $folder_split[self::FOLDER_PART_CLASS];
} else {
$folder_class = $folder_split;
}
switch ($folder_class) {
case Horde_ActiveSync::CLASS_CALENDAR:
// Explicitly set the calendar to search if we are not using
// multiplexed collections since multiple calendars may have
// the same event UID.
$folder_id = is_array($folder_split) ? $folder_split[self::FOLDER_PART_ID] : null;
try {
$message = $this->_connector->calendar_export($id, array('protocolversion' => $this->_version, 'truncation' => empty($collection['truncation']) ? Horde_ActiveSync::TRUNCATION_9 : $collection['truncation'], 'bodyprefs' => $collection['bodyprefs'], 'mimesupport' => $collection['mimesupport']), $folder_id);
// Nokia MfE requires the optional UID element.
if (!$message->getUid()) {
$message->setUid($id);
}
} catch (Horde_Exception $e) {
$this->_logger->err($e->getMessage());
$this->_endBuffer();
throw new Horde_ActiveSync_Exception($e->getMessage());
}
break;
case 'RI':
$id = explode(':', $id);
try {
$recipients = $this->_connector->contacts_search($id[0], array('recipient_cache_search' => true));
} catch (Horde_Exception $e) {
$this->_logger->err($e->getMessage());
$this->_endBuffer();
throw new Horde_ActiveSync_Exception($e->getMessage());
}
if (is_array($recipients) && count($recipients)) {
$row = array_pop(array_pop($recipients));
if (!count($row)) {
$row = array();
}
} else {
$row = array();
}
$message = Horde_ActiveSync::messageFactory('RecipientInformation');
$message->alias = !empty($row['alias']) ? $row['alias'] : $id[0];
$message->email1address = !empty($row['email']) ? $row['email'] : $id[0];
$message->fileas = empty($row['name']) ? $id[0] : $row['name'];
$message->weightedrank = $id[1] + 1;
break;
case Horde_ActiveSync::CLASS_CONTACTS:
try {
$message = $this->_connector->contacts_export($id, array('protocolversion' => $this->_version, 'truncation' => empty($collection['truncation']) ? Horde_ActiveSync::TRUNCATION_9 : $collection['truncation'], 'bodyprefs' => $collection['bodyprefs'], 'mimesupport' => $collection['mimesupport'], 'device' => $this->_device));
} catch (Horde_Exception $e) {
$this->_logger->err($e->getMessage());
$this->_endBuffer();
throw new Horde_ActiveSync_Exception($e->getMessage());
}
break;
case Horde_ActiveSync::CLASS_TASKS:
try {
$message = $this->_connector->tasks_export($id, array('protocolversion' => $this->_version, 'truncation' => $collection['truncation'], 'bodyprefs' => $collection['bodyprefs'], 'mimesupport' => $collection['mimesupport']));
} catch (Horde_Exception $e) {
$this->_logger->err($e->getMessage());
$this->_endBuffer();
throw new Horde_ActiveSync_Exception($e->getMessage);
}
break;
case Horde_ActiveSync::CLASS_NOTES:
try {
$message = $this->_connector->notes_export($id, array('protocolversion' => $this->_version, 'truncation' => $collection['truncation'], 'bodyprefs' => $collection['bodyprefs'], 'mimesupport' => $collection['mimesupport']));
} catch (Horde_Exception $e) {
$this->_logger->err($e->getMessage());
$this->_endBuffer();
throw new Horde_ActiveSync_Exception($e->getMessage);
}
break;
case Horde_ActiveSync::CLASS_EMAIL:
// Get the message from the IMAP server.
try {
$messages = $this->_imap->getMessages($folderid, array($id), array('protocolversion' => $this->_version, 'truncation' => !empty($collection['truncation']) ? $collection['truncation'] : (!empty($collection['mimetruncation']) ? $collection['mimetruncation'] : false), 'bodyprefs' => $collection['bodyprefs'], 'bodypartprefs' => !empty($collection['bodypartprefs']) ? $collection['bodypartprefs'] : false, 'mimesupport' => $collection['mimesupport']));
} catch (Horde_ActiveSync_Exception $e) {
$this->_logger->err($e->getMessage());
$this->_endBuffer();
throw $e;
}
if (empty($messages)) {
$this->_endBuffer();
throw new Horde_Exception_NotFound();
}
$msg = array_pop($messages);
// Check for verb status from the Maillog.
if ($this->_version >= Horde_ActiveSync::VERSION_FOURTEEN) {
$last = null;
if (!empty($msg->messageid)) {
$last = $this->_getLastVerb($msg->messageid);
}
if (!empty($last)) {
switch ($last['action']) {
case 'reply':
case 'reply_list':
$msg->lastverbexecuted = Horde_ActiveSync_Message_Mail::VERB_REPLY_SENDER;
break;
case 'reply_all':
$msg->lastverbexecuted = Horde_ActiveSync_Message_Mail::VERB_REPLY_ALL;
break;
case 'forward':
$msg->lastverbexecuted = Horde_ActiveSync_Message_Mail::VERB_FORWARD;
}
$msg->lastverbexecutiontime = new Horde_Date($last['ts']);
} else {
// No maillog found, double check the IMAP flags.
// We favor the Maillog since EAS allows for a complete log
// of actions - and it requires a timestamp.
if ($msg->answered) {
$msg->lastverbexecuted = Horde_ActiveSync_Message_Mail::VERB_REPLY_SENDER;
$msg->lastverbexecutiontime = new Horde_Date(time());
} elseif ($msg->forwarded) {
$msg->lastverbexecuted = Horde_ActiveSync_Message_Mail::VERB_FORWARD;
$msg->lastverbexecutiontime = new Horde_Date(time());
}
}
}
$this->_endBuffer();
// Should we import an iTip response if we have one and we are in
// the INBOX?
if ($folderid == 'INBOX' && $this->_version >= Horde_ActiveSync::VERSION_TWELVE && $msg->contentclass == 'urn:content-classes:calendarmessage') {
switch ($msg->messageclass) {
case 'IPM.Schedule.Meeting.Resp.Pos':
case 'IPM.Schedule.Meeting.Resp.Neg':
case 'IPM.Schedule.Meeting.Resp.Tent':
$addr = new Horde_Mail_Rfc822_Address($msg->from);
$rq = $msg->meetingrequest;
$this->_connector->calendar_import_attendee($rq->getvEvent(), $addr->bare_address);
}
}
return $msg;
default:
$this->_endBuffer();
throw new Horde_ActiveSync_Exception(sprintf('Unsupported type: %s', $folder_class));
}
$this->_endBuffer();
return $message;
}