Completed
Push — master ( 82fc51...fcdb0d )
by Tobias
03:20
created

Worker::getReadDomainFromArguments()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3.7085

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 4
cts 7
cp 0.5714
rs 9.8666
c 0
b 0
f 0
cc 3
nc 3
nop 2
crap 3.7085
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
    /**
80
     * @return array
81
     */
82 4
    private function extractContextFromJoinedFilters()
83
    {
84 4
        $context = [];
85 4
        for ($i = count($this->stack) - 2; $i >= 0; $i -= 1) {
86 4
            if (!$this->stack[$i] instanceof FilterExpression) {
87 3
                break;
88
            }
89 4
            $name = $this->stack[$i]->getNode('filter')->getAttribute('value');
90 4
            if ('trans' === $name) {
91
                break;
92 4
            } elseif ('desc' === $name) {
93 3
                $arguments = $this->stack[$i]->getNode('arguments');
94 3
                if (!$arguments->hasNode(0)) {
95 2
                    throw new \LogicException(sprintf('The "%s" filter requires exactly one argument, the description text.', $name));
96
                }
97 3
                $text = $arguments->getNode(0);
98 3
                if (!$text instanceof ConstantExpression) {
99 2
                    throw new \LogicException(sprintf('The first argument of the "%s" filter must be a constant expression, such as a string.', $name));
100
                }
101 2
                $context['desc'] = $text->getAttribute('value');
102
            }
103
        }
104
105 3
        return $context;
106
    }
107
108 4
    private function getReadDomainFromArguments(Node $arguments, int $index): ?string
109
    {
110 4
        if ($arguments->hasNode('domain')) {
111
            $argument = $arguments->getNode('domain');
112 4
        } elseif ($arguments->hasNode($index)) {
113
            $argument = $arguments->getNode($index);
114
        } else {
115 4
            return self::UNDEFINED_DOMAIN;
116
        }
117
118
        return $this->getReadDomainFromNode($argument);
119
    }
120
121 2
    private function getReadDomainFromNode(Node $node): ?string
122
    {
123 2
        if ($node instanceof ConstantExpression) {
124 2
            return $node->getAttribute('value');
125
        }
126
127
        return self::UNDEFINED_DOMAIN;
128
    }
129
}
130