AbstractNode   A
last analyzed

Complexity

Total Complexity 25

Size/Duplication

Total Lines 226
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
wmc 25
lcom 1
cbo 6
dl 0
loc 226
rs 10
c 0
b 0
f 0

20 Methods

Rating   Name   Duplication   Size   Complexity  
A getLabel() 0 4 1
A getOption() 0 4 1
A hasPropertyPath() 0 4 1
A getPropertyPath() 0 10 3
A getTransformer() 0 8 2
A hasTransformer() 0 4 1
A getName() 0 4 1
A getDefaultValue() 0 8 2
A hasOption() 0 4 1
A getError() 0 4 1
A setError() 0 4 1
A getOptions() 0 4 1
A setOptions() 0 6 1
A configureOptions() 0 20 1
A getElementType() 0 9 2
A getElementClass() 0 4 1
A prepareAttributesCollection() 0 7 1
A getJavascriptNodeName() 0 7 1
A prepareRepetitions() 0 7 1
A getPropertyAccessor() 0 4 1
1
<?php
2
/*
3
 * WellCommerce Open-Source E-Commerce Platform
4
 *
5
 * This file is part of the WellCommerce package.
6
 *
7
 * (c) Adam Piotrowski <[email protected]>
8
 *
9
 * For the full copyright and license information,
10
 * please view the LICENSE file that was distributed with this source code.
11
 */
12
13
namespace WellCommerce\Component\Form\Elements;
14
15
use Doctrine\Common\Util\ClassUtils;
16
use Symfony\Component\OptionsResolver\OptionsResolver;
17
use Symfony\Component\PropertyAccess\PropertyAccess;
18
use Symfony\Component\PropertyAccess\PropertyPath;
19
use WellCommerce\Component\Form\Exception\TransformerNotFoundException;
20
21
/**
22
 * Class AbstractNode
23
 *
24
 * @author Adam Piotrowski <[email protected]>
25
 */
26
abstract class AbstractNode implements ElementInterface
27
{
28
    /**
29
     * @var array
30
     */
31
    protected $options;
32
33
    /**
34
     * @var mixed
35
     */
36
    protected $error;
37
38
    /**
39
     * {@inheritdoc}
40
     */
41
    public function getLabel()
42
    {
43
        return $this->getOption('label');
44
    }
45
46
    /**
47
     * {@inheritdoc}
48
     */
49
    public function getOption($option)
50
    {
51
        return $this->options[$option];
52
    }
53
54
    /**
55
     * Checks whether element has property_path option
56
     *
57
     * @return bool
58
     */
59
    public function hasPropertyPath()
60
    {
61
        return isset($this->options['property_path']);
62
    }
63
64
    /**
65
     * {@inheritdoc}
66
     */
67
    public function getPropertyPath($indexNotation = false)
68
    {
69
        $path = $this->getOption('property_path');
70
71
        if (null !== $path && $indexNotation) {
72
            return sprintf('[%s]', $path);
73
        }
74
75
        return $path;
76
    }
77
78
    /**
79
     * {@inheritdoc}
80
     */
81
    public function getTransformer()
82
    {
83
        if (!$this->hasTransformer()) {
84
            throw new TransformerNotFoundException($this->getName(), get_class($this));
85
        }
86
87
        return $this->getOption('transformer');
88
    }
89
90
    /**
91
     * {@inheritdoc}
92
     */
93
    public function hasTransformer()
94
    {
95
        return isset($this->options['transformer']);
96
    }
97
98
    /**
99
     * {@inheritdoc}
100
     */
101
    public function getName()
102
    {
103
        return $this->getOption('name');
104
    }
105
106
    /**
107
     * {@inheritdoc}
108
     */
109
    public function getDefaultValue()
110
    {
111
        if ($this->hasOption('default')) {
112
            return $this->getOption('default');
113
        }
114
115
        return null;
116
    }
117
118
    /**
119
     * {@inheritdoc}
120
     */
121
    public function hasOption($option)
122
    {
123
        return isset($this->options[$option]);
124
    }
125
126
    public function getError()
127
    {
128
        return $this->error;
129
    }
130
131
    public function setError($error)
132
    {
133
        $this->error = $error;
134
    }
135
136
    /**
137
     * {@inheritdoc}
138
     */
139
    public function getOptions()
140
    {
141
        return $this->options;
142
    }
143
144
    /**
145
     * {@inheritdoc}
146
     */
147
    public function setOptions(array $options = [])
148
    {
149
        $optionsResolver = new OptionsResolver();
150
        $this->configureOptions($optionsResolver);
151
        $this->options = $optionsResolver->resolve($options);
152
    }
153
154
    /**
155
     * {@inheritdoc}
156
     */
157
    public function configureOptions(OptionsResolver $resolver)
158
    {
159
        $resolver->setRequired([
160
            'name',
161
            'label',
162
            'property_path',
163
            'type'
164
        ]);
165
166
        $resolver->setDefaults([
167
            'class'         => '',
168
            'property_path' => null,
169
            'type'          => $this->getElementType()
170
        ]);
171
172
        $resolver->setAllowedTypes('name', 'string');
173
        $resolver->setAllowedTypes('label', 'string');
174
        $resolver->setAllowedTypes('property_path', ['null', PropertyPath::class]);
175
        $resolver->setAllowedTypes('type', 'string');
176
    }
177
178
    /**
179
     * Returns friendly element type used for example in Twig macros
180
     *
181
     * @return mixed|string
182
     */
183
    protected function getElementType()
184
    {
185
        $class   = $this->getElementClass($this);
186
        $parts   = explode('\\', $class);
187
        $type    = end($parts);
188
        $replace = '$1_$2';
189
190
        return ctype_lower($type) ? $type : strtolower(preg_replace('/(.)([A-Z])/', $replace, $type));
191
    }
192
193
    /**
194
     * Returns FQCN for element
195
     *
196
     * @param ElementInterface $element
197
     *
198
     * @return string
199
     */
200
    protected function getElementClass(ElementInterface $element)
201
    {
202
        return ltrim(ClassUtils::getClass($element), '\\');
203
    }
204
205
    /**
206
     * {@inheritdoc}
207
     */
208
    public function prepareAttributesCollection(AttributeCollection $collection)
209
    {
210
        $collection->add(new Attribute('sName', $this->getName()));
211
        $collection->add(new Attribute('sLabel', $this->getOption('label')));
212
        $collection->add(new Attribute('sClass', $this->getOption('class')));
213
        $collection->add(new Attribute('fType', $this->getJavascriptNodeName($this), Attribute::TYPE_FUNCTION));
214
    }
215
216
    /**
217
     * Returns element javascript-friendly name
218
     *
219
     * @param ElementInterface $element
220
     *
221
     * @return string
222
     */
223
    protected function getJavascriptNodeName(ElementInterface $element)
224
    {
225
        $class = $this->getElementClass($element);
226
        $parts = explode('\\', $class);
227
228
        return 'GForm' . end($parts);
229
    }
230
231
    /**
232
     * Prepares repetition options for element
233
     *
234
     * @return array
235
     */
236
    protected function prepareRepetitions()
237
    {
238
        return [
239
            'iMin' => $this->options['repeat_min'],
240
            'iMax' => $this->options['repeat_max'],
241
        ];
242
    }
243
244
    /**
245
     * @return \Symfony\Component\PropertyAccess\PropertyAccessor
246
     */
247
    protected function getPropertyAccessor()
248
    {
249
        return PropertyAccess::createPropertyAccessor();
250
    }
251
}
252