Completed
Pull Request — master (#18)
by
unknown
02:41
created

DataAttributesAssetHandler::isPropertyGettable()   B

Complexity

Conditions 5
Paths 12

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 10
nc 12
nop 2
1
<?php
2
/*
3
 * 2016 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\Html;
15
16
use Romm\Formz\AssetHandler\AbstractAssetHandler;
17
use Romm\Formz\Error\FormResult;
18
use Romm\Formz\Form\FormInterface;
19
use TYPO3\CMS\Core\Utility\GeneralUtility;
20
use TYPO3\CMS\Extbase\Error\Error;
21
use TYPO3\CMS\Extbase\Error\Result;
22
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
23
24
/**
25
 * This asset handler generates several data attributes which will be added to
26
 * the form element in the Fluid template. Most of these data attributes are
27
 * directly bound to fields and their properties.
28
 *
29
 * Example of data attributes:
30
 *  - Fields values: when a field changes, its new value will be indicated in
31
 *    the form with the attribute: `formz-value-{field name}="value"`.
32
 *  - Fields validation: when a field is considered as valid (it passed all its
33
 *    validation rules), the form gets the attribute: `formz-valid-{field name}`.
34
 *  - Fields errors: when a field validation fails with an error, the form gets
35
 *    the attribute: `formz-error-{field name}-{name of the error}`.
36
 */
37
class DataAttributesAssetHandler extends AbstractAssetHandler
38
{
39
40
    /**
41
     * Handles the data attributes containing the values of the form fields.
42
     *
43
     * Example: `formz-value-color="blue"`
44
     *
45
     * @param FormInterface|array $formInstance
46
     * @param FormResult          $requestResult
47
     * @return array
48
     */
49
    public function getFieldsValuesDataAttributes($formInstance, FormResult $requestResult)
50
    {
51
        $result = [];
52
53
        foreach ($this->getFormObject()->getProperties() as $fieldName) {
54
            if (false === $requestResult->fieldIsDeactivated($fieldName)
55
                && $this->isPropertyGettable($formInstance, $fieldName)
56
            ) {
57
                $value = ObjectAccess::getProperty($formInstance, $fieldName);
58
                $value = (is_array($value))
59
                    ? implode(' ', $value)
60
                    : $value;
61
62
                $result[self::getFieldDataValueKey($fieldName)] = $value;
63
            }
64
        }
65
66
        return $result;
67
    }
68
69
    /**
70
     * Checks if the given field name can be accessed within the form instance,
71
     * whether it is an object or an array.
72
     *
73
     * @param FormInterface|array $formInstance
74
     * @param string              $fieldName
75
     * @return bool
76
     */
77
    protected function isPropertyGettable($formInstance, $fieldName)
78
    {
79
        $objectPropertyIsGettable = (
80
            is_object($formInstance)
81
            && (
82
                in_array($fieldName, get_object_vars($formInstance))
83
                || ObjectAccess::isPropertyGettable($formInstance, $fieldName)
84
            )
85
        );
86
87
        $arrayPropertyGettable = (
88
            is_array($formInstance)
89
            && true === isset($formInstance[$fieldName])
90
        );
91
92
        return ($objectPropertyIsGettable || $arrayPropertyGettable);
93
    }
94
95
    /**
96
     * Handles the data attributes for the fields which got errors.
97
     *
98
     * Examples:
99
     * - `formz-error-email="1"`
100
     * - `formz-error-email-rule-default="1"`
101
     *
102
     * @param FormResult $requestResult
103
     * @return array
104
     */
105
    public function getFieldsErrorsDataAttributes(FormResult $requestResult)
106
    {
107
        $result = [];
108
109
        /** @var Result $fieldResult */
110
        foreach ($requestResult->getSubResults() as $fieldName => $fieldResult) {
111
            if (false === $requestResult->fieldIsDeactivated($fieldName)
112
                && true === $this->getFormConfiguration()->hasField($fieldName)
113
                && true === $fieldResult->hasErrors()
114
                && false === $requestResult->fieldIsDeactivated($fieldName)
115
            ) {
116
                $result[self::getFieldDataErrorKey($fieldName)] = '1';
117
118
                foreach ($fieldResult->getErrors() as $error) {
119
                    /** @var Error $error */
120
                    $errorTitle = ($error->getTitle())
121
                        ? $error->getTitle()
122
                        : 'default';
123
                    $result[self::getFieldDataValidationErrorKey($fieldName, $errorTitle)] = '1';
124
                }
125
            }
126
        }
127
128
        return $result;
129
    }
130
131
    /**
132
     * Handles the data attributes for the fields which are valid.
133
     *
134
     * Example: `formz-valid-email="1"`
135
     *
136
     * @param FormResult $requestResult
137
     * @return array
138
     */
139
    public function getFieldsValidDataAttributes(FormResult $requestResult)
140
    {
141
        $result = [];
142
143
        foreach ($this->getFormConfiguration()->getFields() as $field) {
144
            $fieldName = $field->getFieldName();
145
146
            if (false === $requestResult->fieldIsDeactivated($fieldName)
147
                && false === $requestResult->forProperty($fieldName)->hasErrors()
148
                && false === $requestResult->fieldIsDeactivated($fieldName)
149
            ) {
150
                $result[self::getFieldDataValidKey($fieldName)] = '1';
151
            }
152
        }
153
154
        return $result;
155
    }
156
157
    /**
158
     * Formats the data value attribute key for a given field name.
159
     *
160
     * @param string $fieldName Name of the field.
161
     * @return string
162
     */
163
    public static function getFieldDataValueKey($fieldName)
164
    {
165
        return 'formz-value-' . self::getFieldCleanName($fieldName);
166
    }
167
168
    /**
169
     * Formats the data valid attribute key for a given field name.
170
     *
171
     * @param string $fieldName Name of the field.
172
     * @return string
173
     */
174
    public static function getFieldDataValidKey($fieldName)
175
    {
176
        return 'formz-valid-' . self::getFieldCleanName($fieldName);
177
    }
178
179
    /**
180
     * Formats the data error attribute key for a given field name.
181
     *
182
     * @param string $fieldName Name of the field.
183
     * @return string
184
     */
185
    public static function getFieldDataErrorKey($fieldName)
186
    {
187
        return 'formz-error-' . self::getFieldCleanName($fieldName);
188
    }
189
190
    /**
191
     * Formats the data error attribute key for a given failed validation for
192
     * the given field name.
193
     *
194
     * @param string $fieldName  Name of the field.
195
     * @param string $errorTitle Title of the error.
196
     * @return string
197
     */
198
    public static function getFieldDataValidationErrorKey($fieldName, $errorTitle)
199
    {
200
        return 'formz-error-' . self::getFieldCleanName($fieldName) . '-' . self::getFieldCleanName(str_replace(':', '-', $errorTitle));
201
    }
202
203
    /**
204
     * Replaces underscores with a dash.
205
     *
206
     * @param string $fieldName
207
     * @return string
208
     */
209
    public static function getFieldCleanName($fieldName)
210
    {
211
        return str_replace('_', '-', GeneralUtility::camelCaseToLowerCaseUnderscored($fieldName));
212
    }
213
}
214