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 = []) |
|
|
|
|
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 = []) |
|
|
|
|
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); |
|
|
|
|
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); |
|
|
|
|
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
|
|
|
|
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.