diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index be3ab2d63c1..dca93b9a506 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -583,6 +583,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $arrayoftypes = array( 'loadthirdparty'=>$langs->trans('LoadThirdPartyFromName', $langs->transnoentities("ThirdPartyName")), 'loadandcreatethirdparty'=>$langs->trans('LoadThirdPartyFromNameOrCreate', $langs->transnoentities("ThirdPartyName")), + 'recordjoinpiece'=>$langs->trans('recordjoinpieceonobject'), 'recordevent'=>'RecordEvent'); if ($conf->projet->enabled) { $arrayoftypes['project'] = 'CreateLeadAndThirdParty'; diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index 0a52969f9f6..729762be327 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -1897,6 +1897,164 @@ class EmailCollector extends CommonObject } } } + } elseif ($operation['type'] == 'recordjoinpiece') { + $pj = getAttachments($imapemail, $connection); + foreach ($pj as $key => $val) { + $data[$val['filename']] = getFileData($imapemail, $val['pos'], $val['type'], $connection); + } + if (count($pj) > 0) { + $sql = "SELECT rowid as id FROM " . MAIN_DB_PREFIX . "user WHERE email LIKE '%" . $from . "%'"; + $resql = $this->db->query($sql); + if ($resql->num_rows == 0) { + $this->errors = 'User Not allowed to add documents'; + } + $arrayobject = array( + 'propale' => array('table' => 'propal', + 'fields' => array('ref'), + 'class' => 'comm/propal/class/propal.class.php', + 'object' => 'Propal'), + 'holiday' => array('table' => 'holiday', + 'fields' => array('ref'), + 'class' => 'holiday/class/holiday.class.php', + 'object' => 'Holiday'), + 'expensereport' => array('table' => 'expensereport', + 'fields' => array('ref'), + 'class' => 'expensereport/class/expensereport.class.php', + 'object' => 'ExpenseReport'), + 'recruitment/recruitmentjobposition' => array('table' => 'recruitment_recruitmentjobposition', + 'fields' => array('ref'), + 'class' => 'recruitment/class/recruitmentjobposition.class.php', + 'object' => 'RecruitmentJobPosition'), + 'recruitment/recruitmentjobposition' => array('table' => 'recruitment_recruitmentcandidature', + 'fields' => array('ref'), + 'class' => 'recruitment/class/recruitmentcandidature.class.php', + 'object' => ' RecruitmentCandidature'), + 'societe' => array('table' => 'societe', + 'fields' => array('code_client', 'code_fournisseur'), + 'class' => 'societe/class/societe.class.php', + 'object' => 'Societe'), + 'commande' => array('table' => 'commande', + 'fields' => array('ref'), + 'class' => 'commande/class/commande.class.php', + 'object' => 'Commande'), + 'expedition' => array('table' => 'expedition', + 'fields' => array('ref'), + 'class' => 'expedition/class/expedition.class.php', + 'object' => 'Expedition'), + 'contract' => array('table' => 'contrat', + 'fields' => array('ref'), + 'class' => 'contrat/class/contrat.class.php', + 'object' => 'Contrat'), + 'fichinter' => array('table' => 'fichinter', + 'fields' => array('ref'), + 'class' => 'fichinter/class/fichinter.class.php', + 'object' => 'Fichinter'), + 'ticket' => array('table' => 'ticket', + 'fields' => array('ref'), + 'class' => 'ticket/class/ticket.class.php', + 'object' => ' Ticket'), + 'knowledgemanagement' => array('table' => 'knowledgemanagement_knowledgerecord', + 'fields' => array('ref'), + 'class' => 'knowledgemanagement/class/knowledgemanagement.class.php', + 'object' => 'KnowledgeRecord'), + 'supplier_proposal' => array('table' => 'supplier_proposal', + 'fields' => array('ref'), + 'class' => 'supplier_proposal/class/supplier_proposal.class.php', + 'object' => 'SupplierProposal'), + 'fournisseur/commande' => array('table' => 'commande_fournisseur', + 'fields' => array('ref', 'ref_supplier'), + 'class' => 'fourn/class/fournisseur.commande.class.php', + 'object' => 'SupplierProposal'), + 'facture' => array('table' => 'facture', + 'fields' => array('ref'), + 'class' => 'compta/facture/class/facture.class.php', + 'object' => 'Facture'), + 'fournisseur/facture' => array('table' => 'facture_fourn', + 'fields' => array('ref', ref_client), + 'class' => 'fourn/class/fournisseur.facture.class.php', + 'object' => 'FactureFournisseur'), + 'produit' => array('table' => 'product', + 'fields' => array('ref'), + 'class' => 'product/class/product.class.php', + 'object' => 'Product'), + 'productlot' => array('table' => 'product_lot', + 'fields' => array('batch'), + 'class' => 'product/stock/class/productlot.class.php', + 'object' => 'Productlot'), + 'projet' => array('table' => 'projet', + 'fields' => array('ref'), + 'class' => 'projet/class/projet.class.php', + 'object' => 'Project'), + 'projet_task' => array('table' => 'projet_task', + 'fields' => array('ref'), + 'class' => 'projet/class/task.class.php', + 'object' => 'Task'), + 'ressource' => array('table' => 'resource', + 'fields' => array('ref'), + 'class' => 'ressource/class/dolressource.class.php', + 'object' => 'Dolresource'), + 'bom' => array('table' => 'bom_bom', + 'fields' => array('ref'), + 'class' => 'bom/class/bom.class.php', + 'object' => 'BOM'), + 'mrp' => array('table' => 'mrp_mo', + 'fields' => array('ref'), + 'class' => 'mrp/class/mo.class.php', + 'object' => 'Mo'), + ); + + $hookmanager->initHooks(array('emailcolector')); + $parameters = array('arrayobject' => $arrayobject); + $reshook = $hookmanager->executeHooks('addmoduletoeamailcollectorjoinpiece', $parameters); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) $arrayobject = $hookmanager->resArray; + + $resultobj = array(); + + foreach ($arrayobject as $key => $objectdesc) { + $sql = 'SELECT DISTINCT t.rowid '; + $sql .= ' FROM ' . MAIN_DB_PREFIX . $objectdesc['table'] . ' AS t'; + $sql .= ' WHERE '; + foreach ($objectdesc['fields'] as $field) { + $sql .= "'" .$this->db->escape($subject) . "' LIKE CONCAT('%', t." . $field . ", '%') OR "; + } + $sql = substr($sql, 0, -4); + + $ressqlobj = $this->db->query($sql); + if ($ressqlobj) { + while ($obj = $this->db->fetch_object($ressqlobj)) { + $resultobj[$key][] = $obj->rowid; + } + } + } + $dirs = array(); + foreach ($resultobj as $mod => $ids) { + $moddesc = $arrayobject[$mod]; + $elementpath = $mod; + dol_include_once($moddesc['class']); + $objectmanaged = new $moddesc['object']($this->db); + foreach ($ids as $val) { + $res = $objectmanaged->fetch($val); + if ($res) { + $path = ($objectmanaged->entity > 1 ? "/" . $objectmanaged->entity : ''); + $dirs[] = DOL_DATA_ROOT . $path . "/" . $elementpath . '/' . dol_sanitizeFileName($objectmanaged->ref) . '/'; + } else { + $this->errors = 'object not found'; + } + } + } + foreach ($dirs as $target) { + foreach ($data as $filename => $content) { + $prefix = $this->actions[$this->id]['actionparam']; + + $resr = saveAttachment($target, $prefix . '_' . $filename, $content); + if ($resr == -1) { + $this->errors = 'Doc not saved'; + } + } + } + } else { + $this->errors = 'no joined piece'; + } } elseif ($operation['type'] == 'project') { // Create project / lead $projecttocreate = new Project($this->db); diff --git a/htdocs/emailcollector/lib/emailcollector.lib.php b/htdocs/emailcollector/lib/emailcollector.lib.php index fe4a5f1b19c..9b63bbea66a 100644 --- a/htdocs/emailcollector/lib/emailcollector.lib.php +++ b/htdocs/emailcollector/lib/emailcollector.lib.php @@ -85,3 +85,132 @@ function emailcollectorPrepareHead($object) return $head; } + +/** + * Récupère les parties d'un message + * @param object $structure structure du message + * @return object|boolean parties du message|false en cas d'erreur + */ +function getParts($structure) +{ + return isset($structure->parts) ? $structure->parts : false; +} + +/** + * Tableau définissant la pièce jointe + * @param object $part partie du message + * @return object|boolean définition du message|false en cas d'erreur + */ +function getDParameters($part) +{ + return $part->ifdparameters ? $part->dparameters : false; +} + +/** + * Récupère les pièces d'un mail donné + * @param integer $jk numéro du mail + * @param object $mbox object connection imaap + * @return array type, filename, pos + */ +function getAttachments($jk, $mbox) +{ + $structure = imap_fetchstructure($mbox, $jk); + $parts = getParts($structure); + $fpos = 2; + $attachments = array(); + $nb = count($parts); + if ($parts && $nb) { + for ($i = 1; $i < $nb; $i++) { + $part = $parts[$i]; + + if ($part->ifdisposition && strtolower($part->disposition) == "attachment") { + $ext = $part->subtype; + $params = getDParameters($part); + + if ($params) { + $filename = $part->dparameters[0]->value; + $filename = imap_utf8($filename); + $attachments[] = array('type' => $part->type, 'filename' => $filename, 'pos' => $fpos); + } + } + $fpos++; + } + } + return $attachments; +} + +/** + * Récupère la contenu de la pièce jointe par rapport a sa position dans un mail donné + * @param integer $jk numéro du mail + * @param integer $fpos position de la pièce jointe + * @param integer $type type de la pièce jointe + * @param object $mbox object connection imaap + * @return mixed data + */ +function getFileData($jk, $fpos, $type, $mbox) +{ + $mege = imap_fetchbody($mbox, $jk, $fpos); + $data = getDecodeValue($mege, $type); + + return $data; +} + +/** + * Sauvegarde de la pièce jointe dans le dossier défini avec un nom unique + * @param string $path chemin de sauvegarde dui fichier + * @param string $filename nom du fichier + * @param mixed $data contenu à sauvegarder + * @return string emplacement du fichier + **/ +function saveAttachment($path, $filename, $data) +{ + global $lang; + $tmp = explode('.', $filename); + $ext = array_pop($tmp); + $filename = implode('.', $tmp); + if (!file_exists($path)) { + if (dol_mkdir($path) < 0) { + return -1; + } + } + + $i = 1; + $filepath = $path . $filename . '.' . $ext; + + while (file_exists($filepath)) { + $filepath = $path . $filename . '(' . $i . ').' . $ext; + $i++; + } + file_put_contents($filepath, $data); + return $filepath; +} + +/** + * Décode le contenu du message + * @param string $message message + * @param integer $coding type de contenu + * @return message décodé + **/ +function getDecodeValue($message, $coding) +{ + switch ($coding) { + case 0: //text + case 1: //multipart + $message = imap_8bit($message); + break; + case 2: //message + $message = imap_binary($message); + break; + case 3: //application + case 5: //image + case 6: //video + case 7: //other + $message = imap_base64($message); + break; + case 4: //audio + $message = imap_qprint($message); + break; + } + + return $message; +}