* wrapping a with one row per field. Hidden inputs * and datalist elements are emitted before the table; notices before the card, * submit button after the fields. * * Usage: * echo RsvFormBuilder::create('settings', $action, 'PATCH', 'Saved.') * ->heading('Settings') * ->text('name', 'Name', required: true) * ->email('email', 'Email') * ->submit('Save'); */ class RsvFormBuilder { private string $form_id; /** Where the form submits, and how RsvAdminForm should send it. */ private string $action; private string $rest_method; private string $success_msg; /** Optional heading shown inside the card. */ private string $heading = ''; /** @var string[] Rendered before the table (hidden inputs, datalists). */ private array $before = []; /** @var string[] WP admin notice banners rendered before the card. */ private array $notices = []; /** @var string[] elements inside the table. */ private array $rows = []; /** @var string[] Rendered after the table (submit button). */ private array $after = []; private function __construct() {} /** * @param string $rest_method Verb sent via data-method (POST, PUT, PATCH…). * @param string $success_msg Message RsvAdminForm shows on success. */ public static function create( string $id, string $action, string $rest_method = 'POST', string $success_msg = '' ): static { $builder = new static(); $builder->form_id = $id; $builder->action = $action; $builder->rest_method = $rest_method; $builder->success_msg = $success_msg; return $builder; } /** Heading shown inside the card, above the fields. */ public function heading(string $text): static { $this->heading = $text; return $this; } // ------------------------------------------------------------------------- // Input fields — each becomes a in the table // ------------------------------------------------------------------------- public function text( string $id, string $label, string $desc = '', bool $required = false, string $value = '' ): static { $req = $required ? 'required' : ''; $ctrl = ''; return $this->row($id, $label, $ctrl, $desc); } public function email( string $id, string $label, string $desc = '', bool $required = false, string $value = '', ?string $list_id = null ): static { $req = $required ? 'required' : ''; $list = $list_id !== null ? 'list="' . esc_attr($list_id) . '"' : ''; $ctrl = ''; return $this->row($id, $label, $ctrl, $desc); } public function password( string $id, string $label, string $desc = '', bool $required = false, string $placeholder = '' ): static { $req = $required ? 'required' : ''; $ph = $placeholder !== '' ? 'placeholder="' . esc_attr($placeholder) . '"' : ''; $ctrl = ''; return $this->row($id, $label, $ctrl, $desc); } public function number( string $id, string $label, string $desc = '', bool $required = false, string|int $value = '', ?int $min = null, ?int $max = null ): static { $req = $required ? 'required' : ''; $min_attr = $min !== null ? 'min="' . $min . '"' : ''; $max_attr = $max !== null ? 'max="' . $max . '"' : ''; $ctrl = ''; return $this->row($id, $label, $ctrl, $desc); } public function date( string $id, string $label, string $desc = '', bool $required = false, string $value = '' ): static { $req = $required ? 'required' : ''; $ctrl = ''; return $this->row($id, $label, $ctrl, $desc); } public function time( string $id, string $label, string $desc = '', bool $required = false, string $value = '' ): static { $req = $required ? 'required' : ''; $ctrl = ''; return $this->row($id, $label, $ctrl, $desc); } public function checkbox( string $id, string $label, string $desc = '', bool $checked = false ): static { $c = $checked ? 'checked' : ''; $ctrl = ''; return $this->row($id, $label, $ctrl, $desc); } /** * @param array $options Associative: value => display text. */ public function select( string $id, string $label, array $options, string $desc = '', bool $required = false, string $selected = '' ): static { $req = $required ? 'required' : ''; $opts = $this->build_options($options, $selected); $ctrl = ''; return $this->row($id, $label, $ctrl, $desc); } public function textarea( string $id, string $label, string $desc = '', bool $required = false, string $value = '', int $rows = 5 ): static { $req = $required ? 'required' : ''; $ctrl = ''; return $this->row($id, $label, $ctrl, $desc); } /** * Syntax-highlighted editor backed by WordPress' bundled CodeMirror. * * Serializes exactly like {@see textarea()} — the underlying