hedera-web/rest/edi/lib/message.php

143 lines
2.8 KiB
PHP

<?php
namespace Edi;
require_once(__DIR__.'/section.php');
class SectionInfo {
var $schema;
var $parentInfo;
var $section;
}
class Message {
var $section;
static function loadSchema($schemaName) {
$ediSchemaStr = file_get_contents(__DIR__."/$schemaName.json", TRUE);
if ($ediSchemaStr !== FALSE)
return json_decode($ediSchemaStr, TRUE);
return NULL;
}
static function isEdiString(&$string) {
return substr($string, 0, 4) == 'UNB+';
}
function parse(&$string, &$schema = NULL) {
global $delimiters;
if (!self::isEdiString($string))
throw new \Exception('Not an EDI string.');
$pos = 0;
$error = FALSE;
$endTag = NULL;
$firstLoop = TRUE;
$newSection = TRUE;
$info = new SectionInfo();
$info->schema = $schema;
$info->parentInfo = NULL;
$info->section = NULL;
$topInfo = $info;
try {
while (TRUE) {
$segment = $this->parseSegment($string, $pos);
if (!$segment &&(!$endTag || !$info))
break;
if (!$segment ||($segment && !$info))
throw new \Exception();
if ($firstLoop) {
if ($segment->name != $info->schema['mainTag'])
throw new \Exception();
} else {
for ($i = $info; $i; $i = $i->parentInfo)
if (isset($i->schema['childs'][$segment->name])) {
$info = new SectionInfo();
$info->schema = $i->schema['childs'][$segment->name];
$info->parentInfo = $i;
$newSection = TRUE;
break;
}
}
if ($newSection) {
$section = new Section();
$section->name = $segment->name;
$info->section = $section;
if ($info->parentInfo) {
$section->parent = $info->parentInfo->section;
$section->parent->childs[$segment->name][] = $section;
}
if (isset($info->schema['endTag']))
$endTag = $info;
$newSection = FALSE;
}
if ($endTag && $endTag->schema['endTag'] == $segment->name) {
$endTag->section->segments[] = $segment;
$info = $endTag->parentInfo;
for ($i = $info; $i; $i = $i->parentInfo)
if (isset($i->schema['endTag'])) {
$endTag = $i;
break;
}
} else
$info->section->segments[] = $segment;
$firstLoop = FALSE;
}} catch (\Exception $e) {
throw new \Exception(sprintf('Parse error, something is wrong near "%s"',
substr($string, $pos, 10)));
}
$this->section = $topInfo->section;
}
function parseSegment(&$string, &$pos) {
$empty = TRUE;
$values = [];
while (TRUE) {
if (!isset($string{$pos}))
return NULL;
if (in_array($string{$pos}, ['+', ':', '\''])) {
if (!$empty) {
$values[] =
trim(substr($string, $start, $pos - $start));
$empty = TRUE;
}
}
elseif ($empty) {
$start = $pos;
$empty = FALSE;
}
if ($string{$pos} === '\'')
break;
$pos++;
}
$pos++;
$segment = new Segment();
$segment->name = $values[0];
$segment->values = $values;
return $segment;
}
}