Passed
Branch develop (de4bc5)
by Steve
03:15
created

FieldsBuilder::addText()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 2
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 View Code Duplication
    private function getFieldName($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...
354
        if ($field instanceof NamedBuilder) {
355
            return $field->getName();
356
        }
357
358
        if (!is_array($field)) {
359
            die($field);
0 ignored issues
show
Coding Style Compatibility introduced by
The method getFieldName() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
360
        }
361
362
        if (array_key_exists('name', $field)) {
363
            return $field['name'];
364
        }
365
    }
366
367
    public function getField($name)
368
    {
369
        return $this->getFieldManager()->getField($name);
370
    }
371
372
    /**
373
     * Modify an already defined field
374
     * @param  string $name   Name of the field
375
     * @param  mixed  $modify Array of field configs or a closure that accepts
376
     *                        a FieldsBuilder and returns a FieldsBuilder.
377
     *
378
     * @throws ModifyFieldReturnTypeException if $modify is a closure and doesn't
379
     *                                        return a FieldsBuilder.
380
     * @throws FieldNotFoundException if the field name doesn't exist.
381
     *
382
     * @return FieldsBuilder  $this
383
     */
384
    public function modifyField($name, $modify)
385
    {
386
        if (is_array($modify)) {
387
            $this->getFieldManager()->modifyField($name, $modify);
388
        } else if ($modify instanceof \Closure) {
389
            $field = $this->getField($name);
390
            $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...
391
392
            // Initialize Modifying FieldsBuilder
393
            $modifyBuilder = new FieldsBuilder('');
394
            $modifyBuilder->addFields([$field]);
395
396
            // Modify Field
397
            $modifyBuilder = $modify($modifyBuilder);
398
399
            // Check if a FieldsBuilder is returned
400
            if (!$modifyBuilder instanceof FieldsBuilder) {
401
                throw new ModifyFieldReturnTypeException(gettype($modifyBuilder));
402
            }
403
404
            // Build Modifcations
405
            $modifyConfig = $modifyBuilder->build();
406
407
            // Insert field(s)
408
            $this->getFieldManager()->replaceField($name, $modifyConfig['fields']);
409
        }
410
411
        return $this;
412
    }
413
414
    /**
415
     * Remove a field by name
416
     * @param  string $name Field to remove
417
     *
418
     * @return FieldsBuilder  $this
419
     */
420
    public function removeField($name)
421
    {
422
        $this->getFieldManager()->removeField($name);
423
424
        return $this;
425
    }
426
427
    public function defaultValue($value)
428
    {
429
        return $this->setConfig('default_value', $value);
430
    }
431
432
    public function required($value = true)
433
    {
434
        return $this->setConfig('required', $value ? 1 : 0);
435
    }
436
437
    public function instructions($value)
438
    {
439
        return $this->setConfig('instructions', $value);
440
    }
441
442
    public function setConfig($key, $value)
443
    {
444
        $field = $this->getFieldManager()->popField();
445
        $field[$key] = $value;
446
        $this->getFieldManager()->pushField($field);
447
448
        return $this;
449
    }
450
451
    public function setLocation($param, $operator, $value)
452
    {
453
        if ($this->getParentContext()) {
454
            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...
455
        }
456
457
        $this->location = new LocationBuilder($param, $operator, $value);
458
        $this->location->setParentContext($this);
459
460
        return $this->location;
461
    }
462
463
    public function getLocation()
464
    {
465
        return $this->location;
466
    }
467
468
    protected function generateLabel($name)
469
    {
470
        return ucwords(str_replace("_", " ", $name));
471
    }
472
473
    protected function generateName($name)
474
    {
475
        return strtolower(str_replace(" ", "_", $name));
476
    }
477
}
478