Completed
Push — develop ( 3fec75...18e071 )
by
unknown
07:26
created

FieldsetCustomizationOptions::getFieldOptions()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
rs 9.3142
c 0
b 0
f 0
cc 3
eloc 12
nc 3
nop 1
1
<?php
2
/**
3
 * YAWIK
4
 *
5
 * @filesource
6
 * @license MIT
7
 * @copyright  2013 - 2017 Cross Solution <http://cross-solution.de>
8
 */
9
  
10
/** */
11
namespace Core\Options;
12
13
use Zend\Stdlib\AbstractOptions;
14
15
/**
16
 * Options for fieldset customizations.
17
 *
18
 * Holds options for each element of the fieldset in {@link fields}.
19
 * This will then be merged into the element spec provided by the fieldset class.
20
 *
21
 * <pre>
22
 * $fields = [
23
 *      <fieldname> => [
24
 *          'enabled'      => BOOL,     // if FALSE, the element WILL NOT BE ADDED.
25
 *          'required'     => BOOL,     // Sets the attribute "required", and additionally
26
 *                                         hints to the input filter, that the field is required.
27
 *          'label'        => STRING,   // override ['options']['label']
28
 *          'priority'     => INT,      // override ['flags']['priority']
29
 *          'order'        => INT       // alias for 'priority',
30
 *
31
 *          'options'      => ARRAY     // will get merged to the 'options' key in the element spec.
32
 *          'attributes'   => ARRAY     // merged to the 'attributes' key in the element spec.
33
 *          'flags'        => ARRAY     // merged into the flags array provided in the method "add"
34
 *                                         of the fieldset.
35
 *          'input_filter' => ARRAY,    // merged into the input filter spec of the fieldset.
36
 * ];
37
 * </pre>
38
 *
39
 * 
40
 * @author Mathias Gelhausen <[email protected]>
41
 * @todo since 0.29
42
 */
43
class FieldsetCustomizationOptions extends AbstractOptions
44
{
45
46
    /**
47
     * Field specifications.
48
     *
49
     * @var array
50
     */
51
    protected $fields = [];
52
53
    /**
54
     * Set the fields options.
55
     *
56
     * @param array $fields
57
     *
58
     * @return self
59
     */
60
    public function setFields(array $fields)
61
    {
62
        $this->fields = $fields;
63
64
        return $this;
65
    }
66
67
    /**
68
     * Get the field options.
69
     *
70
     * @return array
71
     */
72
    public function getFields()
73
    {
74
        return $this->fields;
75
    }
76
77
    /**
78
     * Get the names of all customized fields.
79
     *
80
     * @return array
81
     */
82
    public function getFieldNames()
83
    {
84
        return array_keys($this->getFields());
85
    }
86
87
    /**
88
     * Has a field customized options?
89
     *
90
     * @param string $field
91
     *
92
     * @return bool
93
     */
94
    public function hasField($field)
95
    {
96
        return array_key_exists($field, $this->fields);
97
    }
98
99
    /**
100
     * Is a field enabled?
101
     *
102
     * Returns true, if
103
     * - There is no customized $field.
104
     * - The $field spec does not have the key 'enabled'
105
     * - The key 'enabled' is NOT TRUE.
106
     *
107
     * @param string $field
108
     *
109
     * @return bool
110
     */
111
    public function isEnabled($field)
112
    {
113
        return !isset($this->fields[$field]['enabled']) || (bool) $this->fields[$field]['enabled'];
114
    }
115
116
    /**
117
     * Get the field option array compatible with element spec.
118
     *
119
     * @param string $field
120
     *
121
     * @return array
122
     */
123
    public function getFieldOptions($field)
124
    {
125
        if (!$this->hasField($field)) {
126
            return [];
127
        }
128
129
        if (!isset($this->fields[$field]['__options__'])) {
130
            $this->fields[$field]['__options__'] = $this->copyArrayValues(
131
                $this->fields[$field],
132
                [
133
                    'attributes',
134
                    'options',
135
                    'label' => 'options',
136
                    'required' => ['key' => ['attributes','*'], 'value' => 'required', 'if' => true],
137
                    'type',
138
                ]
139
            );
140
        }
141
142
        return $this->fields[$field]['__options__'];
143
    }
144
145
    /**
146
     * Get the field flags array compatible with element flags.
147
     *
148
     * @param string $field
149
     *
150
     * @return array
151
     */
152 View Code Duplication
    public function getFieldFlags($field)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
153
    {
154
        if (!$this->hasField($field)) {
155
            return [];
156
        }
157
158
        if (!isset($this->fields[$field]['__flags__'])) {
159
            $this->fields[$field]['__flags__'] = $this->copyArrayValues(
160
                $this->fields[$field],
161
                [
162
                    'flags' => [],
163
                    'order' => ['priority'],
164
                    'priority'
165
                ]
166
            );
167
        }
168
169
        return $this->fields[$field]['__flags__'];
170
    }
171
172
    /**
173
     * Get input filter spec for a field.
174
     *
175
     * @param string $field
176
     *
177
     * @return array
178
     */
179 View Code Duplication
    public function getFieldInputSpecification($field)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
180
    {
181
        if (!$this->hasField($field)) {
182
            return [];
183
        }
184
185
        if (!isset($this->fields[$field]['__filter__'])) {
186
            $this->fields[$field]['__filter__'] = $this->copyArrayValues(
187
                $this->fields[$field],
188
                [
189
                    'input_filter' => [],
190
                    'required',
191
                ]
192
            );
193
        }
194
195
        return $this->fields[$field]['__filter__'];
196
    }
197
198
    /**
199
     * Copy specified keys from source to a new array.
200
     *
201
     * <pre>
202
     * $keys = [
203
     *      <name>,           // copy $source[<name>] to $target[<name>]
204
     *      <name> => <key>   // copy $source[<name>] to $target[<key][<name>]
205
     *      <name> => [<key>,<key>,..] // copy $source[<name>] to $target[<key>][<key>]..
206
     *      <name> => [
207
     *          'key' => <key>|[<key>,] // copy $source[<name>] to $target[<key]...
208
     *                                  // using '*' as <key> will be replaced by <name>
209
     *          'value' => <mixed>,     // do not use $source[<name>] but <mixed> as target value.
210
     *          'if' => <mixed>,        // only copy, if $source[<name>] equals <mixed>
211
     *      ]
212
     * ]
213
     * </pre>
214
     *
215
     * @param array $source
216
     * @param array $keys
217
     *
218
     * @return array
219
     */
220
    protected function copyArrayValues(array $source, array $keys)
221
    {
222
        $target = [];
223
        foreach ($keys as $key => $spec) {
224
            if (is_int($key)) {
225
                $key = $spec;
226
                $spec = null;
227
            }
228
229
            if (!array_key_exists($key, $source)) {
230
                continue;
231
            }
232
233
            if (null === $spec) {
234
                $target[$key] = $source[$key];
235
                continue;
236
            }
237
238
            if (is_string($spec)) {
239
                $target[$spec][$key] = $source[$key];
240
                continue;
241
            }
242
243
            if (isset($spec['if']) && $source[$key] !== $spec['if']) {
244
                continue;
245
            }
246
247
            if (isset($spec['key'])) {
248
                $targetKeys = is_array($spec['key']) ? $spec['key'] : [$spec['key']];
249
                $value = isset($spec['value']) ? $spec['value'] : $source[$key];
250
            } else {
251
                $targetKeys = $spec;
252
                $value = $source[$key];
253
            }
254
255
            $tmpTarget =& $target;
256
            foreach ($targetKeys as $targetKey) {
257
                if ('*' == $targetKey) {
258
                    $targetKey = $key;
259
                }
260
                if (!isset($tmpTarget[$targetKey])) {
261
                    $tmpTarget[$targetKey] = [];
262
                }
263
                $tmpTarget =& $tmpTarget[$targetKey];
264
            }
265
266
            $tmpTarget = $value;
267
        }
268
269
        return $target;
270
    }
271
}