Jake Vanderwerf
2026-03-08 c19264ac916707096fe294d996a1b7fb85206b34
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
<?php
namespace JVBase\registrar\fields;
 
use JVBase\meta\MetaTypeManager;
 
if (!defined('ABSPATH')) {
    exit;
}
 
class Field {
    protected string $name;             // field name. Will be prefixed with BASE
    protected string $type;             // field type
    protected string $label;            // define its label
    protected mixed $default;           // default value
    protected string $description;
    protected string $hint;
    protected bool $required = false;   // whether it is required
    protected bool $hidden = false;     // whether to show in the editor
    protected bool $quickEdit = true;   // whether to show in quick edit table
    protected bool $quill;              // whether to use quill
    protected int $maxLength;           // of characters
    /**
     * @var ?bool For timeline post types. Indicates whether all posts get this field, or just the parent
     */
    protected ?bool $for_all = null;
    /**
     * @var ?string Rather than manually defining sections, one can define which section a field belongs to here
     */
    protected ?string $section = null;
 
    public function __construct(string $name, array $config) {
        $this->name = $name;
        $required = ['type', 'label'];
        foreach ($required as $r) {
            if (!array_key_exists($r, $config)) {
                error_log('[JVBase\registrar\Field] Missing required '.$r.' for field');
                return;
            }
        }
        $current = get_class($this);
        $class = match($config['type']) {
            'group' => ($current !== GroupedField::class) ? new GroupedField($name, $config) : $this,
            'select', 'radio', 'checkbox' => ($current !== OptionsField::class) ? new OptionsField($name, $config) : $this,
            'repeater' => ($current !== RepeaterField::class) ? new RepeaterField($name, $config) : $this,
            'taglist' => ($current !== TagListField::class) ? new TagListField($name, $config) : $this,
            'taxonomy', 'post', 'user', 'selector' => ($current !== SelectorField::class) ? new SelectorField($name, $config) : $this,
            'upload' => ($current !== UploadField::class) ? new UploadField($name, $config) : $this,
            default => $this
        };
 
        foreach ($config as $key => $value) {
            if (property_exists($class, $key)) {
                $method = 'set' . ucfirst($key);
                $class->$method($value);
            } else {
                error_log('Instance: '.print_r($class, true));
                error_log('[JVBase\registrar\Field] Invalid key for '.$name.': '.$key);
            }
        }
    }
 
    public function setDescription(string $description):void
    {
        $this->description = $description;
    }
    public function getDescription():string
    {
        return $this->description;
    }
    public function setHint(string $hint):void
    {
        $this->hint = $hint;
    }
    public function getHint():string
    {
        return $this->hint;
    }
 
    protected function setType(string $type):void{
        $allowed = array_keys(MetaTypeManager::getTypes());
        if (!in_array($type, $allowed)) {
            error_log('[JVBase\registrar\Field] Invalid type attempted '.$type);
            return;
        }
        $this->type = $type;
    }
 
    protected function setLabel(string $label):void{
        $this->label = $label;
    }
    protected function setRequired(bool $required):void{
        $this->required = $required;
    }
    protected function setHidden(bool $hidden):void{
        $this->hidden = $hidden;
    }
    protected function setQuickEdit(bool $quickEdit):void{
        $this->quickEdit = $quickEdit;
    }
    protected function setDefault(mixed $default):void
    {
        $this->default = $default;
    }
 
    protected function setQuill(bool $quill):void
    {
        $this->quill = $quill;
    }
 
    public function setForAll(bool $set):void
    {
        $this->for_all = $set;
    }
    public function getForAll():?bool
    {
        return $this->for_all??null;
    }
    public function setSection(string $section):void
    {
        $this->section = $section;
    }
    public function getSection():?string
    {
        return $this->section??null;
    }
 
    protected function setMaxLength(int $maxLength):void
    {
        $this->maxLength = $maxLength;
    }
    public function getConfig():array{
        $config = get_object_vars($this);
 
        $config = array_map(function ($item) {
            if (is_a($item, Field::class)) {
                return $item->getConfig();
            } else if (is_array($item)) {
                $temp = [];
                foreach ($item as $v) {
                    if (is_a($v, Field::class)) {
                        $temp[] = $v->getConfig();
                    } else {
                        $temp[] = $v;
                    }
                }
                return $temp;
            } else {
                return $item;
            }
        }, $config);
 
        return $config;
    }
}