Skip to content

Commit 7eb0108

Browse files
authored
Merge pull request #392 from dotkernel/issue-391
Issue #391: Implemented Doctrine table prefixes
2 parents 5852bb2 + f0edc16 commit 7eb0108

File tree

7 files changed

+126
-25
lines changed

7 files changed

+126
-25
lines changed

bin/doctrine

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,25 @@
33

44
declare(strict_types=1);
55

6+
use Core\App\Event\TablePrefixEventListener;
67
use Doctrine\ORM\EntityManager;
8+
use Doctrine\ORM\Events;
79
use Doctrine\ORM\Tools\Console\ConsoleRunner;
810
use Doctrine\ORM\Tools\Console\EntityManagerProvider\SingleManagerProvider;
11+
use Dot\DataFixtures\Command\ExecuteFixturesCommand;
12+
use Dot\DataFixtures\Command\ListFixturesCommand;
913

1014
require_once 'vendor/autoload.php';
1115

12-
$container = require getcwd() . '/config/container.php' ;
16+
$container = require 'config/container.php';
1317

1418
$entityManager = $container->get(EntityManager::class);
19+
$entityManager->getEventManager()
20+
->addEventListener(Events::loadClassMetadata, $container->get(TablePrefixEventListener::class));
1521

1622
$commands = [
17-
$container->get(Dot\DataFixtures\Command\ExecuteFixturesCommand::class),
18-
$container->get(Dot\DataFixtures\Command\ListFixturesCommand::class),
23+
$container->get(ExecuteFixturesCommand::class),
24+
$container->get(ListFixturesCommand::class),
1925
];
2026

21-
ConsoleRunner::run(
22-
new SingleManagerProvider($entityManager),
23-
$commands
24-
);
27+
ConsoleRunner::run(new SingleManagerProvider($entityManager), $commands);

config/autoload/local.php.dist

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,17 @@ $baseUrl = 'http://localhost:8080';
1313

1414
$databases = [
1515
'default' => [
16-
'host' => 'localhost',
17-
'dbname' => 'dotkernel',
18-
'user' => '',
19-
'password' => '',
20-
'port' => 3306,
21-
'driver' => 'pdo_mysql',
22-
'charset' => 'utf8mb4',
23-
'collate' => 'utf8mb4_general_ci',
16+
'host' => 'localhost',
17+
'dbname' => 'dotkernel',
18+
'user' => '',
19+
'password' => '',
20+
'port' => 3306,
21+
'driver' => 'pdo_mysql',
22+
'charset' => 'utf8mb4',
23+
'collate' => 'utf8mb4_general_ci',
24+
'table_prefix' => '',
2425
],
25-
// you can add more database connections into this array
26+
// you can add more database connections to this array
2627
];
2728

2829
return [

config/cli-config.php

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,20 @@
22

33
declare(strict_types=1);
44

5+
use Core\App\Event\TablePrefixEventListener;
56
use Doctrine\Migrations\Configuration\EntityManager\ExistingEntityManager;
67
use Doctrine\Migrations\Configuration\Migration\ConfigurationArray;
78
use Doctrine\Migrations\DependencyFactory;
89
use Doctrine\ORM\EntityManager;
10+
use Doctrine\ORM\Events;
911

10-
$container = require __DIR__ . '/container.php';
12+
$container = require 'config/container.php';
13+
14+
$entityManager = $container->get(EntityManager::class);
15+
$entityManager->getEventManager()
16+
->addEventListener(Events::loadClassMetadata, $container->get(TablePrefixEventListener::class));
1117

1218
return DependencyFactory::fromEntityManager(
13-
new ConfigurationArray(
14-
$container->get('config')['doctrine']['migrations']
15-
),
16-
new ExistingEntityManager(
17-
$container->get(EntityManager::class)
18-
)
19+
new ConfigurationArray($container->get('config')['doctrine']['migrations']),
20+
new ExistingEntityManager($entityManager)
1921
);

log/.gitignore

100644100755
File mode changed.

src/Core/src/App/src/ConfigProvider.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
use Core\App\Command\RouteListCommand;
88
use Core\App\DBAL\Types\SuccessFailureEnumType;
99
use Core\App\DBAL\Types\YesNoEnumType;
10+
use Core\App\Event\TablePrefixEventListener;
1011
use Core\App\Factory\EntityListenerResolverFactory;
12+
use Core\App\Factory\TablePrefixDelegatorFactory;
1113
use Core\App\Resolver\EntityListenerResolver;
1214
use Core\App\Service\MailService;
1315
use Doctrine\ORM\EntityManager;
@@ -23,6 +25,7 @@
2325
use Dot\Mail\Factory\MailOptionsAbstractFactory;
2426
use Dot\Mail\Factory\MailServiceAbstractFactory;
2527
use Dot\Mail\Service\MailService as DotMailService;
28+
use Mezzio\Application;
2629
use Ramsey\Uuid\Doctrine\UuidBinaryOrderedTimeType;
2730
use Ramsey\Uuid\Doctrine\UuidBinaryType;
2831
use Ramsey\Uuid\Doctrine\UuidType;
@@ -117,15 +120,19 @@ public function __invoke(): array
117120
private function getDependencies(): array
118121
{
119122
return [
120-
'factories' => [
123+
'delegators' => [
124+
Application::class => [TablePrefixDelegatorFactory::class],
125+
],
126+
'factories' => [
121127
'doctrine.entity_manager.orm_default' => EntityManagerFactory::class,
122128
'dot-mail.options.default' => MailOptionsAbstractFactory::class,
123129
'dot-mail.service.default' => MailServiceAbstractFactory::class,
124130
EntityListenerResolver::class => EntityListenerResolverFactory::class,
125131
MailService::class => AttributedServiceFactory::class,
126132
RouteListCommand::class => AttributedServiceFactory::class,
133+
TablePrefixEventListener::class => AttributedServiceFactory::class,
127134
],
128-
'aliases' => [
135+
'aliases' => [
129136
DotMailService::class => 'dot-mail.service.default',
130137
EntityManager::class => 'doctrine.entity_manager.orm_default',
131138
EntityManagerInterface::class => 'doctrine.entity_manager.orm_default',
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Core\App\Event;
6+
7+
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
8+
use Doctrine\ORM\Mapping\ClassMetadata;
9+
use Dot\DependencyInjection\Attribute\Inject;
10+
11+
use function array_key_exists;
12+
use function is_string;
13+
14+
class TablePrefixEventListener
15+
{
16+
private string $prefix = '';
17+
18+
/**
19+
* @phpstan-param array<non-empty-string, mixed> $config
20+
*/
21+
#[Inject(
22+
'config.doctrine.connection.orm_default.params',
23+
)]
24+
public function __construct(array $config)
25+
{
26+
if (array_key_exists('table_prefix', $config) && is_string($config['table_prefix'])) {
27+
$this->prefix = $config['table_prefix'];
28+
}
29+
}
30+
31+
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs): void
32+
{
33+
if ($this->prefix === '') {
34+
return;
35+
}
36+
37+
$classMetadata = $eventArgs->getClassMetadata();
38+
if (
39+
! $classMetadata->isInheritanceTypeSingleTable()
40+
|| $classMetadata->getName() === $classMetadata->rootEntityName
41+
) {
42+
$classMetadata->setPrimaryTable([
43+
'name' => $this->prefix . $classMetadata->getTableName(),
44+
]);
45+
}
46+
47+
foreach ($classMetadata->getAssociationMappings() as $fieldName => $mapping) {
48+
if ($mapping['type'] === ClassMetadata::MANY_TO_MANY && $mapping['isOwningSide']) {
49+
$classMetadata->associationMappings[$fieldName]['joinTable']['name'] =
50+
$this->prefix . $mapping['joinTable']['name'];
51+
}
52+
}
53+
}
54+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Core\App\Factory;
6+
7+
use Core\App\Event\TablePrefixEventListener;
8+
use Doctrine\ORM\EntityManagerInterface;
9+
use Doctrine\ORM\Events;
10+
use Mezzio\Application;
11+
use Psr\Container\ContainerExceptionInterface;
12+
use Psr\Container\ContainerInterface;
13+
use Psr\Container\NotFoundExceptionInterface;
14+
15+
class TablePrefixDelegatorFactory
16+
{
17+
/**
18+
* @throws ContainerExceptionInterface
19+
* @throws NotFoundExceptionInterface
20+
*/
21+
public function __invoke(ContainerInterface $container, string $name, callable $callback): Application
22+
{
23+
if ($container->has('doctrine.entity_manager.orm_default')) {
24+
/** @var EntityManagerInterface $entityManager */
25+
$entityManager = $container->get('doctrine.entity_manager.orm_default');
26+
$entityManager->getEventManager()->addEventListener(
27+
Events::loadClassMetadata,
28+
$container->get(TablePrefixEventListener::class)
29+
);
30+
}
31+
32+
return $callback();
33+
}
34+
}

0 commit comments

Comments
 (0)