ediSchema = Edi\Message::loadSchema ('CLOCKT'); if (!$this->ediSchema) throw new Exception ('Can not load EDI schema.'); $this->params = $db->query ( 'SELECT code, name, subname, position, type, required FROM param'); $inbox = imap_search ($this->imap, 'ALL'); if ($inbox) { foreach ($inbox as $msg) $this->loadMail ($db, $msg); $inboxCount = count ($inbox); if ($inboxCount > 0) echo "Total $inboxCount messages readed\n"; } } function loadMail ($db, $msg) { $imap = $this->imap; // Gets EKT messages from email $msgStructure = imap_fetchstructure ($imap, $msg); $result = []; // Gets the mail sender and Message-ID $header = imap_headerinfo ($imap, $msg); $from = $header->from; $mailId = trim ($header->message_id, '<>'); if ($from && count ($from) > 0) $sender = $from[0]->mailbox .'@'. $from[0]->host; else $sender = NULL; // Searches the EDI message on mail parts $matchTypes = [TYPEAPPLICATION, TYPETEXT]; $this->imapFindParts ($msgStructure, $matchTypes, [], $result); $count = 0; $error = NULL; foreach ($result as $msgSection) try { $part = imap_bodystruct ($imap, $msg, $msgSection); $ediString = imap_fetchbody ($imap, $msg, $msgSection); switch ($part->encoding) { case ENCBASE64: $ediString = imap_base64 ($ediString); break; case ENCQUOTEDPRINTABLE: $ediString = imap_qprint ($ediString); break; } if (!Edi\Message::isEdiString ($ediString)) continue; // Creates the EDI object and loads its exchanges $ediMessage = new Edi\Message (); $ediMessage->parse ($ediString, $this->ediSchema); $db->query ('START TRANSACTION'); $db->query ('CALL message_new (#mailId, #sender, @message)', [ 'mailId' => $mailId, 'sender' => $sender ]); $unb = $ediMessage->section; $unhs = $unb->childs['UNH']; foreach ($unhs as $unh) foreach ($lins = $unh->childs['LIN'] as $lin) { $ediValues = []; // Gets the exchange params $this->params->data_seek (0); while ($row = $this->params->fetch_assoc ()) { switch ($row['type']) { case 'INTEGER': $type = Type::INTEGER; break; case 'DOUBLE': $type = Type::DOUBLE; break; case 'DATE': $type = Type::DATE; break; case 'TIME': $type = Type::TIME; break; default: $type = Type::STRING; } $value = $lin->getValue ( $row['name'], $row['position'], $type, $row['subname']); if (!isset ($value) && $row['required']) throw new Exception ('Missing required parameter: '. $row['code']); $ediValues[$row['code']] = $value; } // Gets the exchange features $res = $db->query ( 'SELECT presentation_order, feature ' .'FROM item_feature WHERE item_id = #ref ' .'AND expiry_date IS NULL' ,$ediValues ); if ($res) while ($row = $res->fetch_assoc ()) { $value = $lin->getValue ('IMD', 2, Type::INTEGER, $row['feature']); $ediValues['s'.$row['presentation_order']] = $value; } else throw new Exception ('Can\'t get the item features.'); for ($i = 1; $i <= 6; $i++) if (!isset ($ediValues['s'.$i])) $ediValues['s'.$i] = NULL; // Adds the exchange to the Database $res = $db->queryFromFile (__DIR__.'/sql/batch-add', $ediValues); if (!$res) throw new Exception ('Failed to insert the line.'); $count++; } $db->query ('COMMIT'); } catch (Exception $e) { $db->query ('ROLLBACK'); $error = $e->getMessage (); break; } if (!$error && $count == 0) $error = 'EDI messages not found.'; // Logs information of realized operations if (!$error) { $folder = $this->imapConf['success_folder']; echo "Mail loaded with $count lines.\n"; } else { $folder = $this->imapConf['error_folder']; echo "Mail error: $error\n"; } // Moves the mail to another folder $folder = sprintf ('INBOX.%s', $folder); if (!imap_mail_move ($imap, $msg, $folder)) error_log ('Can\'t move message to %s: %s' ,$folder ,imap_last_error () ); } function imapFindParts (&$part, &$matchTypes, $section, &$result) { if (in_array ($part->type, $matchTypes)) { if (count ($section) > 0) $result[] = implode ('.', $section); else $result[] = '1'; } elseif ($part->type == TYPEMULTIPART) foreach ($part->parts as $i => $subpart) { array_push ($section, $i + 1); $this->imapFindParts ($subpart, $matchTypes, $section, $result); array_pop ($section); } } }