Repository: CuyZ/Valinor (php)

Issue:
How to serialize object collection, ArrayObject used
I have this main Entity:

```
<?php

declare(strict_types=1);

namespace App\ApiModule\Entity\V1\ExpeditionPacking;

use Spatie\TypeScriptTransformer\Attributes\TypeScript;

#[TypeScript]
class CompletionPackageEntity
{

	public function __construct(
		/**
		 *
		 * @var string[]
		 */
		public array                                 $weightOfItems,
		/**
		 * @var ArrayOfCompletionPackageDokladEntity|null
		 */
		public ?ArrayOfCompletionPackageDokladEntity $data,
		public array                                 $EANtoProduktVarianta,
		public bool                                  $iAmNotOwner
	)
	{
		
	}
```

now code for ArrayOfCompletionPackageDokladEntity

```
<?php

declare(strict_types=1);

namespace App\ApiModule\Entity\V1\ExpeditionPacking;

use Romanmatena\PhpTools\Collections\ArrayCollection;
use Spatie\TypeScriptTransformer\Attributes\TypeScript;

#[TypeScript]
class ArrayOfCompletionPackageDokladEntity extends ArrayCollection
{
```

now ArrayCollection

```
<?php

namespace Romanmatena\PhpTools\Collections;

abstract class ArrayCollection extends \ArrayObject implements ICollection, \Traversable, \JsonSerializable
{
	/**
	 * @return array|object
	 */
	public function jsonSerialize(): array|object
	{
		return $this->toArray();
	}
```

if i use json_encode then data includes the objects in ArrayCollection but if i use normalizer, data is empty

```
$normalizer = (new \CuyZ\Valinor\MapperBuilder())
				->normalizer(\CuyZ\Valinor\Normalizer\Format::json());

			$content = $normalizer->normalize($completionPackageEntity);
```

do i missing something?

EDIT:

seems that problem is this row

https://github.com/CuyZ/Valinor/blob/4b688350c69c88552640731e50967aee4d33de75/src/Normalizer/Transformer/RecursiveTransformer.php#L120

get_object_vars used for ArrayObject will not return array, is there any best practise how to solve it?

it means i need to not get inside of this condition

https://github.com/CuyZ/Valinor/blob/4b688350c69c88552640731e50967aee4d33de75/src/Normalizer/Transformer/RecursiveTransformer.php#L100

but ArrayObject is not Closure or Generator and it is not possible for me to extend any of these

Pull request:
fix: properly handle `ArrayObject` normalization
Fixes #486

Patch:
diff --git a/src/Normalizer/Transformer/RecursiveTransformer.php b/src/Normalizer/Transformer/RecursiveTransformer.php
index da202a9..ca365b7 100644
--- a/src/Normalizer/Transformer/RecursiveTransformer.php
+++ b/src/Normalizer/Transformer/RecursiveTransformer.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
 
 namespace CuyZ\Valinor\Normalizer\Transformer;
 
+use ArrayObject;
 use BackedEnum;
 use Closure;
 use CuyZ\Valinor\Definition\AttributeDefinition;
@@ -111,7 +112,7 @@ final class RecursiveTransformer
                 return $value->getName();
             }
 
-            if ($value::class === stdClass::class) {
+            if ($value::class === stdClass::class || $value instanceof ArrayObject) {
                 return array_map(
                     fn (mixed $value) => $this->doTransform($value, $references),
                     (array)$value


Test patch:
diff --git a/tests/Integration/Normalizer/NormalizerTest.php b/tests/Integration/Normalizer/NormalizerTest.php
index 22f0a2e..d120799 100644
--- a/tests/Integration/Normalizer/NormalizerTest.php
+++ b/tests/Integration/Normalizer/NormalizerTest.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
 
 namespace CuyZ\Valinor\Tests\Integration\Normalizer;
 
+use ArrayObject;
 use Attribute;
 use CuyZ\Valinor\Normalizer\Exception\CircularReferenceFoundDuringNormalization;
 use CuyZ\Valinor\Normalizer\Exception\KeyTransformerHasTooManyParameters;
@@ -178,6 +179,24 @@ final class NormalizerTest extends IntegrationTestCase
             'expected json' => '{"foo":"foo","bar":"bar"}',
         ];
 
+        yield 'ArrayObject' => [
+            'input' => new ArrayObject(['foo' => 'foo', 'bar' => 'bar']),
+            'expected array' => [
+                'foo' => 'foo',
+                'bar' => 'bar',
+            ],
+            'expected json' => '{"foo":"foo","bar":"bar"}',
+        ];
+
+        yield 'class inheriting ArrayObject' => [
+            'input' => new class (['foo' => 'foo', 'bar' => 'bar']) extends ArrayObject {},
+            'expected array' => [
+                'foo' => 'foo',
+                'bar' => 'bar',
+            ],
+            'expected json' => '{"foo":"foo","bar":"bar"}',
+        ];
+
         yield 'array of object' => [
             'input' => [
                 'foo' => new BasicObject('foo'),