Kdyby\Doctrine jak nastavit prefix tabulek v db
- lvq
- Člen | 47
Ahoj, používám Kdyby\Doctrine a dostal jsem se do situace, kdy potřebuji
všem tabulkám v db nastavit prefix a nevím, jak na to.
Podle manuálu jsem si vytvořil třídu:
namespace App\Subscriber;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Kdyby\Events\Subscriber;
use Nette\SmartObject;
class TablePrefixSubscriber implements Subscriber
{
use SmartObject;
protected $prefix = '';
/**
* Constructor
*
* @param string $prefix
*/
public function __construct($prefix)
{
$this->prefix = (string) $prefix;
}
/**
* @return array
*/
public function getSubscribedEvents()
{
return array('loadClassMetadata');
}
/**
* @param LoadClassMetadataEventArgs $args
*
* @return void
*/
public function loadClassMetadata(LoadClassMetadataEventArgs $args)
{
$classMetadata = $args->getClassMetadata();
// Only add the prefixes to our own entities.
if (FALSE !== strpos($classMetadata->namespace, 'Some\Namespace\Part'))
{
// Do not re-apply the prefix when the table is already prefixed
if (false === strpos($classMetadata->getTableName(), $this->prefix))
{
$tableName = $this->prefix . $classMetadata->getTableName();
$classMetadata->setPrimaryTable(['name' => $tableName]);
}
foreach ($classMetadata->getAssociationMappings() as $fieldName => $mapping)
{
if ($mapping['type'] == ClassMetadataInfo::MANY_TO_MANY && $mapping['isOwningSide'] == true)
{
$mappedTableName = $classMetadata->associationMappings[$fieldName]['joinTable']['name'];
// Do not re-apply the prefix when the association is already prefixed
if (false !== strpos($mappedTableName, $this->prefix))
{
continue;
}
$classMetadata->associationMappings[$fieldName]['joinTable']['name'] = $this->prefix . $mappedTableName;
}
}
}
}
}
v config.neon
jsem si třídu zaregistroval:
events:
subscribers:
- App\Subscriber\TablePrefixSubscriber('prefix_')
Ale docttrine s tím prefixem nepracuje. Přiznám, že s těma eventama z Kdyby moc neumím. Ví někdo, co dělám špatně? Beru i nějaký jiný návrh řešení toho problému s prefixem.
- Jiří Nápravník
- Člen | 710
Já používám tohle a funguje bez problémů
services:
-
class: JiriNapravnik\Doctrine\EventSubscriber\TablePrefixSubscriber(%database.tablePrefix%)
tags: [kdyby.subscriber]
- lvq
- Člen | 47
Tak už to jede :-)
Ta metoda loadClassMetadata
se právě nespouštěla, teď se
spouští. Pořádně si to nedovedu vysvětlit (cache jsem mazal poctivě si
myslím). Pak jsem v ní řádek
if (FALSE !== strpos($classMetadata->namespace, 'Some\Namespace\Part'))
přespal za svůj namespace a už se to chytá.
V neon
u funguje toto:
events:
subscribers:
- App\Subscriber\TablePrefixSubscriber()
i toto:
-
class: App\Subscriber\TablePrefixSubscriber()
tags: [kdyby.subscriber]
Díky všem přispívajícím.
- looky
- Člen | 99
Ještě dodám, že ten foreach bys neměl mít uvnitř toho ifu, který
kontroluje jestli jde o tvůj namespace. Protože pak se prefixnou všechny
ManyToMany relace z tvých entit na cizí a zároveň se neprefixnou relace
z cizích entit na tvoje. Ten foreach by měl být mimo, a uvnitř něj bys
měl znovu kontrolovat $mapping['targetEntity']
.
Zároveň myslím, že kontrola, jestli už ta tabulka není prefixlá je zbytečná, protože tahle celá mašinérie se volá pouze jednou pro každou entitu.
EDIT: ukázka mojí implementace
Editoval looky (4. 10. 2016 15:10)