Skip to content

Commit d8f2358

Browse files
committed
feat(doctrine): init work on doctrine provider
1 parent b911c3a commit d8f2358

File tree

6 files changed

+171
-2
lines changed

6 files changed

+171
-2
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ tools/phpstan/cache/
88
cache/
99
site/
1010
.build/
11-
.castor*
11+
.castor*
12+
tests/Doctrine/db.sqlite

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@
2929
},
3030
"require-dev": {
3131
"api-platform/core": "^3.0.4 || ^4",
32-
"doctrine/annotations": "~1.0",
32+
"doctrine/annotations": "^2.0",
3333
"doctrine/collections": "^2.2",
3434
"doctrine/inflector": "^2.0",
35+
"doctrine/orm": "^3.3",
3536
"matthiasnoback/symfony-dependency-injection-test": "^5.1",
3637
"moneyphp/money": "^3.3.2",
3738
"phpunit/phpunit": "^9.0",
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace AutoMapper\Provider\Doctrine;
4+
5+
use AutoMapper\Provider\ProviderInterface;
6+
use Doctrine\ORM\EntityManagerInterface;
7+
8+
final readonly class DoctrineProvider implements ProviderInterface
9+
{
10+
public function __construct(private EntityManagerInterface $entityManager)
11+
{
12+
}
13+
14+
public function provide(string $targetType, mixed $source, array $context): object|array|null
15+
{
16+
$metadata = $this->entityManager->getClassMetadata($targetType);
17+
$entity = $metadata->identifier;
18+
19+
$this->entityManager->createQueryBuilder()
20+
->select('e')
21+
->from($targetType, 'e')
22+
->where('e.' . $entity . ' = :id')
23+
->setParameter('id', $source)
24+
->getQuery()
25+
->getOneOrNullResult();
26+
27+
}
28+
}

tests/Doctrine/DoctrineTest.php

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace AutoMapper\Tests\Doctrine;
6+
7+
use AutoMapper\Tests\AutoMapperTestCase;
8+
use AutoMapper\Tests\Doctrine\Entity\Book;
9+
use Doctrine\DBAL\DriverManager;
10+
use Doctrine\ORM\EntityManager;
11+
use Doctrine\ORM\EntityManagerInterface;
12+
use Doctrine\ORM\ORMSetup;
13+
use Doctrine\ORM\Tools\SchemaTool;
14+
15+
/**
16+
* @author Joel Wurtz <[email protected]>
17+
*/
18+
class DoctrineTest extends AutoMapperTestCase
19+
{
20+
private EntityManagerInterface $entityManager;
21+
22+
protected function setUp(): void
23+
{
24+
parent::setUp();
25+
$this->buildDatabase();
26+
}
27+
28+
private function buildDatabase() {
29+
// delete the database file
30+
if (file_exists(__DIR__ . '/db.sqlite')) {
31+
unlink(__DIR__ . '/db.sqlite');
32+
}
33+
34+
$config = ORMSetup::createAttributeMetadataConfiguration(
35+
paths: [__DIR__ . '/Entity'],
36+
isDevMode: true,
37+
);
38+
39+
$connection = DriverManager::getConnection([
40+
'driver' => 'pdo_sqlite',
41+
'path' => __DIR__ . '/db.sqlite',
42+
], $config);
43+
44+
$entityManager = new EntityManager($connection, $config);
45+
46+
// Generate schema
47+
$schemaTool = new SchemaTool($entityManager);
48+
$schemaTool->createSchema($entityManager->getMetadataFactory()->getAllMetadata());
49+
50+
$this->entityManager = $entityManager;
51+
}
52+
53+
public function testAutoMapping(): void
54+
{
55+
$book = new Book();
56+
57+
$this->entityManager->persist($book);
58+
$this->entityManager->flush();
59+
60+
$this->assertNotNull($book->id);
61+
62+
$bookArray = $this->autoMapper->map($book, 'array');
63+
$bookArray['author'] = 'John Doe';
64+
65+
$this->autoMapper->map($bookArray, Book::class);
66+
$this->entityManager->flush();
67+
$this->entityManager->clear();
68+
69+
$book = $this->entityManager->find(Book::class, $book->id);
70+
71+
$this->assertEquals('John Doe', $book->author);
72+
}
73+
}

tests/Doctrine/Entity/Book.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace AutoMapper\Tests\Doctrine\Entity;
6+
7+
use Doctrine\Common\Collections\ArrayCollection;
8+
use Doctrine\Common\Collections\Collection;
9+
use Doctrine\ORM\Mapping as ORM;
10+
11+
#[ORM\Entity]
12+
class Book
13+
{
14+
#[ORM\Id]
15+
#[ORM\Column(type: 'integer')]
16+
#[ORM\GeneratedValue]
17+
public ?int $id = null;
18+
19+
#[ORM\Column(type: 'string')]
20+
public string $title = '';
21+
22+
#[ORM\Column(type: 'string')]
23+
public string $description = '';
24+
25+
#[ORM\Column(type: 'string')]
26+
public string $author = '';
27+
28+
#[ORM\OneToMany(targetEntity: Review::class, mappedBy: 'book', cascade: ['persist', 'remove'])]
29+
public Collection $reviews;
30+
31+
public function __construct()
32+
{
33+
$this->reviews = new ArrayCollection();
34+
35+
}
36+
}

tests/Doctrine/Entity/Review.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace AutoMapper\Tests\Doctrine\Entity;
6+
7+
use Doctrine\ORM\Mapping as ORM;
8+
9+
#[ORM\Entity]
10+
class Review
11+
{
12+
#[ORM\Id, ORM\GeneratedValue]
13+
#[ORM\Column(type: 'integer')]
14+
private ?int $id = null;
15+
16+
#[ORM\Column(type: 'integer')]
17+
public int $rating = 0;
18+
19+
#[ORM\Column(type: 'string')]
20+
public string $body = '';
21+
22+
#[ORM\Column(type: 'string')]
23+
public string $author = '';
24+
25+
#[ORM\Column(type: 'datetime')]
26+
public \DateTimeImmutable $publicationDate;
27+
28+
#[ORM\ManyToOne(targetEntity: Book::class, inversedBy: 'reviews')]
29+
public Book $book;
30+
}

0 commit comments

Comments
 (0)