get_field_info($fieldId); if (! $field) { Hm_Msgs::add('ERRTracker field not found'); return; } $item = $trk->get_item_info($itemId); if (! $item) { Hm_Msgs::add('ERRTracker item not found'); return; } $item[$field['fieldId']] = $trk->get_item_value(null, $item['itemId'], $field['fieldId']); $handler = $trk->get_field_handler($field, $item); $data = $handler->getFieldData(); if (! isset($data['emails']) || ! is_array($data['emails'])) { Hm_Msgs::add('ERRTracker field storage is broken or you are using the wrong field type'); return; } $email = false; foreach ($data['emails'] as $folder => $emails) { $prev = $next = false; foreach ($emails as $eml) { if ($eml['fileId'] == $msg_uid) { $email = $eml; } else { if (! $email) { $prev = $eml; } elseif (! $next) { $next = $eml; } } } if ($email) { $email['show_archive'] = $handler->getOption('useFolders') && $folder != 'archive'; break; } } if (! $email) { Hm_Msgs::add('ERREmail not found in related tracker item'); return; } if (empty($email['message_raw'])) { Hm_Msgs::add('ERREmail could not be parsed'); return; } $email['prev'] = $prev; $email['next'] = $next; return $email; } } /** * Convert MimePart message parts to IMAP-compatible BODYSTRUCTURE * @subpackage tiki/functions * @param ZBateson\MailMimeParser\Message\Part\MimePart $part the mime message part * @param string $part_num the mime message part number * @return array */ if (! hm_exists('tiki_mime_part_to_bodystructure')) { function tiki_mime_part_to_bodystructure($part, $part_num = '0') { $content_type = explode('/', $part->getContentType()); $header = $part->getHeader('Content-Type'); $attributes = []; if ($header) { foreach (['boundary', 'charset', 'name'] as $param) { if ($header->hasParameter($param)) { $attributes[$param] = $header->getValueFor($param); } } } $header = $part->getHeader('Content-Disposition'); $file_attributes = []; if ($header) { $file_attributes[$header->getValue()] = []; if ($header->getValueFor('filename')) { $file_attributes[$header->getValue()][] = 'filename'; $file_attributes[$header->getValue()][] = $header->getValueFor('filename'); } } $result = [$part_num => [ 'type' => $content_type[0], 'subtype' => $content_type[1], 'attributes' => $attributes, "id" => $part->getContentId(), 'description' => false, 'encoding' => $part->getContentTransferEncoding(), 'size' => strlen($part->getContent()), 'lines' => $part->isTextPart() ? substr_count($part->getContent(), "\n") : false, 'md5' => false, 'disposition' => $part->getContentDisposition(false), 'file_attributes' => $file_attributes, 'language' => false, 'location' => false, ]]; if ($part->getChildCount() > 0) { $result[$part_num]['subs'] = []; foreach ($part->getChildParts() as $i => $subpart) { $subpart_num = $part_num . '.' . ($i + 1); $result[$part_num]['subs'] = array_merge($result[$part_num]['subs'], tiki_mime_part_to_bodystructure($subpart, $subpart_num)); } } return $result; } } /** * Retrieve mime part based off part number * @subpackage tiki/functions * @param ZBateson\MailMimeParser\Message\Part\MimePart $part the mime message part * @param string $part_num the mime message part number * @return ZBateson\MailMimeParser\Message\Part\MimePart */ if (! hm_exists('tiki_get_mime_part')) { function tiki_get_mime_part($part, $part_num = '0') { $part_num = explode('.', $part_num); array_shift($part_num); if (empty($part_num)) { return $part; } $part_num = array_values($part_num); foreach ($part->getChildParts() as $i => $subpart) { if ($part_num[0] - 1 == $i) { return tiki_get_mime_part($subpart, implode('.', $part_num)); } } return null; } } /** * Replace inline images in an HTML message part * @subpackage tiki/functions * @param ZBateson\MailMimeParser\Message\Part\MimePart $message the mime message part * @param string $txt HTML */ if (! hm_exists('tiki_add_attached_images')) { function tiki_add_attached_images($message, $txt) { if (preg_match_all("/src=('|\"|)cid:([^\s'\"]+)/", $txt, $matches)) { $cids = array_pop($matches); foreach ($cids as $id) { $part = $message->getPartByContentId($id); if (substr($part->getContentType(), 0, 5) != 'image') { continue; } $txt = str_replace('cid:' . $id, 'data:' . $part->getContentType() . ';base64,' . base64_encode($part->getContent()), $txt); } } return $txt; } } /** * Copy/Move messages from Tiki to an IMAP server * @subpackage tiki/functions * @param array $email Tiki-stored message to move * @param string $action action type, copy or move * @param array $dest_path imap id and folder to copy/move to * @param object $hm_cache cache interface * @return boolean result */ if (! hm_exists('tiki_move_to_imap_server')) { function tiki_move_to_imap_server($email, $action, $dest_path, $hm_cache) { $cache = Hm_IMAP_List::get_cache($hm_cache, $dest_path[1]); $dest_imap = Hm_IMAP_List::connect($dest_path[1], $cache); if ($dest_imap) { $file = Tiki\FileGallery\File::id($email['fileId']); $msg = $file->getContents(); if ($dest_imap->append_start(hex2bin($dest_path[2]), strlen($msg), true)) { $dest_imap->append_feed($msg . "\r\n"); if ($dest_imap->append_end()) { if ($action == 'move') { $trk = TikiLib::lib('trk'); $field = $trk->get_field_info($email['fieldId']); if (! $field) { return false; } $field['value'] = [ 'delete' => $email['fileId'] ]; $trk->replace_item($email['trackerId'], $email['itemId'], [ 'data' => [$field] ]); } return true; } } } return false; } } /** * Toggle a flag from a Tiki-stored message * @subpackage tiki/functions * @param array $fileId Tiki-stored message file ID * @param string $flag the flag to toggle * @return string the current flag state */ if (! hm_exists('tiki_toggle_flag_message')) { function tiki_toggle_flag_message($fileId, $flag) { $file = Tiki\FileGallery\File::id($fileId); if (preg_match("/Flags: (.*?)\r\n/", $file->getContents(), $matches)) { $flags = $matches[1]; } else { $flags = ''; } if (stristr($flags, $flag)) { return tiki_flag_message($fileId, 'remove', $flag); } else { return tiki_flag_message($fileId, 'add', $flag); } } } /** * Add or remove a flag from a Tiki-stored message * @subpackage tiki/functions * @param array $fileId Tiki-stored message file ID * @param string $action action type, add or remove * @param string $flag the flag to add or remove * @return string the current flag state */ if (! hm_exists('tiki_flag_message')) { function tiki_flag_message($fileId, $action, $flag) { $file = Tiki\FileGallery\File::id($fileId); if (preg_match("/Flags: (.*?)\r\n/", $file->getContents(), $matches)) { $flags = $matches[1]; } else { $flags = ''; } if ($action == 'remove') { $flags = preg_replace('/\\\?'.ucfirst($flag).'/', '', $flags); $state = 'un'.$flag; } elseif (! stristr($flags, $flag)) { $flags .= ' \\'.ucfirst($flag); $state = $flag; } $flags = preg_replace("/\s{2,}/", ' ', trim($flags)); $raw = preg_replace("/Flags:.*?\r\n/", "Flags: $flags\r\n", $file->getContents(), -1, $cnt); if ($cnt == 0) { $raw = "Flags: $flags\r\n".$raw; } $file->replaceQuick($raw); return $state; } }