TranslationExtension   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 12
eloc 39
c 3
b 0
f 0
dl 0
loc 74
ccs 0
cts 30
cp 0
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A getConfigSchema() 0 10 1
A beforeCompile() 0 25 4
B loadConfiguration() 0 31 7
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Efabrica\Translatte\Bridge\Nette;
6
7
use Efabrica\Translatte\Latte\TranslateMacros;
8
use Efabrica\Translatte\Resolver\ChainResolver;
9
use Efabrica\Translatte\Resource\NeonDirectoryResource;
10
use Efabrica\Translatte\Translator;
11
use Latte\Engine;
12
use Nette\Application\UI\TemplateFactory;
13
use Nette\DI\CompilerExtension;
14
use Nette\DI\Definitions\FactoryDefinition;
15
use Nette\DI\Definitions\ServiceDefinition;
16
use Nette\DI\Definitions\Statement;
17
use Nette\DI\DynamicParameter;
18
use Nette\PhpGenerator\PhpLiteral;
19
use Nette\Schema\Expect;
20
use Nette\Schema\Schema;
21
22
/**
23
 * @phpstan-type TranslationConfig object{
24
 *     default: string,
25
 *     fallback: array<string>,
26
 *     dirs: array<string>,
27
 *     cache: Statement|DynamicParameter|null,
28
 *     resolvers: array<Statement>,
29
 *     resources: array<Statement>,
30
 *     recordTranslate: Statement|DynamicParameter|null
31
 * }
32
 */
33
class TranslationExtension extends CompilerExtension
34
{
35
    public function getConfigSchema(): Schema
36
    {
37
        return Expect::structure([
38
            'default' => Expect::string()->required(),
39
            'fallback' => Expect::arrayOf('string'),
40
            'dirs' => Expect::arrayOf('string'),
41
            'cache' => Expect::anyOf(Expect::type(Statement::class), Expect::type(DynamicParameter::class)),
42
            'resolvers' => Expect::arrayOf(Statement::class),
43
            'resources' => Expect::arrayOf(Statement::class),
44
            'recordTranslate' => Expect::anyOf(Expect::type(Statement::class), Expect::type(DynamicParameter::class)),
45
        ]);
46
    }
47
48
    public function loadConfiguration(): void
49
    {
50
        $builder = $this->getContainerBuilder();
51
52
        /** @var TranslationConfig $config */
53
        $config = $this->config;
54
55
        // Prepare params for translator
56
        $params = ['defaultLang' => $config->default];
57
        if (!empty($config->resolvers)) {
58
            $params['resolver'] = new Statement(ChainResolver::class, [$config->resolvers]);
59
        }
60
        if ($config->cache !== null) {
61
            $params['cache'] = $config->cache;
62
        }
63
        if ($config->recordTranslate !== null) {
64
            $params['recordTranslate'] = $config->recordTranslate;
65
        }
66
67
        $translator = $builder->addDefinition($this->prefix('translator'))
68
            ->setFactory(Translator::class, $params);
69
70
        // Configure translator
71
        foreach ($config->resources as $resource) {
72
            $translator->addSetup('addResource', [$resource]);
73
        }
74
        if (!empty($config->fallback)) {
75
            $translator->addSetup('setFallbackLanguages', [$config->fallback]);
76
        }
77
        if (!empty($config->dirs)) {
78
            $translator->addSetup('addResource', [new Statement(NeonDirectoryResource::class, [$config->dirs])]);
79
        }
80
    }
81
82
    public function beforeCompile(): void
83
    {
84
        $builder = $this->getContainerBuilder();
85
86
        /** @var ServiceDefinition $translator */
87
        $translator = $builder->getDefinition($this->prefix('translator'));
88
89
        $templateFactoryName = $builder->getByType(TemplateFactory::class);
90
        if ($templateFactoryName !== null) {
91
            /** @var ServiceDefinition $templateFactory */
92
            $templateFactory = $builder->getDefinition($templateFactoryName);
93
            $templateFactory->addSetup('
94
					$service->onCreate[] = function (Nette\\Bridges\\ApplicationLatte\\Template $template): void {
95
						$template->setTranslator(?);
96
					};', [$translator]);
97
        }
98
99
        if ($builder->hasDefinition('latte.latteFactory')) {
100
            /** @var FactoryDefinition $latteFactory */
101
            $latteFactory = $builder->getDefinition('latte.latteFactory');
102
            $latteFactory->getResultDefinition()
103
                ->addSetup('addProvider', ['translator', $builder->getDefinition($this->prefix('translator'))]);
104
105
            if (version_compare(Engine::VERSION, '3', '<')) { // @phpstan-ignore-line
106
                $latteFactory->getResultDefinition()->addSetup('?->onCompile[] = function($engine) { ?::install($engine->getCompiler()); }', ['@self', new PhpLiteral(TranslateMacros::class)]);
107
            }
108
        }
109
    }
110
}
111