diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index 2c1e0948e01..fb08286e0a3 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -660,12 +660,18 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if (empty($reshook)) { + // Edit print '
'.$langs->trans("Edit").'
'; // Clone print '
'.$langs->trans("ToClone").'
'; - print '
'.$langs->trans("CollectNow").'
'; + // Collect now + if (count($object->actions) > 0) { + print '
'.$langs->trans("CollectNow").'
'; + } else { + print '
'.$langs->trans("CollectNow").'
'; + } print '
'.$langs->trans('Delete').'
'; } diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index 91b1b697398..8c8e0daeb26 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -246,7 +246,36 @@ class EmailCollector extends CommonObject */ public function create(User $user, $notrigger = false) { - return $this->createCommon($user, $notrigger); + $id = $this->createCommon($user, $notrigger); + + if (is_array($this->filters) && count($this->filters)) { + $emailcollectorfilter = new EmailCollectorFilter($this->db); + + foreach($this->filters as $filter) { + $emailcollectorfilter->type = $filter['type']; + $emailcollectorfilter->rulevalue = $filter['rulevalue']; + $emailcollectorfilter->fk_emailcollector = $this->id; + $emailcollectorfilter->status = $filter['status']; + + $emailcollectorfilter->create($user); + } + } + + if (is_array($this->filters) && count($this->filters)) { + $emailcollectoroperation = new EmailCollectorAction($this->db); + + foreach($this->actions as $operation) { + $emailcollectoroperation->type = $operation['type']; + $emailcollectoroperation->actionparam = $operation['actionparam']; + $emailcollectoroperation->fk_emailcollector = $this->id; + $emailcollectoroperation->status = $operation['status']; + $emailcollectoroperation->position = $operation['position']; + + $emailcollectoroperation->create($user); + } + } + + return $id; } /** @@ -269,6 +298,10 @@ class EmailCollector extends CommonObject // Load source object $object->fetchCommon($fromid); + + $object->fetchFilters(); // Rules + $object->fetchActions(); // Operations + // Reset some properties unset($object->id); unset($object->fk_user_creat); @@ -295,7 +328,7 @@ class EmailCollector extends CommonObject // Create clone $object->context['createfromclone'] = 'createfromclone'; - $result = $object->createCommon($user); + $result = $object->create($user); if ($result < 0) { $error++; $this->error = $object->error; @@ -605,6 +638,7 @@ class EmailCollector extends CommonObject * Fetch filters * * @return int <0 if KO, >0 if OK + * @see fetchActions() */ public function fetchFilters() { @@ -636,6 +670,7 @@ class EmailCollector extends CommonObject * Fetch actions * * @return int <0 if KO, >0 if OK + * @see fetchFilters() */ public function fetchActions() { @@ -1085,7 +1120,7 @@ class EmailCollector extends CommonObject dol_syslog("Start of loop on email", LOG_INFO, 1); - $i = 0; + $iforemailloop = 0; foreach ($arrayofemail as $imapemail) { if ($nbemailprocessed > 1000) @@ -1093,7 +1128,7 @@ class EmailCollector extends CommonObject break; // Do not process more than 1000 email per launch (this is a different protection than maxnbcollectedpercollect } - $i++; + $iforemailloop++; $header = imap_fetchheader($connection, $imapemail, 0); $header = preg_replace('/\r\n\s+/m', ' ', $header); // When a header line is on several lines, merge lines @@ -1107,9 +1142,12 @@ class EmailCollector extends CommonObject if (!empty($headers['in-reply-to']) && empty($headers['In-Reply-To'])) { $headers['In-Reply-To'] = $headers['in-reply-to']; } if (!empty($headers['references']) && empty($headers['References'])) { $headers['References'] = $headers['references']; } if (!empty($headers['message-id']) && empty($headers['Message-ID'])) { $headers['Message-ID'] = $headers['message-id']; } + $headers['Subject'] = $this->decodeSMTPSubject($headers['Subject']); - dol_syslog("** Process email ".$i." References: ".$headers['References']); + + dol_syslog("** Process email ".$iforemailloop." References: ".$headers['References']); + //print "Process mail ".$iforemailloop." Subject: ".dol_escape_htmltag($headers['Subject'])." References: ".dol_escape_htmltag($headers['References'])." In-Reply-To: ".dol_escape_htmltag($headers['In-Reply-To'])."
\n"; // If there is a filter on trackid if ($searchfilterdoltrackid > 0) @@ -1135,6 +1173,17 @@ class EmailCollector extends CommonObject $nbemailprocessed++; continue; // Exclude email } + // Note: we can have + // Message-ID=A, In-Reply-To=B, References=B and message can BE an answer or NOT (a transfer rewriten) + $isanswer = 0; + if (preg_match('/Re\s*:\s+/i', $headers['Subject'])) $isanswer = 1; + //if ($headers['In-Reply-To'] != $headers['Message-ID'] && empty($headers['References'])) $isanswer = 1; // If in-reply-to differs of message-id, this is a reply + //if ($headers['In-Reply-To'] != $headers['Message-ID'] && !empty($headers['References']) && strpos($headers['References'], $headers['Message-ID']) !== false) $isanswer = 1; + + if (!$isanswer) { + $nbemailprocessed++; + continue; // Exclude email + } } if ($searchfilterisnotanswer > 0) { if (!empty($headers['In-Reply-To'])) @@ -1142,7 +1191,7 @@ class EmailCollector extends CommonObject // Note: we can have // Message-ID=A, In-Reply-To=B, References=B and message can BE an answer or NOT (a transfer rewriten) $isanswer = 0; - if (preg_match('/Re:\s+/i', $headers['Subject'])) $isanswer = 1; + if (preg_match('/Re\s*:\s+/i', $headers['Subject'])) $isanswer = 1; //if ($headers['In-Reply-To'] != $headers['Message-ID'] && empty($headers['References'])) $isanswer = 1; // If in-reply-to differs of message-id, this is a reply //if ($headers['In-Reply-To'] != $headers['Message-ID'] && !empty($headers['References']) && strpos($headers['References'], $headers['Message-ID']) !== false) $isanswer = 1; if ($isanswer) { @@ -1152,6 +1201,7 @@ class EmailCollector extends CommonObject } } + //print "Process mail ".$iforemailloop." Subject: ".dol_escape_htmltag($headers['Subject'])." selected
\n"; $thirdpartystatic = new Societe($this->db); $contactstatic = new Contact($this->db); @@ -1277,10 +1327,12 @@ class EmailCollector extends CommonObject $reg = array(); if (!empty($headers['References'])) { - $arrayofreferences = preg_split('/\s+/', $headers['References']); + $arrayofreferences = preg_split('/(,|\s+)/', $headers['References']); + //var_dump($headers['References']); + //var_dump($arrayofreferences); foreach ($arrayofreferences as $reference) { - //print "Process reference ".dol_escape_htmltag($reference)."
\n"; + //print "Process mail ".$iforemailloop." email_msgid ".$msgid.", date ".dol_print_date($date, 'dayhour').", subject ".$subject.", reference ".dol_escape_htmltag($reference)."
\n"; if (preg_match('/dolibarr-([a-z]+)([0-9]+)@'.preg_quote($host, '/').'/', $reference, $reg)) { // This is a Dolibarr reference $trackid = $reg[1].$reg[2]; @@ -1459,6 +1511,7 @@ class EmailCollector extends CommonObject // Make Operation dol_syslog("Execute action ".$operation['type']." actionparam=".$operation['actionparam'].' thirdpartystatic->id='.$thirdpartystatic->id.' contactstatic->id='.$contactstatic->id.' projectstatic->id='.$projectstatic->id); + dol_syslog("Execute action fk_element_id=".$fk_element_id." fk_element_type=".$fk_element_type); $actioncode = 'EMAIL_IN'; // If we scan the Sent box, we use the code for out email @@ -1646,7 +1699,11 @@ class EmailCollector extends CommonObject if (!in_array($fk_element_type, array('societe', 'contact', 'project', 'user'))) { $actioncomm->fk_element = $fk_element_id; + $actioncomm->elementid = $fk_element_id; $actioncomm->elementtype = $fk_element_type; + if (is_object($objectemail) && $objectemail->module) { + $actioncomm->elementtype .= '@'.$objectemail->module; + } } //$actioncomm->extraparams = $extraparams; @@ -1654,6 +1711,13 @@ class EmailCollector extends CommonObject // Overwrite values with values extracted from source email $errorforthisaction = $this->overwritePropertiesOfObject($actioncomm, $operation['actionparam'], $messagetext, $subject, $header); + /*var_dump($fk_element_id); + var_dump($fk_element_type); + var_dump($alreadycreated); + var_dump($operation['type']); + var_dump($actioncomm); + exit;*/ + if ($errorforthisaction) { $errorforactions++; @@ -2276,10 +2340,14 @@ class EmailCollector extends CommonObject } /** - * Decode a subject string + * Decode a subject string according to RFC2047 + * Example: '=?Windows-1252?Q?RE=A0:_ABC?=' => 'RE : ABC...' + * Example: '=?UTF-8?Q?A=C3=A9B?=' => 'AéB' + * Example: '=?UTF-8?B?2KLYstmF2KfbjNi0?=' => + * Example: '=?utf-8?B?UkU6IG1vZHVsZSBkb2xpYmFyciBnZXN0aW9ubmFpcmUgZGUgZmljaGllcnMg?= =?utf-8?B?UsOpZsOpcmVuY2UgZGUgbGEgY29tbWFuZGUgVFVHRURJSklSIOKAkyBwYXNz?= =?utf-8?B?w6llIGxlIDIyLzA0LzIwMjA=?=' * * @param string $subject Subject - * @return string Decoded subject + * @return string Decoded subject (in UTF-8) */ protected function decodeSMTPSubject($subject) { @@ -2287,20 +2355,22 @@ class EmailCollector extends CommonObject // Can use also imap_mime_header_decode($str) // Can use also mb_decode_mimeheader($str) // Can use also iconv_mime_decode($str, ICONV_MIME_DECODE_CONTINUE_ON_ERROR, 'UTF-8') - if (function_exists('iconv_mime_decode')) { - $subject = iconv_mime_decode($subject, ICONV_MIME_DECODE_CONTINUE_ON_ERROR, 'UTF-8'); - } elseif (function_exists('imap_mime_header_decode')) { + if (function_exists('imap_mime_header_decode') && function_exists('iconv_mime_decode')) { $elements = imap_mime_header_decode($subject); + //var_dump($elements); $newstring = ''; if (!empty($elements)) { $num = count($elements); for ($i = 0; $i < $num; $i++) { - $newstring .= ($newstring ? ' ' : '').$elements[$i]->text; + $stringinutf8 = (in_array(strtoupper($elements[$i]->charset), array('default', 'UTF-8')) ? $elements[$i]->text : iconv_mime_decode($elements[$i]->text, ICONV_MIME_DECODE_CONTINUE_ON_ERROR, $elements[$i]->charset)); + $newstring .= $stringinutf8; } $subject = $newstring; } - } elseif (function_exists('mb_decode_mimeheader')) { - $subject = mb_decode_mimeheader($subject); + } elseif (!function_exists('mb_decode_mimeheader')) { + $subject = mb_decode_mimeheader($subject); + } elseif (function_exists('iconv_mime_decode')) { + $subject = iconv_mime_decode($subject, ICONV_MIME_DECODE_CONTINUE_ON_ERROR, 'UTF-8'); } return $subject; diff --git a/htdocs/emailcollector/class/emailcollectorfilter.class.php b/htdocs/emailcollector/class/emailcollectorfilter.class.php index 5982b5ffd20..40c8a91d235 100644 --- a/htdocs/emailcollector/class/emailcollectorfilter.class.php +++ b/htdocs/emailcollector/class/emailcollectorfilter.class.php @@ -169,7 +169,7 @@ class EmailCollectorFilter extends CommonObject { $langs->load("errors"); $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("SearchString")); - return -1; + return -2; } return $this->createCommon($user, $notrigger);