Completed
Branch develop (629ff8)
by Steve
02:58
created

FieldsBuilder::getFieldName()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 13
Code Lines 7

Duplication

Lines 13
Ratio 100 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 13
loc 13
rs 9.2
cc 4
eloc 7
nc 4
nop 1
1
<?php
2
3
namespace StoutLogic\AcfBuilder;
4
5
class FieldsBuilder extends Builder implements NamedBuilder
6
{
7
    protected $config = [];
8
    protected $fieldManager;
9
    protected $location = null;
10
    protected $name;
11
12
    public function __construct($name, $groupConfig = [])
13
    {
14
        $this->fieldManager = new FieldManager();
15
        $this->name = $name;
16
        $this->setGroupConfig('key', $name);
17
        $this->setGroupConfig('title', $this->generateLabel($name));
18
19
        $this->config = array_merge($this->config, $groupConfig);
20
    }
21
22
    public function setGroupConfig($key, $value)
23
    {
24
        $this->config[$key] = $value;
25
26
        return $this;
27
    }
28
29
    public function getName()
30
    {
31
        return $this->name;
32
    }
33
34
    /**
35
     * Namespace a group key
36
     * Append the namespace 'group' before the set key.
37
     *
38
     * @param  string $key Field Key
39
     * @return string      Field Key
40
     */
41
    private function namespaceGroupKey($key)
42
    {
43
        if (strpos($key, 'group_') !== 0) {
44
            $key = 'group_'.$key;
45
        }
46
        return $key;
47
    }
48
49
    /**
50
     * Build the final config array. Build any other builders that may exist
51
     * in the config.
52
     * @return array    final field config
53
     */
54
    public function build()
55
    {
56
        return array_merge($this->config, [
57
            'fields' => $this->buildFields(),
58
            'location' => $this->buildLocation(),
59
            'key' => $this->namespaceGroupKey($this->config['key']),
60
        ]);
61
    }
62
63
    private function buildFields()
64
    {
65
        $fields = array_map(function($field) {
66
            return ($field instanceof Builder) ? $field->build() : $field;
67
        }, $this->getFields());
68
69
        return $this->transformFields($fields);
70
    }
71
72
    private function transformFields($fields)
73
    {
74
        $conditionalTransform = new Transform\ConditionalLogic($this);
75
        $namespaceFieldKeyTransform = new Transform\NamespaceFieldKey($this);
76
77
        return
78
            $namespaceFieldKeyTransform->transform(
79
                $conditionalTransform->transform($fields)
80
            );
81
    }
82
83
    private function buildLocation()
84
    {
85
        $location = $this->getLocation();
86
        return ($location instanceof Builder) ? $location->build() : $location;
87
    }
88
89
    /**
90
     * Add multiple fields either via an array or from another builder
91
     * @param mixed $fields array of fields or a FieldBuilder
92
     */
93
    public function addFields($fields)
94
    {
95
        if ($fields instanceof FieldsBuilder) {
96
            $builder = clone $fields;
97
            $fields = $builder->getFields();
98
        }
99
100
        foreach ($fields as $field) {
101
            $this->getFieldManager()->pushField($field);
102
        }
103
104
        return $this;
105
    }
106
107
    /**
108
     * Add field to field group
109
     * @param string $name field name
110
     * @param array $args field options
111
     *
112
     * @throws FieldNameCollisionException if name already exists.
113
     *
114
     * @return $this
115
     */
116
    public function addField($name, $args = [])
117
    {
118
        $field = array_merge([
119
            'key' => $name,
120
            'name' => $name,
121
            'label' => $this->generateLabel($name),
122
        ], $args);
123
124
        $this->getFieldManager()->pushField($field);
125
        return $this;
126
    }
127
128
    protected function addFieldType($name, $type, $args = [])
129
    {
130
        return $this->addField($name, array_merge([
131
            'type' => $type,
132
        ], $args));
133
    }
134
135
    public function addText($name, $args = [])
136
    {
137
        return $this->addFieldType($name, 'text', $args);
138
    }
139
140
    public function addTextarea($name, $args = [])
141
    {
142
        return $this->addFieldType($name, 'textarea', $args);
143
    }
144
145
    public function addNumber($name, $args = [])
146
    {
147
        return $this->addFieldType($name, 'number', $args);
148
    }
149
150
    public function addEmail($name, $args = [])
151
    {
152
        return $this->addFieldType($name, 'email', $args);
153
    }
154
155
    public function addUrl($name, $args = [])
156
    {
157
        return $this->addFieldType($name, 'url', $args);
158
    }
159
160
    public function addPassword($name, $args = [])
161
    {
162
        return $this->addFieldType($name, 'password', $args);
163
    }
164
165
    public function addWysiwyg($name, $args = [])
166
    {
167
        return $this->addFieldType($name, 'wysiwyg', $args);
168
    }
169
170
    public function addOembed($name, $args = [])
171
    {
172
        return $this->addFieldType($name, 'oembed', $args);
173
    }
174
175
    public function addImage($name, $args = [])
176
    {
177
        return $this->addFieldType($name, 'image', $args);
178
    }
179
180
    public function addFile($name, $args = [])
181
    {
182
        return $this->addFieldType($name, 'file', $args);
183
    }
184
185
    public function addGallery($name, $args = [])
186
    {
187
        return $this->addFieldType($name, 'gallery', $args);
188
    }
189
190
    public function addTrueFalse($name, $args = [])
191
    {
192
        return $this->addFieldType($name, 'true_false', $args);
193
    }
194
195
    public function addSelect($name, $args = [])
196
    {
197
        return $this->addFieldType($name, 'select', $args);
198
    }
199
200
    public function addRadio($name, $args = [])
201
    {
202
        return $this->addFieldType($name, 'radio', $args);
203
    }
204
205
    public function addCheckbox($name, $args = [])
206
    {
207
        return $this->addFieldType($name, 'checkbox', $args);
208
    }
209
210
    public function addPostObject($name, $args = [])
211
    {
212
        return $this->addFieldType($name, 'post_object', $args);
213
    }
214
215
    public function addPostLink($name, $args = [])
216
    {
217
        return $this->addFieldType($name, 'post_link', $args);
218
    }
219
220
    public function addRelationship($name, $args = [])
221
    {
222
        return $this->addFieldType($name, 'relationship', $args);
223
    }
224
225
    public function addTaxonomy($name, $args = [])
226
    {
227
        return $this->addFieldType($name, 'taxonomy', $args);
228
    }
229
230
    public function addUser($name, $args = [])
231
    {
232
        return $this->addFieldType($name, 'user', $args);
233
    }
234
235
    public function addDatePicker($name, $args = [])
236
    {
237
        return $this->addFieldType($name, 'date_picker', $args);
238
    }
239
240
    public function addTimePicker($name, $args = [])
241
    {
242
        return $this->addFieldType($name, 'time_picker', $args);
243
    }
244
245
    public function addDateTimePicker($name, $args = [])
246
    {
247
        return $this->addFieldType($name, 'date_time_picker', $args);
248
    }
249
250
    public function addColorPicker($name, $args = [])
251
    {
252
        return $this->addFieldType($name, 'color_picker', $args);
253
    }
254
255 View Code Duplication
    public function addTab($label, $args = [])
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...
256
    {
257
        $name = $this->generateName($label).'_tab';
258
        $args = array_merge([
259
            'label' => $label,
260
        ], $args);
261
262
        return $this->addFieldType($name, 'tab', $args);
263
    }
264
265
    public function endpoint($value = 1)
266
    {
267
        return $this->setConfig('endpoint', $value);
268
    }
269
270 View Code Duplication
    public function addMessage($label, $message, $args = [])
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...
271
    {
272
        $name = $this->generateName($label).'_message';
273
        $args = array_merge([
274
            'label' => $label,
275
            'message' => $message,
276
        ], $args);
277
278
        return $this->addFieldType($name, 'message', $args);
279
    }
280
281
    public function addRepeater($name, $args = [])
282
    {
283
        $repeaterBuilder = new RepeaterBuilder($name, $args);
284
        $repeaterBuilder->setParentContext($this);
285
        $this->getFieldManager()->pushField($repeaterBuilder);
286
287
        return $repeaterBuilder;
288
    }
289
290
    public function addFlexibleContent($name, $args = [])
291
    {
292
        $flexibleContentBuilder = new FlexibleContentBuilder($name, $args);
293
        $flexibleContentBuilder->setParentContext($this);
294
        $this->getFieldManager()->pushField($flexibleContentBuilder);
295
296
        return $flexibleContentBuilder;
297
    }
298
299
    public function addChoice($choice, $label = null)
300
    {
301
        $field = $this->getFieldManager()->popField();
302
303
        array_key_exists('choices', $field) ?: $field['choices'] = [];
304
        $label ?: $label = $choice;
305
306
        $field['choices'][$choice] = $label;
307
        $this->getFieldManager()->pushField($field);
308
309
        return $this;
310
    }
311
312
    public function addChoices()
313
    {
314
        foreach (func_get_args() as $choice) {
315
            if (is_array($choice)) {
316
                $values = each($choice);
317
                $this->addChoice($values['key'], $values['value']);
318
            } else {
319
                $this->addChoice($choice);
320
            }
321
        }
322
323
        return $this;
324
    }
325
326
    public function conditional($name, $operator, $value)
327
    {
328
        $field = $this->getFieldManager()->popField();
329
        $conditionalBuilder = new ConditionalBuilder($name, $operator, $value);
330
        $conditionalBuilder->setParentContext($this);
331
332
        $field['conditional_logic'] = $conditionalBuilder;
333
        $this->getFieldManager()->pushField($field);
334
335
        return $conditionalBuilder;
336
    }
337
338
    protected function getFieldManager()
339
    {
340
        return $this->fieldManager;
341
    }
342
343
    public function getFields()
344
    {
345
        return $this->getFieldManager()->getFields();
346
    }
347
348
    protected function getFieldIndex($name)
349
    {
350
        return $this->getFieldManager()->getFieldIndex($name);
351
    }
352
    
353
    public function getField($name)
354
    {
355
        return $this->getFieldManager()->getField($name);
356
    }
357
358
    /**
359
     * Modify an already defined field
360
     * @param  string $name   Name of the field
361
     * @param  mixed  $modify Array of field configs or a closure that accepts
362
     *                        a FieldsBuilder and returns a FieldsBuilder.
363
     *
364
     * @throws ModifyFieldReturnTypeException if $modify is a closure and doesn't
365
     *                                        return a FieldsBuilder.
366
     * @throws FieldNotFoundException if the field name doesn't exist.
367
     *
368
     * @return FieldsBuilder  $this
369
     */
370
    public function modifyField($name, $modify)
371
    {
372
        if (is_array($modify)) {
373
            $this->getFieldManager()->modifyField($name, $modify);
374
        } else if ($modify instanceof \Closure) {
375
            $field = $this->getField($name);
376
            $index = $this->getFieldIndex($name);
0 ignored issues
show
Unused Code introduced by
$index is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
377
378
            // Initialize Modifying FieldsBuilder
379
            $modifyBuilder = new FieldsBuilder('');
380
            $modifyBuilder->addFields([$field]);
381
382
            // Modify Field
383
            $modifyBuilder = $modify($modifyBuilder);
384
385
            // Check if a FieldsBuilder is returned
386
            if (!$modifyBuilder instanceof FieldsBuilder) {
387
                throw new ModifyFieldReturnTypeException(gettype($modifyBuilder));
388
            }
389
390
            // Build Modifcations
391
            $modifyConfig = $modifyBuilder->build();
392
393
            // Insert field(s)
394
            $this->getFieldManager()->replaceField($name, $modifyConfig['fields']);
395
        }
396
397
        return $this;
398
    }
399
400
    /**
401
     * Remove a field by name
402
     * @param  string $name Field to remove
403
     *
404
     * @return FieldsBuilder  $this
405
     */
406
    public function removeField($name)
407
    {
408
        $this->getFieldManager()->removeField($name);
409
410
        return $this;
411
    }
412
413
    public function defaultValue($value)
414
    {
415
        return $this->setConfig('default_value', $value);
416
    }
417
418
    public function required($value = true)
419
    {
420
        return $this->setConfig('required', $value ? 1 : 0);
421
    }
422
423
    public function instructions($value)
424
    {
425
        return $this->setConfig('instructions', $value);
426
    }
427
428
    public function setConfig($key, $value)
429
    {
430
        $field = $this->getFieldManager()->popField();
431
        $field[$key] = $value;
432
        $this->getFieldManager()->pushField($field);
433
434
        return $this;
435
    }
436
437
    public function setLocation($param, $operator, $value)
438
    {
439
        if ($this->getParentContext()) {
440
            return $this->getParentContext()->setLocation($param, $operator, $value);
0 ignored issues
show
Documentation Bug introduced by
The method setLocation does not exist on object<StoutLogic\AcfBuilder\Builder>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
441
        }
442
443
        $this->location = new LocationBuilder($param, $operator, $value);
444
        $this->location->setParentContext($this);
445
446
        return $this->location;
447
    }
448
449
    public function getLocation()
450
    {
451
        return $this->location;
452
    }
453
454
    protected function generateLabel($name)
455
    {
456
        return ucwords(str_replace("_", " ", $name));
457
    }
458
459
    protected function generateName($name)
460
    {
461
        return strtolower(str_replace(" ", "_", $name));
462
    }
463
}
464