Created
August 5, 2019 18:52
-
-
Save jhaoda/dcf8977cc98b6ff69f82282de10b1173 to your computer and use it in GitHub Desktop.
1С:Бром
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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