Skip to content

Instantly share code, notes, and snippets.

@faizanakram99
Created June 30, 2022 16:09
Show Gist options
  • Save faizanakram99/9e90c794c5c3708d597d05daaab9f3ea to your computer and use it in GitHub Desktop.
Save faizanakram99/9e90c794c5c3708d597d05daaab9f3ea to your computer and use it in GitHub Desktop.
Example of ConfigCacheFactory for overriding translation cache for multi-tenant app with tenant specific translations
<?php
namespace Yup\Translation;
use Symfony\Component\Config\ConfigCacheFactoryInterface;
use Symfony\Component\Config\ConfigCacheInterface;
class TranslationConfigCacheFactory implements ConfigCacheFactoryInterface
{
private ConfigCacheFactoryInterface $configCacheFactory;
private string $tenant;
public function __construct(ConfigCacheFactoryInterface $configCacheFactory, string $tenantId)
{
$this->configCacheFactory = $configCacheFactory;
$this->tenant = $tenantId;
}
/**
* {@inheritdoc}
*/
public function cache($file, $callable): ConfigCacheInterface
{
return $this->configCacheFactory->cache(
\str_replace('/translations/', "/translations/{$this->tenant}_", $file),
$callable
);
}
}
<?php
namespace Yup\Tests\Translation;
use PHPUnit\Framework\TestCase;
use Yup\Translation\TranslationConfigCacheFactory;
use Symfony\Component\Config\ConfigCache;
use Symfony\Component\Config\ConfigCacheFactoryInterface;
class TranslationConfigCacheFactoryTest extends TestCase
{
/**
* @dataProvider getTranslationCacheFiles
*/
public function test_cache_appends_installation_name_to_cache_file(
string $cacheFileWithoutTenantId,
string $tenantId,
string $cacheFileWithTenantId
): void {
$configCacheFactory = $this->createMock(ConfigCacheFactoryInterface::class);
$callable = fn (mixed $arg): mixed => $arg;
$configCache = new ConfigCache($cacheFileWithTenantId, true);
$configCacheFactory
->expects(static::once())
->method('cache')
->with($cacheFileWithTenantId, $callable)
->willReturn($configCache);
$translationConfigCacheFactory = new TranslationConfigCacheFactory($configCacheFactory, $tenantId);
$translationConfigCacheFactory->cache($cacheFileWithoutTenantId, $callable);
}
public function getTranslationCacheFiles(): \Generator
{
yield ['foo/translations/bar.php', 'demo', 'foo/translations/demo_bar.php'];
yield ['foo1/translations/bar2.php', 'demo1', 'foo1/translations/demo1_bar2.php'];
yield ['foo1/translations/bar3.php', 'gounsch', 'foo1/translations/gounsch_bar3.php'];
}
}
<?php
namespace Yup\Translation\Compiler;
use Yup\Translation\TranslationConfigCacheFactory;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
final class TranslatorCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container): void
{
$translator = $container->getDefinition('translator.default');
$setConfigCacheFactoryMethodCall = \current(
\array_filter(
$translator->getMethodCalls(),
fn ($methodCall) => 'setConfigCacheFactory' === $methodCall[0]
)
);
$configCacheFactory = \is_array($setConfigCacheFactoryMethodCall)
? \current($setConfigCacheFactoryMethodCall[1])
: new Reference('config_cache_factory');
$container
->getDefinition(TranslationConfigCacheFactory::class)
->setArgument('$configCacheFactory', $configCacheFactory);
$translator
->removeMethodCall('setConfigCacheFactory')
->addMethodCall('setConfigCacheFactory', [new Reference(TranslationConfigCacheFactory::class)]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment