Completed
Push — feature/improve-form-definitio... ( 0cba0f...350a13 )
by Romain
02:18
created

LocalizationJavaScriptAssetHandler   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 178
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 9
dl 0
loc 178
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getJavaScriptCode() 0 18 2
A getTranslationKeysForFieldValidator() 0 8 1
A injectTranslationsForFormFieldsValidator() 0 10 2
B storeTranslationsForFieldValidator() 0 25 4
A addTranslation() 0 4 1
A translationsForFieldValidatorWereInjected() 0 6 1
A getIdentifierForFieldValidator() 0 4 1
A handleRealTranslations() 0 4 1
A handleTranslationsBinding() 0 4 1
1
<?php
2
/*
3
 * 2017 Romain CANON <[email protected]>
4
 *
5
 * This file is part of the TYPO3 FormZ project.
6
 * It is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License, either
8
 * version 3 of the License, or any later version.
9
 *
10
 * For the full copyright and license information, see:
11
 * http://www.gnu.org/licenses/gpl-3.0.html
12
 */
13
14
namespace Romm\Formz\AssetHandler\JavaScript;
15
16
use Romm\Formz\AssetHandler\AbstractAssetHandler;
17
use Romm\Formz\Form\Definition\Field\Field;
18
use Romm\Formz\Form\Definition\Field\Validation\Validator;
19
use Romm\Formz\Service\ArrayService;
20
use Romm\Formz\Service\HashService;
21
use Romm\Formz\Service\MessageService;
22
use Romm\Formz\Service\ValidatorService;
23
24
/**
25
 * This asset handler will manage the translations which will be sent to FormZ
26
 * in JavaScript (`Formz.Localization`).
27
 *
28
 * The validator messages of the fields are handled in this class.
29
 */
30
class LocalizationJavaScriptAssetHandler extends AbstractAssetHandler
31
{
32
33
    /**
34
     * Contains the full list of keys/translations.
35
     *
36
     * @var array
37
     */
38
    protected $translations = [];
39
40
    /**
41
     * Contains the list of keys which are bound to translations, for a field
42
     * validator. The value is an array of keys, because a validator may have
43
     * several messages.
44
     *
45
     * @var array
46
     */
47
    protected $translationKeysForFieldValidator = [];
48
49
    /**
50
     * Contains the list of fields validators which were already processed by
51
     * this asset handler.
52
     *
53
     * @var array
54
     */
55
    protected $injectedTranslationKeysForFieldValidator = [];
56
57
    /**
58
     * Will generate and return the JavaScript code which add all registered
59
     * translations to the JavaScript library.
60
     *
61
     * @return string
62
     */
63
    public function getJavaScriptCode()
64
    {
65
        $realTranslations = [];
66
        $translationsBinding = [];
67
68
        foreach ($this->translations as $key => $value) {
69
            $hash = HashService::get()->getHash($value);
70
            $realTranslations[$hash] = $value;
71
            $translationsBinding[$key] = $hash;
72
        }
73
74
        $jsonRealTranslations = $this->handleRealTranslations(ArrayService::get()->arrayToJavaScriptJson($realTranslations));
75
        $jsonTranslationsBinding = $this->handleTranslationsBinding(ArrayService::get()->arrayToJavaScriptJson($translationsBinding));
76
77
        return <<<JS
78
Fz.Localization.addLocalization($jsonRealTranslations, $jsonTranslationsBinding);
79
JS;
80
    }
81
82
    /**
83
     * Returns the keys which are bound to translations, for a given field
84
     * validator.
85
     *
86
     * @param Field     $field
87
     * @param Validator $validator
88
     * @return array
89
     */
90
    public function getTranslationKeysForFieldValidator(Field $field, Validator $validator)
91
    {
92
        $key = $field->getName() . '-' . $validator->getName();
93
94
        $this->storeTranslationsForFieldValidator($field);
95
96
        return $this->translationKeysForFieldValidator[$key];
97
    }
98
99
    /**
100
     * Will loop on each field of the given form, and get every translations for
101
     * the validator rules messages.
102
     *
103
     * @return $this
104
     */
105
    public function injectTranslationsForFormFieldsValidator()
106
    {
107
        $formConfiguration = $this->getFormObject()->getDefinition();
108
109
        foreach ($formConfiguration->getFields() as $field) {
110
            $this->storeTranslationsForFieldValidator($field);
111
        }
112
113
        return $this;
114
    }
115
116
    /**
117
     * Will loop on each validator rule of the given field, and get the
118
     * translations of the rule messages.
119
     *
120
     * @param Field $field
121
     * @return $this
122
     */
123
    protected function storeTranslationsForFieldValidator(Field $field)
124
    {
125
        if (false === $this->translationsForFieldValidatorWereInjected($field)) {
126
            $fieldName = $field->getName();
127
128
            foreach ($field->getValidators() as $validator) {
129
                $messages = ValidatorService::get()->getValidatorMessages($validator);
130
131
                foreach ($messages as $key => $message) {
132
                    $message = MessageService::get()->parseMessageArray($message, ['{0}', '{1}', '{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}', '{10}']);
133
134
                    $localizationKey = $this->getIdentifierForFieldValidator($field, $validator, $key);
135
                    $this->addTranslation($localizationKey, $message);
136
                    $messages[$key] = $localizationKey;
137
                }
138
139
                $this->translationKeysForFieldValidator[$fieldName . '-' . $validator->getName()] = $messages;
140
141
                $key = $this->getFormObject()->getClassName() . '-' . $field->getName();
142
                $this->injectedTranslationKeysForFieldValidator[$key] = true;
143
            }
144
        }
145
146
        return $this;
147
    }
148
149
    /**
150
     * Adds a global translation value which will be added to the FormZ
151
     * JavaScript localization service.
152
     *
153
     * @param string $key
154
     * @param string $value
155
     */
156
    protected function addTranslation($key, $value)
157
    {
158
        $this->translations[(string)$key] = (string)$value;
159
    }
160
161
    /**
162
     * Checks if the given field validator were already handled by this
163
     * asset handler.
164
     *
165
     * @param Field $field
166
     * @return bool
167
     */
168
    protected function translationsForFieldValidatorWereInjected(Field $field)
169
    {
170
        $key = $this->getFormObject()->getClassName() . '-' . $field->getName();
171
172
        return true === isset($this->injectedTranslationKeysForFieldValidator[$key]);
173
    }
174
175
    /**
176
     * @param Field     $field
177
     * @param Validator $validator
178
     * @param string    $messageKey
179
     * @return string
180
     */
181
    protected function getIdentifierForFieldValidator(Field $field, Validator $validator, $messageKey)
182
    {
183
        return str_replace(['\\', '_'], '', $this->getFormObject()->getClassName()) . '-' . $field->getName() . '-' . $validator->getName() . '-' . $messageKey;
184
    }
185
186
    /**
187
     * This function is here to help unit tests mocking.
188
     *
189
     * @param string $realTranslations
190
     * @return string
191
     */
192
    protected function handleRealTranslations($realTranslations)
193
    {
194
        return $realTranslations;
195
    }
196
197
    /**
198
     * This function is here to help unit tests mocking.
199
     *
200
     * @param string $translationsBinding
201
     * @return string
202
     */
203
    protected function handleTranslationsBinding($translationsBinding)
204
    {
205
        return $translationsBinding;
206
    }
207
}
208