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