143 lines
2.8 KiB
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;
|
|
}
|
|
}
|
|
|