| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- <?php
- namespace MailPoet\Doctrine;
- if (!defined('ABSPATH')) exit;
- use MailPoet\Config\Env;
- use MailPoetVendor\Doctrine\ORM\Mapping\ClassMetadata;
- use MailPoetVendor\Doctrine\ORM\Mapping\ClassMetadataFactory;
- use MailPoetVendor\Doctrine\ORM\Mapping\ClassMetadataInfo;
- // Taken from Doctrine docs (see link bellow) but implemented in metadata factory instead of an event
- // because we need to add prefix at runtime, not at metadata dump (which is included in builds).
- // @see https://www.doctrine-project.org/projects/doctrine-orm/en/2.5/cookbook/sql-table-prefixes.html
- class TablePrefixMetadataFactory extends ClassMetadataFactory {
- /** @var string */
- private $prefix;
- /** @var array */
- private $prefixedMap = [];
- public function __construct() {
- if (Env::$dbPrefix === null) {
- throw new \RuntimeException('DB table prefix not initialized');
- }
- $this->prefix = Env::$dbPrefix;
- $this->setProxyClassNameResolver(new ProxyClassNameResolver());
- }
- /**
- * @return ClassMetadata<object>
- */
- public function getMetadataFor($className) {
- $classMetadata = parent::getMetadataFor($className);
- if (isset($this->prefixedMap[$classMetadata->getName()])) {
- return $classMetadata;
- }
- // prefix tables only after they are saved to cache so the prefix does not get included in cache
- // (getMetadataFor can call itself recursively but it saves to cache only after the recursive calls)
- $cacheKey = $this->getCacheKey($classMetadata->getName());
- $isCached = ($cache = $this->getCache()) ? $cache->hasItem($cacheKey) : false;
- if ($classMetadata instanceof ClassMetadata && $isCached) {
- $this->addPrefix($classMetadata);
- $this->prefixedMap[$classMetadata->getName()] = true;
- }
- return $classMetadata;
- }
- /**
- * @param ClassMetadata<object> $classMetadata
- */
- public function addPrefix(ClassMetadata $classMetadata) {
- if (!$classMetadata->isInheritanceTypeSingleTable() || $classMetadata->getName() === $classMetadata->rootEntityName) {
- $classMetadata->setPrimaryTable([
- 'name' => $this->prefix . $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->prefix . $mappedTableName;
- }
- }
- }
- }
|