diff --git a/tests/Annotated/Fixtures/Fixtures6/Address.php b/tests/Annotated/Fixtures/Fixtures6/Address.php index d552af52..b125223f 100644 --- a/tests/Annotated/Fixtures/Fixtures6/Address.php +++ b/tests/Annotated/Fixtures/Fixtures6/Address.php @@ -19,9 +19,9 @@ ])] class Address { - /** @Column(type="string") */ - #[Column(type: 'string')] - protected $city; + /** @Column(type="string", typecast="city") */ + #[Column(type: 'string', typecast: CityTypecast::NAME)] + protected City $city; /** @Column(type="string") */ #[Column(type: 'string')] diff --git a/tests/Annotated/Fixtures/Fixtures6/City.php b/tests/Annotated/Fixtures/Fixtures6/City.php new file mode 100644 index 00000000..e8c455ad --- /dev/null +++ b/tests/Annotated/Fixtures/Fixtures6/City.php @@ -0,0 +1,27 @@ +value = $value; + } + + public function __toString(): string + { + return $this->value; + } + + public static function fromString(string $value): self + { + return new self($value); + } +} diff --git a/tests/Annotated/Fixtures/Fixtures6/CityTypecast.php b/tests/Annotated/Fixtures/Fixtures6/CityTypecast.php new file mode 100644 index 00000000..846e484f --- /dev/null +++ b/tests/Annotated/Fixtures/Fixtures6/CityTypecast.php @@ -0,0 +1,70 @@ +rules) as $column) { + if (!isset($data[$column])) { + continue; + } + + if (!\is_string($data[$column]) || $data[$column] === '') { + $data[$column] = null; + + continue; + } + + $data[$column] = City::fromString($data[$column]); + } + + return $data; + } + + public function uncast(array $data): array + { + foreach (array_keys($this->rules) as $column) { + if (!isset($data[$column])) { + continue; + } + + /** @var T $value */ + $value = $data[$column]; + + if (!$value instanceof City) { + continue; + } + + $data[$column] = (string)$value; + } + + return $data; + } + + public function setRules(array $rules): array + { + /** @var non-empty-string $rule */ + foreach ($rules as $key => $rule) { + if ($rule !== self::NAME) { + continue; + } + + unset($rules[$key]); + + $this->rules[$key] = $rule; + } + + return $rules; + } +} diff --git a/tests/Annotated/Fixtures/Fixtures6/User.php b/tests/Annotated/Fixtures/Fixtures6/User.php index ba30f479..4b35074a 100644 --- a/tests/Annotated/Fixtures/Fixtures6/User.php +++ b/tests/Annotated/Fixtures/Fixtures6/User.php @@ -7,11 +7,17 @@ use Cycle\Annotated\Annotation\Column; use Cycle\Annotated\Annotation\Entity; use Cycle\Annotated\Annotation\Relation\Embedded; +use Cycle\ORM\Parser\Typecast as DefaultTypecast; /** * @Entity() */ -#[Entity] +#[Entity( + typecast: [ + CityTypecast::class, + DefaultTypecast::class, + ] +)] class User { /** @Column(type="primary") */ diff --git a/tests/Annotated/Functional/Driver/Common/Relation/EmbeddedTestCase.php b/tests/Annotated/Functional/Driver/Common/Relation/EmbeddedTestCase.php index 5998e34d..74d1d46e 100644 --- a/tests/Annotated/Functional/Driver/Common/Relation/EmbeddedTestCase.php +++ b/tests/Annotated/Functional/Driver/Common/Relation/EmbeddedTestCase.php @@ -10,6 +10,7 @@ use Cycle\Annotated\Locator\TokenizerEntityLocator; use Cycle\Annotated\MergeColumns; use Cycle\Annotated\MergeIndexes; +use Cycle\Annotated\Tests\Fixtures\Fixtures6\CityTypecast; use Cycle\Annotated\Tests\Functional\Driver\Common\BaseTestCase; use Cycle\ORM\Relation; use Cycle\ORM\Schema; @@ -56,6 +57,9 @@ public function testRelation(ReaderInterface $reader): void $this->assertArrayHasKey('address', $schema['user'][Schema::RELATIONS]); $this->assertSame(Relation::EMBEDDED, $schema['user'][Schema::RELATIONS]['address'][Relation::TYPE]); + $this->assertSame(CityTypecast::class, $schema['user'][Schema::TYPECAST_HANDLER][0]); + $this->assertSame(CityTypecast::class, $schema['user:address:address'][Schema::TYPECAST_HANDLER][0]); + $this->assertSame('user:address:address', $schema['user'][Schema::RELATIONS]['address'][Relation::TARGET]); $this->assertSame(Relation::LOAD_EAGER, $schema['user'][Schema::RELATIONS]['address'][Relation::LOAD]); $this->assertTrue($r->getTableSchema($r->getEntity('user'))->hasIndex(['address_zipcode']));