Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for symfony translations providers like loco #130

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
"nette/routing": "^3.0",
"nette/utils": "^3.2.1|~4.0.0",
"symfony/translation": "^6.0|^7.0",
"symfony/config": "^6.0|^7.0"
"symfony/config": "^6.0|^7.0",
"symfony/finder": "^6.0|^7.0"
},
"require-dev": {
"doctrine/orm": "^2.8",
Expand Down
85 changes: 85 additions & 0 deletions src/DI/TranslationExtension.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?php declare(strict_types = 1);

Check failure on line 1 in src/DI/TranslationExtension.php

View workflow job for this annotation

GitHub Actions / Static analysis (phpstan)

Ignored error pattern #^Fetching class constant class of deprecated class Nette\\Bridges\\ApplicationLatte\\ILatteFactory\: use Nette\\Bridges\\ApplicationLatte\\LatteFactory$# in path /home/runner/work/translation/translation/src/DI/TranslationExtension.php was not matched in reported errors.

Check failure on line 1 in src/DI/TranslationExtension.php

View workflow job for this annotation

GitHub Actions / Static analysis (phpstan)

Ignored error pattern #^Fetching class constant class of deprecated class Nette\\Localization\\ITranslator\: use Nette\\Localization\\Translator$# in path /home/runner/work/translation/translation/src/DI/TranslationExtension.php was not matched in reported errors.

namespace Contributte\Translation\DI;

Expand Down Expand Up @@ -34,9 +34,22 @@
use Symfony\Component\Config\ConfigCacheFactory;
use Symfony\Component\Config\ConfigCacheFactoryInterface;
use Symfony\Component\Translation\Loader\LoaderInterface;
use Symfony\Component\Translation\Loader\XliffFileLoader;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Component\Translation\Provider\ProviderFactoryInterface;
use Symfony\Component\Translation\Provider\ProviderInterface;
use Symfony\Component\Translation\Provider\TranslationProviderCollection;
use Symfony\Component\Translation\Provider\TranslationProviderCollectionFactory;
use Contributte\Translation\Dumpers\NeonFileDumper;
use Symfony\Component\Translation\Writer\TranslationWriter;
use Symfony\Component\Translation\Reader\TranslationReader;
use Symfony\Component\Translation\Command\TranslationPushCommand;
use Symfony\Component\Translation\Command\TranslationPullCommand;
use Symfony\Component\Translation\Command\XliffLintCommand;
use Symfony\Component\HttpClient\CurlHttpClient;
use Tracy\IBarPanel;


/**
* @property stdClass $config
*/
Expand Down Expand Up @@ -82,7 +95,8 @@
'translatorFactory' => Expect::string()->default(null),
'returnOriginalMessage' => Expect::bool()->default(true),
'autowired' => Expect::type('bool|array')->default(true),
'latteFactory' => Expect::string(ILatteFactory::class)->nullable(),

Check failure on line 98 in src/DI/TranslationExtension.php

View workflow job for this annotation

GitHub Actions / Static analysis (phpstan)

Fetching class constant class of deprecated interface Nette\Bridges\ApplicationLatte\ILatteFactory: use Nette\Bridges\ApplicationLatte\LatteFactory
'providers' => Expect::array()->default([]),
]);
}

Expand Down Expand Up @@ -144,7 +158,7 @@

if ($this->config->autowired === true) {
$autowired = [
ITranslator::class,

Check failure on line 161 in src/DI/TranslationExtension.php

View workflow job for this annotation

GitHub Actions / Static analysis (phpstan)

Fetching class constant class of deprecated interface Nette\Localization\ITranslator: use Nette\Localization\Translator
TranslatorInterface::class,
Translator::class,
];
Expand Down Expand Up @@ -187,6 +201,9 @@
$translator->setAutowired($autowired);
}

$reader = $builder->addDefinition($this->prefix('providerTranslationReader'))
->setFactory(TranslationReader::class);

// Loaders
foreach ($this->config->loaders as $k1 => $v1) {
$reflection = new ReflectionClass(DIHelpers::unwrapEntity($v1));
Expand All @@ -199,8 +216,76 @@
->setFactory($v1);

$translator->addSetup('addLoader', [$k1, $loader]);
$reader->addSetup('addLoader', [$k1, $loader]);

}


$neonFileDumper = $builder->addDefinition($this->prefix('neonFileDumper'))
->setFactory(NeonFileDumper::class);

$write = $builder->addDefinition($this->prefix('providerTranslationWriter'))
->setFactory(TranslationWriter::class)
->addSetup('addDumper', ['neon', $neonFileDumper]);

// Symfony providers

$builder->addDefinition($this->prefix('providerCurlHttpClient'))
->setFactory(CurlHttpClient::class);

Check failure on line 234 in src/DI/TranslationExtension.php

View workflow job for this annotation

GitHub Actions / Static analysis (phpstan)

Class Symfony\Component\HttpClient\CurlHttpClient not found.

Check failure on line 234 in src/DI/TranslationExtension.php

View workflow job for this annotation

GitHub Actions / Static analysis (--prefer-lowest, phpstan-lowest)

Class Symfony\Component\HttpClient\CurlHttpClient not found.

$xlfLoader = $builder->addDefinition($this->prefix('loaderXLF'))
->setFactory(XliffFileLoader::class);

$providers = [];
foreach ($this->config->providers as $k1 => $v1) {

if (!isset($v1['provider']))
throw new InvalidArgument('Missing provider parameter in definitions of providers.');
if (!isset($v1['dsn']))
throw new InvalidArgument('Missing DSN parameter in definitions of providers.');

$reflection = new ReflectionClass(DIHelpers::unwrapEntity($v1['provider']));
bdump($reflection);
if (!$reflection->implementsInterface(ProviderFactoryInterface::class)) {
throw new InvalidArgument('Provider must implement interface "' . ProviderFactoryInterface::class . '".');

}

$provider = $builder->addDefinition($this->prefix('provider' . Strings::firstUpper($k1)))
->setFactory($v1['provider'],['defaultLocale' => $this->config->locales->default, 'loader' => $xlfLoader]);

$providers[$k1] = $provider;

/*if (!isset($this->config->providers[$k1]['domains']) || empty($this->config->providers[$k1]['domains'])) {
$this->config->providers[$k1]['domains'] = ['common'];
}*/

}

$builder->addDefinition($this->prefix('providerCollectionFatory'))
->setFactory(TranslationProviderCollectionFactory::class, ["factories" => $providers, 'enabledLocales' => $this->config->locales->whitelist]);


$providerCollections = $builder->addDefinition($this->prefix('providerCollection'))
->setFactory('@'.$this->prefix('providerCollectionFatory').'::fromConfig', ['config' => $this->config->providers]);


// Symfony commands
$builder->addDefinition($this->prefix('translationPullCommand'))
->setFactory(TranslationPullCommand::class, ['providerCollection' => $providerCollections, 'defaultLocale' => $this->config->locales->default, 'enabledLocales' => $this->config->locales->whitelist, 'transPaths' => $this->config->dirs])
->setAutowired(false);

$builder->addDefinition($this->prefix('translationPushCommand'))
->setFactory(TranslationPushCommand::class, ['providers' => $providerCollections, 'enabledLocales' => $this->config->locales->whitelist, 'transPaths' => $this->config->dirs])
->setAutowired(false);

$builder->addDefinition($this->prefix('translationXliffLintCommand'))
->setFactory(XliffLintCommand::class)
->setAutowired(false);




// Tracy\Panel
if (!$this->config->debug || !$this->config->debugger) {
return;
Expand Down Expand Up @@ -233,7 +318,7 @@
$latteFactoryName = $this->config->latteFactory ? $builder->getByType($this->config->latteFactory) : null;

if ($latteFactoryName !== null) {
$iTranslator = $builder->getDefinitionByType(ITranslator::class);

Check failure on line 321 in src/DI/TranslationExtension.php

View workflow job for this annotation

GitHub Actions / Static analysis (phpstan)

Fetching class constant class of deprecated interface Nette\Localization\ITranslator: use Nette\Localization\Translator

$latteFilters = $builder->addDefinition($this->prefix('latte.filters'))
->setFactory(Filters::class);
Expand Down
56 changes: 56 additions & 0 deletions src/Dumpers/NeonFileDumper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

/*
* Nette neon dumper for contributte translation and symfony translation
*
* (c) Lukas Divacky <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
*/

namespace Contributte\Translation\Dumpers;

use Symfony\Component\Translation\Exception\LogicException;
use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\Util\ArrayConverter;
use Symfony\Component\Translation\Dumper\FileDumper;
use Symfony\Component\Yaml\Yaml;
use Nette\Neon\Neon as NetteNeon;

/**
* NeonFileDumper generates yaml files from a message catalogue.
*
* @author Lukas Divacky <[email protected]>
*/
class NeonFileDumper extends FileDumper
{
private string $extension;

public function __construct(string $extension = 'neon')
{
$this->extension = $extension;
}

public function formatCatalogue(MessageCatalogue $messages, string $domain, array $options = []): string

Check failure on line 36 in src/Dumpers/NeonFileDumper.php

View workflow job for this annotation

GitHub Actions / Static analysis (phpstan)

Method Contributte\Translation\Dumpers\NeonFileDumper::formatCatalogue() has parameter $options with no value type specified in iterable type array.

Check failure on line 36 in src/Dumpers/NeonFileDumper.php

View workflow job for this annotation

GitHub Actions / Static analysis (--prefer-lowest, phpstan-lowest)

Method Contributte\Translation\Dumpers\NeonFileDumper::formatCatalogue() has parameter $options with no value type specified in iterable type array.
{
if (!class_exists(NetteNeon::class)) {
throw new LogicException('Dumping translations in the neon format requires the Nette neon component.');
}

$data = $messages->all($domain);

$data = ArrayConverter::expandToTree($data);

$neon = NetteNeon::encode($data, true);

return $neon;

}

protected function getExtension(): string
{
return $this->extension;
}
}
Loading