Completed
Push — master ( 89c348...e1d3d5 )
by Kristijan
32:50 queued 06:08
created

FormHelper   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 272
Duplicated Lines 0 %

Coupling/Cohesion

Components 3
Dependencies 4

Test Coverage

Coverage 98.75%

Importance

Changes 15
Bugs 2 Features 8
Metric Value
wmc 31
c 15
b 2
f 8
lcom 3
cbo 4
dl 0
loc 272
ccs 79
cts 80
cp 0.9875
rs 9.8

13 Methods

Rating   Name   Duplication   Size   Complexity  
A getConfig() 0 4 1
A getView() 0 4 1
A __construct() 0 7 1
A mergeOptions() 0 4 1
A addCustomField() 0 8 2
A convertModelToArray() 0 16 4
A formatLabel() 0 12 3
A transformToDotSyntax() 0 4 1
B getFieldType() 0 26 5
B prepareAttributes() 0 17 5
A loadCustomTypes() 0 10 3
A mergeFieldsRules() 0 17 3
A getTranslator() 0 4 1
1
<?php  namespace Kris\LaravelFormBuilder;
2
3
use Illuminate\Support\Collection;
4
use Illuminate\Translation\Translator;
5
use Illuminate\Database\Eloquent\Model;
6
use Kris\LaravelFormBuilder\Fields\FormField;
7
use Illuminate\Contracts\View\Factory as View;
8
9
class FormHelper
10
{
11
12
    /**
13
     * @var View
14
     */
15
    protected $view;
16
17
    /**
18
     * @var Translator
19
     */
20
    protected $translator;
21
22
    /**
23
     * @var array
24
     */
25
    protected $config;
26
27
    /**
28
     * @var FormBuilder
29
     */
30
    protected $formBuilder;
31
32
    /**
33
     * All available field types
34
     *
35
     * @var array
36
     */
37
    protected static $availableFieldTypes = [
38
        'text'           => 'InputType',
39
        'email'          => 'InputType',
40
        'url'            => 'InputType',
41
        'tel'            => 'InputType',
42
        'search'         => 'InputType',
43
        'password'       => 'InputType',
44
        'hidden'         => 'InputType',
45
        'number'         => 'InputType',
46
        'date'           => 'InputType',
47
        'file'           => 'InputType',
48
        'image'          => 'InputType',
49
        'color'          => 'InputType',
50
        'datetime-local' => 'InputType',
51
        'month'          => 'InputType',
52
        'range'          => 'InputType',
53
        'time'           => 'InputType',
54
        'week'           => 'InputType',
55
        'select'         => 'SelectType',
56
        'textarea'       => 'TextareaType',
57
        'button'         => 'ButtonType',
58
        'submit'         => 'ButtonType',
59
        'reset'          => 'ButtonType',
60
        'radio'          => 'CheckableType',
61
        'checkbox'       => 'CheckableType',
62
        'choice'         => 'ChoiceType',
63
        'form'           => 'ChildFormType',
64
        'entity'         => 'EntityType',
65
        'collection'     => 'CollectionType',
66
        'repeated'       => 'RepeatedType',
67
        'static'         => 'StaticType'
68
    ];
69
70
    /**
71
     * Custom types
72
     *
73
     * @var array
74
     */
75
    private $customTypes = [];
76
77
    /**
78
     * @param View    $view
79
     * @param Translator $translator
80
     * @param array   $config
81
     */
82 86
    public function __construct(View $view, Translator $translator, array $config = [])
83
    {
84 86
        $this->view = $view;
85 86
        $this->translator = $translator;
86 86
        $this->config = $config;
87 86
        $this->loadCustomTypes();
88 86
    }
89
90
    /**
91
     * @param string $key
92
     * @param string $default
93
     * @return mixed
94
     */
95 86
    public function getConfig($key, $default = null)
96
    {
97 86
        return array_get($this->config, $key, $default);
98
    }
99
100
    /**
101
     * @return View
102
     */
103 29
    public function getView()
104
    {
105 29
        return $this->view;
106
    }
107
108
    /**
109
     * Merge options array
110
     *
111
     * @param array $first
112
     * @param array $second
113
     * @return array
114
     */
115 86
    public function mergeOptions(array $first, array $second)
116
    {
117 86
        return array_replace_recursive($first, $second);
118
    }
119
120
    /**
121
     * Get proper class for field type
122
     *
123
     * @param $type
124
     * @return string
125
     */
126 57
    public function getFieldType($type)
127
    {
128 57
        $types = array_keys(static::$availableFieldTypes);
129
130 57
        if (!$type || trim($type) == '') {
131 1
            throw new \InvalidArgumentException('Field type must be provided.');
132
        }
133
134 56
        if (array_key_exists($type, $this->customTypes)) {
135 2
            return $this->customTypes[$type];
136
        }
137
138 54
        if (!in_array($type, $types)) {
139 2
            throw new \InvalidArgumentException(
140 2
                sprintf(
141 2
                    'Unsupported field type [%s]. Available types are: %s',
142 2
                    $type,
143 2
                    join(', ', array_merge($types, array_keys($this->customTypes)))
144 2
                )
145 2
            );
146
        }
147
148 52
        $namespace = __NAMESPACE__.'\\Fields\\';
149
150 52
        return $namespace . static::$availableFieldTypes[$type];
151
    }
152
153
    /**
154
     * Convert array of attributes to html attributes
155
     *
156
     * @param $options
157
     * @return string
158
     */
159 68
    public function prepareAttributes($options)
160
    {
161 68
        if (!$options) {
162 4
            return null;
163
        }
164
165 68
        $attributes = [];
166
167 68
        foreach ($options as $name => $option) {
168 68
            if ($option !== null) {
169 68
                $name = is_numeric($name) ? $option : $name;
170 68
                $attributes[] = $name.'="'.$option.'" ';
171 68
            }
172 68
        }
173
174 68
        return join('', $attributes);
175
    }
176
177
    /**
178
     * Add custom field
179
     *
180
     * @param $name
181
     * @param $class
182
     */
183 3
    public function addCustomField($name, $class)
184
    {
185 3
        if (!array_key_exists($name, $this->customTypes)) {
186 3
            return $this->customTypes[$name] = $class;
187
        }
188
189 1
        throw new \InvalidArgumentException('Custom field ['.$name.'] already exists on this form object.');
190
    }
191
192
    /**
193
     * Load custom field types from config file
194
     */
195 86
    private function loadCustomTypes()
196
    {
197 86
        $customFields = (array) $this->getConfig('custom_fields');
198
199 86
        if (!empty($customFields)) {
200 1
            foreach ($customFields as $fieldName => $fieldClass) {
201 1
                $this->addCustomField($fieldName, $fieldClass);
202 1
            }
203 1
        }
204 86
    }
205
206 5
    public function convertModelToArray($model)
207
    {
208 5
        if (!$model) {
209 1
            return null;
210
        }
211
212 5
        if ($model instanceof Model) {
213 1
            return $model->toArray();
214
        }
215
216 5
        if ($model instanceof Collection) {
217 2
            return $model->all();
218
        }
219
220 5
        return $model;
221
    }
222
223
    /**
224
     * Format the label to the proper format
225
     *
226
     * @param $name
227
     * @return string
228
     */
229 68
    public function formatLabel($name)
230
    {
231 68
        if (!$name) {
232 1
            return null;
233
        }
234
235 68
        if ($this->translator->has($name)) {
236
            return $this->translator->get($name);
237
        }
238
239 68
        return ucfirst(str_replace('_', ' ', $name));
240
    }
241
242
    /**
243
     * @param FormField[] $fields
244
     * @return array
245
     */
246 3
    public function mergeFieldsRules($fields)
247
    {
248 3
        $rules = [];
249 3
        $attributes = [];
250
251 3
        foreach ($fields as $field) {
252 3
            if ($fieldRules = $field->getValidationRules()) {
253 3
                $rules = array_merge($rules, $fieldRules['rules']);
254 3
                $attributes = array_merge($attributes, $fieldRules['attributes']);
255 3
            }
256 3
        }
257
258
        return [
259 3
            'rules' => $rules,
260
            'attributes' => $attributes
261 3
        ];
262
    }
263
264
    /**
265
     * @param string $string
266
     * @return string
267
     */
268 67
    public function transformToDotSyntax($string)
269
    {
270 67
        return str_replace(['.', '[]', '[', ']'], ['_', '', '.', ''], $string);
271
    }
272
273
    /**
274
     * @return Translator
275
     */
276 3
    public function getTranslator()
277
    {
278 3
        return $this->translator;
279
    }
280
}
281