Created
February 21, 2020 08:56
-
-
Save KaiCMueller/54007f72496564cce1195307af1a7cef to your computer and use it in GitHub Desktop.
Symfony: Add an automatic table prefix with Doctrine
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
services: | |
kernel.listener.prefix: | |
class: App\EventListener\TablePrefixEventListener | |
# Adding the table_prefix configuration | |
calls: | |
- [ setConfig, [ '%table_prefix%' ] ] | |
tags: | |
- { name: doctrine.event_listener, event: loadClassMetadata, method: loadClassMetadata } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# mapping from bundle name to table prefix | |
parameters: | |
table_prefix: | |
calendar: calendar_ | |
foo: bar_ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\EventListener; | |
use Doctrine\ORM\Event\LoadClassMetadataEventArgs; | |
use Doctrine\ORM\Mapping\ClassMetadataInfo; | |
class TablePrefixEventListener | |
{ | |
/** | |
* @var array | |
*/ | |
protected $config; | |
/** | |
* @param array $config | |
*/ | |
public function setConfig(array $config) | |
{ | |
$this->config = $config; | |
} | |
/** | |
* @param \Doctrine\ORM\Event\LoadClassMetadataEventArgs $eventArgs | |
* | |
* @return void | |
*/ | |
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs): void | |
{ | |
$classMetadata = $eventArgs->getClassMetadata(); | |
if (!$classMetadata->isInheritanceTypeSingleTable() || $classMetadata->getName() === $classMetadata->rootEntityName) { | |
$classMetadata->setPrimaryTable([ | |
'name' => $this->getPrefix($classMetadata->getName(), $classMetadata->getTableName()) . $classMetadata->getTableName() | |
]); | |
} | |
foreach ($classMetadata->getAssociationMappings() as $fieldName => $mapping) { | |
if ($mapping['type'] == ClassMetadataInfo::MANY_TO_MANY && $mapping['isOwningSide']) { | |
$mappedTableName = $mapping['joinTable']['name']; | |
$classMetadata->associationMappings[$fieldName]['joinTable']['name'] = $this->getPrefix($mapping['targetEntity'], $mappedTableName) . $mappedTableName; | |
} | |
} | |
} | |
/** | |
* @param string $className | |
* @param string $tableName | |
* | |
* @return string | |
*/ | |
protected function getPrefix(string $className, string $tableName): string | |
{ | |
// get the namespaces from the class name | |
// $className might be "App\Calendar\Entity\CalendarEntity" | |
$nameSpaces = explode('\\', $className); | |
$bundleName = isset($nameSpaces[1]) ? strtolower($nameSpaces[1]) : null; | |
if (!$bundleName || !isset($this->config[$bundleName])) { | |
return ''; | |
} | |
$prefix = $this->config[$bundleName]; | |
// table is already prefixed with bundle name | |
if (strpos($tableName, $prefix) === 0) { | |
return ''; | |
} | |
return $prefix; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment