$method($field, $item_index, $item_value); } // Fallback to text field return $this->renderItemTextField($field, $item_index, $item_value); } /** * Render an item text field * * @since 1.0.0 * @param array $field Field configuration * @param int $item_index Item index * @param string|null $item_value Current item value * @return string Rendered HTML */ private function renderItemTextField(array $field, int $item_index, ?string $item_value = ''): string { $id = $field['id'] ?? ''; $name = $field['name'] ?? ''; $label = $field['label'] ?? ''; $placeholder = $field['placeholder'] ?? ''; $required = $field['required'] ?? false; $readonly = $field['readonly'] ?? false; $container_class = $field['container_class'] ?? 'sm:col-span-6'; $value = $item_value ?: ($field['default_value'] ?? ''); $description = $field['description'] ?? ''; $required_attr = $required ? 'required' : ''; $readonly_attr = $readonly ? 'readonly' : ''; $required_class = $required ? 'required' : ''; $description_html = $description ? '

' . esc_html($description) . '

' : ''; return sprintf( '
%s
', esc_attr($container_class), esc_attr($id), $item_index, esc_attr($required_class), esc_html($label), esc_attr($id), $item_index, $item_index, esc_attr($name), esc_attr($value), esc_attr($placeholder), esc_attr($required_class), $required_attr, $readonly_attr, $description_html ); } /** * Render an item textarea field * * @since 1.0.0 * @param array $field Field configuration * @param int $item_index Item index * @param string|null $item_value Current item value * @return string Rendered HTML */ private function renderItemTextareaField(array $field, int $item_index, ?string $item_value = ''): string { $id = $field['id'] ?? ''; $name = $field['name'] ?? ''; $label = $field['label'] ?? ''; $placeholder = $field['placeholder'] ?? ''; $required = $field['required'] ?? false; $readonly = $field['readonly'] ?? false; $container_class = $field['container_class'] ?? 'sm:col-span-6'; $value = $item_value ?: ($field['default_value'] ?? ''); $rows = $field['rows'] ?? 3; $description = $field['description'] ?? ''; $required_attr = $required ? 'required' : ''; $readonly_attr = $readonly ? 'readonly' : ''; $required_class = $required ? 'required' : ''; $description_html = $description ? '

' . esc_html($description) . '

' : ''; return sprintf( '
%s
', esc_attr($container_class), esc_attr($id), $item_index, esc_attr($required_class), esc_html($label), esc_attr($id), $item_index, $item_index, esc_attr($name), esc_attr($rows), esc_attr($placeholder), esc_attr($required_class), $required_attr, $readonly_attr, wp_kses_post($value), $description_html ); } /** * Render an item number field * * @since 1.0.0 * @param array $field Field configuration * @param int $item_index Item index * @param string $item_value Current item value * @return string Rendered HTML */ private function renderItemNumberField(array $field, int $item_index, ?string $item_value = ''): string { $id = $field['id'] ?? ''; $name = $field['name'] ?? ''; $label = $field['label'] ?? ''; $placeholder = $field['placeholder'] ?? ''; $required = $field['required'] ?? false; $readonly = $field['readonly'] ?? false; $container_class = $field['container_class'] ?? 'sm:col-span-6'; $value = $item_value ?: ($field['default_value'] ?? ''); $min = $field['min'] ?? ''; $max = $field['max'] ?? ''; $step = $field['step'] ?? ''; $description = $field['description'] ?? ''; $required_attr = $required ? 'required' : ''; $readonly_attr = $readonly ? 'readonly' : ''; $required_class = $required ? 'required' : ''; $min_attr = $min !== '' ? 'min="' . esc_attr($min) . '"' : ''; $max_attr = $max !== '' ? 'max="' . esc_attr($max) . '"' : ''; $step_attr = $step !== '' ? 'step="' . esc_attr($step) . '"' : ''; $description_html = $description ? '

' . esc_html($description) . '

' : ''; return sprintf( '
%s
', esc_attr($container_class), esc_attr($id), $item_index, esc_attr($required_class), esc_html($label), esc_attr($id), $item_index, $item_index, esc_attr($name), esc_attr($value), esc_attr($placeholder), esc_attr($required_class), $required_attr, $readonly_attr, $min_attr, $max_attr, $step_attr, $description_html ); } /** * Render an item checkbox field * * @since 1.0.0 * @param array $field Field configuration * @param int $item_index Item index * @param string $item_value Current item value * @return string Rendered HTML */ private function renderItemCheckboxField(array $field, int $item_index, ?string $item_value = ''): string { $id = $field['id'] ?? ''; $name = $field['name'] ?? ''; $label = $field['label'] ?? ''; $required = $field['required'] ?? false; $container_class = $field['container_class'] ?? 'sm:col-span-6'; $value = (boolean)$item_value ; $description = $field['description'] ?? ''; $required_attr = $required ? 'required' : ''; $required_class = $required ? 'required' : ''; $checked = ($value == '1' || $value === true) ? 'checked' : ''; $description_html = $description ? '

' . esc_html($description) . '

' : ''; return sprintf( '
%s
', esc_attr($container_class), esc_attr($id), $item_index, $item_index, esc_attr($name), esc_attr($required_class), $checked, $required_attr, esc_attr($id), $item_index, esc_attr($required_class), esc_html($label), $description_html ); } /** * Generate HTML for a blank (template) item * * @since 1.0.0 * @param BaseFieldRegistration|null $field_registration Optional field registration to use * @return string */ public function generateItemTemplateHtml($field_registration = null): string { $html = ''; // If no field registration provided, use a default one if (!$field_registration) { // Try to determine the correct field registration based on context // This is a fallback for backward compatibility $field_registration = new \EasyInvoice\Forms\Invoice\InvoiceFieldRegistration(); } $fields = $field_registration->getItemFields(); // Wrap fields in a grid container $html .= '
'; // Use index -1 for template fields foreach ($fields as $field) { $html .= $this->renderItemField($field, -1, ''); } $html .= '
'; return $html; } }