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 messageNew(#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 entry_date <= CURDATE() AND(expiry_date IS NULL OR expiry_date >= CURDATE()) GROUP BY presentation_order' ,$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('%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); } } }