Completed
Push — middleware-wip ( 5cfd03...f2f782 )
by Romain
05:53
created

FormzLocalizationJavaScriptAssetHandler::storeTranslationsForFieldValidator()   B

Complexity

Conditions 4
Paths 2

Size

Total Lines 26
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 26
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 15
nc 2
nop 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 FormzLocalizationJavaScriptAssetHandler 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
                $validatorName = $validator->getName();
130
                $messages = ValidatorService::get()->getValidatorMessages($validator->getClassName(), $validator->getMessages());
131
132
                foreach ($messages as $key => $message) {
133
                    $message = MessageService::get()->parseMessageArray($message, ['{0}', '{1}', '{2}', '{3}', '{4}', '{5}', '{6}', '{7}', '{8}', '{9}', '{10}']);
134
135
                    $localizationKey = $this->getIdentifierForFieldValidator($field, $validator, $key);
136
                    $this->addTranslation($localizationKey, $message);
137
                    $messages[$key] = $localizationKey;
138
                }
139
140
                $this->translationKeysForFieldValidator[$fieldName . '-' . $validatorName] = $messages;
141
142
                $key = $this->getFormObject()->getClassName() . '-' . $field->getName();
143
                $this->injectedTranslationKeysForFieldValidator[$key] = true;
144
            }
145
        }
146
147
        return $this;
148
    }
149
150
    /**
151
     * Adds a global translation value which will be added to the FormZ
152
     * JavaScript localization service.
153
     *
154
     * @param string $key
155
     * @param string $value
156
     */
157
    protected function addTranslation($key, $value)
158
    {
159
        $this->translations[(string)$key] = (string)$value;
160
    }
161
162
    /**
163
     * Checks if the given field validator were already handled by this
164
     * asset handler.
165
     *
166
     * @param Field $field
167
     * @return bool
168
     */
169
    protected function translationsForFieldValidatorWereInjected(Field $field)
170
    {
171
        $key = $this->getFormObject()->getClassName() . '-' . $field->getName();
172
173
        return true === isset($this->injectedTranslationKeysForFieldValidator[$key]);
174
    }
175
176
    /**
177
     * @param Field     $field
178
     * @param Validator $validator
179
     * @param string    $messageKey
180
     * @return string
181
     */
182
    protected function getIdentifierForFieldValidator(Field $field, Validator $validator, $messageKey)
183
    {
184
        return str_replace(['\\', '_'], '', $this->getFormObject()->getClassName()) . '-' . $field->getName() . '-' . $validator->getName() . '-' . $messageKey;
185
    }
186
187
    /**
188
     * This function is here to help unit tests mocking.
189
     *
190
     * @param string $realTranslations
191
     * @return string
192
     */
193
    protected function handleRealTranslations($realTranslations)
194
    {
195
        return $realTranslations;
196
    }
197
198
    /**
199
     * This function is here to help unit tests mocking.
200
     *
201
     * @param string $translationsBinding
202
     * @return string
203
     */
204
    protected function handleTranslationsBinding($translationsBinding)
205
    {
206
        return $translationsBinding;
207
    }
208
}
209