165 lines
2.9 KiB
PHP
165 lines
2.9 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;
|
|
}
|
|
}
|
|
|