Skip to content

Instantly share code, notes, and snippets.

@jhaoda
Created August 5, 2019 18:52
Show Gist options
  • Save jhaoda/dcf8977cc98b6ff69f82282de10b1173 to your computer and use it in GitHub Desktop.
Save jhaoda/dcf8977cc98b6ff69f82282de10b1173 to your computer and use it in GitHub Desktop.
1С:Бром
<?php interface ИНаблюдатель
{
function ВнешнееСобытие($источник, $имяСобытия, ...$параметры);
}
class ИсточникСобытий
{
private $observers;
public function ОповеститьНаблюдателей($имяСобытия, ...$параметры)
{
if (!empty($this->observers)) {
foreach ($this->observers as $observer) {
call_user_func_array([$observer, "ВнешнееСобытие"], array_merge([$this, $имяСобытия], $параметры));
}
}
}
public function ДобавитьНаблюдателя(ИНаблюдатель $наблюдатель)
{
if ($this->observers === null) {
$this->observers = [];
}
if (!empty($наблюдатель)) {
if (array_search($наблюдатель, $this->observers) === false) {
$this->observers[] = $наблюдатель;
}
}
}
public function УдалитьНаблюдателя(ИНаблюдатель $наблюдатель)
{
if ($this->observers === null) {
return null;
}
if (!empty($наблюдатель)) {
$index = array_search($наблюдатель, $this->observers);
if ($index !== false) {
unset($this->observers[$index]);
}
}
}
}
abstract class ПеречислениеБром
{
protected function __construct($index, $name)
{
$this->name = $name;
$this->index = $index;
}
protected static $data;
protected static $values;
private $name;
private $index;
public function __toString()
{
return $this->name;
}
public function getIndex()
{
return $this->index;
}
public function getName()
{
return $this->name;
}
public function __get($name)
{
$tempName = mb_strtolower($name);
switch ($tempName) {
case "name":
return $this->getName();
break;
case "имя":
return $this->getName();
break;
case "index":
return $this->getIndex();
break;
case "индекс":
return $this->getIndex();
break;
}
return null;
}
protected abstract function enumValues();
protected static function&getData()
{
$className = get_called_class();
if (ПеречислениеБром::$data == null) {
ПеречислениеБром::$data = [];
}
if (ПеречислениеБром::$data[$className] == null) {
ПеречислениеБром::$data[$className] = ['data' => $className::enumValues(), 'values' => []];
}
return ПеречислениеБром::$data[$className];
}
public static function Values()
{
$tempData =& self::getData()['data'];
$result = [];
foreach ($tempData as $tempVal) {
$result[] = $tempVal[0];
}
return $result;
}
public static function Parse($name)
{
$tempData =& self::getData();
if ($tempData == null) {
return null;
}
$className = get_called_class();
$count = count($tempData['data']);
for ($i = 0; $i < $count; $i++) {
$tempDataBlock =& $tempData['data'][$i];
foreach ($tempDataBlock as $tempVal) {
if (mb_strtolower($name) == mb_strtolower($tempVal)) {
if ($tempData['values'][$i] == null) {
$tempData['values'][$i] = new $className($i, $tempDataBlock[0]);
}
return $tempData['values'][$i];
}
}
}
return null;
}
public static function GetByIndex($index)
{
$tempData =& self::getData();
if ($tempData == null) {
return null;
}
$className = get_called_class();
if ($tempData['data'][$index] != null) {
if ($tempData['values'][$index] == null) {
$tempData['values'][$index] = new $className($index, $tempData['data'][$index][0]);
}
return $tempData['values'][$index];
}
return null;
}
public static function Значения()
{
return self::Values();
}
public static function Получить($имя)
{
return self::Parse($имя);
}
public static function ПолучитьПоИндексу($индекс)
{
return self::GetByIndex($индекс);
}
public static function __callStatic($name, $arguments)
{
return self::Parse($name);
}
}
abstract class ValueBase
{
function __construct()
{
}
public $Name;
const NS_XS = "http://www.w3.org/2001/XMLSchema";
const NS_BROM = "https://brom.itworks.group";
public static function From($val)
{
if (is_null($val)) {
return new ValueNull();
}
$type = gettype($val);
switch ($type) {
case 'string':
return new ValueString($val);
break;
case 'integer':
case 'float':
case 'double':
return new ValueNumber($val);
break;
case 'boolean':
return new ValueBoolean($val);
break;
case 'array':
return new ValueArray($val);
break;
case 'object':
$className = get_class($val);
if ($val instanceof DateTime) {
return new ValueDate($val);
} else if ($val instanceof Массив) {
return new ValueArray($val);
} else if ($val instanceof Структура) {
return new ValueStruct($val);
} else if ($val instanceof Соответствие) {
return new ValueMap($val);
} else if ($val instanceof DBNull) {
return new ValueDBNull($val);
} else if ($val instanceof ДвоичныеДанные) {
return new ValueBinaryData($val);
} else if ($val instanceof ХранилищеЗначения) {
return new ValueStorage($val);
} else if ($val instanceof УникальныйИдентификатор) {
return new ValueGuid($val);
} else if ($val instanceof ОбъектСсылка) {
return new ValueObjectRef($val);
} else if ($val instanceof ПеречислениеСсылка) {
return new ValueEnumRef($val);
} else if ($val instanceof ТаблицаЗначений) {
return new ValueTable($val);
} else if ($val instanceof ТабличнаяЧасть) {
return new ValueTable($val->Выгрузить());
} else if ($val instanceof ДеревоЗначений) {
return new ValueTree($val);
} else if ($val instanceof КлючИЗначение) {
return new ValueKeyValue($val);
} else if ($val instanceof ВидДвиженияНакопления) {
return new ValueAccumulationRecordType($val);
} else if ($val instanceof ВидДвиженияБухгалтерии) {
return new ValueAccountingRecordType($val);
} else if ($val instanceof ВидСчета) {
return new ValueAccountType($val);
} else if ($val instanceof Тип) {
return new ValueType($val);
} else if ($val instanceof ОписаниеТипов) {
return new ValueTypeDescription($val);
} else if ($val instanceof МоментВремени) {
return new ValuePointInTime($val);
} else if ($val instanceof Граница) {
return new ValueBoundary($val);
}
break;
}
throw new Exception("Не удалось сериализовать данные.");
}
public static function SoapValue($type, $val)
{
return new SoapVar($val, SOAP_ENC_OBJECT, $type, ValueBase::NS_BROM);
}
public abstract function GetValue($клиент = null);
}
abstract class ValueSimple extends ValueBase
{
function __construct($val = null)
{
$this->Value = $val;
}
public $Value;
}
abstract class ValueSystemEnum extends ValueBase
{
public $Value;
}
abstract class ValueStructured extends ValueBase
{
public $Property;
public function ToStruct($client = null)
{
$result = new Структура();
if ($this->Property != null) {
foreach ($this->Property as $property) {
$result->Вставить($property->Name, $property->GetValue($client));
}
}
return $result;
}
public function ToTree($client = null)
{
$дерево = new ДеревоЗначений();
$дерево->Колонки->Добавить("Ключ");
$дерево->Колонки->Добавить("Значение");
$this->PropertyToTreeRow($this->Property, $дерево->Строки(), $client);
return $дерево;
}
private function PropertyToTreeRow($properties, $строки, $client)
{
if ($properties != null) {
foreach ($properties as $property) {
$стр = $строки->Добавить();
$стр->Ключ = $property->Name;
$стр->Значение = $property->GetValue($client);
if ($property instanceof ValueStructured) {
$this->PropertyToTreeRow($property->Property, $стр->Строки(), $client);
}
}
}
}
}
abstract class ValueDataSet extends ValueBase
{
function __construct($collection = null)
{
$this->Column = [];
$this->Row = [];
if ($collection != null) {
if ($collection instanceof ДвумернаяКоллекцияЗначений) {
foreach ($collection->Колонки as $колонка) {
$this->Column[] = ValueBase::SoapValue("DataTableColumn", ['Name' => $колонка->Имя()]);
}
} else {
throw new Exception("Указанный параметр не является двумерной коллекцией значений.");
}
}
}
public $Column;
public $Row;
}
abstract class ValueRef extends ValueStructured
{
public $Type;
public $Presentation;
}
class ValueNull extends ValueBase
{
public function GetValue($client = null)
{
return null;
}
}
class ValueDBNull extends ValueBase
{
public function GetValue($client = null)
{
return new DBNull();
}
}
class ValueString extends ValueSimple
{
function __construct($val = null)
{
$this->Value = strval($val);
}
public function GetValue($client = null)
{
return strval($this->Value);
}
}
class ValueBoolean extends ValueSimple
{
function __construct($val = null)
{
$this->Value = boolval($val);
}
public function GetValue($клиент = null)
{
return boolval($this->Value);
}
}
class ValueNumber extends ValueSimple
{
function __construct($val = null)
{
$this->Value = floatval($val);
}
public function GetValue($client = null)
{
return floatval($this->Value);
}
}
class ValueDate extends ValueSimple
{
function __construct($val = null)
{
$dateTime = $val ? $val : new DateTime();
$this->Value = $dateTime->format('c');
}
public function GetValue($клиент = null)
{
return new Дата($this->Value);
}
}
class ValueArray extends ValueBase
{
function __construct($items = null)
{
$this->Item = [];
if ($items instanceof Массив || is_array($items)) {
foreach ($items as $value) {
$this->Item[] = ValueBase::From($value);
}
}
}
public $Item;
public function GetValue($client = null)
{
$result = new Массив();
foreach ($this->Item as $val) {
$result->Добавить($val->GetValue($client));
}
return $result;
}
}
class ValueStruct extends ValueStructured
{
function __construct($val = null)
{
$this->Property = [];
if ($val instanceof Структура) {
foreach ($val as $key => $value) {
$prop = ValueBase::From($value);
$prop->Name = $key;
$this->Property[] = $prop;
}
}
}
public function GetValue($client = null)
{
$result = new Структура();
if ($this->Property) {
foreach ($this->Property as $prop) {
$result->Вставить($prop->Name, $prop->GetValue($client));
}
}
return $result;
}
}
class ValueMap extends ValueBase
{
function __construct($items = null)
{
$this->KeyValue = [];
if ($items instanceof Соответствие) {
foreach ($items as $key => $value) {
$this->KeyValue[] = ['Key' => ValueBase::From($key), 'Value' => ValueBase::From($value)];
}
}
}
public $KeyValue;
public function GetValue($client = null)
{
$result = new Соответствие();
foreach ($this->KeyValue as $keyVal) {
$result->Вставить($keyVal->Key->GetValue($client), $keyVal->Value->GetValue($client));
}
return $result;
}
}
class ValueKeyValue extends ValueBase
{
function __construct($val = null)
{
$this->Key = ValueBase::From($val->Ключ);
$this->Value = ValueBase::From($val->Значение);
}
public $Key;
public $Value;
public function GetValue($клиент = null)
{
return new КлючИЗначение($this->Key->GetValue($клиент), $this->Value->GetValue($клиент));
}
}
class ValueTable extends ValueDataSet
{
function __construct($table = null)
{
parent::__construct($table);
if ($table != null) {
if ($table instanceof ТаблицаЗначений) {
foreach ($table as $стр) {
$values = [];
foreach ($table->Колонки as $колонка) {
$property = ValueBase::From($стр[$колонка->Имя()]);
$property->Name = $колонка->Имя();
$values[] = $property;
}
$this->Row[] = ValueBase::SoapValue("DataTableRow", ['Property' => $values]);
}
} else {
throw new Exception("Указанный параметр не является таблицей значений.");
}
}
}
public function GetValue($client = null)
{
$result = new ТаблицаЗначений();
if (!empty($this->Column)) {
foreach ($this->Column as $column) {
$result->Колонки->Добавить($column->Name);
}
}
if (!empty($this->Row)) {
foreach ($this->Row as $row) {
$temRow = $result->Добавить();
if ($row->Property != null) {
foreach ($row->Property as $property) {
$temRow[$property->Name] = $property->GetValue($client);
}
}
}
}
return $result;
}
}
class ValueTree extends ValueDataSet
{
function __construct($tree = null)
{
parent::__construct($tree);
if (!empty($tree)) {
if ($tree instanceof ДеревоЗначений) {
$строки =& $tree->Строки();
$this->AddRowsSOAP($tree, $this->Row, $строки);
} else {
throw new Exception("Указанный параметр не является деревом значений.");
}
}
}
public function GetValue($client = null)
{
$result = new ДеревоЗначений();
if (!empty($this->Column)) {
foreach ($this->Column as $column) {
$result->Колонки->Добавить($column->Name);
}
}
$строки =& $result->Строки();
$this->AddRows($строки, $this->Row, $client);
return $result;
}
private function AddRowsSOAP($tree, &$rowsSOAP, &$rows)
{
foreach ($rows as $currentRow) {
$properties = [];
foreach ($tree->Колонки as $column) {
$property = ValueBase::From($currentRow[$column->Имя()]);
$property->Name = $column->Имя();
$properties[] = $property;
}
$childRows = null;
if ($currentRow->Строки()->Количество() > 0) {
$childRows = [];
$строки =& $currentRow->Строки();
$this->AddRowsSOAP($tree, $childRows, $строки);
}
$rowSOAP = ValueBase::SoapValue("DataTableRow", ['Property' => $properties, 'Row' => $childRows]);
$rowsSOAP[] = $rowSOAP;
}
}
private function AddRows(&$rows, &$rowsSOAP, $client)
{
if (empty($rowsSOAP)) {
return;
}
foreach ($rowsSOAP as $rowSOAP) {
$currentRow = $rows->Добавить();
if (!empty($rowSOAP->Property)) {
foreach ($rowSOAP->Property as $property) {
$currentRow[$property->Name] = $property->GetValue($client);
}
}
$строки =& $currentRow->Строки();
$this->AddRows($строки, $rowSOAP->Row, $client);
}
}
}
class ValueBinaryData extends ValueBase
{
function __construct($val = null)
{
$this->Value = $val ? $val->ПолучитьДанные() : "";
}
public $Value;
public function GetValue($client = null)
{
return new ДвоичныеДанные($this->Value);
}
}
class ValueStorage extends ValueBase
{
function __construct($data = null)
{
$this->Data = ValueBase::From($data->Получить());
}
public $Data;
public function GetValue($client = null)
{
return new ХранилищеЗначения($this->Data->GetValue());
}
}
class ValueGuid extends ValueBase
{
function __construct($val = null)
{
$this->Value = strval($val);
}
public $Value;
public function GetValue($клиент = null)
{
return new УникальныйИдентификатор($this->Value);
}
}
class ValueEnumRef extends ValueRef
{
function __construct($value = null)
{
$this->Type = $value != null ? $value->ПолноеИмяТипа() : "";
$this->Value = $value->Имя();
}
public $Value;
public function GetValue($клиент = null)
{
if (!empty($клиент)) {
return $клиент->Контекст()->ПолучитьПеречислениеСсылку($this->Type, $this->Value, $this->Presentation);
}
throw new Exception("Не указан клиент при получении ссылки.");
}
}
class ValueObjectRef extends ValueRef
{
function __construct($value = null)
{
$this->Type = $value != null ? $value->ПолноеИмяТипа() : "";
$this->Value = $value != null ? strval($value->УникальныйИдентификатор()) : "";
}
public $Value;
public function GetValue($клиент = null)
{
if ($клиент != null) {
$ссылка = $клиент->Контекст()->ПолучитьОбъектСсылку($this->Type, new УникальныйИдентификатор($this->Value));
} else {
throw new Exception("Не указан клиент при получении ссылки.");
}
if ($this->Presentation != null) {
$клиент->Контекст()->УстановитьПредставлениеОбъекта($ссылка, $this->Presentation);
}
if ($this->Property != null) {
$клиент->Контекст()->УстановитьЗначенияИзСвойствSOAP($ссылка, $this->Property);
}
return $ссылка;
}
}
class ValueAccumulationRecordType extends ValueSystemEnum
{
function __construct($val = null)
{
$this->Value = $val ? $val->getName() : "";
}
public function GetValue($client = null)
{
return ВидДвиженияНакопления::Получить($this->Value);
}
}
class ValueAccountingRecordType extends ValueSystemEnum
{
function __construct($val = null)
{
$this->Value = $val ? $val->getName() : "";
}
public function GetValue($client = null)
{
return ВидДвиженияБухгалтерии::Получить($this->Value);
}
}
class ValueAccountType extends ValueSystemEnum
{
function __construct($val = null)
{
$this->Value = $val ? $val->getName() : "";
}
public function GetValue($client = null)
{
return ВидСчета::Получить($this->Value);
}
}
class ValueNonserializable extends ValueBase
{
public function GetValue($client = null)
{
return new НесериализуемыеДанные();
}
}
class ValueType extends ValueBase
{
function __construct($value = null)
{
if (!empty($value)) {
$this->Value = $value->XmlИмя();
$this->Namespace = $value->XmlПространствоИмен();
if (mb_strtolower($this->Namespace) == "http://www.w3.org/2001/XMLSchema") {
$this->Namespace = Тип::XMLПространствоИменXmlSchema();
} else if (mb_strtolower($this->Namespace) == "http://v8.1c.ru/data") {
$this->Namespace = Тип::XMLПространствоИмен1C();
}
}
}
public $Value;
public $Namespace;
public function GetValue($client = null)
{
$ns = mb_strtolower($this->Namespace);
if ($ns == Тип::XMLПространствоИменXmlSchema()) {
$ns = "http://www.w3.org/2001/XMLSchema";
} else if ($ns == Тип::XMLПространствоИмен1C()) {
$ns = "http://v8.1c.ru/data";
}
return new Тип($this->Value, $ns);
}
}
class ValueTypeDescription extends ValueBase
{
function __construct($value = null)
{
$this->Item = [];
if (!empty($value)) {
$типы = $value->Типы();
foreach ($типы as $тип) {
$this->Item[] = new ValueType($тип);
}
$this->NumberQualifiers = $value->КвалификаторыЧисла() != null ? new NumberQualifiers($value->КвалификаторыЧисла()) : null;
$this->StringQualifiers = $value->КвалификаторыСтроки() != null ? new StringQualifiers($value->КвалификаторыСтроки()) : null;
$this->DateQualifiers = $value->КвалификаторыДаты() != null ? new DateQualifiers($value->КвалификаторыДаты()) : null;
$this->BinaryDataQualifiers = $value->КвалификаторыДвоичныхДанных() != null ? new BinaryDataQualifiers($value->КвалификаторыДвоичныхДанных()) : null;
}
}
public $Item;
public $NumberQualifiers;
public $StringQualifiers;
public $DateQualifiers;
public $BinaryDataQualifiers;
public function GetValue($client = null)
{
$types = [];
if (!empty($this->Item)) {
foreach ($this->Item as $typeItem) {
$types[] = $typeItem->GetValue($client);
}
}
return new ОписаниеТипов($types, $this->NumberQualifiers != null ? $this->NumberQualifiers->GetValue($client) : null, this.StringQualifiers != null ? $this->StringQualifiers->GetValue() : null, this.DateQualifiers != null ? $this->DateQualifiers->GetValue() : null, this.BinaryDataQualifiers != null ? $this->BinaryDataQualifiers->GetValue() : null);
}
}
class ValuePointInTime extends ValueBase
{
function __construct($val = null)
{
$this->Date = $val->Дата()->format("c");
$this->Ref = new ValueObjectRef($val->Ссылка());
}
public $Date;
public $Ref;
public function GetValue($клиент = null)
{
return new МоментВремени(new Дата($this->Date), $this->Ref->GetValue($клиент));
}
}
class ValueBoundary extends ValueBase
{
function __construct($val = null)
{
$this->Value = ValueBase::From($val->Значение());
$this->Type = $val->ВидГраницы()->getName();
}
public $Value;
public $Type;
public function GetValue($клиент = null)
{
$curValue = $this->Value->GetValue($клиент);
$boundaryType = ВидГраницы::Получить($this->Type);
return new Граница($curValue, $boundaryType);
}
}
class StringQualifiers
{
function __construct($квалификаторы)
{
$this->Length = $квалификаторы->Длина();
$this->AllowedLength = $квалификаторы->ДопустимаяДлина()->getName();
}
public $Length;
public $AllowedLength;
public function GetValue()
{
return new КвалификаторыСтроки(intval($this->Length), ДопустимаяДлина::Получить($this->AllowedLength));
}
}
class NumberQualifiers
{
function __construct($квалификаторы)
{
$this->Digits = $квалификаторы->Разрядность();
$this->FractionDigits = $квалификаторы->РазрядностьДробнойЧасти();
$this->OnlyPositive = $квалификаторы->ДопустимыйЗнак() == ДопустимыЗнак::Неотрицательный();
}
public $Digits;
public $FractionDigits;
public $OnlyPositive;
public function GetValue()
{
return new КвалификаторыЧисла(intval($this->Digits), intval($this->FractionDigits), $this->OnlyPositive ? ДопустимыЗнак::Неотрицательный() : ДопустимыЗнак::Любой());
}
}
class DateQualifiers
{
function __construct($квалификаторы)
{
$this->DateFractions = $квалификаторы->ЧастиДаты()->getName();
}
public $DateFractions;
public function GetValue()
{
return new КвалификаторыДаты(ЧастиДаты::Получить($this->DateFractions));
}
}
class BinaryDataQualifiers
{
function __construct($квалификаторы)
{
$this->Length = $квалификаторы->Длина();
$this->AllowedLength = $квалификаторы->ДопустимаяДлина()->getName();
}
public $Length;
public $AllowedLength;
public function GetValue()
{
return new КвалификаторыДвоичныхДанных(intval($this->Length), ДопустимаяДлина::Получить($this->AllowedLength));
}
}
abstract class MetadataNode
{
function __construct()
{
}
public $Name;
public $FullName;
public $Title;
public function GetValue($родитель)
{
return null;
}
}
class MetadataModule extends MetadataNode
{
function __construct()
{
}
public function GetValue($родитель)
{
return new МетаданныеМодуль($родитель, $this);
}
}
class MetadataCollection extends MetadataNode
{
function __construct()
{
}
public $Item;
public $TotalObjectsCount;
public $RequestedObjectsCount;
public $PackObjectsCount;
public function GetValue($родитель)
{
return new МетаданныеКоллекция($родитель, $this);
}
}
class MetadataAttribute extends MetadataNode
{
function __construct()
{
}
public function GetValue($родитель)
{
return new МетаданныеРеквизит($родитель, $this);
}
}
class MetadataTableSection extends MetadataNode
{
function __construct()
{
}
public $Attribute;
public function GetValue($родитель)
{
return new МетаданныеТабличнаяЧасть($родитель, $this);
}
}
class MetadataObject extends MetadataNode
{
function __construct()
{
}
public $CollectionType;
public $Attribute;
public $TableSection;
public $Predefined;
public function GetValue($родитель)
{
return new МетаданныеОбъект($родитель, $this);
}
}
class MetadataApplication extends MetadataNode
{
function __construct()
{
}
public $Collection;
public $TotalObjectsCount;
public $RequestedObjectsCount;
public $PackSize;
public $PackIndex;
public function GetValue($родитель)
{
return new МетаданныеКонфигурация($родитель, $this);
}
}
class PostObject_Settings
{
function __construct($допСвойства, $режимЗаписи, $режимПроведения, $режимЗагрузки)
{
$this->AdditionalProperties = ValueBase::From($допСвойства);
$this->ExchangeLoadMode = boolval($режимЗагрузки);
$this->DocumentWriteMode = $режимЗаписи != null ? $режимЗаписи->getName() : null;
$this->DocumentPostingMode = $режимПроведения != null ? $режимПроведения->getName() : null;
}
public $AdditionalProperties;
public $ExchangeLoadMode;
public $DocumentWriteMode;
public $DocumentPostingMode;
}
class Дата extends DateTime
{
public function __toString()
{
return $this->format("c");
}
}
class Массив extends ArrayObject
{
function __construct(...$элементы)
{
foreach ($элементы as $элемент) {
$this->Добавить($элемент);
}
$this->eventDispatcher = new ИсточникСобытий();
}
private $eventDispatcher;
public function ИсточникСобытий()
{
return $this->eventDispatcher;
}
public static function ИзМассива($array)
{
$result = new Массив();
foreach ($array as $val) {
$result->Добавить($val);
}
return $result;
}
public function Скопировать()
{
$result = new Массив();
foreach ($this as $val) {
$result->Добавить($val);
}
return $result;
}
public function ToArray()
{
$result = [];
foreach ($this as $val) {
$result[] = $val;
}
return $result;
}
public function Добавить($значение)
{
$this->eventDispatcher->ОповеститьНаблюдателей("ПередИзменением");
parent::append($значение);
$this->eventDispatcher->ОповеститьНаблюдателей("ПриИзменении");
}
public function Вставить($индекс, $значение)
{
if (gettype($индекс) != "integer") {
throw new InvalidArgumentException("Ошибка. Индекс коллекции должен быть неотрицательным целым числом.");
}
$count = parent::count();
if ($индекс < 0 || $индекс > $count) {
throw new InvalidArgumentException("Индекс выходит за границы коллекции.");
}
$this->eventDispatcher->ОповеститьНаблюдателей("ПередИзменением");
for ($i = $count; $i > $индекс; $i--) {
parent::offsetSet($i, parent::offsetGet($i - 1));
}
parent::offsetSet($индекс, $значение);
$this->eventDispatcher->ОповеститьНаблюдателей("ПриИзменении");
}
public function Удалить($индекс)
{
$this->eventDispatcher->ОповеститьНаблюдателей("ПередИзменением");
$this->offsetUnset($индекс);
$this->eventDispatcher->ОповеститьНаблюдателей("ПриИзменении");
}
public function Очистить()
{
$this->eventDispatcher->ОповеститьНаблюдателей("ПередИзменением");
$iterator = parent::getIterator();
foreach ($iterator as $key => $value) {
parent::offsetUnset($key);
}
$this->eventDispatcher->ОповеститьНаблюдателей("ПриИзменении");
}
public function Получить($индекс)
{
return $this->offsetGet($индекс);
}
public function Установить($индекс, $значение)
{
$this->eventDispatcher->ОповеститьНаблюдателей("ПередИзменением");
return $this->offsetSet($индекс, $значение);
$this->eventDispatcher->ОповеститьНаблюдателей("ПриИзменении");
}
public function Количество()
{
return count($this);
}
public function Найти($значение)
{
$iterator = parent::getIterator();
foreach ($iterator as $key => $value) {
if ($value === $значение) {
return $key;
}
}
return null;
}
public function offsetGet($index)
{
if (is_null($index)) {
return parent::offsetSet($index, $newVal);
}
if (gettype($index) != "integer") {
throw new InvalidArgumentException("Ошибка. Индекс массива должен быть неотрицательным целым числом.");
}
if ($index < 0 || $index >= parent::count()) {
throw new InvalidArgumentException("Индекс выходит за границы массива.");
}
return parent::offsetGet($index);
}
public function offsetSet($index, $newVal)
{
if (is_null($index)) {
return parent::offsetSet($index, $newVal);
}
if (gettype($index) != "integer") {
throw new InvalidArgumentException("Ошибка. Индекс массива должен быть неотрицательным целым числом.");
}
if ($index < 0 || $index >= parent::count()) {
throw new InvalidArgumentException("Индекс выходит за границы массива.");
}
$this->eventDispatcher->ОповеститьНаблюдателей("ПередИзменением");
parent::offsetSet($index, $newVal);
$this->eventDispatcher->ОповеститьНаблюдателей("ПриИзменении");
}
public function offsetUnset($index)
{
if (gettype($index) != "integer" || $index < 0) {
throw new InvalidArgumentException("Ошибка. Индекс массива должен быть неотрицательным целым числом. Текущее значение: {$index}");
}
$this->eventDispatcher->ОповеститьНаблюдателей("ПередИзменением");
$count = $this->count();
for ($i = $index; $i < $count - 1; $i++) {
parent::offsetSet($i, parent::offsetGet($i + 1));
}
parent::offsetUnset($count - 1);
$this->eventDispatcher->ОповеститьНаблюдателей("ПриИзменении");
}
}
class Структура extends ArrayObject
{
function __construct($args = null)
{
$argsCount = func_num_args();
if ($argsCount >= 1) {
$strProps = func_get_arg(0);
$props = explode(",", strval($strProps));
$propsCount = count($props);
for ($i = 0; $i < $propsCount; $i++) {
$this->Вставить(trim($props[$i]), $i + 1 < $argsCount ? func_get_arg($i + 1) : null);
}
}
}
private static function isValidPropertyName($propName)
{
return preg_match("/^[A-Za-zА-Яа-я_]{1}[A-Za-zА-Яа-я_0-9]*/", $propName);
}
public function Вставить($ключ, $значение = null)
{
if (gettype($ключ) != "string" || !Структура::isValidPropertyName($ключ)) {
throw new Exception("Ошибка при указании ключа структуры. Ключ должен быть корректным идентификатором.");
}
$tempKey = mb_strtolower($ключ);
return parent::offsetSet($tempKey, [$ключ, $значение]);
}
public function Свойство($ключ, &$найденноеЗначение)
{
$tempKey = mb_strtolower($ключ);
if (parent::offsetExists($tempKey)) {
$найденноеЗначение = $this->offsetGet($tempKey);
return true;
}
return false;
}
public function Удалить($ключ)
{
$tempKey = mb_strtolower($ключ);
parent::offsetUnset($tempKey);
}
public function Очистить()
{
$iterator = parent::getIterator();
foreach ($iterator as $key => $value) {
parent::offsetUnset($key);
}
}
public function Количество()
{
return count($this);
}
public function offsetSet($key, $newVal)
{
if (gettype($key) != "string" || !Структура::isValidPropertyName($key)) {
throw new InvalidArgumentException("Ошибка при указании ключа структуры. Ключ должен быть корректным идентификатором.");
}
$tempKey = mb_strtolower($key);
$tempVal = parent::offsetGet($tempKey);
if (is_array($tempVal)) {
parent::offsetSet($tempKey, [$tempVal[0], $newVal]);
return;
}
throw new InvalidArgumentException("Свойство '{$key}' не существует в данном контексте.");
}
public function offsetGet($key)
{
if (gettype($key) != "string" || !Структура::isValidPropertyName($key)) {
throw new InvalidArgumentException("Ошибка при указании ключа структуры. Ключ должен быть корректным идентификатором.");
}
$tempKey = mb_strtolower($key);
$tempVal = parent::offsetGet($tempKey);
if (is_array($tempVal)) {
return $tempVal[1];
}
throw new InvalidArgumentException("Свойство '{$key}' не существует в данном контексте.");
}
public function offsetUnset($index)
{
if (gettype($key) != "string" || !Структура::isValidPropertyName($key)) {
throw new InvalidArgumentException("Ошибка при указании ключа структуры. Ключ должен быть корректным идентификатором.");
}
$tempKey = mb_strtolower($key);
parent::offsetUnset($tempKey);
}
public function getIterator()
{
$iterator = parent::getIterator();
foreach ($iterator as $key => $value) {
yield $value[0] => $value[1];
}
}
public function __get($name)
{
return $this->offsetGet($name);
}
public function __set($name, $val)
{
return $this->offsetSet($name, $val);
}
public function __isset($name)
{
return $this->Свойство($name);
}
}
class Соответствие implements IteratorAggregate, ArrayAccess, Serializable, Countable
{
function __construct()
{
$this->keyValues = [];
}
private $keyValues;
public function Получить($ключ)
{
return $this->offsetGet($ключ);
}
public function Вставить($ключ, $значение)
{
$this->offsetSet($ключ, $значение);
}
public function Удалить($ключ)
{
$this->offsetUnset($ключ);
}
public function Очистить()
{
$this->keyValues = [];
}
public function Количество()
{
return $this->count();
}
public function getIterator()
{
foreach ($this->keyValues as $key => $val) {
yield $val->Ключ => $val->Значение;
}
}
public function offsetGet($offset)
{
foreach ($this->keyValues as $key => $val) {
if ($val->Ключ === $offset) {
return $val->Значение;
}
}
return null;
}
public function offsetSet($offset, $value)
{
$tempKey = null;
foreach ($this->keyValues as $key => $val) {
if ($val->Ключ === $offset) {
$tempKey = $key;
break;
}
}
if ($tempKey !== null) {
$this->keyValues[$key] = new КлючИЗначение($offset, $value);
} else {
$this->keyValues[] = new КлючИЗначение($offset, $value);
}
}
public function offsetUnset($offset)
{
$tempKey = null;
foreach ($this->keyValues as $key => $val) {
if ($val->Ключ === $offset) {
$tempKey = $key;
break;
}
}
if ($tempKey !== null) {
unset($this->keyValues[$tempKey]);
}
}
public function offsetExists($offset)
{
foreach ($this->keyValues as $key => $val) {
if ($val->Ключ === $offset) {
return true;
}
}
return false;
}
public function count()
{
return count($this->keyValues);
}
public function serialize()
{
return serialize($this->keyValues);
}
public function unserialize($data)
{
$this->keyValues = unserialize($data);
}
public function ToArray()
{
$result = [];
foreach ($this->keyValues as $key => $val) {
$result[$val->Ключ] = $val->Значение;
}
return $result;
}
public static function ИзМассива($значения)
{
$result = new Соответствие();
foreach ($значения as $ключ => $значение) {
$result->Вставить($ключ, $значение);
}
return $result;
}
}
class DBNull
{
public function __toString()
{
return "";
}
}
class КлючИЗначение
{
function __construct($ключ, $значение)
{
$this->key = $ключ;
$this->value = $значение;
}
private $key;
private $value;
public function __get($name)
{
$strName = mb_strtolower($name);
switch ($strName) {
case 'ключ':
return $this->key;
case 'key':
return $this->key;
case 'значение':
return $this->value;
case 'value':
return $this->value;
}
return null;
}
public function __isset($name)
{
$strName = mb_strtolower($name);
switch ($strName) {
case 'ключ':
return isset($this->key);
case 'key':
return isset($this->key);
case 'значение':
return isset($this->value);
case 'value':
return isset($this->value);
}
return false;
}
}
class ДвоичныеДанные
{
function __construct($данные = null)
{
$this->value = $данные;
}
private $value;
public function ПолучитьДанные()
{
return $this->value;
}
public static function ИзСтроки($строка)
{
return new ДвоичныеДанные($строка);
}
public static function ИзФайла($путьКФайлу)
{
$data = file_get_contents($путьКФайлу);
return new ДвоичныеДанные($data);
}
public function Записать($путьКФайлу)
{
file_put_contents($путьКФайлу, $this->value);
}
}
class ХранилищеЗначения
{
function __construct($значение)
{
$this->data = $значение;
}
private $data;
public function Получить()
{
return $this->data;
}
}
class УникальныйИдентификатор
{
function __construct($значение = null)
{
if ($значение === null) {
$this->value = $this->generateNewString();
} else {
$tempVal = strtolower($значение);
if (preg_match("/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/", $tempVal)) {
$this->value = $значение ? strtolower($значение) : $this->generateNewString();
} else {
throw new InvalidArgumentException("Ошибка при указании идентификатора. Представление идентификатора не соответствует шаблону.");
}
}
}
private $value;
private function generateNewString()
{
if (function_exists('com_create_guid') === true) {
return trim(com_create_guid(), '{}');
}
$data = openssl_random_pseudo_bytes(16);
$data[6] = chr(ord($data[6]) & 0x0f | 0x40);
$data[8] = chr(ord($data[8]) & 0x3f | 0x80);
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
}
public function Пустой()
{
return $this->value == "00000000-0000-0000-0000-000000000000";
}
public function __toString()
{
return $this->value;
}
public function Равно($идентификатор)
{
return $this->__toString() == strval($идентификатор);
}
public static function Сгенерировать()
{
return $this->generateNewString();
}
public static function ПолучитьПустой()
{
return new УникальныйИдентификатор("00000000-0000-0000-0000-000000000000");
}
}
class МоментВремени
{
function __construct($дата, $ссылка)
{
$this->date = $дата;
$this->reference = $ссылка;
}
private $date;
private $reference;
public function __toString()
{
return $this->date->format('c')."; ".strval($this->reference);
}
public function Дата()
{
return $this->date;
}
public function Ссылка()
{
return $this->reference;
}
public function __get($name)
{
$tempName = mb_strtolower($name);
if ($tempName == 'дата' || $tempName == 'date') {
return $this->date;
}
if ($tempName == 'ссылка' || $tempName == 'ref') {
return $this->reference;
}
return null;
}
}
class Граница
{
function __construct($значение, $видГраницы = null)
{
$this->value = $значение;
$this->boundaryType = $видГраницы instanceof ВидГраницы ? $видГраницы : ВидГраницы::Включая();
}
private $value;
private $boundaryType;
public function Значение()
{
return $this->value;
}
public function ВидГраницы()
{
return $this->boundaryType;
}
public function __get($name)
{
$tempName = mb_strtolower($name);
if ($tempName == 'значение' || $tempName == 'value') {
return $this->value;
}
if ($tempName == 'видграницы' || $tempName == 'boundarytype') {
return $this->boundaryType;
}
return null;
}
public function __toString()
{
return get_class($this);
}
}
class Тип
{
function __construct($xmlИмяТипа, $xmlПространствоИмен)
{
$this->name = $xmlИмяТипа;
$this->nameSpace = $xmlПространствоИмен;
}
private $name;
private $nameSpace;
public function Получить()
{
return $this->data;
}
public function XmlИмя()
{
return $this->name;
}
public function XmlПространствоИмен()
{
return $this->nameSpace;
}
public function __toString()
{
return $this->name;
}
public static function XMLПространствоИменXmlSchema()
{
return "#xs";
}
public static function XMLПространствоИмен1C()
{
return "#1c";
}
public static function Строка()
{
return new Тип("string", Тип::XMLПространствоИменXmlSchema());
}
public static function Число()
{
return new Тип("decimal", Тип::XMLПространствоИменXmlSchema());
}
public static function Дата()
{
return new Тип("dateTime", Тип::XMLПространствоИменXmlSchema());
}
public static function Булево()
{
return new Тип("boolean", Тип::XMLПространствоИменXmlSchema());
}
public static function ДвоичныеДанные()
{
return new Тип("base64Binary", Тип::XMLПространствоИменXmlSchema());
}
public static function ХранилищеЗначения()
{
return new Тип("ValueStorage", Тип::XMLПространствоИмен1C());
}
public static function УникальныйИдентификатор()
{
return new Тип("UUID", Тип::XMLПространствоИмен1C());
}
public static function ВидДвиженияНакопления()
{
return new Тип("AccumulationMovementType", Тип::XMLПространствоИмен1C());
}
public static function ВидДвиженияБухгалтерии()
{
return new Тип("AccountingMovementType", Тип::XMLПространствоИмен1C());
}
public static function ВидСчета()
{
return new Тип("AccountType", Тип::XMLПространствоИмен1C());
}
public static function СправочникСсылка($имя)
{
return new Тип("CatalogRef.{$имя}", "");
}
public static function ДокументСсылка($имя)
{
return new Тип("DocumentRef.{$имя}", "");
}
public static function ПеречислениеСсылка($имя)
{
return new Тип("EnumRef.{$имя}", "");
}
public static function ПланВидовХарактеристикСсылка($имя)
{
return new Тип("ChartOfCharacteristicTypesRef.{$имя}", "");
}
public static function ПланСчетовСсылка($имя)
{
return new Тип("ChartOfAccountsRef.{$имя}", "");
}
public static function ПланВидовРасчетаСсылка($имя)
{
return new Тип("ChartOfCalculationTypesRef.{$имя}", "");
}
public static function БизнесПроцессСсылка($имя)
{
return new Тип("BusinessProcessRef.{$имя}", "");
}
public static function ЗадачаСсылка($имя)
{
return new Тип("TaskRef.{$имя}", "");
}
}
class ОписаниеТипов implements IteratorAggregate, ArrayAccess, Countable
{
function __construct($типы, $квалификаторыЧисла = null, $квалификаторыСтроки = null, $квалификаторыДаты = null, $квалификаторыДвоичныхДанных = null)
{
$this->types = $типы;
$this->numberQualifiers = $квалификаторыЧисла;
$this->stringQualifiers = $квалификаторыСтроки;
$this->dateQualifiers = $квалификаторыДаты;
$this->binaryDataQualifiers = $квалификаторыДвоичныхДанных;
}
private $types;
private $stringQualifiers;
private $numberQualifiers;
private $dateQualifiers;
private $binaryDataQualifiers;
public function КвалификаторыЧисла()
{
return $this->numberQualifiers;
}
public function КвалификаторыСтроки()
{
return $this->stringQualifiers;
}
public function КвалификаторыДаты()
{
return $this->dateQualifiers;
}
public function КвалификаторыДвоичныхДанных()
{
return $this->binaryDataQualifiers;
}
public function Типы()
{
return $this->types;
}
public function __toString()
{
return implode(", ", $this->types);
}
public function getIterator()
{
foreach ($this->types as $key => $val) {
yield $key => $val;
}
}
public function offsetGet($offset)
{
return $this->types[$offset];
}
public function offsetSet($offset, $value)
{
}
public function offsetUnset($offset)
{
}
public function offsetExists($offset)
{
return isset($this->types[$offset]);
}
public function count()
{
return count($this->types[$offset]);
}
}
class ДопустимаяДлина extends ПеречислениеБром
{
protected function enumValues()
{
return [["Переменная", "Variable"], ["Фиксированная", "Fixed"]];
}
}
class ДопустимыЗнак extends ПеречислениеБром
{
protected function enumValues()
{
return [["Любой", "Any"], ["Неотрицательный", "Nonnegative"]];
}
}
class ЧастиДаты extends ПеречислениеБром
{
protected function enumValues()
{
return [["Время", "Time"], ["Дата", "Date"], ["ДатаВремя", "DateTime"]];
}
}
class ВидДвиженияНакопления extends ПеречислениеБром
{
protected function enumValues()
{
return [["Приход", "Receipt"], ["Расход", "Expense"]];
}
}
class ВидДвиженияБухгалтерии extends ПеречислениеБром
{
protected function enumValues()
{
return [["Дебет", "Debit"], ["Кредит", "Credit"]];
}
}
class ВидСчета extends ПеречислениеБром
{
protected function enumValues()
{
return [["АктивноПассивный", "ActivePassive"], ["Активный", "Active"], ["Пассивный", "Passive"]];
}
}
class КолонкаКоллекцииЗначений
{
function __construct($коллекцияКолонок, $имя, $заголовок = null)
{
if (!КолонкаКоллекцииЗначений::IsPropertyNameValid($имя)) {
throw new Exception("Недопустимое имя колонки.");
}
$this->columnCollection = $коллекцияКолонок;
$this->name = $имя;
$this->title = empty($заголовок) ? $имя : $заголовок;
}
private $columnCollection;
private $name;
private $title;
private static function IsPropertyNameValid($name)
{
return preg_match("/^[A-Za-zА-Яа-я_]{1}[A-Za-zА-Яа-я_0-9]*/", $name);
}
public function Имя()
{
return $this->name;
}
public function __get($name)
{
$tempName = mb_strtolower($name);
if ($tempName == 'имя' || $tempName == 'name') {
return $this->name;
}
}
public function __set($name, $value)
{
$tempName = mb_strtolower($name);
if ($tempName == 'имя' || $tempName == 'name') {
$this->name = $value;
}
}
public function __toString()
{
return $this->name;
}
}
class КоллекцияКолонок implements IteratorAggregate, ArrayAccess, Countable
{
function __construct($коллекция)
{
$this->parentCollection = $коллекция;
$this->columns = new Массив();
}
private $parentCollection;
private $columns;
public function Добавить($имя, $заголовок = null)
{
if ($this->Найти($имя) != null) {
throw new Exception("Колонка с именем \"{$имя}\" уже присутствует в таблице.");
}
$column = new КолонкаКоллекцииЗначений($this, $имя, $заголовок);
$this->columns->Добавить($column);
}
public function Наименования()
{
$имена = [];
foreach ($this->columns as $val) {
$имена[] = $val->Имя();
}
return $имена;
}
public function OnColumnStartRename($column, $name)
{
$this->parentCollection->OnColumnStartRename($column, $name);
}
public function OnColumnEndRename($column)
{
$this->parentCollection->OnColumnEndRename($column, $name);
}
public function Количество()
{
return $this->columns->Количество();
}
public function Вставить($индекс, $имя, $заголовок = null)
{
if ($this->Найти($имя) != null) {
throw new Exception("Колонка с именем \"{$имя}\" уже присутствует в таблице.");
}
$column = new КолонкаКоллекцииЗначений($this, $имя, $заголовок);
$this->columns->Вставить($индекс, $column);
}
public function Найти($имяКолонки)
{
$tempName = mb_strtolower($имяКолонки);
foreach ($this->columns as $column) {
if ($tempName == mb_strtolower($column->Имя())) {
return $column;
}
}
return null;
}
public function Удалить($колонка)
{
if (gettype($колонка) == 'integer') {
$текКолонка = $this->columns[$колонка];
$this->columns->Удалить($колонка);
$this->parentCollection->OnColumnDelete($текКолонка);
} else if ($колонка instanceof КолонкаКоллекцииЗначений) {
$индекс = $this->columns->Найти($колонка);
$this->Удалить($индекс);
} else if (gettype($колонка) == 'string') {
$текКолонка = $this->Найти($колонка);
if ($текКолонка !== null) {
$this->Удалить($текКолонка);
}
}
}
public function getIterator()
{
foreach ($this->columns as $key => $val) {
yield $key => $val;
}
}
public function offsetGet($offset)
{
return $this->columns[$offset];
}
public function offsetSet($offset, $value)
{
}
public function offsetUnset($offset)
{
}
public function offsetExists($offset)
{
return $this->columns->offsetExists($offset);
}
public function count()
{
return $this->columns->Количество();
}
}
abstract class СтрокаДвумернойКоллекцииЗначений implements ArrayAccess
{
function __construct($коллекция)
{
$this->parentCollection = $коллекция;
$this->values = new Соответствие();
}
private $parentCollection;
private $values;
public function commonGet($fieldName)
{
$column = $this->parentCollection->Колонки->Найти($fieldName);
if ($column != null) {
return $this->values[$column];
}
return null;
}
private function commonSet($fieldName, $value)
{
$column = $this->parentCollection->Колонки->Найти($fieldName);
if ($column != null) {
$this->values[$column] = $value;
}
}
public function __get($name)
{
return $this->commonGet($name);
}
public function __set($name, $value)
{
return $this->commonSet($name, $value);
}
public function offsetGet($offset)
{
return $this->commonGet($offset);
}
public function offsetSet($offset, $value)
{
return $this->commonSet($offset, $value);
}
public function offsetUnset($offset)
{
}
public function offsetExists($offset)
{
return $this->parentCollection->Колонки->Найти($offset) !== null;
}
public function OnColumnRemove($column)
{
$this->values->Удалить($column);
}
}
class СтрокаТаблицыЗначений extends СтрокаДвумернойКоллекцииЗначений
{
function __construct($коллекция)
{
parent::__construct($коллекция);
}
}
class СтрокаДереваЗначений extends СтрокаДвумернойКоллекцииЗначений
{
function __construct($коллекция)
{
parent::__construct($коллекция);
$this->rows = new КоллекцияСтрокДереваЗначений($коллекция);
}
private $rows;
public function&Строки()
{
return $this->rows;
}
}
abstract class ДвумернаяКоллекцияЗначений
{
function __construct()
{
$this->columns = new КоллекцияКолонок($this);
}
private $columns;
public function __get($name)
{
$tempName = mb_strtolower($name);
if ($tempName == 'колонки' || $tempName == 'columns') {
return $this->columns;
}
}
public function OnColumnStartRename($column, $name)
{
$tempColumn = $this->Колонки->Найти($name);
if ($tempColumn != null && $tempColumn != $column) {
throw new Exception("Колонка с именем \"{$tempColumn->Имя()}\" уже существует в данной коллекции.");
}
}
public function OnColumnEndRename($column)
{
}
}
class ТаблицаЗначений extends ДвумернаяКоллекцияЗначений implements IteratorAggregate, ArrayAccess, Countable
{
function __construct()
{
parent::__construct();
$this->rows = new Массив();
}
private $rows;
public function Количество()
{
return $this->rows->Количество();
}
public function Добавить()
{
$newRow = new СтрокаТаблицыЗначений($this);
$this->rows->Добавить($newRow);
return $newRow;
}
public function Вставить($индекс)
{
$newRow = new СтрокаТаблицыЗначений($this);
$this->rows->Вставить($индекс, $newRow);
return $newRow;
}
public function Удалить($строка)
{
$индекс = $this->rows->Найти($строка);
if ($индекс !== null) {
$this->rows->Удалить($индекс);
}
}
public function Очистить()
{
$количество = $this->Количество();
for ($i = $количество - 1; $i >= 0; $i--) {
$стр = $this->rows[$i];
$this->Удалить($i);
}
}
public function Получить($индекс)
{
return $this->rows[$индекс];
}
public function getIterator()
{
foreach ($this->rows as $key => $val) {
yield $key => $val;
}
}
public function offsetGet($offset)
{
return $this->rows[$offset];
}
public function offsetSet($offset, $value)
{
}
public function offsetUnset($offset)
{
}
public function offsetExists($offset)
{
return $this->rows->offsetExists($offset);
}
public function count()
{
return count($this->rows);
}
public function OnColumnDelete($column)
{
foreach ($this->rows as $row) {
$row->OnColumnRemove($column);
}
}
}
class ДеревоЗначений extends ДвумернаяКоллекцияЗначений
{
function __construct()
{
parent::__construct();
$this->rows = new КоллекцияСтрокДереваЗначений($this);
}
private $rows;
public function&Строки()
{
return $this->rows;
}
public function OnColumnDelete($column)
{
$tempRows =& $this->Строки();
$this->UpdateRowsOnColumnDelete($tempRows, $column);
}
private function UpdateRowsOnColumnDelete(&$rows, $column)
{
foreach ($rows as $row) {
$row->OnColumnRemove($column);
$tempRows =& $row->Строки();
$this->UpdateRowsOnColumnDelete($tempRows, $column);
}
}
}
class КоллекцияСтрокДереваЗначений implements IteratorAggregate, ArrayAccess, Countable
{
function __construct($дерево)
{
$this->parentCollection = $дерево;
$this->rows = new Массив();
}
private $parentCollection;
private $rows;
public function Количество()
{
return $this->rows->Количество();
}
public function Добавить()
{
$newRow = new СтрокаДереваЗначений($this->parentCollection);
$this->rows->Добавить($newRow);
return $newRow;
}
public function Вставить($индекс)
{
$newRow = new СтрокаДереваЗначений($this->parentCollection);
$this->rows->Вставить($индекс, $newRow);
return $newRow;
}
public function Удалить($строка)
{
$индекс = $this->rows->Найти($строка);
if ($индекс !== null) {
$this->rows->Удалить($индекс);
}
}
public function Очистить()
{
$количество = $this->Количество();
for ($i = $количество - 1; $i >= 0; $i--) {
$стр = $this->rows[$i];
$this->Удалить($i);
}
}
public function Получить($индекс)
{
return $this->rows[$индекс];
}
public function getIterator()
{
foreach ($this->rows as $key => $val) {
yield $key => $val;
}
}
public function offsetGet($offset)
{
return $this->rows[$offset];
}
public function offsetSet($offset, $value)
{
}
public function offsetUnset($offset)
{
}
public function offsetExists($offset)
{
return $this->rows->offsetExists($offset);
}
public function count()
{
return count($this->rows);
}
}
abstract class Ссылка
{
protected function __construct($клиент, $типКоллекции, $имяКоллекции)
{
$this->bromClient = $клиент;
$this->collectionType = $типКоллекции;
$this->collectionName = $имяКоллекции;
}
protected $bromClient;
protected $collectionType;
protected $collectionName;
public function ТипКоллекции()
{
return $this->collectionType;
}
public function ИмяКоллекции()
{
return $this->collectionName;
}
public function Клиент()
{
return $this->bromClient;
}
public function ПолноеИмяТипа()
{
return $this->collectionType->getName().".".$this->collectionName;
}
public function Метаданные()
{
$метаданные = null;
$this->bromClient->Метаданные->ПопыткаПолучить($this->ПолноеИмяТипа(), $метаданные);
return $метаданные;
}
public abstract function Пустая();
public static function СоздатьСсылку($клиент, $типКоллекции, $имяКоллекци, $указатель)
{
if ($типКоллекции == ТипКоллекции::Перечисление()) {
return $клиент->Контекст()->ПолучитьПеречислениеСсылку("{$типКоллекции->getName()}.{$имяКоллекци}", $указатель);
} else {
return $клиент->Контекст()->ПолучитьОбъектСсылку("{$типКоллекции->getName()}.{$имяКоллекци}", $указатель);
}
}
public static function СоздатьСсылкуПоИмениТипа($клиент, $полноеИмяТипа, $указатель)
{
$фрагментыИмени = explode(".", $полноеИмяТипа);
return self::СоздатьСсылку($клиент, $фрагментыИмени[0], $фрагментыИмени[1], $указатель);
}
}
class ПеречислениеСсылка extends Ссылка
{
public function __construct($клиент, $имяКоллекци, $имя, $синоним = "")
{
parent::__construct($клиент, ТипКоллекции::Перечисление(), $имяКоллекци);
$this->name = $имя;
$this->title = !empty($синоним) ? $синоним : $this->name;
}
private $name;
private $title;
public function Имя()
{
return $this->name;
}
public function Синоним()
{
return $this->title;
}
public function Пустая()
{
return empty($this->name);
}
public function __toString()
{
return $this->Синоним();
}
}
class ОбъектСсылка extends Ссылка implements ArrayAccess
{
public function __construct($клиент, $типКоллекции, $имяКоллекци, $идентификатор)
{
parent::__construct($клиент, $типКоллекции, $имяКоллекци);
$this->guid = $идентификатор;
}
private $guid;
public function УникальныйИдентификатор()
{
return $this->guid;
}
public function Пустая()
{
return $this->guid->Пустой();
}
public function ПолучитьОбъект()
{
if ($this->Пустая()) {
throw new Exception("Невозможно получить объект пустой ссылки. Воспользуйтесь методом \"СоздатьОбъект\" модуля менеджера коллекции.");
}
$контекст = КонтекстОбъекта::ПолучитьКонтекстОбъекта($this);
$контекст->ЗагрузитьДанные();
return $контекст;
}
public function __toString()
{
$представление = $this->bromClient->Контекст()->ПолучитьПредставлениеОбъекта($this);
return $представление !== null ? $представление : "{$this->ПолноеИмяТипа()}: ({$this->guid})";
}
public function Равно($ссылка)
{
return $ссылка != null && $this->guid->Равно($ссылка->guid) && $this->ИмяКоллекции() == $ссылка->ИмяКоллекции() && $this->ТипКоллекции() == $ссылка->ТипКоллекции();
}
private function commonGet($fieldName)
{
$value = null;
$this->bromClient->Контекст()->ПопыткаПолучитьЗначение($this, $fieldName, $value);
return $value;
}
public function __get($name)
{
return $this->commonGet($name);
}
public function offsetGet($offset)
{
return $this->commonGet($offset);
}
public function offsetSet($offset, $value)
{
}
public function offsetUnset($offset)
{
}
public function offsetExists($offset)
{
$metadata = $this->Метаданные();
return $metadata->Реквизиты->Содержит($offset) || $metadata->ТабличныеЧасти->Содержит($offset);
}
}
class СправочникСсылка extends ОбъектСсылка
{
public function __construct($клиент, $имяКоллекци, $идентификатор)
{
parent::__construct($клиент, ТипКоллекции::Справочник(), $имяКоллекци, $идентификатор);
}
}
class ДокументСсылка extends ОбъектСсылка
{
public function __construct($клиент, $имяКоллекци, $идентификатор)
{
parent::__construct($клиент, ТипКоллекции::Документ(), $имяКоллекци, $идентификатор);
}
}
class ПланВидовХарактеристикСсылка extends ОбъектСсылка
{
public function __construct($клиент, $имяКоллекци, $идентификатор)
{
parent::__construct($клиент, ТипКоллекции::ПланВидовХарактеристик(), $имяКоллекци, $идентификатор);
}
}
class ПланСчетовСсылка extends ОбъектСсылка
{
public function __construct($клиент, $имяКоллекци, $идентификатор)
{
parent::__construct($клиент, ТипКоллекции::ПланСчетов(), $имяКоллекци, $идентификатор);
}
}
class ПланВидовРасчетаСсылка extends ОбъектСсылка
{
public function __construct($клиент, $имяКоллекци, $идентификатор)
{
parent::__construct($клиент, ТипКоллекции::ПланВидовРасчета(), $имяКоллекци, $идентификатор);
}
}
class БизнесПроцессСсылка extends ОбъектСсылка
{
public function __construct($клиент, $имяКоллекци, $идентификатор)
{
parent::__construct($клиент, ТипКоллекции::БизнесПроцесс(), $имяКоллекци, $идентификатор);
}
}
class ЗадачаСсылка extends ОбъектСсылка
{
public function __construct($клиент, $имяКоллекци, $идентификатор)
{
parent::__construct($клиент, ТипКоллекции::Задача(), $имяКоллекци, $идентификатор);
}
}
class НесериализуемыеДанные
{
}
class КвалификаторыСтроки
{
function __construct($длинаСтроки, $допустимаяДлина)
{
$this->length = empty($длинаСтроки) ? 0 : $длинаСтроки;
$this->allowedLength = empty($допустимаяДлина) ? ДопустимаяДлина::Переменная() : $допустимаяДлина;
}
private $length;
private $allowedLength;
public function Длина()
{
return $this->length;
}
public function ДопустимаяДлина()
{
return $this->allowedLength;
}
}
class КвалификаторыЧисла
{
function __construct($числоРазрядов, $числоРазрядовДробнойЧасти, $допустимыйЗнак)
{
$this->digits = empty($числоРазрядов) ? 0 : $числоРазрядов;
$this->fractionDigits = empty($числоРазрядовДробнойЧасти) ? 0 : $числоРазрядовДробнойЧасти;
$this->allowedSign = empty($допустимыйЗнак) ? ДопустимыЗнак::Любой() : $допустимыйЗнак;
}
private $digits;
private $fractionDigits;
private $allowedSign;
public function Разрядность()
{
return $this->digits;
}
public function РазрядностьДробнойЧасти()
{
return $this->fractionDigits;
}
public function ДопустимыйЗнак()
{
return $this->allowedSign;
}
}
class КвалификаторыДаты
{
function __construct($частиДаты)
{
$this->dateFractions = empty($частиДаты) ? ЧастиДаты::ДатаВремя() : $частиДаты;
}
private $dateFractions;
public function ЧастиДаты()
{
return $this->dateFractions;
}
}
class КвалификаторыДвоичныхДанных
{
function __construct($длина, $допустимаяДлина)
{
$this->length = empty($длина) ? 0 : $длина;
$this->allowedLength = empty($допустимаяДлина) ? ДопустимаяДлина::Переменная() : $допустимаяДлина;
}
private $length;
private $allowedLength;
public function Длина()
{
return $this->length;
}
public function ДопустимаяДлина()
{
return $this->allowedLength;
}
}
class ВидГраницы extends ПеречислениеБром
{
protected function enumValues()
{
return [["Включая", "Including"], ["Исключая", "Excluding"]];
}
}
interface ИКешМетаданных
{
public function ПопыткаПолучитьЗначение($ключ, &$значение);
public function УстановитьЗначение($ключ, $значение);
public function Очистить();
public function СодержитКлюч($ключ);
}
class ФайловыйКешМетаданных implements ИКешМетаданных
{
function __construct($адресДиректории)
{
$this->rootDirectoryPath = $адресДиректории;
$this->dataDirectoryPath = $this->СоединитьПуть($this->rootDirectoryPath, "data");
}
private $rootDirectoryPath;
private $dataDirectoryPath;
private function СоединитьПуть()
{
$path = '';
$arguments = func_get_args();
$args = [];
foreach ($arguments as $a) if ($a !== '') $args[] = $a;
$arg_count = count($args);
for ($i = 0; $i < $arg_count; $i++) {
$folder = $args[$i];
if ($i != 0 and $folder[0] == DIRECTORY_SEPARATOR) $folder = substr($folder, 1);
if ($i != $arg_count - 1 and substr($folder, -1) == DIRECTORY_SEPARATOR) $folder = substr($folder, 0, -1);
$path .= $folder;
if ($i != $arg_count - 1) $path .= DIRECTORY_SEPARATOR;
}
return $path;
}
private function УдалитьДиректорию($dir)
{
foreach (glob($dir.'/*') as $file) {
if (is_dir($file)) {
$this->УдалитьДиректорию($file);
} else {
unlink($file);
}
}
rmdir($dir);
}
public function АдресДиректории()
{
return $this->rootDirectoryPath;
}
public function ПопыткаПолучитьЗначение($key, &$value)
{
$hash = md5(mb_strtolower($key));
$path = $this->СоединитьПуть($this->dataDirectoryPath, $hash);
if (file_exists($path)) {
$value = file_get_contents($path);
return true;
}
$value = null;
return false;
}
public function УстановитьЗначение($key, $value)
{
if (!file_exists($this->dataDirectoryPath)) {
mkdir($this->dataDirectoryPath, 0777, true);
}
$hash = md5(mb_strtolower($key));
$path = $this->СоединитьПуть($this->dataDirectoryPath, $hash);
file_put_contents($path, $value);
}
public function Очистить()
{
if (file_exists($this->dataDirectoryPath)) {
$this->УдалитьДиректорию($this->dataDirectoryPath);
}
}
public function СодержитКлюч($key)
{
$hash = md5(mb_strtolower($key));
$path = $this->СоединитьПуть($this->dataDirectoryPath, $hash);
return file_exists($path);
}
}
abstract class УзелМетаданных implements ArrayAccess, Countable, IteratorAggregate
{
function __construct($корень, $родитель, $имя, $полноеИмя, $синоним)
{
$this->root = $корень;
$this->name = $имя;
$this->fullName = $полноеИмя;
$this->title = $синоним ? $имя : $синоним;
$this->parentNode = $родитель;
$this->children = [];
if ($родитель !== null) {
$родитель->ДобавитьУзел($this);
}
}
private $name;
private $fullName;
private $title;
private $parentNode;
private $root;
private $children;
protected function Очистить()
{
foreach ($this->children as $key => $value) {
unset($this->children[$key]);
}
}
protected function ПопыткаНайтиПодчиненный($имя, &$узел)
{
$текИмя = mb_strtolower($имя);
if (isset($this->children[$текИмя])) {
$узел = $this->children[$текИмя][1];
return true;
}
return false;
}
protected function НайтиПодчиненный($имя)
{
$узел = null;
$this->ПопыткаНайтиПодчиненный($имя, $узел);
return $узел;
}
public function Имя()
{
return $this->name;
}
public function ПолноеИмя()
{
return $this->fullName;
}
public function Синоним()
{
return $this->title;
}
public function Родитель()
{
return $this->parentNode;
}
public function Корень()
{
if (get_class($this) == "МетаданныеКонфигурация") {
return $this;
}
return $this->root;
}
public function Путь()
{
if ($this->Родитель() == null) {
return "";
}
if (!$this->Родитель()->Путь()) {
return $this->Имя();
}
return $this->Родитель()->Путь().".".$this->Имя();
}
public function Клиент()
{
return $this->Корень()->Клиент();
}
public function ДобавитьУзел($узел)
{
$tempName = mb_strtolower($узел->name);
$this->children[$tempName] = [$узел->name, $узел];
$this->Корень()->ЗарегистрироватьУзел($узел);
}
public function Найти($имя)
{
$результат = null;
$this->ПопыткаНайти($имя, $результат);
return $результат;
}
public function ПопыткаНайти($имя, &$узел)
{
$имена = explode(".", $имя);
$результат = $this;
foreach ($имена as $текИмя) {
if (!$результат->ПопыткаНайтиПодчиненный($текИмя, $результат)) {
$узел = null;
return false;
}
}
$узел = $результат;
return true;
}
public function Содержит($имя)
{
$temp = null;
return $this->ПопыткаНайти($имя, $temp);
}
public function __toString()
{
return $this->fullName;
}
public function __get($offset)
{
return $this->НайтиПодчиненный($offset);
}
public function offsetGet($offset)
{
return $this->НайтиПодчиненный($offset);
}
public function offsetSet($offset, $value)
{
}
public function offsetExists($offset)
{
return $this->Содержит($offset);
}
public function offsetUnset($offset)
{
}
public function count()
{
return count($this->children);
}
public function getIterator()
{
$iterator = new ArrayIterator($this->children);
foreach ($iterator as $key => $val) {
yield $val[0] => $val[1];
}
}
public function&ИменаПодчиненных()
{
$result = [];
foreach ($this->children as $key => $val) {
$result[] = $val[0];
}
return $result;
}
protected static function ЗагрузитьРеквизиты($корень, $узелРодитель, $attributesSOAP)
{
$реквизиты = new МетаданныеКоллекция($корень, $узелРодитель, "Реквизиты", "{$узелРодитель->ПолноеИмя()}.Реквизиты", "Реквизиты", "MetadataAttribute");
if ($attributesSOAP != null) {
foreach ($attributesSOAP as $attribute) {
new МетаданныеРеквизит($реквизиты, $attribute);
}
}
}
protected static function ЗагрузитьТабличныеЧасти($корень, $узелРодитель, $tablesSOAP)
{
$табличныеЧасти = new МетаданныеКоллекция($корень, $узелРодитель, "ТабличныеЧасти", "{$узелРодитель->ПолноеИмя()}.ТабличныеЧасти", "ТабличныеЧасти", "MetadataTableSection");
if ($tablesSOAP != null) {
foreach ($tablesSOAP as $table) {
new МетаданныеТабличнаяЧасть($табличныеЧасти, $table);
}
}
}
}
class МетаданныеМодуль extends УзелМетаданных
{
function __construct($родитель, $metadata)
{
parent::__construct($родитель->Корень(), $родитель, $metadata->Name, $metadata->FullName, $metadata->Title);
}
}
class МетаданныеКоллекция extends УзелМетаданных
{
function __construct($корень, $родитель, $имя, $полноеИмя, $синоним, $типSoap, $проверятьКеш = false)
{
parent::__construct($родитель->Корень(), $родитель, $имя, $полноеИмя, $синоним);
$this->checkCache = $проверятьКеш;
$this->soapType = $типSoap;
}
private $checkCache;
private $soapType;
private $childrenNames;
public function&ИменаПодчиненных()
{
if (!$this->checkCache) {
return parent::ИменаПодчиненных();
}
if ($this->childrenNames != null) {
return $this->childrenNames;
}
$кеш = $this->Корень()->ПолучитьКеш();
if ($кеш != null) {
$именаXML;
if ($кеш->ПопыткаПолучитьЗначение("#list.".$this->Путь(), $именаXML)) {
$this->childrenNames = unserialize($именаXML);
return $this->childrenNames;
}
}
$картаИмен =& $this->Корень()->ПолучитьИменаОбъектовКоллекций($this->Путь());
$именаВрем =& $картаИмен[$this->Путь()];
if ($именаВрем != null) {
$имена = [];
foreach ($именаВрем as $имяВрем) {
$имена[] = $имяВрем;
}
$this->childrenNames =& $имена;
if ($кеш != null) {
$кеш->УстановитьЗначение("#list.".$this->Путь(), serialize($имена));
}
return $this->childrenNames;
}
throw new Exception("Не удалось получить имена подчиненых узлов для коллекции \"{$this->Путь()}\".");
}
protected function ПопыткаНайтиПодчиненный($имя, &$узел)
{
if (parent::ПопыткаНайтиПодчиненный($имя, $узел)) {
return true;
}
if ($this->checkCache) {
$кеш = $this->Корень()->ПолучитьКеш();
$xmlМетаданные;
if ($кеш != null && $кеш->ПопыткаПолучитьЗначение($this->Путь().".".$имя, $xmlМетаданные)) {
$узел = unserialize($xmlМетаданные)->GetValue($this);
return true;
}
$именаПодчиненных = $this->ИменаПодчиненных();
if (array_search($имя, $именаПодчиненных) !== false) {
$this->Корень()->Загрузить("{$this->Путь()}.{$имя}");
return $this->ПопыткаНайтиПодчиненный($имя, $узел);
}
}
$узел = null;
return false;
}
public function getIterator()
{
if ($this->checkCache) {
$names = $this->ИменаПодчиненных();
foreach ($names as $name) {
$узел = null;
if ($this->ПопыткаНайтиПодчиненный($name, $узел)) {
yield $name => $узел;
}
}
} else {
$iterator = parent::getIterator();
foreach ($iterator as $key => $val) {
yield $key => $val;
}
}
}
}
class МетаданныеРеквизит extends УзелМетаданных
{
function __construct($родитель, $metadata)
{
parent::__construct($родитель->Корень(), $родитель, $metadata->Name, "{$родитель->ПолноеИмя()}.Реквизит.{$metadata->Name}", $metadata->Title);
}
}
class МетаданныеТабличнаяЧасть extends УзелМетаданных
{
function __construct($родитель, $metadata)
{
parent::__construct($родитель->Корень(), $родитель, $metadata->Name, "{$родитель->ПолноеИмя()}.ТабличнаяЧасть.{$metadata->Name}", $metadata->Title);
УзелМетаданных::ЗагрузитьРеквизиты($родитель->Корень(), $this, $metadata->Attribute);
}
}
class МетаданныеОбъект extends УзелМетаданных
{
function __construct($родитель, $metadata)
{
parent::__construct($родитель->Корень(), $родитель, $metadata->Name, $metadata->FullName, $metadata->Title);
$this->collectionType = ТипКоллекции::Получить($metadata->CollectionType);
$this->predefinedValues = new Структура();
УзелМетаданных::ЗагрузитьРеквизиты($родитель->Корень(), $this, $metadata->Attribute);
УзелМетаданных::ЗагрузитьТабличныеЧасти($родитель->Корень(), $this, $metadata->TableSection);
$предопределенные = $metadata->Predefined != null ? $metadata->Predefined->GetValue($родитель->Клиент()) : null;
if ($предопределенные != null) {
foreach ($предопределенные as $key => $val) {
$this->predefinedValues->Вставить($key, $val);
}
}
}
private $collectionType;
private $predefinedValues;
public function ТипКоллекции()
{
return $this->collectionType;
}
public function Предопределенные()
{
return $this->predefinedValues;
}
public function __get($name)
{
$tempName = mb_strtolower($name);
switch ($tempName) {
case "предопределенные":
case "predefined":
return $this->predefinedValues;
}
return parent::__get($name);
}
}
class МетаданныеКонфигурация extends УзелМетаданных
{
function __construct($клиент)
{
parent::__construct(null, null, "", "", "");
$this->bromClient = $клиент;
$this->metadataMap = [];
$this->Init();
}
private $bromClient;
private $metadataMap;
private $cache;
private $fullNameToPathMap;
private function Init()
{
$this->Очистить();
foreach ($this->metadataMap as $key => $val) {
unset($this->metadataMap[$key]);
}
$this->fullNameToPathMap = ["Справочник" => "Справочники", "Документ" => "Документы", "Перечисление" => "Перечисления", "ПланВидовХарактеристик" => "ПланыВидовХарактеристик", "ПланСчетов" => "ПланыСчетов", "ПланВидовРасчета" => "ПланыВидовРасчета", "БизнесПроцесс" => "БизнесПроцессы", "Задача" => "Задачи", "Константа" => "Константы", "ОбщийМодуль" => "ОбщиеМодули", "ПараметрСеанса" => "ПараметрыСеанса", "КритерийОтбора" => "КритерииОтбора", "Обработка" => "Обработки", "Отчет" => "Отчеты", "ЖурналДокументов" => "ЖурналыДокументов", "РегистрСведений" => "РегистрыСведений", "РегистрНакопления" => "РегистрыНакопления", "РегистрБухгалтерии" => "РегистрыБухгалтерии", "РегистрРасчета" => "РегистрыРасчета", "Последовательность" => "Последовательности", "Реквизит" => "Реквизиты", "ТабличнаяЧасть" => "ТабличныеЧасти",];
new МетаданныеКоллекция($this, $this, "ПараметрыСеанса", "ПараметрыСеанса", "ПараметрыСеанса", "MetadataAttribute", true);
new МетаданныеКоллекция($this, $this, "КритерииОтбора", "КритерииОтбора", "Критерии отбора", "MetadataModule", true);
new МетаданныеКоллекция($this, $this, "Константы", "Константы", "Константы", "MetadataAttribute", true);
new МетаданныеКоллекция($this, $this, "Справочники", "Справочники", "Справочники", "MetadataObject", true);
new МетаданныеКоллекция($this, $this, "Документы", "Документы", "Документы", "MetadataObject", true);
new МетаданныеКоллекция($this, $this, "Перечисления", "Перечисления", "Перечисления", "MetadataObject", true);
new МетаданныеКоллекция($this, $this, "ПланыВидовХарактеристик", "ПланыВидовХарактеристик", "Планы видов характеристик", "MetadataObject", true);
new МетаданныеКоллекция($this, $this, "ПланыСчетов", "ПланыСчетов", "Планы счетов", "MetadataObject", true);
new МетаданныеКоллекция($this, $this, "ПланыВидовРасчета", "ПланыВидовРасчета", "Планы видов расчета", "MetadataObject", true);
new МетаданныеКоллекция($this, $this, "БизнесПроцессы", "БизнесПроцессы", "Бизнес-процессы", "MetadataObject", true);
new МетаданныеКоллекция($this, $this, "Задачи", "Задачи", "Задачи", "MetadataObject", true);
new МетаданныеКоллекция($this, $this, "ЖурналыДокументов", "ЖурналыДокументов", "Журналы документов", "MetadataModule", true);
new МетаданныеКоллекция($this, $this, "Обработки", "Обработки", "Обработки", "MetadataModule", true);
new МетаданныеКоллекция($this, $this, "Отчеты", "Отчеты", "Отчеты", "MetadataModule", true);
new МетаданныеКоллекция($this, $this, "РегистрыСведений", "РегистрыСведений", "Регистры сведений", "MetadataModule", true);
new МетаданныеКоллекция($this, $this, "РегистрыНакопления", "РегистрыНакопления", "Регистры накопления", "MetadataModule", true);
new МетаданныеКоллекция($this, $this, "РегистрыБухгалтерии", "РегистрыБухгалтерии", "Регистры бухгалтерии", "MetadataModule", true);
new МетаданныеКоллекция($this, $this, "РегистрыРасчета", "РегистрыРасчета", "Регистры расчета", "MetadataModule", true);
new МетаданныеКоллекция($this, $this, "Последовательности", "Последовательности", "Последовательности", "MetadataModule", true);
new МетаданныеКоллекция($this, $this, "ОбщиеМодули", "ОбщиеМодули", "Общие модули", "MetadataModule", true);
}
private function ЗакешироватьЭлементКоллекции($узелМетаданных, $node)
{
if ($this->cache != null) {
$this->cache->УстановитьЗначение($узелМетаданных->Путь(), serialize($node));
}
}
public function ПолучитьКеш()
{
return $this->cache;
}
public function УстановитьКеш($кеш)
{
$this->cache = $кеш;
}
public function ЗарегистрироватьУзел($узел)
{
if ($this->metadataMap != null) {
$текИмя = mb_strtolower($узел->ПолноеИмя());
$this->metadataMap[$текИмя] = $узел;
}
}
public function Загрузить($состав, $размерПакета = 0)
{
$индексПакета = 0;
while (true) {
$soapMetadataPack = $this->ПолучитьМетаданныеSOAP($состав, $размерПакета, $индексПакета);
$this->ЗаполнитьМетаданныеИзПакетаSOAP($soapMetadataPack);
$запрошеноПакетов = $soapMetadataPack->RequestedObjectsCount;
$текРазмерПакета = $soapMetadataPack->PackSize;
$всегоПакетов = $текРазмерПакета > 0 ? (int) (($запрошеноПакетов + $текРазмерПакета - 1) / $текРазмерПакета) : 0;
if ($индексПакета >= $всегоПакетов - 1) {
break;
}
$индексПакета++;
}
}
public function ЗаполнитьМетаданныеИзПакетаSOAP($soapMetadataPack)
{
if ($soapMetadataPack->Collection == null) {
return;
}
foreach ($soapMetadataPack->Collection as $collection) {
$узелКоллекции;
if ($this->ПопыткаНайтиПодчиненный($collection->Name, $узелКоллекции)) {
if ($collection->Item != null) {
foreach ($collection->Item as $node) {
$узел = $node->GetValue($узелКоллекции);
$this->ЗакешироватьЭлементКоллекции($узел, $node);
}
}
}
}
}
public function Клиент()
{
return $this->bromClient;
}
private function ПолучитьМетаданныеSOAP($состав, $размерПакета, $индексПакета)
{
return $this->bromClient->SoapКлиент()->GetMetadata(['nodes' => $состав, 'pack_size' => $размерПакета, 'pack_index' => $индексПакета])->return;
}
public function ПолучитьИменаОбъектовКоллекций($коллекции)
{
$result = $this->bromClient->SoapКлиент()->GetMetadaChildrenNames(['parents' => $коллекции])->return;
return $result->GetValue($this->bromClient);
}
public function ПопыткаПолучить($полноеИмя, &$метаданные)
{
if (isset($this->metadataMap[$полноеИмя])) {
$метаданные = $this->metadataMap[$полноеИмя];
return true;
}
$фрагменты = explode(".", $полноеИмя);
if (count($фрагменты) >= 1) {
if (isset($this->fullNameToPathMap[$фрагменты[0]])) {
$фрагменты[0] = $this->fullNameToPathMap[$фрагменты[0]];
}
}
if (count($фрагменты) >= 3) {
if (isset($this->fullNameToPathMap[$фрагменты[2]])) {
$фрагменты[2] = $this->fullNameToPathMap[$фрагменты[2]];
}
}
$путь = implode(".", $фрагменты);
return $this->ПопыткаНайти($путь, $метаданные);
}
public function __get($name)
{
$tempName = mb_strtolower($name);
if ($tempName == 'кеш' || $tempName == 'cache') {
return $this->cache;
}
return null;
}
public function __set($name, $value)
{
$tempName = mb_strtolower($name);
if ($tempName == 'кеш' || $tempName == 'cache') {
$this->cache = $value instanceof ИКешМетаданных ? $value : null;
}
return null;
}
}
class БромКлиент implements ArrayAccess
{
function __construct($publication, $user, $password)
{
$normalPublication = trim(strval($publication), "/");
$wsdl_link = "{$normalPublication}/ws/brom_api?wsdl";
$service_link = "{$normalPublication}/ws/brom_api";
$this->soapClient = new SoapClient($wsdl_link, ['login' => $user, 'password' => $password, 'location' => $service_link, 'exceptions' => 1, 'encoding' => 'UTF-8', 'classmap' => $this->getClassMap(), 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, 'trace' => 1]);
$this->metadata = new МетаданныеКонфигурация($this);
$this->dataContext = new КонтекстДанных($this);
}
private static $version = "1.0.1-beta";
private $soapClient;
private $metadata;
private $dataContext;
private function getClassMap()
{
$types = ['MetadataModule', 'MetadataCollection', 'MetadataAttribute', 'MetadataTableSection', 'MetadataObject', 'MetadataApplication', 'ValueNull', 'ValueDBNull', 'ValueString', 'ValueNumber', 'ValueBoolean', 'ValueDate', 'ValueArray', 'ValueStruct', 'ValueMap', 'ValueTable', 'ValueTree', 'ValueKeyValue', 'ValueObjectRef', 'ValueEnumRef', 'ValueStorage', 'ValueBinaryData', 'ValueGuid', 'ValueType', 'ValueTypeDescription', 'ValuePointInTime', 'ValueBoundary', 'ValueAccountingRecordType', 'ValueAccumulationRecordType', 'ValueAccountType', 'ValueNonserializable', 'NumberQualifiers', 'StringQualifiers', 'DateQualifiers', 'BinaryDataQualifiers', 'PostObject_Settings',];
$classMap = [];
foreach ($types as $type => $val) {
$classMap[$val] = $val;
}
return $classMap;
}
private function ВыполнитьЗапросОбщее($текстЗапроса, $параметры = null, $отбор = null, $поля = null, $порядок = null, $пакетный = false, $типОбхода = null, $включатьВременныеДанные = false)
{
$parameters = [];
if ($параметры instanceof Структура) {
foreach ($параметры as $key => $val) {
$parameters[] = ValueBase::SoapValue("RequestParameter", ['Key' => $key, 'Value' => ValueBase::From($val)]);
}
}
$filters = [];
if ($отбор instanceof Массив || is_array($отбор)) {
foreach ($отбор as $key => $val) {
$filters[] = ValueBase::SoapValue("RequestFilter", ['Key' => $val->Ключ(), 'Value' => ValueBase::From($val->Значение()), 'ComparisonType' => $val->ВидСравнения()->getName()]);
}
}
$fields = [];
if ($поля instanceof Массив || is_array($поля)) {
foreach ($поля as $key => $val) {
$fields[] = ValueBase::SoapValue("RequestField", ['Key' => $val->Ключ(), 'Name' => $val->Псевдоним()]);
}
}
$sort = [];
if ($порядок instanceof Массив || is_array($порядок)) {
foreach ($порядок as $key => $val) {
$sort[] = ValueBase::SoapValue("RequestSort", ['Key' => $val->Ключ(), 'Direction' => $val->Направление() == НаправлениеСортировки::Убывание() ? "Убыв" : "Возр"]);
}
}
$settings = ValueBase::SoapValue("ExecuteRequest_Settings", ['Parameter' => $parameters, 'Filter' => $filters, 'Field' => $fields, 'Sort' => $sort, 'QueryResultIteration' => $типОбхода instanceof ОбходРезультатаЗапроса ? $типОбхода->getName() : ОбходРезультатаЗапроса::Прямой()->getName(), 'IncludeTemporalData' => boolval($включатьВременныеДанные)]);
if (!boolval($пакетный)) {
return $this->SoapКлиент()->ExecuteRequest(['request' => $текстЗапроса, 'settings' => $settings])->return->GetValue($this);
} else {
return $this->SoapКлиент()->ExecuteRequestBatch(['request' => $текстЗапроса, 'settings' => $settings])->return->GetValue($this);
}
}
public function SoapКлиент()
{
return $this->soapClient;
}
public function Контекст()
{
return $this->dataContext;
}
public function ЗагрузитьМетаданные($состав = "", $размерПакета = 0)
{
$this->metadata->Загрузить($состав, $размерПакета);
}
public function ПолучитьЗначениеПараметраСеанса($имяПараметраСеанса)
{
$result = $this->SoapКлиент()->GetSessionParameter(['name' => $имяПараметраСеанса])->return;
return $result->GetValue($this);
}
public function ПолучитьЗначениеКонстанты($имяКонстанты)
{
return $this->soapClient->GetConstant(['name' => $имяКонстанты])->return->GetValue($this);
}
public function УстановитьЗначениеКонстанты($имяКонстанты, $значение)
{
$this->soapClient->SetConstant(['name' => $имяКонстанты, 'value' => ValueBase::From($значение)]);
}
public function ВызватьМетод($модуль, $метод, ...$параметры)
{
return $this->ВызватьМетодСМассивомПараметров($модуль, $метод, $параметры);
}
public function ВызватьМетодСМассивомПараметров($модуль, $метод, &$параметры = null)
{
$текПараметры = is_array($параметры) ? $параметры : [];
$result = $this->SoapКлиент()->ExecuteMethod(['module' => $модуль, 'method' => $метод, 'params' => ValueBase::From(Массив::ИзМассива($текПараметры))])->return;
return $result->GetValue($this);
}
public function Выполнить($код, $параметр = null)
{
$result = $this->SoapКлиент()->ExecuteCode(['code' => $код, 'param' => ValueBase::From($параметр)])->return;
return $result->GetValue($this);
}
public function ВыполнитьЗапрос($текстЗапроса, $параметры = null, $отборы = null, $поля = null, $порядок = null, $типОбхода = null)
{
return $this->ВыполнитьЗапросОбщее($текстЗапроса, $параметры, $отборы, $поля, $порядок, false, $типОбхода);
}
public function ВыполнитьПакетныйЗапрос($текстЗапроса, $параметры = null, $отборы = null, $поля = null, $порядок = null, $типОбхода = null, $включатьВременныеДанные = false)
{
return $this->ВыполнитьЗапросОбщее($текстЗапроса, $параметры, $отборы, $поля, $порядок, true, $типОбхода, $включатьВременныеДанные);
}
public function Ping()
{
return $this->SoapКлиент()->GebugPing()->return;
}
public function Эхо($value)
{
$soapValue = ValueBase::From($value);
$result = $this->SoapКлиент()->DebugEcho(['param' => $soapValue])->return;
return $result->GetValue($this);
}
public function СоздатьЗапрос($текст = "")
{
return new Запрос($this, $текст);
}
public function СоздатьСелектор()
{
return new Селектор($this);
}
public function ПолучитьИнформациюОСистеме()
{
return $this->soapClient->GetSystemInfo()->return->GetValue($this);
}
public function ПолучитьДанныеОбъекта($ссылка, $поля = null, $автозагрузкаПолей = null)
{
$автозагрузкаПолей = empty($автозагрузкаПолей) ? АвтозагрузкаПолейОбъектов::Ничего() : $автозагрузкаПолей;
$fields = [];
if ($поля instanceof Массив || is_array($поля)) {
foreach ($поля as $fieldName) {
$fields[] = ValueBase::SoapValue("RequestField", ['Key' => $fieldName]);
}
}
$settings = ValueBase::SoapValue("GetObject_Settings", ['Field' => $fields, 'AddSkippedProperties' => true, 'PropertiesHierarchyType' => "Hierarchy", 'FieldAutoinclusion' => ValueBase::SoapValue("RequestFieldAutoinclusionSettings", ['DefaultFields' => $автозагрузкаПолей->ЗагружатьСтандартныеРеквизиты, 'CustomFields' => $автозагрузкаПолей->ЗагружатьПользовательскиеРеквизиты, 'Tables' => $автозагрузкаПолей->ЗагружатьТабличныеЧасти])]);
$soapValue = $this->soapClient->GetObject(['reference' => ValueBase::From($ссылка), 'settings' => $settings])->return;
return $soapValue->ToTree($this);
}
private function commonGet($name)
{
$tempName = mb_strtolower($name);
if ($tempName == "метаданные") {
return $this->metadata;
}
$текМетаданные = null;
if ($this->metadata->ПопыткаНайти($name, $текМетаданные)) {
switch ($текМетаданные->Имя()) {
case "ПараметрыСеанса":
return new ПараметрыСеансаМенеджер($this);
case "КритерииОтбора":
return new КритерииОтбораМенеджер($this);
case "Константы":
return new КонстантыМенеджер($this);
case "Справочники":
return new ОбъектыМенеджер($this, $текМетаданные, ТипКоллекции::Справочник());
case "Документы":
return new ОбъектыМенеджер($this, $текМетаданные, ТипКоллекции::Документ());
case "Перечисления":
return new ОбъектыМенеджер($this, $текМетаданные, ТипКоллекции::Перечисление());
case "ПланыВидовХарактеристик":
return new ОбъектыМенеджер($this, $текМетаданные, ТипКоллекции::ПланВидовХарактеристик());
case "ПланыСчетов":
return new ОбъектыМенеджер($this, $текМетаданные, ТипКоллекции::ПланСчетов());
case "ПланыВидовРасчета":
return new ОбъектыМенеджер($this, $текМетаданные, ТипКоллекции::ПланВидовРасчета());
case "БизнесПроцессы":
return new ОбъектыМенеджер($this, $текМетаданные, ТипКоллекции::БизнесПроцесс());
case "Задачи":
return new ОбъектыМенеджер($this, $текМетаданные, ТипКоллекции::Задача());
case "ЖуралыДокументов":
return new КоллекцияМенеджер($this, $текМетаданные);
case "Обработки":
return new КоллекцияМенеджер($this, $текМетаданные);
case "Отчеты":
return new КоллекцияМенеджер($this, $текМетаданные);
case "РегистрыСведений":
return new КоллекцияМенеджер($this, $текМетаданные);
case "РегистрыНакопления":
return new КоллекцияМенеджер($this, $текМетаданные);
case "РегистрыБухгалтерии":
return new КоллекцияМенеджер($this, $текМетаданные);
case "РегистрыРасчета":
return new КоллекцияМенеджер($this, $текМетаданные);
case "Последовательности":
return new КоллекцияМенеджер($this, $текМетаданные);
case "ОбщиеМодули":
return null;
}
} else if ($this->metadata->ПопыткаНайти("ОбщиеМодули.{$name}", $текМетаданные)) {
return new ОбщийМодуль($this, $текМетаданные);
}
return null;
}
public function __get($fieldName)
{
return $this->commonGet($fieldName);
}
public function offsetGet($offset)
{
return $this->commonGet($offset);
}
public function offsetSet($offset, $value)
{
}
public function offsetUnset($offset)
{
}
public function offsetExists($offset)
{
$метаданные = null;
$check = $this->Метаданные->ПопыткаНайти($offset, $метаданные) || $this->Метаданные->ПопыткаНайти("ОбщиеМодули.{$offset}", $метаданные);
return $check && $метаданные->Имя() != "ОбщиеМодули";
}
public function __call($name, $args)
{
return $this->ВызватьМетодСМассивомПараметров("", $name, $args);
}
public static function Версия()
{
return self::version;
}
public static function ИнформацияОбАвторе()
{
return "Библиотека разработана ООО \"ИТВОРКС\". Автор исходного кода - Шаганов Антон Павлович (ООО \"ИТВОРКС\").";
}
}
abstract class ПрограммныйМодуль
{
function __construct($клиент, $метаданныеМодуля)
{
if (!$клиент) {
throw new Exception("Параметр \"клиент\" не определен.");
}
if (!$метаданныеМодуля) {
throw new Exception("Параметр \"метаданныеМодуля\" не определен.");
}
$this->bromClient = $клиент;
$this->moduleMetadata = $метаданныеМодуля;
}
protected $moduleMetadata;
protected $bromClient;
}
class ОбщийМодуль extends ПрограммныйМодуль
{
function __construct($клиент, $метаданныеМодуля)
{
parent::__construct($клиент, $метаданныеМодуля);
}
public function __call($name, $arguments)
{
return $this->bromClient->ВызватьМетодСМассивомПараметров($this->moduleMetadata->Имя(), $name, $arguments);
}
public function __toString()
{
return "{base::__toString()}.{$this->moduleMetadata->Имя()}";
}
}
abstract class МодульМенеджер extends ПрограммныйМодуль
{
function __construct($клиент, $метаданныеМодуля)
{
parent::__construct($клиент, $метаданныеМодуля);
}
public function __call($name, $arguments)
{
return $this->bromClient->ВызватьМетодСМассивомПараметров($this->moduleMetadata->Путь(), $name, $arguments);
}
}
class КонстантаМенеджер extends МодульМенеджер
{
function __construct($клиент, $метаданныеМодуля)
{
parent::__construct($клиент, $метаданныеМодуля);
}
}
class ПеречислениеМенеджер extends МодульМенеджер
{
function __construct($клиент, $метаданныеМодуля)
{
parent::__construct($клиент, $метаданныеМодуля);
}
public function СоздатьСелектор()
{
$селектор = new Селектор($this->bromClient);
$селектор->УстановитьКоллекцию(ТипКоллекции::Перечисление(), $this->moduleMetadata->Имя());
return $селектор;
}
public function ПолучитьСсылку($идентификатор)
{
return Ссылка::СоздатьСсылку($this->bromClient, ТипКоллекции::Перечисление(), $this->moduleMetadata->Имя(), $идентификатор);
}
public function ПустаяСсылка()
{
return Ссылка::СоздатьСсылку($this->bromClient, ТипКоллекции::Перечисление(), $this->moduleMetadata->Имя());
}
public function __get($name)
{
$predefined = $this->moduleMetadata->Предопределенные();
$value = null;
if ($predefined->Свойство($name, $value)) {
return $value;
}
return null;
}
}
abstract class ОбъектМенеджер extends МодульМенеджер
{
function __construct($клиент, $метаданныеМодуля, $типКоллекции)
{
parent::__construct($клиент, $метаданныеМодуля);
$this->типКоллекции = $типКоллекции;
}
protected $типКоллекции;
public function СоздатьСелектор()
{
$селектор = new Селектор($this->bromClient);
$селектор->УстановитьКоллекцию($this->типКоллекции, $this->moduleMetadata->Имя());
return $селектор;
}
public function ПолучитьСсылку($идентификатор)
{
return Ссылка::СоздатьСсылку($this->bromClient, $this->типКоллекции, $this->moduleMetadata->Имя(), $идентификатор);
}
public function ПустаяСсылка()
{
return Ссылка::СоздатьСсылку($this->bromClient, $this->типКоллекции, $this->moduleMetadata->Имя());
}
protected function СоздатьОбъект()
{
return КонтекстОбъекта::ПолучитьКонтекстОбъекта(Ссылка::СоздатьСсылку($this->bromClient, $this->типКоллекции, $this->moduleMetadata->Имя(), УникальныйИдентификатор::ПолучитьПустой()));
}
public function __get($name)
{
$predefined = $this->moduleMetadata->Предопределенные();
$value = null;
if ($predefined->Свойство($name, $value)) {
return $value;
}
return null;
}
}
class СправочникМенеджер extends ОбъектМенеджер
{
function __construct($клиент, $метаданныеМодуля)
{
parent::__construct($клиент, $метаданныеМодуля, ТипКоллекции::Справочник());
}
public function СоздатьЭлемент()
{
$объект = $this->СоздатьОбъект();
$реквизит = null;
if ($this->moduleMetadata->ПопыткаНайти("Реквизиты.ЭтоГруппа", $реквизит)) {
$объект->ЭтоГруппа = false;
}
return $объект;
}
public function СоздатьГруппу()
{
$объект = $this->СоздатьОбъект();
$реквизит = null;
if ($this->moduleMetadata->ПопыткаНайти("Реквизиты.ЭтоГруппа", $реквизит)) {
$объект->ЭтоГруппа = true;
}
return $объект;
}
}
class ДокументМенеджер extends ОбъектМенеджер
{
function __construct($клиент, $метаданныеМодуля)
{
parent::__construct($клиент, $метаданныеМодуля, ТипКоллекции::Документ());
}
public function СоздатьДокумент()
{
return $this->СоздатьОбъект();
}
}
class ПланВидовХарактеристикМенеджер extends ОбъектМенеджер
{
function __construct($клиент, $метаданныеМодуля)
{
parent::__construct($клиент, $метаданныеМодуля, ТипКоллекции::ПланВидовХарактеристик());
}
public function СоздатьЭлемент()
{
$объект = $this->СоздатьОбъект();
$реквизит = null;
if ($this->moduleMetadata->ПопыткаНайти("Реквизиты.ЭтоГруппа", $реквизит)) {
$объект->ЭтоГруппа = false;
}
return $объект;
}
public function СоздатьГруппу()
{
$объект = $this->СоздатьОбъект();
$реквизит = null;
if ($this->moduleMetadata->ПопыткаНайти("Реквизиты.ЭтоГруппа", $реквизит)) {
$объект->ЭтоГруппа = true;
}
return $объект;
}
}
class ПланСчетовМенеджер extends ОбъектМенеджер
{
function __construct($клиент, $метаданныеМодуля)
{
parent::__construct($клиент, $метаданныеМодуля, ТипКоллекции::ПланСчетов());
}
public function СоздатьСчет()
{
return $this->СоздатьОбъект();
}
}
class ПланВидовРасчетаМенеджер extends ОбъектМенеджер
{
function __construct($клиент, $метаданныеМодуля)
{
parent::__construct($клиент, $метаданныеМодуля, ТипКоллекции::ПланВидовРасчета());
}
public function СоздатьВидРасчета()
{
return $this->СоздатьОбъект();
}
}
class БизнесПроцессМенеджер extends ОбъектМенеджер
{
function __construct($клиент, $метаданныеМодуля)
{
parent::__construct($клиент, $метаданныеМодуля, ТипКоллекции::БизнесПроцесс());
}
public function СоздатьБизнесПроцесс()
{
return $this->СоздатьОбъект();
}
}
class ЗадачаМенеджер extends ОбъектМенеджер
{
function __construct($клиент, $метаданныеМодуля)
{
parent::__construct($клиент, $метаданныеМодуля, ТипКоллекции::Задача());
}
public function СоздатьЗадачу()
{
return $this->СоздатьОбъект();
}
}
class КоллекцияМенеджер extends ПрограммныйМодуль implements ArrayAccess
{
function __construct($клиент, $метаданныеМодуля)
{
parent::__construct($клиент, $метаданныеМодуля);
}
private function commonGet($fieldName)
{
$метаданные = null;
if ($this->moduleMetadata->ПопыткаНайти($fieldName, $метаданные)) {
return new МодульМенеджер($this->bromClient, $метаданные);
}
return null;
}
public function __get($name)
{
return $this->commonGet($name);
}
public function offsetGet($offset)
{
return $this->commonGet($offset);
}
public function offsetSet($offset, $value)
{
}
public function offsetUnset($offset)
{
}
public function offsetExists($offset)
{
return $this->moduleMetadata->Содержит($offset);
}
}
class КонстантыМенеджер extends КоллекцияМенеджер
{
function __construct($клиент)
{
parent::__construct($клиент, $клиент->Метаданные->Найти("Константы"));
}
private function commonGet($name)
{
$метаданные = null;
if ($this->moduleMetadata->ПопыткаНайти($name, $метаданные)) {
return new КонстантаМенеджер($this->bromClient, $метаданные);
}
return null;
}
public function __get($name)
{
return $this->commonGet($name);
}
public function offsetGet($offset)
{
return $this->commonGet($offset);
}
}
class КритерииОтбораМенеджер extends КоллекцияМенеджер
{
function __construct($клиент)
{
parent::__construct($клиент, $клиент->Метаданные->Найти("КритерииОтбора"));
}
private function commonGet($name)
{
$метаданные = null;
if ($this->moduleMetadata->ПопыткаНайти($name, $метаданные)) {
return new КритерийОтбораМенеджер($this->bromClient, $метаданные);
}
return null;
}
public function __get($name)
{
return $this->commonGet($name);
}
public function offsetGet($offset)
{
return $this->commonGet($offset);
}
}
class ПараметрыСеансаМенеджер extends КоллекцияМенеджер
{
function __construct($клиент)
{
parent::__construct($клиент, $клиент->Метаданные->Найти("ПараметрыСеанса"));
}
private function commonGet($name)
{
$метаданные = null;
if ($this->moduleMetadata->ПопыткаНайти($name, $метаданные)) {
return $this->bromClient->ПолучитьЗначениеПараметраСеанса($метаданные->Имя());
}
return null;
}
public function __get($name)
{
return $this->commonGet($name);
}
public function offsetGet($offset)
{
return $this->commonGet($offset);
}
}
class ОбъектыМенеджер extends КоллекцияМенеджер
{
function __construct($клиент, $метаданныеКоллекции, $типКоллекции)
{
parent::__construct($клиент, $метаданныеКоллекции);
$this->типКоллекции = $типКоллекции;
}
protected $типКоллекции;
private function commonGet($name)
{
$текМетаданные = null;
if ($this->moduleMetadata->ПопыткаНайти($name, $текМетаданные)) {
$типКоллекцииСтр = $this->типКоллекции->getName();
switch ($типКоллекцииСтр) {
case "Справочник":
return new СправочникМенеджер($this->bromClient, $текМетаданные);
case "Документ":
return new ДокументМенеджер($this->bromClient, $текМетаданные);
case "Перечисление":
return new ПеречислениеМенеджер($this->bromClient, $текМетаданные);
case "ПланВидовХарактеристик":
return new ПланВидовХарактеристикМенеджер($this->bromClient, $текМетаданные);
case "ПланСчетов":
return new ПланСчетовМенеджер($this->bromClient, $текМетаданные);
case "ПланВидовРасчета":
return new ПланВидовРасчетаМенеджер($this->bromClient, $текМетаданные);
case "БизнесПроцесс":
return new БизнесПроцессМенеджер($this->bromClient, $текМетаданные);
case "Задача":
return new ЗадачаМенеджер($this->bromClient, $текМетаданные);
}
}
return null;
}
public function __get($name)
{
return $this->commonGet($name);
}
public function offsetGet($offset)
{
return $this->commonGet($offset);
}
}
class КонтекстДанных
{
function __construct($клиент)
{
if (empty($клиент)) {
throw new Exception("Не указан клиент при создании контекста данных.");
}
$this->bromClient = $клиент;
$this->data = [];
$this->references = [];
}
private $bromClient;
private $data;
private $references;
public function Клиент()
{
return $this->bromClient;
}
private function&ПолучитьУзелДанныхОбъекта($ссылка)
{
$идСсылки = КонтекстДанных::ПолучитьОбобщенныйИдентификаторСсылки($ссылка);
$node = $this->data[$идСсылки];
if (empty($node)) {
$this->data[$идСсылки] = [];
}
return $this->data[$идСсылки];
}
private function УдалитьУзелДанныхОбъекта($ссылка)
{
$идСсылки = КонтекстДанных::ПолучитьОбобщенныйИдентификаторСсылки($ссылка);
unset($this->data[$идСсылки]);
}
private function ИнициализироватьДанныеОбъекта($ссылка)
{
$данныеОбъекта =& $this->ПолучитьУзелДанныхОбъекта($ссылка);
foreach ($данныеОбъекта as $key => $val) {
unset($данныеОбъекта[$key]);
}
$реквизиты = $ссылка->Метаданные()->Найти("Реквизиты");
foreach ($реквизиты as $key => $val) {
$данныеОбъекта[$key] = null;
}
$данныеОбъекта["#"] = null;
}
private function ПолучитьТабличнуюЧасть($ссылка, $метаданные)
{
$данныеОбъекта =& $this->ПолучитьУзелДанныхОбъекта($ссылка);
$таблЧасть = $данныеОбъекта[$метаданные->Имя()];
if (!($таблЧасть instanceof ТабличнаяЧасть)) {
$таблЧасть = new ТабличнаяЧасть($метаданные);
$this->УстановитьЗначениеПоляОбъекта($ссылка, $метаданные->Имя(), $таблЧасть);
}
return $таблЧасть;
}
public function УстановитьЗначениеПоляОбъекта($ссылка, $имяПоля, $значение)
{
$tempName = mb_strtolower($имяПоля);
$данныеОбъекта =& $this->ПолучитьУзелДанныхОбъекта($ссылка);
$данныеОбъекта[$tempName] = $значение;
}
public function УстановитьПредставлениеОбъекта($ссылка, $представление)
{
if ($представление === null) {
return;
}
$данныеОбъекта =& $this->ПолучитьУзелДанныхОбъекта($ссылка);
$данныеОбъекта["#"] = $представление;
}
public function УстановитьЗначенияИзСвойствSOAP($ссылка, $properties)
{
if ($properties === null) {
return;
}
$реквизиты = $ссылка->Метаданные()->Найти("Реквизиты");
$таблЧасти = $ссылка->Метаданные()->Найти("ТабличныеЧасти");
foreach ($properties as $property) {
$текМета = null;
if ($реквизиты->ПопыткаНайти($property->Name, $текМета)) {
$значение = $property->GetValue($this->Клиент());
$this->УстановитьЗначениеПоляОбъекта($ссылка, $текМета->Имя(), $значение);
} else if ($таблЧасти->ПопыткаНайти($property->Name, $текМета)) {
$значение = $property->GetValue($this->Клиент());
if ($значение instanceof ТаблицаЗначений) {
$таблЧасть = $this->ПолучитьТабличнуюЧасть($ссылка, $текМета);
$таблЧасть->ЗагрузитьДанные($значение);
}
}
}
}
public function УничтожитьСсылку($ссылка)
{
$идСсылки = КонтекстДанных::ПолучитьОбобщенныйИдентификаторСсылки($ссылка);
if ($ссылка instanceof ОбъектСсылка) {
$this->ОчиститьДанныеОбъекта($ссылка);
}
unset($this->references[$идСсылки]);
}
public function ПопыткаПолучитьЗначение($ссылка, $имяПоля, &$значение)
{
if (empty($ссылка)) {
throw new Exception("Не указана ссылка.");
}
$времИмяПоля = mb_strtolower($имяПоля);
if ($времИмяПоля == "ссылка") {
$значение = $ссылка;
return true;
}
$реквизит = null;
if ($ссылка->Метаданные()->Реквизиты->ПопыткаНайти($имяПоля, $реквизит)) {
if ($ссылка->Пустая()) {
$значение = null;
return true;
}
$данныеОбъекта = $this->ПолучитьУзелДанныхОбъекта($ссылка);
if (isset($данныеОбъекта[$времИмяПоля])) {
$значение = $данныеОбъекта[$времИмяПоля];
return true;
}
$this->ЗагрузитьДанныеОбъекта($ссылка);
return $this->ПопыткаПолучитьЗначение($ссылка, $имяПоля, $значение);
}
if ($ссылка->Метаданные()->ТабличныеЧасти->ПопыткаНайти($имяПоля, $реквизит)) {
if ($ссылка->Пустая()) {
$значение = $this->ПолучитьТабличнуюЧасть($ссылка, $реквизит);
return true;
}
$данныеОбъекта = $this->ПолучитьУзелДанныхОбъекта($ссылка);
if (isset($данныеОбъекта[$времИмяПоля])) {
$таблЧасть = $данныеОбъекта[$времИмяПоля];
if (!($таблЧасть instanceof ТабличнаяЧасть)) {
$таблЧасть = $this->ПолучитьТабличнуюЧасть($ссылка, $реквизит);
$данныеОбъекта[$времИмяПоля] = $таблЧасть;
}
$значение = $таблЧасть;
return true;
}
$this->ЗагрузитьДанныеОбъекта($ссылка);
return $this->ПопыткаПолучитьЗначение($ссылка, $имяПоля, $значение);
}
$значение = null;
return false;
}
public function ПолучитьПредставлениеОбъекта($ссылка)
{
if (empty($ссылка)) {
throw new Exception("Не указана ссылка.");
}
if ($ссылка->Пустая()) {
return "";
}
$данныеОбъекта = $this->ПолучитьУзелДанныхОбъекта($ссылка);
if (isset($данныеОбъекта["#"])) {
return strval($данныеОбъекта["#"]);
}
$this->ЗагрузитьДанныеОбъекта($ссылка);
return $this->ПолучитьПредставлениеОбъекта($ссылка);
}
public function ОчиститьДанныеОбъекта($ссылка)
{
$this->УдалитьУзелДанныхОбъекта($ссылка);
}
public function ЗагрузитьДанныеОбъекта($ссылка)
{
$settings = ValueBase::SoapValue("GetObject_Settings", ['AddSkippedProperties' => true, 'FieldAutoinclusion' => ValueBase::SoapValue("RequestFieldAutoinclusionSettings", ['DefaultFields' => true, 'CustomFields' => true, 'Tables' => true,])]);
$refSoap = $this->bromClient->SoapКлиент()->GetObject(['reference' => ValueBase::From($ссылка), 'settings' => $settings])->return;
$this->ИнициализироватьДанныеОбъекта($ссылка);
$this->УстановитьПредставлениеОбъекта($ссылка, $refSoap->Presentation);
$this->УстановитьЗначенияИзСвойствSOAP($ссылка, $refSoap->Property);
}
public function ПолучитьОбъектСсылку($полноеИмяТипа, $указатель)
{
$узелМетаданных = null;
if (!$this->Клиент()->Метаданные->ПопыткаПолучить($полноеИмяТипа, $узелМетаданных)) {
throw new Exception("Ошибка при получении ссылки на объект. Не удалось обнаружить объект метаданных \"{$полноеИмяТипа}\".");
}
$идСсылки = КонтекстДанных::ПолучитьОбобщенныйИдентификаторСсылкиПоПолномуИмениТипа($полноеИмяТипа, strval($указатель));
$ссылка = $this->references[$идСсылки];
if (!empty($ссылка)) {
return $ссылка;
}
switch ($узелМетаданных->ТипКоллекции()->getName()) {
case 'Справочник':
$ссылка = new СправочникСсылка($this->bromClient, $узелМетаданных->Имя(), $указатель);
break;
case 'Документ':
$ссылка = new ДокументСсылка($this->bromClient, $узелМетаданных->Имя(), $указатель);
break;
case 'ПланВидовХарактеристик':
$ссылка = new ПланВидовХарактеристикСсылка($this->bromClient, $узелМетаданных->Имя(), $указатель);
break;
case 'ПланСчетов':
$ссылка = new ПланСчетовСсылка($this->bromClient, $узелМетаданных->Имя(), $указатель);
break;
case 'ПланВидовРасчета':
$ссылка = new ПланВидовРасчетаСсылка($this->bromClient, $узелМетаданных->Имя(), $указатель);
break;
case 'Задача':
$ссылка = new ЗадачаСсылка($this->bromClient, $узелМетаданных->Имя(), $указатель);
break;
case 'БизнесПроцесс':
$ссылка = new БизнесПроцессСсылка($this->bromClient, $узелМетаданных->Имя(), $указатель);
break;
default:
throw new Exception("Указан неверный тип коллекции.");
}
$this->references[$идСсылки] = $ссылка;
return $ссылка;
}
public function ПолучитьПеречислениеСсылку($полноеИмяТипа, $указатель, $синоним = "")
{
$узелМетаданных = null;
if (!$this->Клиент()->Метаданные->ПопыткаПолучить($полноеИмяТипа, $узелМетаданных)) {
throw new Exception("Ошибка при получении ссылки на объект. Не удалось обнаружить объект метаданных \"{$полноеИмяТипа}\".");
}
if ($узелМетаданных->ТипКоллекции() != ТипКоллекции::Перечисление()) {
throw new Exception("Указан неверный тип коллекции.");
}
$идСсылки = КонтекстДанных::ПолучитьОбобщенныйИдентификаторСсылкиПоПолномуИмениТипа($полноеИмяТипа, $указатель);
$ссылка = $this->references[$идСсылки];
if (!empty($ссылка)) {
return $ссылка;
}
$ссылка = new ПеречислениеСсылка($this->bromClient, $узелМетаданных->Имя(), $указатель, $синоним);
$this->references[$идСсылки] = $ссылка;
return $ссылка;
}
private static function ПолучитьОбобщенныйИдентификаторСсылкиПоПолномуИмениТипа($полноеИмяТипа, $указатель)
{
$representation = mb_strtolower($полноеИмяТипа."#".$указатель);
return sha1($representation);
}
private static function ПолучитьОбобщенныйИдентификаторСсылки($ссылка)
{
if ($ссылка instanceof ОбъектСсылка) {
return self::ПолучитьОбобщенныйИдентификаторСсылкиПоПолномуИмениТипа($ссылка->ПолноеИмяТипа(), strval($ссылка->УникальныйИдентификатор()));
} else {
return self::ПолучитьОбобщенныйИдентификаторСсылкиПоПолномуИмениТипа($ссылка->ПолноеИмяТипа(), $ссылка->Имя());
}
}
}
class ТабличнаяЧасть implements IteratorAggregate, ArrayAccess, Countable
{
function __construct($метаданные)
{
if (empty($метаданные)) {
throw new Exception("Не указаны метаданные табличной части.");
}
$this->metadata = $метаданные;
$this->rows = new Массив();
}
private $metadata;
protected $rows;
public function Метаданные()
{
return $this->metadata;
}
public function Количество()
{
return $this->rows->Количество();
}
protected function ДобавитьСтроку()
{
$стр = new СтрокаТабличнойЧасти($this);
$this->rows->Добавить($стр);
return $стр;
}
protected function УдалитьСтроку($строка)
{
$индекс = $this->rows->Найти($строка);
if ($индекс !== null) {
$this->rows->Удалить($индекс);
}
}
public function ЗагрузитьДанные($таблица)
{
$реквизиты = $this->metadata->Реквизиты;
$поля = [];
foreach ($таблица->Колонки as $колонкаТаблицы) {
if ($реквизиты->Содержит($колонкаТаблицы->Имя())) {
$поля[] = $колонкаТаблицы->Имя();
}
}
$this->rows->Очистить();
foreach ($таблица as $стр) {
$новСтр = $this->ДобавитьСтроку();
foreach ($поля as $имяПоля) {
$новСтр->УстановитьЗначение($имяПоля, $стр[$имяПоля]);
}
}
}
public function Выгрузить()
{
$таблица = new ТаблицаЗначений();
$именаПолей = $this->metadata->Реквизиты->ИменаПодчиненных();
foreach ($именаПолей as $имяПоля) {
$таблица->Колонки->Добавить($имяПоля);
}
foreach ($this->rows as $стр) {
$новСтр = $таблица->Добавить();
foreach ($именаПолей as $имяПоля) {
$новСтр[$имяПоля] = $стр[$имяПоля];
}
}
return $таблица;
}
public function getIterator()
{
foreach ($this->rows as $key => $val) {
yield $key => $val;
}
}
public function offsetGet($offset)
{
return $this->rows[$offset];
}
public function offsetSet($offset, $value)
{
}
public function offsetUnset($offset)
{
}
public function offsetExists($offset)
{
return $this->rows->offsetExists($offset);
}
public function count()
{
return count($this->rows);
}
public function __toString()
{
return $this->metadata->ПолноеИмя();
}
}
class ТабличнаяЧастьКонтекст extends ТабличнаяЧасть
{
function __construct($контекстОбъекта, $метаданные)
{
parent::__construct($метаданные);
$this->objectContext = $контекстОбъекта;
$this->isModified = false;
}
private $objectContext;
private $isModified;
public function УстановитьМодифицированность($value)
{
if ($this->isModified != $value) {
$this->objectContext->УстановитьМодифицированность($this->Метаданные()->Имя(), $value);
$this->isModified = $value;
}
}
public function Добавить()
{
$стр = $this->ДобавитьСтроку();
$this->УстановитьМодифицированность(true);
return $стр;
}
public function Удалить($строка)
{
$this->УдалитьСтроку($строка);
$this->УстановитьМодифицированность(true);
}
public function Очистить()
{
$this->rows->Очистить();
$this->УстановитьМодифицированность(true);
}
}
class СтрокаТабличнойЧасти implements ArrayAccess
{
function __construct($таблЧасть)
{
if (empty($таблЧасть)) {
throw new Exception("Не указана табличная часть.");
}
$this->tableSection = $таблЧасть;
$this->values = [];
}
private $tableSection;
private $values;
public function УстановитьЗначение($имяПоля, $значение)
{
$this->values[$имяПоля] = $значение;
}
private function commonGet($fieldName)
{
$result = null;
$реквизит = null;
if ($this->tableSection->Метаданные()->ПопыткаНайти("Реквизиты.{$fieldName}", $реквизит)) {
return $this->values[$реквизит->Имя()];
}
return $result;
}
private function commonSet($fieldName, $value)
{
$реквизит = null;
if ($this->tableSection->Метаданные()->ПопыткаНайти("Реквизиты.{$fieldName}", $реквизит)) {
if (get_class($this->tableSection) == 'ТабличнаяЧастьКонтекст') {
$this->values[$реквизит->Имя()] = $value;
$this->tableSection->УстановитьМодифицированность(true);
}
}
}
public function __get($name)
{
return $this->commonGet($name);
}
public function __set($name, $value)
{
$this->commonSet($name, $value);
}
public function offsetSet($key, $newVal)
{
$this->offsetSet($key, $newVal);
}
public function offsetGet($key)
{
return $this->commonGet($key);
}
public function offsetUnset($index)
{
}
public function offsetExists($key)
{
return $this->tableSection->Метаданные()->Реквизиты->Содержит($fieldName);
}
}
class КонтекстОбъекта
{
function __construct($ссылка)
{
$this->reference = $ссылка;
$this->data = [];
$this->modifiedFields = [];
$this->additionalProperties = new Структура();
$this->isExchangeLoadMode = false;
}
private $reference;
private $data;
private $additionalProperties;
private $modifiedFields;
private $isExchangeLoadMode;
public function ОчиститьМодифицированность()
{
foreach ($this->modifiedFields as $key => $val) {
unset($this->modifiedField[$key]);
}
}
public function УстановитьМодифицированность($имяПоля, $value = true)
{
$метаданные = $this->reference->Метаданные();
$текМета = null;
if ($метаданные->Реквизиты->ПопыткаНайти($имяПоля, $текМета) || $метаданные->ТабличныеЧасти->ПопыткаНайти($имяПоля, $текМета)) {
if ($value) {
$this->modifiedFields[$текМета->Имя()] = true;
} else {
unset($this->modifiedFields[$текМета->Имя()]);
}
}
}
private function ДобавитьТабличнуюЧасть($метаданные)
{
$таблЧасть = $this->data[$метаданные->Имя()];
if ($таблЧасть === null) {
$таблЧасть = new ТабличнаяЧастьКонтекст($this, $метаданные);
$this->data[$метаданные->Имя()] = $таблЧасть;
}
return $таблЧасть;
}
public function УстановитьЗначенияИзСвойствSOAP($properties)
{
if ($properties == null) {
return;
}
$реквизиты = $this->reference->Метаданные()->Реквизиты;
foreach ($properties as $property) {
$реквизит = null;
if ($реквизиты->ПопыткаНайти($property->Name, $реквизит)) {
$значение = $property->GetValue($this->Клиент());
$this->data[$реквизит->Имя()] = $значение;
}
}
$таблЧасти = $this->reference->Метаданные()->ТабличныеЧасти;
foreach ($properties as $property) {
$таблЧастьМета = null;
if ($таблЧасти->ПопыткаНайти($property->Name, $таблЧастьМета)) {
$значение = $property->GetValue($this->Клиент());
$табличнаяЧасть = $this->ДобавитьТабличнуюЧасть($таблЧастьМета);
if ($значение instanceof ТаблицаЗначений) {
$табличнаяЧасть->ЗагрузитьДанные($значение);
} else {
$табличнаяЧасть->ЗагрузитьДанные(new ТаблицаЗначений());
}
$табличнаяЧасть->УстановитьМодифицированность(false);
}
}
}
protected function ЗаписатьДанные($режимЗаписиДокумента, $режимПроведенияДокумента)
{
$tempObject = new ValueObjectRef($this->reference);
$tempObject->Property = [];
foreach ($this->modifiedFields as $key => $none) {
$value = $this->data[$key];
$property = ValueBase::From($value);
$property->Name = $key;
$tempObject->Property[] = $property;
}
$settings = new PostObject_Settings($this->ДополнительныеСвойства, $режимЗаписиДокумента, $режимПроведенияДокумента, $this->isExchangeLoadMode);
$returnObject = $this->Клиент()->SoapКлиент()->PostObject(['object' => $tempObject, 'settings' => $settings])->return;
$ссылка = $returnObject->GetValue($this->Клиент());
$this->УстановитьСсылку($ссылка);
$this->УстановитьЗначенияИзСвойствSOAP($returnObject->Property);
$this->ОчиститьМодифицированность();
}
public function Клиент()
{
return $this->reference->Клиент();
}
public function Метаданные()
{
return $this->reference->Метаданные();
}
public function ЭтоНовый()
{
return $this->reference->Пустая();
}
public function УстановитьСсылку($ссылка)
{
if ($this->reference->Равно($ссылка)) {
return;
}
if ($ссылка->ТипКоллекции() != $this->reference->ТипКоллекции() || $ссылка->ИмяКоллекции() != $this->reference->ИмяКоллекции()) {
throw new Exception("Тип аргумента \"ссылка\" не соответствует требуемому типу \"{$this->reference->ПолноеИмяТипа()}\".");
}
$this->reference = $ссылка;
}
public function УстановитьПометкуУдаления($значение)
{
$this->ПометкаУдаления = $значение;
}
public function __toString()
{
return base::__toString().".".$this->reference->ИмяКоллекции();
}
public function ЗагрузитьДанные()
{
$settings = ValueBase::SoapValue("GetObject_Settings", ['FieldAutoinclusion' => ValueBase::SoapValue("RequestFieldAutoinclusionSettings", ['DefaultFields' => true, 'CustomFields' => true, 'Tables' => true])]);
$refSoap = $this->Клиент()->SoapКлиент()->GetObject(['reference' => new ValueObjectRef($this->reference), 'settings' => $settings])->return;
$this->Клиент()->Контекст()->УстановитьПредставлениеОбъекта($this->reference, $refSoap->Presentation);
$this->Клиент()->Контекст()->УстановитьЗначенияИзСвойствSOAP($this->reference, $refSoap->Property);
$this->УстановитьЗначенияИзСвойствSOAP($refSoap->Property);
$this->ОчиститьМодифицированность();
}
public function Записать()
{
$this->ЗаписатьДанные();
}
public function Удалить()
{
if ($this->ЭтоНовый()) {
throw new Exception("Не возможно удалить объект, который является новым.");
}
$this->Клиент()->SoapКлиент()->DeleteObject(['object' => new ValueObjectRef($this->reference)]);
$this->Клиент()->Контекст()->ОчиститьДанныеОбъекта($this->reference);
$this->ОчиститьМодифицированность();
}
private function commonGet($name)
{
$tempName = mb_strtolower($name);
if ($tempName == 'ссылка' || $tempName == 'ref') {
return $this->reference;
}
if ($tempName == 'дополнительныесвойства' || $tempName == 'additionalproperties') {
return $this->additionalProperties;
}
if ($tempName == 'режимзагрузки' || $tempName == 'exchangemode') {
return $this->isExchangeLoadMode;
}
$метаданные = $this->reference->Метаданные();
$текМета = null;
if ($метаданные->Реквизиты->ПопыткаНайти($name, $текМета)) {
return $this->data[$текМета->Имя()];
} else if ($метаданные->ТабличныеЧасти->ПопыткаНайти($name, $текМета)) {
return $this->ДобавитьТабличнуюЧасть($текМета);
}
return null;
}
private function commonset($name, $value)
{
$tempName = mb_strtolower($name);
if ($tempName == 'режимзагрузки' || $tempName == 'exchangemode') {
$this->isExchangeLoadMode = boolval($value);
}
$метаданные = $this->reference->Метаданные();
$текМета = null;
if ($метаданные->Реквизиты->ПопыткаНайти($name, $текМета)) {
$this->data[$текМета->Имя()] = $value;
$this->УстановитьМодифицированность($текМета->Имя(), true);
return $this->data[$текМета->Имя()];
}
}
public function __get($name)
{
return $this->commonGet($name);
}
public function __set($name, $value)
{
$this->commonset($name, $value);
}
public static function ПолучитьКонтекстОбъекта($ссылка)
{
if ($ссылка == null) {
throw new Exception("Не указана ссылка.");
}
switch ($ссылка->ТипКоллекции()->getName()) {
case 'Справочник':
return new СправочникОбъект($ссылка);
case 'Документ':
return new ДокументОбъект($ссылка);
case 'ПланВидовХарактеристик':
return new ПланВидовХарактеристикОбъект($ссылка);
case 'ПланСчетов':
return new ПланСчетовОбъект($ссылка);
case 'ПланВидовРасчета':
return new ПланВидовРасчетаОбъект($ссылка);
case 'БизнесПроцесс':
return new БизнесПроцессОбъект($ссылка);
case 'Задача':
return new ЗадачаОбъект($ссылка);
default:
throw new Exception("Указана некорректная ссылка.");
}
}
}
class СправочникОбъект extends КонтекстОбъекта
{
function __construct($ссылка)
{
parent::__construct($ссылка);
}
}
class ДокументОбъект extends КонтекстОбъекта
{
function __construct($ссылка)
{
parent::__construct($ссылка);
}
public function Записать($режимЗаписи = null, $режимПроведения = null)
{
$this->ЗаписатьДанные($режимЗаписи != null ? $режимЗаписи : РежимЗаписиДокумента::Запись(), $режимПроведения != null ? $режимПроведения : РежимПроведенияДокумента::Неоперативный());
}
}
class ПланВидовХарактеристикОбъект extends КонтекстОбъекта
{
function __construct($ссылка)
{
parent::__construct($ссылка);
}
}
class ПланВидовРасчетаОбъект extends КонтекстОбъекта
{
function __construct($ссылка)
{
parent::__construct($ссылка);
}
}
class ПланСчетовОбъект extends КонтекстОбъекта
{
function __construct($ссылка)
{
parent::__construct($ссылка);
}
}
class БизнесПроцессОбъект extends КонтекстОбъекта
{
function __construct($ссылка)
{
parent::__construct($ссылка);
}
}
class ЗадачаОбъект extends КонтекстОбъекта
{
function __construct($ссылка)
{
parent::__construct($ссылка);
}
}
class РежимЗаписиДокумента extends ПеречислениеБром
{
protected function enumValues()
{
return [["Запись", "Write"], ["ОтменаПроведения", "UndoPosting"], ["Проведение", "Posting"]];
}
}
class РежимПроведенияДокумента extends ПеречислениеБром
{
protected function enumValues()
{
return [["Неоперативный", "Regular"], ["Оперативный", "RealTime"]];
}
}
class ТипКоллекции extends ПеречислениеБром
{
protected function enumValues()
{
return [["Справочник", "Catalog"], ["Документ", "Document"], ["Перечисление", "Enum"], ["ПланВидовХарактеристик", "ChartOfCharacteristicTypes"], ["ПланСчетов", "ChartOfAccounts"], ["ПланВидовРасчета", "ChartOfCalculationTypes"], ["Задача", "BusinessProcess"], ["БизнесПроцесс", "Task"]];
}
}
class Запрос
{
function __construct($клиент, $текст = "")
{
$this->bromClient = $клиент;
$this->parameters = new Структура();
$this->filters = new Массив();
$this->fields = new Массив();
$this->sort = new Массив();
$this->text = $текст;
}
private $text;
private $bromClient;
private $parameters;
private $filters;
private $sort;
private $fields;
public function __get($name)
{
$tempName = mb_strtolower($name);
if ($tempName == 'клиент') {
return $this->bromClient;
}
if ($tempName == 'текст') {
return $this->text;
}
if ($tempName == 'параметры') {
return $this->parameters;
}
if ($tempName == 'выбранныеполя') {
return $this->fields;
}
if ($tempName == 'порядок') {
return $this->sort;
}
if ($tempName == 'отбор') {
return $this->filters;
}
return null;
}
public function __set($name, $value)
{
$tempName = mb_strtolower($name);
if ($tempName == 'текст') {
$this->text = $value;
}
}
public function УстановитьПараметр($имя, $значение)
{
$this->parameters->Вставить($имя, $значение);
}
public function ДобавитьУсловиеОтбора($путьКДанным, $значение, $видСравнения = null)
{
$условие = new УсловиеОтбора($путьКДанным, $значение, $видСравнения);
$this->filters->Добавить($условие);
return условие;
}
public function ДобавитьУпорядочение($путьКДанным, $направление = null)
{
$this->sort->Добавить(new Сортировка($путьКДанным, $направление));
}
public function ДобавитьПоле($путьКДанным, $псевдоним = null)
{
$this->fields->Добавить(new ПолеДанных($путьКДанным, $псевдоним));
}
public function Выполнить($типОбхода = null)
{
return $this->bromClient->ВыполнитьЗапрос($this->text, $this->parameters, $this->filters, $this->fields, $this->sort, $типОбхода);
}
public function ВыполнитьПакет($типОбхода = null, $включатьВременныеДанные = false)
{
return $this->bromClient->ВыполнитьПакетныйЗапрос($this->text, $this->parameters, $this->filters, $this->fields, $this->sort, $типОбхода, $включатьВременныеДанные);
}
}
class Селектор implements IteratorAggregate, ArrayAccess, Countable, ИНаблюдатель
{
function __construct($клиент)
{
$this->bromClient = $клиент;
$this->fields = new Массив();
$this->filters = new Массив();
$this->sort = new Массив();
$this->fieldsAutoloadSettings = АвтозагрузкаПолейОбъектов::Ничего();
$this->items = new Массив();
$this->isModified = false;
$this->fields->ИсточникСобытий()->ДобавитьНаблюдателя($this);
$this->filters->ИсточникСобытий()->ДобавитьНаблюдателя($this);
$this->sort->ИсточникСобытий()->ДобавитьНаблюдателя($this);
}
private $bromClient;
private $items;
private $collectionType;
private $collectionName;
private $collectionMetadata;
private $fieldsAutoloadSettings;
private $limit;
private $isModified;
private $fields;
private $filters;
private $sort;
public function __get($name)
{
$tempName = mb_strtolower($name);
if ($tempName == 'клиент') {
return $this->bromClient;
}
if ($tempName == 'типколлекции') {
return $this->collectionType;
}
if ($tempName == 'имяколлекции') {
return $this->collectionName;
}
if ($tempName == 'лимит') {
return $this->limit;
}
if ($tempName == 'метаданныеколлекции') {
return $this->collectionMetadata;
}
if ($tempName == 'автозагрузкаполей') {
return $this->fieldsAutoloadSettings;
}
if ($tempName == 'поля') {
return $this->fields;
}
if ($tempName == 'отбор') {
return $this->filters;
}
if ($tempName == 'порядок') {
return $this->sort;
}
return null;
}
public function __set($name, $value)
{
$tempName = mb_strtolower($name);
if ($tempName == 'лимит') {
$this->limit = $value;
$this->isModified = true;
}
if ($tempName == 'автозагрузкаполей') {
$this->fieldsAutoloadSettings = $value;
$this->isModified = true;
}
}
public function Количество()
{
return count($this->items);
}
public function ВыгрузитьРезультат()
{
if ($this->isModified) {
$this->Выполнить();
}
return $this->items->ToArray();
}
private function УстановитьКоллекциюПоТипуИИмени($типКоллекции, $имяКоллекции)
{
if (!($типКоллекции instanceof ТипКоллекции)) {
throw new Exception("Тип коллекции \"{$типКоллекции}\" не определен.");
}
$метаданные = null;
if (!$this->bromClient->Метаданные->ПопыткаПолучить("{$типКоллекции}.{$имяКоллекции}", $метаданные) || !($метаданные instanceof МетаданныеОбъект)) {
throw new Exception("Коллекция с именем \"{$типКоллекции}.{$имяКоллекции}\" не определена.");
}
$this->collectionType = $типКоллекции;
$this->collectionName = $метаданные->Имя();
$this->collectionMetadata = $метаданные;
$this->isModified = true;
}
private function УстановитьКоллекциюПоПолномуИмени($полноеИмяКоллекции)
{
if (empty($полноеИмяКоллекции)) {
throw new Exception("Указано некорректное полное имя коллекции коллекции.");
}
$фрагментыИмени = explode(".", $полноеИмяКоллекции);
if (count($фрагментыИмени) != 2) {
throw new Exception("Указано некорректное полное имя коллекции коллекции.");
}
$типКоллекции = ТипКоллекции::Получить($фрагментыИмени[0]);
if ($типКоллекции == null) {
throw new Exception("Тип коллекции \"{$фрагментыИмени[0]}\" не определен.");
}
$метаданные = null;
if (!$this->bromClient->Метаданные->ПопыткаПолучить($полноеИмяКоллекции, $метаданные) || !($метаданные instanceof МетаданныеОбъект)) {
throw new Exception("Коллекция с именем \"{$полноеИмяКоллекции}\" не определена.");
}
$this->collectionType = $типКоллекции;
$this->collectionName = $метаданные->Имя();
$this->collectionMetadata = $метаданные;
$this->isModified = true;
}
public function УстановитьКоллекцию(...$args)
{
$numargs = count($args);
if ($numargs >= 2) {
return $this->УстановитьКоллекциюПоТипуИИмени($args[0], $args[1]);
} else if ($numargs == 1) {
return $this->УстановитьКоллекциюПоПолномуИмени($args[0]);
}
throw new Exception("Не указана коллекция.");
}
public function ДобавитьПоля(...$ключиПолей)
{
foreach ($ключиПолей as $ключ) {
$фрагментыКлючей = explode(",", $ключ);
foreach ($фрагментыКлючей as $фрагмент) {
$времФрагмент = trim($фрагмент);
if (!empty($времФрагмент)) {
$this->fields->Добавить($времФрагмент);
}
}
}
$this->isModified = true;
}
public function ДобавитьСортировку($ключПоля, $направление = null)
{
$this->ДобавитьЭлементыСортировки(new Сортировка($ключПоля, $направление));
}
public function ДобавитьЭлементыСортировки(...$элементыСортировки)
{
foreach ($элементыСортировки as $элемент) {
$this->sort->Добавить($элемент);
}
$this->isModified = true;
}
public function ДобавитьОтбор($ключПоля, $значение, $видСравнения = null)
{
$this->ДобавитьЭлементыОтбора(new УсловиеОтбора($ключПоля, $значение, $видСравнения));
}
public function ДобавитьЭлементыОтбора(...$элементыОтбора)
{
foreach ($элементыОтбора as $элемент) {
$this->filters->Добавить($элемент);
}
$this->isModified = true;
}
public function Выполнить()
{
if (empty($this->collectionMetadata)) {
throw new Exception("Не установлена коллекция для получения выборки.");
}
$fields = [];
foreach ($this->fields as $fieldName) {
$fields[] = ValueBase::SoapValue("RequestField", ['Key' => $fieldName]);
}
$filters = [];
foreach ($this->filters as $element) {
$filters[] = ValueBase::SoapValue("RequestFilter", ['Key' => $element->Ключ(), 'Value' => ValueBase::From($element->Значение()), 'ComparisonType' => $element->ВидСравнения()->getName()]);
}
$sort = [];
foreach ($this->sort as $element) {
$sort[] = ValueBase::SoapValue("RequestSort", ['Key' => $element->Ключ(), 'Direction' => $element->Направление() == НаправлениеСортировки::Убывание() ? "Убыв" : "Возр"]);
}
$autoinclusion = $this->fieldsAutoloadSettings instanceof АвтозагрузкаПолейОбъектов ? ValueBase::SoapValue("RequestFieldAutoinclusionSettings", ['DefaultFields' => $this->fieldsAutoloadSettings->ЗагружатьСтандартныеРеквизиты, 'CustomFields' => $this->fieldsAutoloadSettings->ЗагружатьПользовательскиеРеквизиты, 'Tables' => $this->fieldsAutoloadSettings->ЗагружатьТабличныеЧасти]) : null;
$settings = ValueBase::SoapValue("GetObjectList_Settings", ['Filter' => $filters, 'Field' => $fields, 'Sort' => $sort, 'Limit' => $this->limit > 0 ? intval($this->limit) : 0, 'FieldAutoinclusion' => $autoinclusion, 'AddSkippedProperties' => true, 'PropertiesHierarchyType' => "Hierarchy"]);
$soapItems = $this->bromClient->SoapКлиент()->GetObjectList(['type' => $this->ТипКоллекции->getName(), 'name' => $this->ИмяКоллекции, 'settings' => $settings])->return;
$this->items->Очистить();
if ($soapItems->Item != null) {
foreach ($soapItems->Item as $item) {
$this->items->Добавить($item->GetValue($this->bromClient));
}
}
$this->isModified = false;
return $this;
}
public function Сбросить()
{
$this->items->Очистить();
$this->fields.Очистить();
$this->filters.Очистить();
$this->sort.Очистить();
$this->limit = 0;
$this->collectionMetadata = null;
$this->collectionName = null;
$this->isModified = false;
return $this;
}
public function Выбрать(...$ключиПолей)
{
call_user_func_array([$this, 'ДобавитьПоля'], $ключиПолей);
return $this;
}
public function Первые($лимит)
{
$this->Лимит = intval($лимит);
return $this;
}
public function Из($полноеИмяКоллекции)
{
$this->УстановитьКоллекцию($полноеИмяКоллекции);
return $this;
}
public function Где($ключПоля, $значение, $видСравнения = null)
{
$this->ДобавитьОтбор($ключПоля, $значение, $видСравнения);
return $this;
}
public function Упорядочить($ключПоля, $направление = null)
{
$this->ДобавитьСортировку($ключПоля, $направление);
return $this;
}
public function getIterator()
{
if ($this->isModified) {
$this->Выполнить();
}
foreach ($this->items as $key => $val) {
yield $key => $val;
}
}
public function offsetGet($offset)
{
return $this->items->offsetGet($offset);
}
public function offsetSet($offset, $value)
{
throw new Exception("Селектор доступен только для чтения.");
}
public function offsetUnset($offset)
{
throw new Exception("Селектор доступен только для чтения.");
}
public function offsetExists($offset)
{
return $this->items->offsetExists($offset);
}
public function count()
{
return $this->items->count();
}
public function ВнешнееСобытие($источник, $имяСобытия, ...$параметры)
{
if ($имяСобытия == "ПриИзменении") {
$this->isModified = true;
}
}
}
class ПолеДанных
{
function __construct($ключ, $псевдоним)
{
$this->key = $ключ;
$this->name = $псевдоним;
}
private $key;
private $name;
public function Ключ()
{
return $this->key;
}
public function Псевдоним()
{
return $this->name;
}
}
class УсловиеОтбора
{
function __construct($ключ, $значение, $видСравнения = null)
{
$this->key = $ключ;
$this->value = $значение;
$this->comparationType = $видСравнения instanceof ВидСравнения ? $видСравнения : ВидСравнения::Равно();
}
private $key;
private $value;
private $comparationType;
public function Ключ()
{
return $this->key;
}
public function Значение()
{
return $this->value;
}
public function ВидСравнения()
{
return $this->comparationType;
}
}
class Сортировка
{
function __construct($ключ, $направлениеСортировки = null)
{
$this->key = $ключ;
$this->sortDirection = $направлениеСортировки instanceof НаправлениеСортировки ? $направлениеСортировки : НаправлениеСортировки::Возрастание();
}
private $key;
private $sortDirection;
public function Ключ()
{
return $this->key;
}
public function Направление()
{
return $this->sortDirection;
}
}
class ВидСравнения extends ПеречислениеБром
{
protected function enumValues()
{
return [["Равно", "Equal"], ["НеРавно", "NotEqual"], ["Больше", "Greater"], ["БольшеИлиРавно", "GreaterOrEqual"], ["Меньше", "Less"], ["МеньшеИлиРавно", "LessOrEqual"], ["Содержит", "Contains"], ["НеСодержит", "NotContains"], ["ВСписке", "InList"], ["НеВСписке", "NotInList"], ["ВИерархии", "InHierarchy"], ["НеВИерархии", "NotInHierarchy"]];
}
}
class НаправлениеСортировки extends ПеречислениеБром
{
protected function enumValues()
{
return [["Возрастание", "Возр", "Ascending", "Asc"], ["Убывание", "Убыв", "Descending", "Desc"]];
}
}
class ОбходРезультатаЗапроса extends ПеречислениеБром
{
protected function enumValues()
{
return [["Прямой", "Linear"], ["ПоГруппировкам", "ByGroups"], ["ПоГруппировкамСИерархией", "ByGroupsWithHierarchy"]];
}
}
class АвтозагрузкаПолейОбъектов
{
function __construct($загружатьСтандартныеРеквизиты = false, $загружатьПользовательскиеРеквизиты = false, $загружатьТабличныеЧасти = false)
{
$this->loadDefaultAttributes = boolval($загружатьСтандартныеРеквизиты);
$this->loadCustomAttributes = boolval($загружатьПользовательскиеРеквизиты);
$this->loadTableSections = boolval($загружатьТабличныеЧасти);
}
private $loadDefaultAttributes;
private $loadCustomAttributes;
private $loadTableSections;
public function __get($name)
{
$tempName = mb_strtolower($name);
if ($tempName == 'загружатьстандартныереквизиты') {
return $this->loadDefaultAttributes;
}
if ($tempName == 'загружатьпользовательскиереквизиты') {
return $this->loadCustomAttributes;
}
if ($tempName == 'загружатьтабличныечасти') {
return $this->loadTableSections;
}
return null;
}
public static function Ничего()
{
return new АвтозагрузкаПолейОбъектов(false, false, false);
}
public static function ВсеПоля()
{
return new АвтозагрузкаПолейОбъектов(true, true, true);
}
public static function ТолькоСтандартныеРеквизиты()
{
return new АвтозагрузкаПолейОбъектов(true, false, false);
}
public static function ТолькоПользовательскиеРеквизиты()
{
return new АвтозагрузкаПолейОбъектов(false, true, false);
}
public static function ТолькоРеквизиты()
{
return new АвтозагрузкаПолейОбъектов(true, true, false);
}
public static function ТолькоТабличныеЧасти()
{
return new АвтозагрузкаПолейОбъектов(false, false, true);
}
} ?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment