Completed
Push — master ( 559ead...29bb5d )
by Maximilian
9s
created

formatTranslatableViolationList()   C

Complexity

Conditions 12
Paths 2

Size

Total Lines 121
Code Lines 65

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 121
rs 5.034
cc 12
eloc 65
nc 2
nop 5

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * This file is part of the Sententiaregum project.
5
 *
6
 * (c) Maximilian Bosch <[email protected]>
7
 * (c) Ben Bieler <[email protected]>
8
 *
9
 * For the full copyright and license information, please view the LICENSE
10
 * file that was distributed with this source code.
11
 */
12
13
namespace AppBundle\View;
14
15
use Symfony\Component\Translation\TranslatorInterface;
16
use Symfony\Component\Validator\ConstraintViolation;
17
use Symfony\Component\Validator\ConstraintViolationListInterface;
18
19
/**
20
 * Concrete implementation of a formatter which transforms constraint violations into i18n
21
 * format that can be used in the HTTP response.
22
 *
23
 * It converts a violation list to the following format:
24
 *
25
 * [
26
 *   'de' => ['German translation'],
27
 *   'en' => ['English translation'],
28
 * ]
29
 *
30
 * Furthermore it is possible to sort all the violations by the property which caused the violation:
31
 *
32
 * [
33
 *   'property' => [
34
 *     [
35
 *       'de' => ['German translation'],
36
 *       'en' => ['English translation'],
37
 *     ]
38
 *   ],
39
 *   'another_property' => [
40
 *     [
41
 *       // ...
42
 *     ]
43
 *   ]
44
 * ]
45
 *
46
 * @author Maximilian Bosch <[email protected]>
47
 */
48
class I18nResponseFormatBuilder implements I18nResponseFormatBuilderInterface
49
{
50
    /**
51
     * @var TranslatorInterface
52
     */
53
    private $translator;
54
55
    /**
56
     * Constructor.
57
     *
58
     * @param TranslatorInterface $translator
59
     */
60
    public function __construct(TranslatorInterface $translator)
61
    {
62
        $this->translator = $translator;
63
    }
64
65
    /**
66
     * {@inheritdoc}
67
     */
68
    public function formatTranslatableViolationList(
69
        ConstraintViolationListInterface $violations,
70
        $sortProperties = true,
71
        $useAllLanguages = true,
72
        array $targetLocales = [],
73
        $domain = 'messages'
74
    ) {
75
        $violationList = iterator_to_array($violations, false);
76
        $hasLocales    = count($targetLocales) > 0;
77
78
        if (!$useAllLanguages && $hasLocales || $useAllLanguages && !$hasLocales) {
79
            throw new \InvalidArgumentException(
80
                'Wrong usage of $targetLocales: If all languages should be rendered, $targetLocales should be set, if not, $targetLocales should be an empty array!'
81
            );
82
        }
83
84
        $fixtures = [];
85
        array_walk(
86
            $violationList,
87
            function (ConstraintViolation $violation) use (
88
                $targetLocales,
89
                $domain,
90
                $useAllLanguages,
91
                $sortProperties,
92
                &$fixtures
93
            ) {
94
                // Every translation entry (whether sorted by properties in deeper levels or as top level)
95
                // should provide a basic structure.
96
                switch (true) {
97
                    // If sorted by $targetLanguages, it may look like this:
98
                    //
99
                    // [
100
                    //   'de' => ['Deutscher Text'],
101
                    //   'en' => ['English text'],
102
                    // ]
103
                    //
104
                    // When sorting by property, the structure will be merged recursively into the property list:
105
                    //
106
                    // [
107
                    //   'property' => [
108
                    //     // this is the structure merged into the property.
109
                    //     'de' => ['Deutscher Text'],
110
                    //     'en' => ['English text'],
111
                    //   ]
112
                    // ]
113
                    case $useAllLanguages:
114
                        $structure = array_reduce(
115
                            $targetLocales,
116
                            function ($carry, $locale) use ($violation, $domain) {
117
                                if (!isset($carry[$locale])) {
118
                                    $carry[$locale] = [];
119
                                }
120
121
                                if ($locale === $this->translator->getLocale()) {
122
                                    $carry[$locale][] = $violation->getMessage();
123
                                } else {
124
                                    $messageTemplate = $violation->getMessageTemplate();
125
                                    $parameters      = $violation->getParameters();
126
127
                                    if ($plural = $violation->getPlural()) {
128
                                        try {
129
                                            $message = $this->translator->transChoice(
130
                                                $messageTemplate,
131
                                                $plural,
132
                                                $parameters,
133
                                                $domain,
134
                                                $locale
135
                                            );
136
                                        } catch (\InvalidArgumentException $ex) {
137
                                            // we do nothing here.
138
                                            // If the pluralization fails, the default translation method will be used.
139
140
                                            $message = $this->translator->trans(
141
                                                $messageTemplate,
142
                                                $parameters,
143
                                                $domain,
144
                                                $locale
145
                                            );
146
                                        }
147
                                    } else {
148
                                        $message = $this->translator->trans(
149
                                            $messageTemplate,
150
                                            $parameters,
151
                                            $domain,
152
                                            $locale
153
                                        );
154
                                    }
155
156
                                    $carry[$locale][] = $message;
157
                                }
158
159
                                return $carry;
160
                            },
161
                            []
162
                        );
163
                        break;
164
                    default:
165
                        // If the default language is in use and nothing more, the structure looks like this:
166
                        //
167
                        // ['Message in the currently selected language']
168
                        $structure = [$violation->getMessage()];
169
                }
170
171
                if (!$sortProperties) {
172
                    $fixtures = array_merge_recursive($fixtures, $structure);
173
174
                    return;
175
                }
176
177
                $propertyPath = $violation->getPropertyPath();
178
                if (!isset($fixtures[$violation->getPropertyPath()])) {
179
                    $fixtures[$violation->getPropertyPath()] = [];
180
                }
181
182
                $fixtures[$propertyPath] = array_merge_recursive($fixtures[$propertyPath], $structure);
183
            },
184
            []
185
        );
186
187
        return $fixtures;
188
    }
189
}
190