'Nome Modulo', * 'cardTitle' => 'Titolo Card', * // ...altre proprietà... * ]); * echo $page->render(); * ``` */ abstract class ElixFormsComponent { /** * Proprietà della pagina (equivalente a IElixFormsComponentProperties). * * Chiavi supportate: * - isDarkTheme: bool (opzionale) * - userDisplayName: string (opzionale) * - additionalFieldsJson: string (opzionale, JSON schema per campi dinamici) * - moduleName: string (obbligatorio) * - headerTitle: string (opzionale) * - headerHeroImageSrc: string (opzionale) * - cardTitle: string (obbligatorio) * - cardDescription: string (opzionale) * - alertInfoTitle: string (opzionale) * - alertInfoMessage: string (opzionale) * - instructionsTitle: string (opzionale) * - instructionsMessage: string (opzionale) * - submitText: string (opzionale, default 'INVIA') * * @var array */ protected array $properties; /** * Nomi dei parametri obbligatori che elixForms passa in query string. * Se mancano, la pagina mostra un errore di autenticazione. * * @var string[] */ private array $mandatoryFormFieldNames = [ 'RWE2_MODULE_ID', 'RWE2_REQUEST_ID', 'custom-workflow-back-url', 'custom-workflow-generic-id', 'custom-workflow-current-tabrel-genid', 'custom-workflow-source-field', 'crc', 'MODULE_TESTMODE_KEY', 'ELANG', ]; /** * @param array $properties Proprietà della pagina */ public function __construct(array $properties) { $this->properties = $properties; } // ========================================================================= // Metodi estensibili (da sovrascrivere nelle pagine figlie) // ========================================================================= /** * Genera i campi custom del form. * Da sovrascrivere nelle pagine figlie per definire i campi specifici. * * @return string HTML dei campi custom */ protected function createCustomFormFields(): string { return ''; } /** * Contenuto extra da renderizzare PRIMA del form. * Sovrascrivere per aggiungere contenuto personalizzato. * * @return string HTML del contenuto extra */ protected function renderExtraContentPre(): string { return ''; } /** * Contenuto extra da renderizzare DOPO il form. * Sovrascrivere per aggiungere contenuto personalizzato. * * @return string HTML del contenuto extra */ protected function renderExtraContentPost(): string { return ''; } // ========================================================================= // Metodi factory per campi form // ========================================================================= /** * Crea un campo di testo (input type="text"). * * @param string $paramName Nome/ID del campo (corrisponde alla colonna elixForms) * @param string $label Etichetta del campo * @param bool $required Se il campo è obbligatorio * @return string HTML del campo */ protected function createTextInput(string $paramName, string $label, bool $required = false): string { $currentValue = htmlspecialchars(QueryParamHelper::getDecodedTextFromQuery($paramName) ?? '', ENT_QUOTES, 'UTF-8'); $requiredAttr = $required ? ' required' : ''; $labelHtml = ''; $inputHtml = ''; return (new ElixFormsElement($labelHtml, $inputHtml))->render(); } /** * Crea un campo textarea. * * @param string $paramName Nome/ID del campo * @param string $label Etichetta del campo * @param bool $required Se il campo è obbligatorio * @return string HTML del campo */ protected function createTextAreaInput(string $paramName, string $label, bool $required = false): string { $currentValue = htmlspecialchars(QueryParamHelper::getDecodedTextFromQuery($paramName) ?? '', ENT_QUOTES, 'UTF-8'); $requiredAttr = $required ? ' required' : ''; $labelHtml = ''; $inputHtml = ''; return (new ElixFormsElement($labelHtml, $inputHtml))->render(); } /** * Crea un campo numerico (input type="number"). * * @param string $paramName Nome/ID del campo * @param string $label Etichetta del campo * @param bool $required Se il campo è obbligatorio * @return string HTML del campo */ protected function createNumberInput(string $paramName, string $label, bool $required = false): string { $currentValue = htmlspecialchars(QueryParamHelper::getDecodedTextFromQuery($paramName) ?? '', ENT_QUOTES, 'UTF-8'); $requiredAttr = $required ? ' required' : ''; $labelHtml = ''; $inputHtml = ''; return (new ElixFormsElement($labelHtml, $inputHtml))->render(); } /** * Crea un campo booleano (radio Sì/No). * * @param string $paramName Nome/ID del campo * @param string $label Etichetta del campo * @param bool $required Se il campo è obbligatorio * @return string HTML del campo */ protected function createBooleanInput(string $paramName, string $label, bool $required = false): string { $currentValue = QueryParamHelper::getDecodedTextFromQuery($paramName) ?? ''; $requiredAttr = $required ? ' required' : ''; $escapedName = htmlspecialchars($paramName); $escapedLabel = htmlspecialchars($label); $labelHtml = '' . $escapedLabel . ''; $options = [ ['value' => 'true', 'label' => 'Sì'], ['value' => 'false', 'label' => 'No'], ]; $inputHtml = '
'; foreach ($options as $option) { $id = $escapedName . '_' . $option['value']; $checked = $currentValue === $option['value'] ? ' checked' : ''; $inputHtml .= <<
HTML; } $inputHtml .= ''; return (new ElixFormsElement($labelHtml, $inputHtml))->render(); } /** * Crea un campo radio con opzioni personalizzate. * * @param string $paramName Nome/ID del campo * @param string $label Etichetta del campo * @param array $options Opzioni radio * @param bool $required Se il campo è obbligatorio * @return string HTML del campo */ protected function createRadioInput(string $paramName, string $label, array $options, bool $required = false): string { $currentValue = (string)(QueryParamHelper::getOptionFromQuery($paramName) ?? ''); $requiredAttr = $required ? ' required' : ''; $escapedName = htmlspecialchars($paramName); $escapedLabel = htmlspecialchars($label); $labelHtml = '' . $escapedLabel . ''; $inputHtml = '
'; foreach ($options as $option) { $id = $escapedName . '_' . $option['value']; $checked = $currentValue === (string)$option['value'] ? ' checked' : ''; $optionLabel = htmlspecialchars($option['label']); $inputHtml .= <<
HTML; } $inputHtml .= ''; return (new ElixFormsElement($labelHtml, $inputHtml))->render(); } /** * Crea un campo checkbox con opzioni multiple. * I valori selezionati vengono inviati come stringa separata da virgola in un input hidden. * * @param string $paramName Nome/ID del campo (usato per l'hidden input) * @param string $label Etichetta del campo * @param array $options Opzioni checkbox * @return string HTML del campo */ protected function createCheckboxInput(string $paramName, string $label, array $options): string { $checkedValues = QueryParamHelper::getCheckedFromQuery($paramName); $currentValue = implode(',', $checkedValues); $escapedName = htmlspecialchars($paramName); $escapedLabel = htmlspecialchars($label); $labelHtml = ''; $inputHtml = '
'; foreach ($options as $entryIndex => $entry) { $id = $escapedName . '_' . $entryIndex; $isChecked = in_array($entryIndex, $checkedValues) ? ' checked' : ''; $optionLabel = htmlspecialchars($entry['label']); $inputHtml .= <<
HTML; } $inputHtml .= ''; // Hidden input che contiene il valore aggregato (aggiornato via JS client-side) $inputHtml .= ''; return (new ElixFormsElement($labelHtml, $inputHtml))->render(); } /** * Crea un campo dropdown (select). * * @param string $paramName Nome/ID del campo * @param string $label Etichetta del campo * @param array $options Opzioni dropdown * @param bool $required Se il campo è obbligatorio * @return string HTML del campo */ protected function createDropdownInput(string $paramName, string $label, array $options, bool $required = false): string { $queryValue = QueryParamHelper::getOptionFromQuery($paramName); $currentValue = $queryValue !== null ? (string)$queryValue : ''; $requiredAttr = $required ? ' required' : ''; $escapedName = htmlspecialchars($paramName); $escapedLabel = htmlspecialchars($label); $labelHtml = ''; $inputHtml = ''; return (new ElixFormsElement($labelHtml, $inputHtml))->render(); } /** * Crea un campo nascosto (hidden input). * L'ID dell'hidden ha il suffisso _hidden per evitare conflitti. * * @param string $paramName Nome del campo * @return string HTML dell'input hidden */ protected function createHiddenInput(string $paramName): string { $value = htmlspecialchars(QueryParamHelper::getDecodedTextFromQuery($paramName) ?? '', ENT_QUOTES, 'UTF-8'); $escapedName = htmlspecialchars($paramName); return ''; } // ========================================================================= // Metodi interni di rendering // ========================================================================= /** * Genera gli hidden input per tutti i parametri obbligatori elixForms. * * @return string HTML degli hidden input */ private function createMandatoryFormFields(): string { $html = ''; foreach ($this->mandatoryFormFieldNames as $paramName) { $html .= $this->createHiddenInput($paramName); } return $html; } /** * Genera i campi form da uno schema JSON (additionalFieldsJson). * * @return string HTML dei campi aggiuntivi */ private function createAdditionalFormFields(): string { $json = $this->properties['additionalFieldsJson'] ?? '[]'; $schema = json_decode($json, true); if (!is_array($schema)) { return ''; } $html = ''; foreach ($schema as $field) { $html .= $this->renderField($field); } return $html; } /** * Renderizza un singolo campo form in base al tipo specificato nello schema. * * @param array $field Definizione del campo * @return string HTML del campo */ private function renderField(array $field): string { $key = $field['key'] ?? ''; $fieldLabel = $field['label'] ?? ''; $required = $field['required'] ?? false; $fieldOptions = $field['options'] ?? []; return match ($field['type'] ?? '') { 'text' => $this->createTextInput($key, $fieldLabel, $required), 'textarea' => $this->createTextAreaInput($key, $fieldLabel, $required), 'number' => $this->createNumberInput($key, $fieldLabel, $required), 'boolean' => $this->createBooleanInput($key, $fieldLabel, $required), 'radio' => $this->createRadioInput($key, $fieldLabel, $fieldOptions, $required), 'checkbox' => $this->createCheckboxInput($key, $fieldLabel, $fieldOptions), 'dropdown' => $this->createDropdownInput($key, $fieldLabel, $fieldOptions, $required), default => '', }; } // ========================================================================= // Render principale // ========================================================================= /** * Genera l'HTML completo della pagina. * Include: head con CSS, header Bootstrap Italia, breadcrumb, card con form, footer. * * @return string HTML completo della pagina */ public function render(): string { $userDisplayName = $this->properties['userDisplayName'] ?? ''; $moduleName = htmlspecialchars($this->properties['moduleName'] ?? ''); $headerTitle = $this->properties['headerTitle'] ?? ''; $headerHeroImageSrc = $this->properties['headerHeroImageSrc'] ?? ''; $cardTitle = $this->properties['cardTitle'] ?? ''; $cardDescription = $this->properties['cardDescription'] ?? ''; $alertInfoTitle = $this->properties['alertInfoTitle'] ?? ''; $alertInfoMessage = $this->properties['alertInfoMessage'] ?? ''; $instructionsTitle = $this->properties['instructionsTitle'] ?? ''; $instructionsMessage = $this->properties['instructionsMessage'] ?? ''; $submitText = $this->properties['submitText'] ?? 'INVIA'; // Verifica parametri obbligatori $missingParams = array_filter($this->mandatoryFormFieldNames, fn($p) => !isset($_GET[$p])); $hasAuthenticationError = count($missingParams) > 0; // Contenuti del form $mandatoryFields = $this->createMandatoryFormFields(); $additionalFields = $this->createAdditionalFormFields(); $customFields = $this->createCustomFormFields(); $extraContentPre = $this->renderExtraContentPre(); $extraContentPost = $this->renderExtraContentPost(); // Costruisci l'HTML della pagina ob_start(); ?> <?= htmlspecialchars($cardTitle) ?> — elixForms
Hero Image

renderCheckboxScript() ?> con il codice JS */ private function renderCheckboxScript(): string { return <<<'SCRIPT' SCRIPT; } }