Skip to content

Instantly share code, notes, and snippets.

@faizanakram99
Last active May 31, 2024 09:41
Show Gist options
  • Save faizanakram99/8745e6b3fb1411918d0792e6b53b6a9d to your computer and use it in GitHub Desktop.
Save faizanakram99/8745e6b3fb1411918d0792e6b53b6a9d to your computer and use it in GitHub Desktop.
Single entity with multiple entity manager (a real production code example)
<?php
declare(strict_types=1);
namespace Tld\Translation\Infrastructure\Doctrine\Repository;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Tld\Translation\Domain\Entity\Translation;
use Tld\Translation\Domain\Repository\TranslationRepository;
abstract class AbstractTranslationRepository implements TranslationRepository
{
private array $translations = [];
public function __construct(private ManagerRegistry $registry)
{
}
abstract public static function getConnectionName(): string;
public function findTranslationsByLocaleAndDomain(string $locale, string $domain = 'messages'): array
{
$translations = [];
foreach ($this->findTranslationsByDomain($domain) as $translation) {
$translations[$translation->code] = $translation->translations->{$locale};
}
return $translations;
}
public function findTranslationsByDomain(string $domain): array
{
if (!\array_key_exists($domain, $this->translations)) {
$this->translations[$domain] = $this->repository()->findBy(['domain' => $domain]);
}
return $this->translations[$domain];
}
/**
* @return EntityRepository<Translation>
*/
private function repository(): EntityRepository
{
return $this->getEntityManager()->getRepository(Translation::class);
}
private function getEntityManager(): EntityManagerInterface
{
$entityManager = $this->registry->getManager(static::getConnectionName());
\assert($entityManager instanceof EntityManagerInterface);
return $entityManager;
}
}
<!-- src/Translation/Infrastructure/Doctrine/Mapping/Tenant/Translation.orm.xml -->
<!-- The actual name of file is Translation.orm.xml but github doesn't allow duplicate filenames in gist -->
<?xml version="1.0" encoding="utf-8" ?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://raw.github.com/doctrine/doctrine2/master/doctrine-mapping.xsd">
<entity name="Tld\Translation\Domain\Entity\Translation"
table="translations"
>
<id name="code" type="string" />
<id name="domain" type="string" />
<field name="translations" type="translation_type" />
</entity>
</doctrine-mapping>
<?php
declare(strict_types=1);
namespace Tld\Translation\Infrastructure\Doctrine\Repository;
class CentralTranslationRepository extends AbstractTranslationRepository
{
public static function getConnectionName(): string
{
return 'central';
}
}
<!-- src/Translation/Infrastructure/Doctrine/Mapping/Central/Translation.orm.xml -->
<!-- The actual name of file is Translation.orm.xml but github doesn't allow duplicate filenames in gist -->
<?xml version="1.0" encoding="utf-8" ?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://raw.github.com/doctrine/doctrine2/master/doctrine-mapping.xsd">
<entity name="Tld\Translation\Domain\Entity\Translation"
table="translations"
>
<id name="code" type="string" />
<id name="domain" type="string" />
<field name="translations" type="translation_type" />
</entity>
</doctrine-mapping>
<?php
declare(strict_types=1);
namespace Tld\Translation\Infrastructure\Doctrine\Repository;
class TenantTranslationRepository extends AbstractTranslationRepository
{
public static function getConnectionName(): string
{
return 'tenant';
}
}
<?php
declare(strict_types=1);
namespace Tld\Translation\Domain\Entity;
class Translation
{
public const SUPPORTED_LOCALES = ['en', 'es', 'de', 'fr', 'nl'];
public function __construct(
/** @psalm-readonly */
public string $code,
/** @psalm-readonly */
public string $domain,
public TranslationValues $translations,
) {
}
}
<?php
declare(strict_types=1);
namespace Tld\Translation\Domain\Repository;
use Tld\Translation\Domain\Entity\Translation;
interface TranslationRepository
{
/**
* @return array<string, string>
*/
public function findTranslationsByLocaleAndDomain(string $locale, string $domain = 'messages'): array;
/**
* @return Translation[]
*/
public function findTranslationsByDomain(string $domain): array;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment