Created
February 21, 2020 09:06
-
-
Save KaiCMueller/c6a39c9cf82eb01bc32bb0b7fe57b4fd 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
<?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