/** function buildTicket - Builds,and returns, the major structure of the ticket to be entered.
*
* @param $i mail ID
* @param $options array of possible options
*
* @return ticket fields array
*/
function buildTicket($i, $options = array())
{
global $CFG_GLPI;
$play_rules = isset($options['play_rules']) && $options['play_rules'];
$head = $this->getHeaders($i);
// Get Header Info Return Array Of Headers
// **Key Are (subject,to,toOth,toNameOth,from,fromName)
$tkt = array();
$tkt['_blacklisted'] = false;
// For RuleTickets
$tkt['_mailgate'] = $options['mailgates_id'];
// Use mail date if it's defined
if ($this->fields['use_mail_date']) {
$tkt['date'] = $head['date'];
}
// Detect if it is a mail reply
$glpi_message_match = "/GLPI-([0-9]+)\\.[0-9]+\\.[0-9]+@\\w*/";
// Check if email not send by GLPI : if yes -> blacklist
if (!isset($head['message_id']) || preg_match($glpi_message_match, $head['message_id'], $match)) {
$tkt['_blacklisted'] = true;
return $tkt;
}
// manage blacklist
$blacklisted_emails = Blacklist::getEmails();
// Add name of the mailcollector as blacklisted
$blacklisted_emails[] = $this->fields['name'];
if (Toolbox::inArrayCaseCompare($head['from'], $blacklisted_emails)) {
$tkt['_blacklisted'] = true;
return $tkt;
}
// max size = 0 : no import attachments
if ($this->fields['filesize_max'] > 0) {
if (is_writable(GLPI_TMP_DIR)) {
$tkt['_filename'] = $this->getAttached($i, GLPI_TMP_DIR . "/", $this->fields['filesize_max']);
$tkt['_tag'] = $this->tags;
} else {
//TRANS: %s is a directory
Toolbox::logInFile('mailgate', sprintf(__('%s is not writable'), GLPI_TMP_DIR . "/"));
}
}
// Who is the user ?
$tkt['_users_id_requester'] = User::getOrImportByEmail($head['from']);
$tkt["_users_id_requester_notif"]['use_notification'] = 1;
// Set alternative email if user not found / used if anonymous mail creation is enable
if (!$tkt['_users_id_requester']) {
$tkt["_users_id_requester_notif"]['alternative_email'] = $head['from'];
}
// Add to and cc as additional observer if user found
if (count($head['ccs'])) {
foreach ($head['ccs'] as $cc) {
if ($cc != $head['from'] && !Toolbox::inArrayCaseCompare($cc, $blacklisted_emails) && ($tmp = User::getOrImportByEmail($cc)) > 0) {
$tkt['_additional_observers'][] = array('users_id' => $tmp, 'use_notification' => 1);
}
}
}
if (count($head['tos'])) {
foreach ($head['tos'] as $to) {
if ($to != $head['from'] && !Toolbox::inArrayCaseCompare($to, $blacklisted_emails) && ($tmp = User::getOrImportByEmail($to)) > 0) {
$tkt['_additional_observers'][] = array('users_id' => $tmp, 'use_notification' => 1);
}
}
}
// Auto_import
$tkt['_auto_import'] = 1;
// For followup : do not check users_id = login user
$tkt['_do_not_check_users_id'] = 1;
$body = $this->getBody($i);
// Do it before using charset variable
$head['subject'] = $this->decodeMimeString($head['subject']);
$tkt['_head'] = $head;
if (!empty($this->charset) && !$this->body_converted) {
$body = Toolbox::encodeInUtf8($body, $this->charset);
$this->body_converted = true;
}
if (!Toolbox::seems_utf8($body)) {
$tkt['content'] = Toolbox::encodeInUtf8($body);
} else {
$tkt['content'] = $body;
}
// See In-Reply-To field
if (isset($head['in_reply_to'])) {
if (preg_match($glpi_message_match, $head['in_reply_to'], $match)) {
$tkt['tickets_id'] = intval($match[1]);
}
}
// See in References
if (!isset($tkt['tickets_id']) && isset($head['references'])) {
if (preg_match($glpi_message_match, $head['references'], $match)) {
$tkt['tickets_id'] = intval($match[1]);
}
}
// See in title
if (!isset($tkt['tickets_id']) && preg_match('/\\[.+#(\\d+)\\]/', $head['subject'], $match)) {
$tkt['tickets_id'] = intval($match[1]);
}
$is_html = false;
//If files are present and content is html
if (isset($this->files) && count($this->files) && $tkt['content'] != strip_tags($tkt['content']) && !isset($tkt['tickets_id'])) {
$is_html = true;
$tkt['content'] = Ticket::convertContentForTicket($tkt['content'], array_merge($this->files, $this->altfiles), $this->tags);
}
$tkt['content'] = $this->cleanMailContent($tkt['content']);
if ($is_html && !isset($tkt['tickets_id'])) {
$tkt['content'] = nl2br($tkt['content']);
}
$tkt['_supplier_email'] = false;
// Found ticket link
if (isset($tkt['tickets_id'])) {
// it's a reply to a previous ticket
$job = new Ticket();
$tu = new Ticket_User();
$st = new Supplier_Ticket();
// Check if ticket exists and users_id exists in GLPI
/// TODO check if users_id have right to add a followup to the ticket
if ($job->getFromDB($tkt['tickets_id']) && $job->fields['status'] != CommonITILObject::CLOSED && ($CFG_GLPI['use_anonymous_followups'] || $tkt['_users_id_requester'] > 0 || $tu->isAlternateEmailForITILObject($tkt['tickets_id'], $head['from']) || ($tkt['_supplier_email'] = $st->isSupplierEmail($tkt['tickets_id'], $head['from'])))) {
if ($tkt['_supplier_email']) {
$tkt['content'] = sprintf(__('From %s'), $head['from']) . "\n\n" . $tkt['content'];
}
$content = explode("\n", $tkt['content']);
$tkt['content'] = "";
$to_keep = array();
// Move requester to author of followup :
$tkt['users_id'] = $tkt['_users_id_requester'];
$begin_strip = -1;
$end_strip = -1;
$begin_match = "/" . NotificationTargetTicket::HEADERTAG . ".*" . NotificationTargetTicket::HEADERTAG . "/";
$end_match = "/" . NotificationTargetTicket::FOOTERTAG . ".*" . NotificationTargetTicket::FOOTERTAG . "/";
foreach ($content as $ID => $val) {
// Get first tag for begin
if ($begin_strip < 0) {
if (preg_match($begin_match, $val)) {
$begin_strip = $ID;
}
}
// Get last tag for end
if ($begin_strip >= 0) {
if (preg_match($end_match, $val)) {
$end_strip = $ID;
continue;
}
}
}
if ($begin_strip >= 0) {
// Clean first and last lines
$content[$begin_strip] = preg_replace($begin_match, '', $content[$begin_strip]);
}
if ($end_strip >= 0) {
// Clean first and last lines
$content[$end_strip] = preg_replace($end_match, '', $content[$end_strip]);
}
if ($begin_strip >= 0) {
$length = count($content);
// Use end strip if set
if ($end_strip >= 0 && $end_strip < $length) {
$length = $end_strip;
}
for ($i = $begin_strip + 1; $i < $length; $i++) {
unset($content[$i]);
}
}
$to_keep = array();
// Aditional clean for thunderbird
foreach ($content as $ID => $val) {
if (!isset($val[0]) || $val[0] != '>') {
$to_keep[$ID] = $ID;
}
}
$tkt['content'] = "";
foreach ($to_keep as $ID) {
$tkt['content'] .= $content[$ID] . "\n";
}
// Do not play rules for followups : WRONG : play rules only for refuse options
//$play_rules = false;
} else {
// => to handle link in Ticket->post_addItem()
$tkt['_linkedto'] = $tkt['tickets_id'];
unset($tkt['tickets_id']);
}
}
// Add message from getAttached
if ($this->addtobody) {
$tkt['content'] .= $this->addtobody;
}
$tkt['name'] = $this->textCleaner($head['subject']);
if (!isset($tkt['tickets_id'])) {
// Which entity ?
//$tkt['entities_id']=$this->fields['entities_id'];
//$tkt['Subject']= $head['subject']; // not use for the moment
// Medium
$tkt['urgency'] = "3";
// No hardware associated
$tkt['itemtype'] = "";
// Mail request type
} else {
// Reopen if needed
$tkt['add_reopen'] = 1;
}
$tkt['requesttypes_id'] = RequestType::getDefault('mail');
if ($play_rules) {
$rule_options['ticket'] = $tkt;
$rule_options['headers'] = $head;
$rule_options['mailcollector'] = $options['mailgates_id'];
$rule_options['_users_id_requester'] = $tkt['_users_id_requester'];
$rulecollection = new RuleMailCollectorCollection();
$output = $rulecollection->processAllRules(array(), array(), $rule_options);
// New ticket : compute all
if (!isset($tkt['tickets_id'])) {
foreach ($output as $key => $value) {
$tkt[$key] = $value;
}
} else {
// Followup only copy refuse data
$tobecopied = array('_refuse_email_no_response', '_refuse_email_with_response');
foreach ($tobecopied as $val) {
if (isset($output[$val])) {
$tkt[$val] = $output[$val];
}
}
}
}
$tkt = Toolbox::addslashes_deep($tkt);
return $tkt;
}