Improve table prefixing to allow Doctrine entities for WP tables
WordPress tables use only the DB prefix, but MailPoet tables use DB prefix + plugin prefix (mailpoet). This commit changes TablePrefixMetadataFactory to be able to distiguish WP table for posts and adds proper prefix. [MAILPOET-5646]
This commit is contained in:
committed by
Aschepikov
parent
1565151179
commit
c9c7146ef1
@@ -23,7 +23,10 @@ class Env {
|
|||||||
public static $languagesPath;
|
public static $languagesPath;
|
||||||
public static $libPath;
|
public static $libPath;
|
||||||
public static $pluginPrefix;
|
public static $pluginPrefix;
|
||||||
|
/** @var string WP DB prefix + plugin prefix */
|
||||||
public static $dbPrefix;
|
public static $dbPrefix;
|
||||||
|
/** @var string WP DB prefix only */
|
||||||
|
public static $wpDbPrefix;
|
||||||
public static $dbHost;
|
public static $dbHost;
|
||||||
public static $dbIsIpv6;
|
public static $dbIsIpv6;
|
||||||
public static $dbSocket;
|
public static $dbSocket;
|
||||||
@@ -78,6 +81,7 @@ class Env {
|
|||||||
|
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
self::$dbPrefix = $wpdb->prefix . self::$pluginPrefix;
|
self::$dbPrefix = $wpdb->prefix . self::$pluginPrefix;
|
||||||
|
self::$wpDbPrefix = $wpdb->prefix;
|
||||||
self::$dbHost = $host;
|
self::$dbHost = $host;
|
||||||
self::$dbIsIpv6 = $isIpv6;
|
self::$dbIsIpv6 = $isIpv6;
|
||||||
self::$dbPort = $port;
|
self::$dbPort = $port;
|
||||||
|
@@ -11,9 +11,17 @@ use MailPoetVendor\Doctrine\ORM\Mapping\ClassMetadataInfo;
|
|||||||
// because we need to add prefix at runtime, not at metadata dump (which is included in builds).
|
// 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
|
// @see https://www.doctrine-project.org/projects/doctrine-orm/en/2.5/cookbook/sql-table-prefixes.html
|
||||||
class TablePrefixMetadataFactory extends ClassMetadataFactory {
|
class TablePrefixMetadataFactory extends ClassMetadataFactory {
|
||||||
|
// WordPress tables that are used by MailPoet via Doctrine
|
||||||
|
const WP_TABLES = [
|
||||||
|
'posts',
|
||||||
|
];
|
||||||
|
|
||||||
/** @var string */
|
/** @var string */
|
||||||
private $prefix;
|
private $prefix;
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
private $wpDbPrefix;
|
||||||
|
|
||||||
/** @var array */
|
/** @var array */
|
||||||
private $prefixedMap = [];
|
private $prefixedMap = [];
|
||||||
|
|
||||||
@@ -22,6 +30,7 @@ class TablePrefixMetadataFactory extends ClassMetadataFactory {
|
|||||||
throw new \RuntimeException('DB table prefix not initialized');
|
throw new \RuntimeException('DB table prefix not initialized');
|
||||||
}
|
}
|
||||||
$this->prefix = Env::$dbPrefix;
|
$this->prefix = Env::$dbPrefix;
|
||||||
|
$this->wpDbPrefix = Env::$wpDbPrefix;
|
||||||
$this->setProxyClassNameResolver(new ProxyClassNameResolver());
|
$this->setProxyClassNameResolver(new ProxyClassNameResolver());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,15 +60,29 @@ class TablePrefixMetadataFactory extends ClassMetadataFactory {
|
|||||||
public function addPrefix(ClassMetadata $classMetadata) {
|
public function addPrefix(ClassMetadata $classMetadata) {
|
||||||
if (!$classMetadata->isInheritanceTypeSingleTable() || $classMetadata->getName() === $classMetadata->rootEntityName) {
|
if (!$classMetadata->isInheritanceTypeSingleTable() || $classMetadata->getName() === $classMetadata->rootEntityName) {
|
||||||
$classMetadata->setPrimaryTable([
|
$classMetadata->setPrimaryTable([
|
||||||
'name' => $this->prefix . $classMetadata->getTableName(),
|
'name' => $this->createPrefixedName($classMetadata->getTableName()),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($classMetadata->getAssociationMappings() as $fieldName => $mapping) {
|
foreach ($classMetadata->getAssociationMappings() as $fieldName => $mapping) {
|
||||||
if ($mapping['type'] === ClassMetadataInfo::MANY_TO_MANY && $mapping['isOwningSide']) {
|
if ($mapping['type'] === ClassMetadataInfo::MANY_TO_MANY && $mapping['isOwningSide']) {
|
||||||
|
/** @var string $mappedTableName */
|
||||||
$mappedTableName = $mapping['joinTable']['name'];
|
$mappedTableName = $mapping['joinTable']['name'];
|
||||||
$classMetadata->associationMappings[$fieldName]['joinTable']['name'] = $this->prefix . $mappedTableName;
|
$classMetadata->associationMappings[$fieldName]['joinTable']['name'] = $this->createPrefixedName($mappedTableName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MailPoet tables are prefixed by WP prefix + plugin prefix.
|
||||||
|
* For entities for WP tables we use WP prefix only.
|
||||||
|
*/
|
||||||
|
private function createPrefixedName(string $tableName): string {
|
||||||
|
// Use WP prefix for WP tables
|
||||||
|
if (in_array($tableName, self::WP_TABLES, true)) {
|
||||||
|
return $this->wpDbPrefix . $tableName;
|
||||||
|
}
|
||||||
|
// Use WP + plugin prefix for MailPoet tables
|
||||||
|
return $this->prefix . $tableName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,15 @@
|
|||||||
|
<?php declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace MailPoet\Doctrine;
|
||||||
|
|
||||||
|
use MailPoet\Entities\NewsletterEntity;
|
||||||
|
use MailPoet\Entities\WpPostEntity;
|
||||||
|
|
||||||
|
class TablePrefixMetadataFactoryTest extends \MailPoetTest {
|
||||||
|
public function testItPrefixTablesCorrectly() {
|
||||||
|
$wpPostMetadata = $this->entityManager->getClassMetadata(WpPostEntity::class);
|
||||||
|
$newslettersMetadata = $this->entityManager->getClassMetadata(NewsletterEntity::class);
|
||||||
|
verify($wpPostMetadata->getTableName())->equals('mp_posts');
|
||||||
|
verify($newslettersMetadata->getTableName())->equals('mp_mailpoet_newsletters');
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user