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:
Rostislav Wolny
2023-11-06 16:49:38 +01:00
committed by Aschepikov
parent 1565151179
commit c9c7146ef1
3 changed files with 44 additions and 2 deletions

View File

@@ -23,7 +23,10 @@ class Env {
public static $languagesPath;
public static $libPath;
public static $pluginPrefix;
/** @var string WP DB prefix + plugin prefix */
public static $dbPrefix;
/** @var string WP DB prefix only */
public static $wpDbPrefix;
public static $dbHost;
public static $dbIsIpv6;
public static $dbSocket;
@@ -78,6 +81,7 @@ class Env {
global $wpdb;
self::$dbPrefix = $wpdb->prefix . self::$pluginPrefix;
self::$wpDbPrefix = $wpdb->prefix;
self::$dbHost = $host;
self::$dbIsIpv6 = $isIpv6;
self::$dbPort = $port;

View File

@@ -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).
// @see https://www.doctrine-project.org/projects/doctrine-orm/en/2.5/cookbook/sql-table-prefixes.html
class TablePrefixMetadataFactory extends ClassMetadataFactory {
// WordPress tables that are used by MailPoet via Doctrine
const WP_TABLES = [
'posts',
];
/** @var string */
private $prefix;
/** @var string */
private $wpDbPrefix;
/** @var array */
private $prefixedMap = [];
@@ -22,6 +30,7 @@ class TablePrefixMetadataFactory extends ClassMetadataFactory {
throw new \RuntimeException('DB table prefix not initialized');
}
$this->prefix = Env::$dbPrefix;
$this->wpDbPrefix = Env::$wpDbPrefix;
$this->setProxyClassNameResolver(new ProxyClassNameResolver());
}
@@ -51,15 +60,29 @@ class TablePrefixMetadataFactory extends ClassMetadataFactory {
public function addPrefix(ClassMetadata $classMetadata) {
if (!$classMetadata->isInheritanceTypeSingleTable() || $classMetadata->getName() === $classMetadata->rootEntityName) {
$classMetadata->setPrimaryTable([
'name' => $this->prefix . $classMetadata->getTableName(),
'name' => $this->createPrefixedName($classMetadata->getTableName()),
]);
}
foreach ($classMetadata->getAssociationMappings() as $fieldName => $mapping) {
if ($mapping['type'] === ClassMetadataInfo::MANY_TO_MANY && $mapping['isOwningSide']) {
/** @var string $mappedTableName */
$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;
}
}

View File

@@ -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');
}
}