Worker   A
last analyzed

Complexity

Total Complexity 22

Size/Duplication

Total Lines 99
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 87.5%

Importance

Changes 0
Metric Value
wmc 22
lcom 1
cbo 7
dl 0
loc 99
c 0
b 0
f 0
ccs 49
cts 56
cp 0.875
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
B work() 0 44 10
B extractContextFromJoinedFilters() 0 25 7
A getReadDomainFromArguments() 0 12 3
A getReadDomainFromNode() 0 8 2
1
<?php
2
3
/*
4
 * This file is part of the PHP Translation package.
5
 *
6
 * (c) PHP Translation team <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Translation\Extractor\Visitor\Twig;
13
14
use Symfony\Bridge\Twig\Node\TransNode;
15
use Translation\Extractor\Model\Error;
16
use Translation\Extractor\Model\SourceCollection;
17
use Translation\Extractor\Model\SourceLocation;
18
use Twig\Node\Expression\ConstantExpression;
19
use Twig\Node\Expression\FilterExpression;
20
use Twig\Node\Node;
21
22
/**
23
 * The Worker that actually extract the translations.
24
 *
25
 * @author Tobias Nyholm <[email protected]>
26
 * @author Fabien Potencier <[email protected]>
27
 */
28
final class Worker
29
{
30
    const UNDEFINED_DOMAIN = 'messages';
31
32
    private $stack = [];
33
34 5
    public function work(Node $node, SourceCollection $collection, callable $getAbsoluteFilePath): Node
35
    {
36 5
        $this->stack[] = $node;
37 5
        if ($node instanceof FilterExpression && $node->getNode('node') instanceof ConstantExpression) {
38 4
            $domain = null;
39 4
            if ('trans' === $node->getNode('filter')->getAttribute('value')) {
40 4
                $domain = $this->getReadDomainFromArguments($node->getNode('arguments'), 1);
41
            } elseif ('transchoice' === $node->getNode('filter')->getAttribute('value')) {
42
                $domain = $this->getReadDomainFromArguments($node->getNode('arguments'), 2);
43
            }
44
45 4
            if ($domain) {
46
                try {
47 4
                    $context = $this->extractContextFromJoinedFilters();
48 2
                } catch (\LogicException $e) {
49 2
                    $collection->addError(new Error($e->getMessage(), $getAbsoluteFilePath(), $node->getTemplateLine()));
50
                }
51 4
                $context['domain'] = $domain;
52 4
                $collection->addLocation(
53 4
                    new SourceLocation(
54 4
                        $node->getNode('node')->getAttribute('value'),
55 4
                        $getAbsoluteFilePath(),
56 4
                        $node->getTemplateLine(),
57
                        $context
58
                    )
59
                );
60
            }
61 5
        } elseif ($node instanceof TransNode) {
62
            // extract trans nodes
63 2
            $domain = self::UNDEFINED_DOMAIN;
64 2
            if ($node->hasNode('domain') && null !== $node->getNode('domain')) {
65 2
                $domain = $this->getReadDomainFromNode($node->getNode('domain'));
66
            }
67
68 2
            $collection->addLocation(new SourceLocation(
69 2
                $node->getNode('body')->getAttribute('data'),
70 2
                $getAbsoluteFilePath(),
71 2
                $node->getTemplateLine(),
72 2
                ['domain' => $domain]
73
            ));
74
        }
75
76 5
        return $node;
77
    }
78
79 4
    private function extractContextFromJoinedFilters(): array
80
    {
81 4
        $context = [];
82 4
        for ($i = \count($this->stack) - 2; $i >= 0; --$i) {
83 4
            if (!$this->stack[$i] instanceof FilterExpression) {
84 3
                break;
85
            }
86 4
            $name = $this->stack[$i]->getNode('filter')->getAttribute('value');
87 4
            if ('trans' === $name) {
88
                break;
89 4
            } elseif ('desc' === $name) {
90 3
                $arguments = $this->stack[$i]->getNode('arguments');
91 3
                if (!$arguments->hasNode(0)) {
92 2
                    throw new \LogicException(sprintf('The "%s" filter requires exactly one argument, the description text.', $name));
93
                }
94 3
                $text = $arguments->getNode(0);
95 3
                if (!$text instanceof ConstantExpression) {
96 2
                    throw new \LogicException(sprintf('The first argument of the "%s" filter must be a constant expression, such as a string.', $name));
97
                }
98 2
                $context['desc'] = $text->getAttribute('value');
99
            }
100
        }
101
102 3
        return $context;
103
    }
104
105 4
    private function getReadDomainFromArguments(Node $arguments, int $index): ?string
106
    {
107 4
        if ($arguments->hasNode('domain')) {
108
            $argument = $arguments->getNode('domain');
109 4
        } elseif ($arguments->hasNode($index)) {
110
            $argument = $arguments->getNode($index);
111
        } else {
112 4
            return self::UNDEFINED_DOMAIN;
113
        }
114
115
        return $this->getReadDomainFromNode($argument);
116
    }
117
118 2
    private function getReadDomainFromNode(Node $node): ?string
119
    {
120 2
        if ($node instanceof ConstantExpression) {
121 2
            return $node->getAttribute('value');
122
        }
123
124
        return self::UNDEFINED_DOMAIN;
125
    }
126
}
127