From 5d596fe584cf1c3d0636f0d1ed64470302fc501e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 16 Nov 2018 16:43:13 +0100 Subject: [PATCH] Fix trackid must contains an id of instance --- htdocs/core/class/CMailFile.class.php | 8 +- htdocs/core/class/smtps.class.php | 2 +- htdocs/core/lib/functions.lib.php | 20 ++- .../class/emailcollector.class.php | 153 ++++++++++++++++-- .../class/emailcollectorfilter.class.php | 2 +- htdocs/langs/en_US/admin.lang | 2 +- 6 files changed, 155 insertions(+), 32 deletions(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 2b7532481c0..015abf0d89d 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -381,7 +381,7 @@ class CMailFile //$this->message = new Swift_SignedMessage(); // Adding a trackid header to a message $headers = $this->message->getHeaders(); - $headers->addTextHeader('X-Dolibarr-TRACKID', $trackid); + $headers->addTextHeader('X-Dolibarr-TRACKID', $trackid . '@' . $host); $headerID = time() . '.swiftmailer-dolibarr-' . $trackid . '@' . $host; $msgid = $headers->get('Message-ID'); $msgid->setId($headerID); @@ -1011,9 +1011,9 @@ class CMailFile if ($trackid) { // References is kept in response and Message-ID is returned into In-Reply-To: - $out.= 'Message-ID: <' . time() . '.phpmail-dolibarr-'.$trackid.'@' . $host . ">" . $this->eol2; // Uppercase seems replaced by phpmail - $out.= 'References: <' . time() . '.phpmail-dolibarr-'.$trackid.'@' . $host . ">" . $this->eol2; - $out.= 'X-Dolibarr-TRACKID: '.$trackid. $this->eol2; + $out.= 'Message-ID: <' . time() . '.phpmail-dolibarr-'. $trackid . '@' . $host . ">" . $this->eol2; // Uppercase seems replaced by phpmail + $out.= 'References: <' . time() . '.phpmail-dolibarr-'. $trackid . '@' . $host . ">" . $this->eol2; + $out.= 'X-Dolibarr-TRACKID: ' . $trackid . '@' . $host. $this->eol2; } else { diff --git a/htdocs/core/class/smtps.class.php b/htdocs/core/class/smtps.class.php index 113f5a6f278..1ade95098fa 100644 --- a/htdocs/core/class/smtps.class.php +++ b/htdocs/core/class/smtps.class.php @@ -1310,7 +1310,7 @@ class SMTPs // References is kept in response and Message-ID is returned into In-Reply-To: $_header .= 'Message-ID: <' . time() . '.SMTPs-dolibarr-'.$trackid.'@' . $host . ">\r\n"; $_header .= 'References: <' . time() . '.SMTPs-dolibarr-'.$trackid.'@' . $host . ">\r\n"; - $_header .= 'X-Dolibarr-TRACKID: ' . $trackid . "\r\n"; + $_header .= 'X-Dolibarr-TRACKID: ' . $trackid . '@' . $host . "\r\n"; } else { diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 7bb634cde2a..81ea685f68a 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -610,9 +610,9 @@ if (! function_exists('dol_getprefix')) { /** * Return a prefix to use for this Dolibarr instance, for session/cookie names or email id. - * This prefix is valid in a web context only and is unique for instance and avoid conflict - * between multi-instances, even when having two instances with one root dir or two instances - * in virtual servers. + * The prefix for session is unique in a web context only and is unique for instance and avoid conflict + * between multi-instances, even when having two instances with one root dir or two instances in virtual servers. + * The prefix for email is unique if MAIL_PREFIX_FOR_EMAIL_ID is set to a value, otherwise value may be same than other instance. * * @param string $mode '' (prefix for session name) or 'email' (prefix for email id) * @return string A calculated prefix @@ -621,11 +621,15 @@ if (! function_exists('dol_getprefix')) { global $conf; - // If MAIL_PREFIX_FOR_EMAIL_ID is set and prefix is for email - if ($mode == 'email' && ! empty($conf->global->MAIL_PREFIX_FOR_EMAIL_ID)) + // If prefix is for email + if ($mode == 'email') { - if ($conf->global->MAIL_PREFIX_FOR_EMAIL_ID != 'SERVER_NAME') return $conf->global->MAIL_PREFIX_FOR_EMAIL_ID; - else if (isset($_SERVER["SERVER_NAME"])) return $_SERVER["SERVER_NAME"]; + if (! empty($conf->global->MAIL_PREFIX_FOR_EMAIL_ID)) // If MAIL_PREFIX_FOR_EMAIL_ID is set (a value initialized with a random value is recommended) + { + if ($conf->global->MAIL_PREFIX_FOR_EMAIL_ID != 'SERVER_NAME') return $conf->global->MAIL_PREFIX_FOR_EMAIL_ID; + else if (isset($_SERVER["SERVER_NAME"])) return $_SERVER["SERVER_NAME"]; + } + return dol_hash(DOL_DOCUMENT_ROOT.DOL_URL_ROOT); } if (isset($_SERVER["SERVER_NAME"]) && isset($_SERVER["DOCUMENT_ROOT"])) @@ -634,7 +638,7 @@ if (! function_exists('dol_getprefix')) // Use this for a "readable" cookie name //return dol_sanitizeFileName($_SERVER["SERVER_NAME"].$_SERVER["DOCUMENT_ROOT"].DOL_DOCUMENT_ROOT.DOL_URL_ROOT); } - else return dol_hash(DOL_DOCUMENT_ROOT.DOL_URL_ROOT); + return dol_hash(DOL_DOCUMENT_ROOT.DOL_URL_ROOT); } } diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index e710fd90771..0f744387cce 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -745,13 +745,13 @@ class EmailCollector extends CommonObject $sourcestring=''; $sourcefield=''; $regexstring=''; - $transformationstring=''; + //$transformationstring=''; $regforregex=array(); if (preg_match('/^REGEX:([a-zA-Z0-9]+):(.*):([^:])$/', $valueforproperty, $regforregex)) { $sourcefield=$regforregex[0]; $regexstring=$regforregex[1]; - $transofrmationstring=$regforregex[2]; + //$transofrmationstring=$regforregex[2]; } elseif (preg_match('/^REGEX:([a-zA-Z0-9]+):(.*)$/', $valueforproperty, $regforregex)) { @@ -759,7 +759,7 @@ class EmailCollector extends CommonObject $regexstring=$regforregex[1]; } - if (! empty($sourcestring) && ! empty($regexstring)) + if (! empty($sourcefield) && ! empty($regexstring)) { if (strtolower($sourcefield) == 'body') $sourcestring=$messagetext; elseif (strtolower($sourcefield) == 'subject') $sourcestring=$subject; @@ -902,14 +902,28 @@ class EmailCollector extends CommonObject $headers = array_combine($matches[1], $matches[2]); //var_dump($headers); + // $conf->global->MAIL_PREFIX_FOR_EMAIL_ID must be defined + $host=dol_getprefix('email'); + // If there is a filter on trackid + //var_dump($host);exit; if ($searchfilterdoltrackid > 0) { - if (empty($headers['X-Dolibarr-TRACKID'])) continue; + //if (empty($headers['X-Dolibarr-TRACKID'])) continue; + if (empty($headers['References']) || ! preg_match('/@'.preg_quote($host,'/').'/', $headers['References'])) + { + $nbemailprocessed++; + continue; + } } if ($searchfilternodoltrackid > 0) { - if (! empty($headers['X-Dolibarr-TRACKID'])) continue; + if (! empty($headers['References']) && preg_match('/@'.preg_quote($host,'/').'/', $headers['References'])) + { + $nbemailprocessed++; + continue; + } + //if (! empty($headers['X-Dolibarr-TRACKID']) continue; } $thirdpartystatic=new Societe($this->db); @@ -967,10 +981,11 @@ class EmailCollector extends CommonObject $contactid = 0; $thirdpartyid = 0; $projectid = 0; - // Analyze TrackId + // Analyze TrackId in field References + // For example: References: <1542377954.SMTPs-dolibarr-thi649@8f6014fde11ec6cdec9a822234fc557e> $trackid = ''; $reg=array(); - if (! empty($headers['X-Dolibarr-TRACKID']) && preg_match('/:\s*([a-z]+)([0-9]+)$/', $headers['X-Dolibarr-TRACKID'], $reg)) + if (! empty($headers['References']) && preg_match('/dolibarr-([a-z]+)([0-9]+)@'.preg_quote($host,'/').'/', $headers['References'], $reg)) { $trackid = $reg[0].$reg[1]; @@ -1002,17 +1017,20 @@ class EmailCollector extends CommonObject $objectemail = new User($this->db); } - $result = $objectemail->fetch($objectid); - if ($result > 0) + if (is_object($objectemail)) { - $fk_element_id = $objectemail->id; - $fk_element_type = $objectemail->element; - // Fix fk_element_type - if ($fk_element_type == 'facture') $fk_element_type = 'invoice'; + $result = $objectemail->fetch($objectid); + if ($result > 0) + { + $fk_element_id = $objectemail->id; + $fk_element_type = $objectemail->element; + // Fix fk_element_type + if ($fk_element_type == 'facture') $fk_element_type = 'invoice'; - $thirdpartyid = $objectemail->fk_soc; - $contactid = $objectemail->fk_socpeople; - $projectid = isset($objectemail->fk_project)?$objectemail->fk_project:$objectemail->fk_projet; + $thirdpartyid = $objectemail->fk_soc; + $contactid = $objectemail->fk_socpeople; + $projectid = isset($objectemail->fk_project)?$objectemail->fk_project:$objectemail->fk_projet; + } } // Project @@ -1087,14 +1105,115 @@ class EmailCollector extends CommonObject if (empty($operation['status'])) continue; // Make Operation + dol_syslog("Execute action ".$operation['type']." actionparam=".$operation['actionparam'].' thirdpartystatic->id='.$thirdpartystatic->id.' contactstatic->id='.$contactstatic->id.' projectstatic->id='.$projectstatic->id); // Search and create thirdparty - if ($operation['type'] == 'searchandcreatethirdparty') + if ($operation['type'] == 'loadthirdparty' && $operation['type'] == 'loadandcreatethirdparty') { + if (empty($operation['actionparam'])) + { + $errorforactions++; + $this->errors = "Action loadthirdparty or loadandcreatethirdparty has empty parameter. Must be 'VALUE:xxx' or 'REGEX:(body|subject):regex' to extract"; + } + else + { + $actionparam = $operation['actionparam']; + $nametouseforthirdparty=''; + // $this->actionparam = 'VALUE:aaa' or 'REGEX:BODY:....' + $arrayvaluetouse = dolExplodeIntoArray($actionparam, ';', '='); + foreach($arrayvaluetouse as $propertytooverwrite => $valueforproperty) + { + $tmpclass=''; $tmpproperty=''; + $tmparray=explode('.', $propertytooverwrite); + if (count($tmparray) == 2) + { + $tmpclass=$tmparray[0]; + $tmpproperty=$tmparray[1]; + } + else + { + $tmpproperty=$tmparray[0]; + } + //if ($tmpclass && ($tmpclass != $object->element)) continue; // Property is for another type of object + $sourcestring=''; + $sourcefield=''; + $regexstring=''; + $regforregex=array(); + if (preg_match('/^REGEX:([a-zA-Z0-9]+):(.*)$/', $valueforproperty, $regforregex)) + { + $sourcefield=$regforregex[0]; + $regexstring=$regforregex[1]; + } + if (! empty($sourcefield) && ! empty($regexstring)) + { + if (strtolower($sourcefield) == 'body') $sourcestring=$messagetext; + elseif (strtolower($sourcefield) == 'subject') $sourcestring=$subject; + $regforval=array(); + if (preg_match('/'.preg_quote($regexstring, '/').'/', $sourcestring, $regforval)) + { + // Overwrite param $tmpproperty + $nametouseforthirdparty = $regforval[0]; + } + else + { + // Nothing can be done for this param + } + } + elseif (preg_match('/^VALUE:(.*)$/', $valueforproperty, $reg)) + { + $nametouseforthirdparty = $reg[0]; + } + else + { + $errorforactions++; + $this->error = 'Bad syntax for description of action parameters: '.$actionparam; + $this->errors[] = $this->error; + break; + } + } + + if (! $errorforactions && $nametouseforthirdparty) + { + $result = $thirdpartystatic->fetch(0, $nametouseforthirdparty); + if ($result < 0) + { + $errorforactions++; + $this->error = 'Error when getting thirdparty with name '.$nametouseforthirdparty.' (may be 2 record exists with same name ?)'; + $this->errors[] = $this->error; + break; + } + elseif ($result == 0) + { + if ($operation['type'] == 'loadandcreatethirdparty') + { + // Create thirdparty + $thirdpartystatic->name = $nametouseforthirdparty; + + // Overwrite values with values extracted from source email + $errorforthisaction = $this->overwritePropertiesOfObject($thirdpartystatic, $operation['actionparam'], $messagetext, $subject); + + if ($errorforthisaction) + { + $errorforactions++; + } + else + { + $result = $thirdpartystatic->create($user); + if ($result <= 0) + { + $errorforactions++; + $this->error = $thirdpartystatic->error; + $this->errors = $thirdpartystatic->errors; + } + } + } + } + } + } } // Create event elseif ($operation['type'] == 'recordevent') diff --git a/htdocs/emailcollector/class/emailcollectorfilter.class.php b/htdocs/emailcollector/class/emailcollectorfilter.class.php index c4e94b5e4bb..ddf68ce9512 100644 --- a/htdocs/emailcollector/class/emailcollectorfilter.class.php +++ b/htdocs/emailcollector/class/emailcollectorfilter.class.php @@ -159,7 +159,7 @@ class EmailCollectorFilter extends CommonObject $this->errors[]=$langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Type")); return -1; } - if (! in_array($this->type, array('seen','unseen')) && empty($this->rulevalue)) + if (! in_array($this->type, array('seen','unseen','withtrackingid','withouttrackingid')) && empty($this->rulevalue)) { $langs->load("errors"); $this->errors[]=$langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("StringToFilter")); diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index dd570e9a357..563d0852956 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1833,7 +1833,7 @@ EmailCollectorConfirmCollectTitle=Email collect confirmation EmailCollectorConfirmCollect=Do you want to run the collect for this collector now ? NoNewEmailToProcess=No new email (matching filters) to process NothingProcessed=Nothing done -XEmailsDoneYActionsDone=%s emails analyzed, %s emails successfuly processed (for %s record/actions done) by collector +XEmailsDoneYActionsDone=%s emails qualified, %s emails successfuly processed (for %s record/actions done) by collector RecordEvent=Record email event CreateLeadAndThirdParty=Create lead (and thirdparty if necessary) CodeLastResult=Result code of last collect