From 2c3ea12fc126aa7459f77daafbca900de5e6926c Mon Sep 17 00:00:00 2001 From: babaev-an Date: Mon, 14 Jul 2025 16:09:49 +0300 Subject: [PATCH] 20250714 1.1.3 --- .gitignore | 1 + sources/classes/ObjectArray.php | 7 +- .../ObjectArray/ObjectArraySpecialTrait.php | 4 +- .../ObjectArray/ObjectArrayToArrayTrait.php | 104 ++++++++++++++++++ tests/classes/ObjectArrayTest.php | 55 ++++++++- 5 files changed, 166 insertions(+), 5 deletions(-) create mode 100644 sources/traits/ObjectArray/ObjectArrayToArrayTrait.php diff --git a/.gitignore b/.gitignore index 62e7b7a..9459c1f 100644 --- a/.gitignore +++ b/.gitignore @@ -83,3 +83,4 @@ vendor/ /tests/classesserialized1.txt /tests/classesserialized2.txt /tests/classesserialized3.txt +/tests/classesserialized4.txt diff --git a/sources/classes/ObjectArray.php b/sources/classes/ObjectArray.php index 8c17f21..a9a9510 100644 --- a/sources/classes/ObjectArray.php +++ b/sources/classes/ObjectArray.php @@ -4,6 +4,7 @@ namespace goodboyalex\php_components_pack\classes; use ArrayAccess; use Countable; +use goodboyalex\php_components_pack\interfaces\IArrayable; use goodboyalex\php_components_pack\interfaces\ISerializable; use goodboyalex\php_components_pack\traits\ArrayBasicTrait; use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArrayConstantsTrait; @@ -11,6 +12,7 @@ use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArrayLINQTrait; use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArraySearchAndSortTrait; use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArraySerializeExTrait; use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArraySpecialTrait; +use goodboyalex\php_components_pack\traits\ObjectArray\ObjectArrayToArrayTrait; use IteratorAggregate; /** @@ -21,7 +23,7 @@ use IteratorAggregate; * @version 1.0.6 * @since 1.0 */ -final class ObjectArray implements ArrayAccess, IteratorAggregate, Countable, ISerializable +final class ObjectArray implements ArrayAccess, IteratorAggregate, Countable, ISerializable, IArrayable { /** * @var array $Container Массив объектов, хранящихся в данном классе. @@ -46,6 +48,9 @@ final class ObjectArray implements ArrayAccess, IteratorAggregate, Countable, IS // Расширенные методы для сериализации use ObjectArraySerializeExTrait; + // Реализация методов интерфейса IArrayable + use ObjectArrayToArrayTrait; + /** * Конструктор класса. * diff --git a/sources/traits/ObjectArray/ObjectArraySpecialTrait.php b/sources/traits/ObjectArray/ObjectArraySpecialTrait.php index f87f50e..c50641e 100644 --- a/sources/traits/ObjectArray/ObjectArraySpecialTrait.php +++ b/sources/traits/ObjectArray/ObjectArraySpecialTrait.php @@ -51,7 +51,7 @@ trait ObjectArraySpecialTrait public function AddRange (ObjectArray|array $objects): void { // Если передан массив, то не изменяем его, а если передан объект класса ObjectArray, то конвертируем его в массив объектов - $objectsToAdd = is_array($objects) ? $objects : $objects->ToArray(); + $objectsToAdd = is_array($objects) ? $objects : $objects->AsArray(); // Добавляем массив объектов $this->Merge($objectsToAdd); @@ -62,7 +62,7 @@ trait ObjectArraySpecialTrait * * @return array Массив объектов, хранящихся в данном классе. */ - public function ToArray (): array + public function AsArray (): array { return $this->Container; } diff --git a/sources/traits/ObjectArray/ObjectArrayToArrayTrait.php b/sources/traits/ObjectArray/ObjectArrayToArrayTrait.php new file mode 100644 index 0000000..ed56d0e --- /dev/null +++ b/sources/traits/ObjectArray/ObjectArrayToArrayTrait.php @@ -0,0 +1,104 @@ + ObjectArray::class + ]; + + // Перебираю все элементы + foreach ($this->Container as $item) { + // - если элемент реализует интерфейс IArrayable + if ($item instanceof IArrayable) + // -- то вызываю метод ToArray и добавляю в массив его результат + $result[] = $item->ToArray(); + else + // -- иначе вызываю метод ToArray из класса TypeExtension и добавляю в массив его результат + $result[] = TypeExtension::ToArray($item); + } + + // Возвращаю массив + return $result; + } + + /** + * @inheritDoc + * @throws TypeException Если в массиве есть объекты, которые невозможно преобразовать в массив (происходит ошибка + * метода FromArray из класса TypeExtension) или класс не существует. + */ + public function FromArray (array $array): void + { + // Очищаю массив + $this->Clear(); + + // Перебираю все элементы массива + foreach ($array as $key => $value) { + // - пропускаю специальные элементы, которые не являются объектами + if ($key == "type_class") + continue; + + // - если элемент реализует интерфейс IArrayable + if ($this->IsArrayable($value)) { + // -- то получаю имя класса + $className = $array["type_class"]; + // -- создаю объект + $instance = new $className(); + // -- вызываю метод FromArray + $instance->FromArray($value); + // -- и добавляю в массив + $this->Container[] = $instance; + } + else + // -- иначе вызываю метод FromArray из класса TypeExtension + $this->Container[] = TypeExtension::FromArray($value, TypeExtension::DEFAULT_FROM_ARRAY_ON_CLASS()); + } + } + + /** + * Проверяет, реализует ли класс интерфейс IArrayable. + * + * @param array $array Массив. + * + * @return bool Возвращает true, если класс реализует интерфейс IArrayable, иначе + * false. + * @throws TypeException Если класс не существует. + */ + private function IsArrayable (array $array): bool + { + // Получаю имя класса + $className = $array["type_class"]; + + // Проверяем, существует ли класс вообще + if (!class_exists($className)) + throw new TypeException($className, "Class $className is not exists / Класс $className не существует"); + + // Получаем список всех интерфейсов, реализуемых данным классом + $interfaces = class_implements($className); + + // Проверка, присутствует ли IArrayable среди списка реализованных интерфейсов и возвращаем результат + return in_array('IArrayable', $interfaces); + } +} \ No newline at end of file diff --git a/tests/classes/ObjectArrayTest.php b/tests/classes/ObjectArrayTest.php index 9b6ecb4..14f1183 100644 --- a/tests/classes/ObjectArrayTest.php +++ b/tests/classes/ObjectArrayTest.php @@ -228,7 +228,7 @@ class ObjectArrayTest extends TestCase $this->assertSame(['c', 'b'], $sr); } - public function testToArray () + public function testAsArray () { $this->PrepareForTest(); @@ -240,7 +240,7 @@ class ObjectArrayTest extends TestCase $a_Array = new ObjectArray($array); - $sr = $a_Array->ToArray(); + $sr = $a_Array->AsArray(); $this->assertIsArray($sr); $this->assertSame($array, $sr); @@ -550,4 +550,55 @@ class ObjectArrayTest extends TestCase $this->assertEquals('test_string_C3', $objectArray3->GetRow(fn (D $value) => $value->stringD == 'test_string3')->c->stringC); } + + public function testToArray () + { + $this->PrepareForTest(); + + // Создаём тестовые классы + $class1 = new D ('test_string1', 12345, true, new A("test_string_A1", 6789, false), + new B("test_string_B1", 9876, "false"), new C("test_string_C1", 54321, true)); + $class2 = new D ('test_string2', 123456, false, new A("test_string_A1", 678910, true), + new B("test_string_B2", 98765, "true"), new C("test_string_C2", 543210, false)); + $class = new D ('test_string3', 123450, true, new A("test_string_A2", 67890, false), + new B("test_string_B3", 90876, "false"), new C("test_string_C3", 543201, true)); + + // Создаём массив объектов + $objectArray = new ObjectArray([$class1, $class2, $class]); + + // Сериализуем + $asArray = $objectArray->ToArray(); + + // Сохраняем в файл + file_put_contents(__DIR__ . 'serialized4.txt', + json_encode($asArray, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)); + + // Проверяем, что всё хорошо + $this->assertNotEmpty($asArray); + } + + public function testFromArray () + { + $this->PrepareForTest(); + + // Загружаем данные + $serialized = file_get_contents(__DIR__ . 'serialized4.txt'); + + // Десериализуем + $array = json_decode($serialized, true, flags: JSON_UNESCAPED_UNICODE); + + // Создаём массив объектов + $objectArray = new ObjectArray(); + + // Получаем из массива + $objectArray->FromArray($array); + + // Проверяем, что всё хорошо + $this->assertEquals('test_string_A1', + $objectArray->GetRow(fn (D $value) => $value->stringD == 'test_string1')->a->a); + $this->assertEquals('test_string_B2', + $objectArray->GetRow(fn (D $value) => $value->stringD == 'test_string2')->b->a); + $this->assertEquals('test_string_C3', + $objectArray->GetRow(fn (D $value) => $value->stringD == 'test_string3')->c->stringC); + } } \ No newline at end of file