Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: allow interfaces as the target type of object mapper #242

Merged
merged 2 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## 1.13.1

* fix: allow interfaces as the target type of object mapper

## 1.13.0

* feat: `Map(property: null)` ignores the mapping
Expand Down
7 changes: 5 additions & 2 deletions src/Transformer/Implementation/ObjectMapperTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,12 @@ public function transform(

if (
!\is_string($targetClass)
|| !class_exists($targetClass)
|| (
!class_exists($targetClass)
&& !interface_exists($targetClass)
)
) {
throw new InvalidArgumentException(\sprintf('Target class "%s" is not a valid class.', (string) $targetClass), context: $context);
throw new InvalidArgumentException(\sprintf('Target "%s" is not a valid class or interface.', (string) $targetClass), context: $context);
}

// get source class
Expand Down
32 changes: 22 additions & 10 deletions tests/config/rekalogika-mapper/generated-mappings.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,35 +26,41 @@
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 47
// tests/src/IntegrationTest/ObjectMapperTest.php on line 49
source: \Brick\Money\Money::class,
target: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDto::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 67
// tests/src/IntegrationTest/ObjectMapperTest.php on line 90
source: \Brick\Money\Money::class,
target: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoForProxy::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 109
// tests/src/IntegrationTest/ObjectMapperTest.php on line 132
source: \Brick\Money\Money::class,
target: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoForTargetInvalidTypeHint::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 82
// tests/src/IntegrationTest/ObjectMapperTest.php on line 105
source: \Brick\Money\Money::class,
target: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoForTargetModification::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 95
// tests/src/IntegrationTest/ObjectMapperTest.php on line 118
source: \Brick\Money\Money::class,
target: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoForTargetReplacement::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 69
source: \Brick\Money\Money::class,
target: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoInterface::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/AdderTest.php on lines 46, 55
source: \Rekalogika\Mapper\Tests\Fixtures\Adder\Comment::class,
Expand Down Expand Up @@ -694,31 +700,37 @@
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 155
// tests/src/IntegrationTest/ObjectMapperTest.php on line 178
source: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\Baz::class,
target: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\Foo::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 145
// tests/src/IntegrationTest/ObjectMapperTest.php on line 168
source: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\Foo::class,
target: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\Baz::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 57
// tests/src/IntegrationTest/ObjectMapperTest.php on line 59
source: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDto::class,
target: \Brick\Money\Money::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 139
// tests/src/IntegrationTest/ObjectMapperTest.php on line 80
source: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoToo::class,
target: \Brick\Money\Money::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 162
source: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\Person::class,
target: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\FinalPersonDto::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 115
// tests/src/IntegrationTest/ObjectMapperTest.php on line 138
source: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\Person::class,
target: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\PersonDto::class
);
Expand Down
2 changes: 1 addition & 1 deletion tests/src/Fixtures/ObjectMapper/MoneyDto.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace Rekalogika\Mapper\Tests\Fixtures\ObjectMapper;

final readonly class MoneyDto
final readonly class MoneyDto implements MoneyDtoInterface
{
public function __construct(
private string $amount,
Expand Down
21 changes: 21 additions & 0 deletions tests/src/Fixtures/ObjectMapper/MoneyDtoInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

/*
* This file is part of rekalogika/mapper package.
*
* (c) Priyadi Iman Nurcahyo <https://rekalogika.dev>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

namespace Rekalogika\Mapper\Tests\Fixtures\ObjectMapper;

interface MoneyDtoInterface
{
public function getAmount(): string;

public function getCurrency(): string;
}
32 changes: 32 additions & 0 deletions tests/src/Fixtures/ObjectMapper/MoneyDtoToo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

/*
* This file is part of rekalogika/mapper package.
*
* (c) Priyadi Iman Nurcahyo <https://rekalogika.dev>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

namespace Rekalogika\Mapper\Tests\Fixtures\ObjectMapper;

final readonly class MoneyDtoToo implements MoneyDtoInterface
{
public function __construct(
private string $amount,
private string $currency,
) {}

public function getAmount(): string
{
return $this->amount;
}

public function getCurrency(): string
{
return $this->currency;
}
}
23 changes: 23 additions & 0 deletions tests/src/IntegrationTest/ObjectMapperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
use Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoForTargetInvalidTypeHint;
use Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoForTargetModification;
use Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoForTargetReplacement;
use Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoInterface;
use Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoToo;
use Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\Person;
use Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\PersonDto;
use Rekalogika\Mapper\Tests\Services\ObjectMapper\MoneyObjectMapper;
Expand Down Expand Up @@ -61,6 +63,27 @@ public function testMoneyDtoToMoney(): void
$this->assertSame('USD', $result->getCurrency()->getCurrencyCode());
}

public function testMoneyToMoneyDtoInterface(): void
{
$money = Money::of('100.00', 'USD');
$result = $this->mapper->map($money, MoneyDtoInterface::class);

$this->assertInstanceOf(MoneyDtoInterface::class, $result);
$this->assertInstanceOf(MoneyDto::class, $result);
$this->assertSame('100.00', $result->getAmount());
$this->assertSame('USD', $result->getCurrency());
}

public function testMoneyDtoInterfaceToMoney(): void
{
$moneyDto = new MoneyDtoToo('100.00', 'USD');
$result = $this->mapper->map($moneyDto, Money::class);

$this->assertInstanceOf(Money::class, $result);
$this->assertSame('100.00', $result->getAmount()->__toString());
$this->assertSame('USD', $result->getCurrency()->getCurrencyCode());
}

public function testMoneyToMoneyDtoProxy(): void
{
$money = Money::of('100.00', 'USD');
Expand Down
16 changes: 16 additions & 0 deletions tests/src/Services/ObjectMapper/MoneyObjectMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoForTargetInvalidTypeHint;
use Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoForTargetModification;
use Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoForTargetReplacement;
use Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoInterface;

class MoneyObjectMapper
{
Expand All @@ -39,6 +40,21 @@ public function mapMoneyDtoToMoney(MoneyDto $moneyDto): Money
return Money::of($moneyDto->getAmount(), $moneyDto->getCurrency());
}

#[AsObjectMapper]
public function mapMoneyToMoneyDtoInterface(Money $money): MoneyDtoInterface
{
return new MoneyDto(
$money->getAmount()->__toString(),
$money->getCurrency()->getCurrencyCode(),
);
}

#[AsObjectMapper]
public function mapMoneyDtoInterfaceToMoney(MoneyDtoInterface $moneyDto): Money
{
return Money::of($moneyDto->getAmount(), $moneyDto->getCurrency());
}

#[AsObjectMapper]
public function mapMoneyToMoneyDtoForProxy(
Money $money,
Expand Down