Skip to content

Commit 715eef1

Browse files
committed
Code chapter 2
Signed-off-by: Howriq <[email protected]>
1 parent 6a8465e commit 715eef1

File tree

14 files changed

+397
-8
lines changed

14 files changed

+397
-8
lines changed

bin/doctrine-migrations.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/env php
2+
<?php
3+
4+
declare(strict_types=1);
5+
6+
namespace Doctrine\Migrations;
7+
8+
require __DIR__ . '/../vendor/doctrine/migrations/bin/doctrine-migrations.php';

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@
5252
"autoload": {
5353
"psr-4": {
5454
"Light\\App\\": "src/App/src/",
55-
"Light\\Page\\": "src/Page/src/"
55+
"Light\\Page\\": "src/Page/src/",
56+
"Light\\Book\\": "src/Book/src/"
5657
}
5758
},
5859
"autoload-dev": {

config/cli-config.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Doctrine\Migrations\Configuration\EntityManager\ExistingEntityManager;
6+
use Doctrine\Migrations\Configuration\Migration\ConfigurationArray;
7+
use Doctrine\Migrations\DependencyFactory;
8+
use Doctrine\ORM\EntityManager;
9+
10+
$container = require 'config/container.php';
11+
12+
$entityManager = $container->get(EntityManager::class);
13+
$entityManager->getEventManager();
14+
15+
return DependencyFactory::fromEntityManager(
16+
new ConfigurationArray($container->get('config')['doctrine']['migrations']),
17+
new ExistingEntityManager($entityManager)
18+
);

config/config.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
// Default App module config
3232
\Light\App\ConfigProvider::class,
3333
\Light\Page\ConfigProvider::class,
34+
\Light\Book\ConfigProvider::class,
3435

3536
// Load application config in a pre-defined order in such a way that local settings
3637
// overwrite global settings. (Loaded as first to last):

src/App/src/ConfigProvider.php

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66

77
use Doctrine\ORM\EntityManager;
88
use Doctrine\ORM\EntityManagerInterface;
9+
use Doctrine\ORM\Mapping\EntityListenerResolver;
910
use Doctrine\Persistence\Mapping\Driver\MappingDriverChain;
1011
use Dot\Cache\Adapter\ArrayAdapter;
1112
use Dot\Cache\Adapter\FilesystemAdapter;
13+
use Light\App\Factory\EntityListenerResolverFactory;
1214
use Light\App\Factory\GetIndexViewHandlerFactory;
1315
use Light\App\Handler\GetIndexViewHandler;
16+
use Light\App\Types\UuidType;
1417
use Mezzio\Application;
15-
use Ramsey\Uuid\Doctrine\UuidType;
1618
use Roave\PsrContainerDoctrine\EntityManagerFactory;
1719

1820
use function getcwd;
@@ -51,6 +53,8 @@ public function getDependencies(): array
5153
'factories' => [
5254
'doctrine.entity_manager.orm_default' => EntityManagerFactory::class,
5355
GetIndexViewHandler::class => GetIndexViewHandlerFactory::class,
56+
EntityListenerResolver::class => EntityListenerResolverFactory::class,
57+
5458
],
5559
'aliases' => [
5660
EntityManager::class => 'doctrine.entity_manager.orm_default',
@@ -96,12 +100,13 @@ private function getDoctrineConfig(): array
96100
],
97101
'configuration' => [
98102
'orm_default' => [
99-
'result_cache' => 'filesystem',
100-
'metadata_cache' => 'filesystem',
101-
'query_cache' => 'filesystem',
102-
'hydration_cache' => 'array',
103-
'typed_field_mapper' => null,
104-
'second_level_cache' => [
103+
'entity_listener_resolver' => EntityListenerResolver::class,
104+
'result_cache' => 'filesystem',
105+
'metadata_cache' => 'filesystem',
106+
'query_cache' => 'filesystem',
107+
'hydration_cache' => 'array',
108+
'typed_field_mapper' => null,
109+
'second_level_cache' => [
105110
'enabled' => true,
106111
'default_lifetime' => 3600,
107112
'default_lock_lifetime' => 60,
@@ -117,6 +122,21 @@ private function getDoctrineConfig(): array
117122
'class' => MappingDriverChain::class,
118123
],
119124
],
125+
'migrations' => [
126+
'table_storage' => [
127+
'table_name' => 'doctrine_migration_versions',
128+
'version_column_name' => 'version',
129+
'version_column_length' => 191,
130+
'executed_at_column_name' => 'executed_at',
131+
'execution_time_column_name' => 'execution_time',
132+
],
133+
// Modify this line based on where you would like to have you migrations
134+
'migrations_paths' => [
135+
'Migrations' => 'src/Migrations',
136+
],
137+
'all_or_nothing' => true,
138+
'check_database_platform' => true,
139+
],
120140
'types' => [
121141
UuidType::NAME => UuidType::class,
122142
],
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Light\App\Entity;
6+
7+
use Doctrine\ORM\Mapping as ORM;
8+
use Laminas\Stdlib\ArraySerializableInterface;
9+
10+
use function is_array;
11+
use function method_exists;
12+
use function ucfirst;
13+
14+
#[ORM\MappedSuperclass]
15+
abstract class AbstractEntity implements ArraySerializableInterface
16+
{
17+
public function __construct()
18+
{
19+
$this->initId();
20+
}
21+
22+
protected function initId(): void
23+
{
24+
}
25+
26+
/**
27+
* Override this method in soft-deletable entities
28+
*/
29+
public function isDeleted(): bool
30+
{
31+
return false;
32+
}
33+
34+
/**
35+
* @param array<non-empty-string, mixed> $array
36+
*/
37+
public function exchangeArray(array $array): void
38+
{
39+
foreach ($array as $property => $values) {
40+
if (is_array($values)) {
41+
$method = 'add' . ucfirst($property);
42+
if (! method_exists($this, $method)) {
43+
continue;
44+
}
45+
foreach ($values as $value) {
46+
$this->$method($value);
47+
}
48+
} else {
49+
$method = 'set' . ucfirst($property);
50+
if (! method_exists($this, $method)) {
51+
continue;
52+
}
53+
$this->$method($values);
54+
}
55+
}
56+
}
57+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Light\App\Entity;
6+
7+
use DateTimeImmutable;
8+
use Doctrine\ORM\Mapping as ORM;
9+
10+
trait TimestampsTrait
11+
{
12+
#[ORM\Column(name: 'created', type: 'datetime_immutable', nullable: false)]
13+
protected DateTimeImmutable $created;
14+
15+
#[ORM\Column(name: 'updated', type: 'datetime_immutable', nullable: true)]
16+
protected ?DateTimeImmutable $updated = null;
17+
18+
public function getCreated(): ?DateTimeImmutable
19+
{
20+
return $this->created;
21+
}
22+
23+
public function getCreatedFormatted(string $dateFormat = 'Y-m-d H:i:s'): string
24+
{
25+
return $this->created->format($dateFormat);
26+
}
27+
28+
public function getUpdated(): ?DateTimeImmutable
29+
{
30+
return $this->updated;
31+
}
32+
33+
public function getUpdatedFormatted(string $dateFormat = 'Y-m-d H:i:s'): ?string
34+
{
35+
if ($this->updated instanceof DateTimeImmutable) {
36+
return $this->updated->format($dateFormat);
37+
}
38+
39+
return null;
40+
}
41+
42+
#[ORM\PrePersist]
43+
public function created(): void
44+
{
45+
$this->created = new DateTimeImmutable();
46+
}
47+
48+
#[ORM\PreUpdate]
49+
public function touch(): void
50+
{
51+
$this->updated = new DateTimeImmutable();
52+
}
53+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Light\App\Entity;
6+
7+
use Doctrine\ORM\Mapping as ORM;
8+
use Ramsey\Uuid\Uuid;
9+
use Ramsey\Uuid\UuidInterface;
10+
11+
trait UuidIdentifierTrait
12+
{
13+
#[ORM\Id]
14+
#[ORM\Column(name: 'id', type: 'uuid', unique: true, nullable: false)]
15+
protected UuidInterface $uuid;
16+
17+
public function getId(): UuidInterface
18+
{
19+
return $this->uuid;
20+
}
21+
22+
public function setId(UuidInterface $id): static
23+
{
24+
$this->uuid = $id;
25+
26+
return $this;
27+
}
28+
29+
protected function initId(): void
30+
{
31+
$this->uuid = Uuid::uuid7();
32+
}
33+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Light\App\Factory;
6+
7+
use Light\App\Resolver\EntityListenerResolver;
8+
use Psr\Container\ContainerInterface;
9+
10+
class EntityListenerResolverFactory
11+
{
12+
public function __invoke(ContainerInterface $container): EntityListenerResolver
13+
{
14+
return new EntityListenerResolver($container);
15+
}
16+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Light\App\Resolver;
6+
7+
use Doctrine\ORM\Mapping\DefaultEntityListenerResolver;
8+
use Psr\Container\ContainerExceptionInterface;
9+
use Psr\Container\ContainerInterface;
10+
use Psr\Container\NotFoundExceptionInterface;
11+
12+
class EntityListenerResolver extends DefaultEntityListenerResolver
13+
{
14+
public function __construct(
15+
protected ContainerInterface $container,
16+
) {
17+
}
18+
19+
/**
20+
* @throws ContainerExceptionInterface
21+
* @throws NotFoundExceptionInterface
22+
*/
23+
public function resolve(string $className): object
24+
{
25+
return $this->container->get($className);
26+
}
27+
}

0 commit comments

Comments
 (0)