ediSchema = Edi\Message::loadSchema('CLOCKT'); if (!$this->ediSchema) throw new Exception('Can not load EDI schema.'); $this->restrictToSenders = $db->getValue( "SELECT restrictToSenders FROM exchangeConfig LIMIT 1"); $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 processed.\n"; } } function loadMail($db, $msg) { $imap = $this->imap; // Gets EKT messages from email try { $msgStructure = imap_fetchstructure($imap, $msg); $result = []; // Gets the mail sender and Message-ID $header = imap_headerinfo($imap, $msg); $from = $header->from; if (property_exists($header, 'message_id')) $messageId = trim($header->message_id, '<>'); else $messageId = NULL; if ($from && count($from) > 0) $sender = $from[0]->mailbox .'@'. $from[0]->host; else $sender = NULL; if ($this->restrictToSenders) { $isAllowed = $db->getValue( "SELECT COUNT(*) > 0 FROM mailSender WHERE mail = #", [$sender] ); if (!$isAllowed) throw new Exception('Mail processing from unknown senders is disabled'); } $db->query('CALL mail_new(#messageId, #sender, @mailFk)', [ 'messageId' => $messageId, 'sender' => $sender ]); $mailId = $db->getValue("SELECT @mailFk"); echo "Message from: $sender\n"; echo " -> Message id: $messageId\n"; // 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; $db->query( 'UPDATE mail SET source = #source WHERE id = #mailId', [ 'source' => $ediString, 'mailId' => $mailId ]); // Creates the EDI object and loads its exchanges $ediMessage = new Edi\Message(); $ediMessage->parse($ediString, $this->ediSchema); $db->query('START TRANSACTION'); $unb = $ediMessage->section; $unhs = $unb->childs['UNH']; foreach ($unhs as $unh) foreach ($lins = $unh->childs['LIN'] as $lin) { $ediValues = ['mailId' => $mailId]; // 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/exchange-new', $ediValues); if (!$res) throw new Exception('Failed to insert the line.'); $count++; } $db->query('COMMIT'); } catch (Exception $e) { $db->query('ROLLBACK'); throw $e; } if ($count == 0) throw new Exception('No part with EDI format was found'); echo " -> Mail id: $mailId\n"; echo " -> Loaded exchanges: $count\n"; $folder = $this->imapConf['successFolder']; $db->query( "UPDATE mail SET nExchanges = #, error = NULL WHERE id = #", [$count, $mailId] ); } catch (Exception $e) { $error = $e->getMessage(); error_log($error); $folder = $this->imapConf['errorFolder']; $db->query( "UPDATE mail SET error = # WHERE id = #", [$error, $mailId] ); } // 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); } } }