Нет описания

TablePrefixMetadataFactory.php 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. <?php
  2. namespace MailPoet\Doctrine;
  3. if (!defined('ABSPATH')) exit;
  4. use MailPoet\Config\Env;
  5. use MailPoetVendor\Doctrine\ORM\Mapping\ClassMetadata;
  6. use MailPoetVendor\Doctrine\ORM\Mapping\ClassMetadataFactory;
  7. use MailPoetVendor\Doctrine\ORM\Mapping\ClassMetadataInfo;
  8. // Taken from Doctrine docs (see link bellow) but implemented in metadata factory instead of an event
  9. // because we need to add prefix at runtime, not at metadata dump (which is included in builds).
  10. // @see https://www.doctrine-project.org/projects/doctrine-orm/en/2.5/cookbook/sql-table-prefixes.html
  11. class TablePrefixMetadataFactory extends ClassMetadataFactory {
  12. /** @var string */
  13. private $prefix;
  14. /** @var array */
  15. private $prefixedMap = [];
  16. public function __construct() {
  17. if (Env::$dbPrefix === null) {
  18. throw new \RuntimeException('DB table prefix not initialized');
  19. }
  20. $this->prefix = Env::$dbPrefix;
  21. $this->setProxyClassNameResolver(new ProxyClassNameResolver());
  22. }
  23. /**
  24. * @return ClassMetadata<object>
  25. */
  26. public function getMetadataFor($className) {
  27. $classMetadata = parent::getMetadataFor($className);
  28. if (isset($this->prefixedMap[$classMetadata->getName()])) {
  29. return $classMetadata;
  30. }
  31. // prefix tables only after they are saved to cache so the prefix does not get included in cache
  32. // (getMetadataFor can call itself recursively but it saves to cache only after the recursive calls)
  33. $cacheKey = $this->getCacheKey($classMetadata->getName());
  34. $isCached = ($cache = $this->getCache()) ? $cache->hasItem($cacheKey) : false;
  35. if ($classMetadata instanceof ClassMetadata && $isCached) {
  36. $this->addPrefix($classMetadata);
  37. $this->prefixedMap[$classMetadata->getName()] = true;
  38. }
  39. return $classMetadata;
  40. }
  41. /**
  42. * @param ClassMetadata<object> $classMetadata
  43. */
  44. public function addPrefix(ClassMetadata $classMetadata) {
  45. if (!$classMetadata->isInheritanceTypeSingleTable() || $classMetadata->getName() === $classMetadata->rootEntityName) {
  46. $classMetadata->setPrimaryTable([
  47. 'name' => $this->prefix . $classMetadata->getTableName(),
  48. ]);
  49. }
  50. foreach ($classMetadata->getAssociationMappings() as $fieldName => $mapping) {
  51. if ($mapping['type'] === ClassMetadataInfo::MANY_TO_MANY && $mapping['isOwningSide']) {
  52. $mappedTableName = $mapping['joinTable']['name'];
  53. $classMetadata->associationMappings[$fieldName]['joinTable']['name'] = $this->prefix . $mappedTableName;
  54. }
  55. }
  56. }
  57. }