Files
elixforms-web-pages/.agents/skills/php-create-new-page/SKILL.md
T

7.8 KiB

name, description
name description
elixforms-php-create-new-page Guida step-by-step per creare una nuova pagina custom PHP nel progetto elixForms. Copre la struttura dei file, l'importazione della libreria common, le convenzioni di naming, e la configurazione per il deploy su Apache. Attiva questa skill quando devi creare una nuova pagina PHP, duplicare una pagina esistente, o scaffoldare un nuovo micro-progetto PHP nel monorepo.

Creare una Nuova Pagina PHP elixForms Custom

Prerequisiti

  • PHP 8.0+ installato
  • Web server Apache configurato per servire la cartella php/

Step 1: Creare la Cartella della Pagina

cd php
mkdir <nome-pagina>

Il nome della cartella deve essere in kebab-case (es. scelta-carriera, recupero-proposta).

Step 2: Creare il File index.php

Creare php/<nome-pagina>/index.php:

<?php

declare(strict_types=1);

require_once __DIR__ . '/../common/ElixFormsComponent.php';

use ElixForms\Common\ElixFormsComponent;

/**
 * Pagina custom "<NomePagina>" per elixForms.
 */
class NomePaginaPage extends ElixFormsComponent
{
    protected function createCustomFormFields(): string
    {
        $html = '';

        // Aggiungi qui i campi del form usando i metodi factory:
        // $html .= $this->createTextInput('COL0001', 'Campo Testo', true);
        // $html .= $this->createDropdownInput('COL0002', 'Scelta', [...options], true);

        return $html;
    }

    // Opzionale: contenuto extra prima del form
    // protected function renderExtraContentPre(): string { return ''; }

    // Opzionale: contenuto extra dopo il form
    // protected function renderExtraContentPost(): string { return ''; }
}

// Entry point
$page = new NomePaginaPage([
    'moduleName' => 'Nome Modulo',
    'cardTitle' => 'Titolo Pagina',
    'cardDescription' => 'Descrizione della pagina.',
    'userDisplayName' => '',         // Verrà popolato da elixForms
    'headerTitle' => '',
    'headerHeroImageSrc' => '',
    'alertInfoTitle' => '',
    'alertInfoMessage' => '',
    'instructionsTitle' => '',
    'instructionsMessage' => '',
    'submitText' => 'INVIA',
]);

echo $page->render();

Step 3: Definire i Campi Custom

Sovrascrivere createCustomFormFields() con i campi necessari:

protected function createCustomFormFields(): string
{
    $html = '';

    // Dropdown
    $html .= $this->createDropdownInput('COL0015', 'Scelta', [
        ['value' => 0, 'label' => 'Opzione A'],
        ['value' => 1, 'label' => 'Opzione B'],
        ['value' => 2, 'label' => 'Opzione C'],
    ], true);

    // Testo
    $html .= $this->createTextInput('COL0002', 'Nome', true);

    // Textarea
    $html .= $this->createTextAreaInput('COL0003', 'Note', false);

    // Booleano (Sì/No)
    $html .= $this->createBooleanInput('COL0004', 'Conferma', true);

    // Radio
    $html .= $this->createRadioInput('COL0005', 'Preferenza', [
        ['value' => 1, 'label' => 'Prima scelta'],
        ['value' => 2, 'label' => 'Seconda scelta'],
    ], true);

    // Checkbox
    $html .= $this->createCheckboxInput('COL0006', 'Opzioni Multiple', [
        ['value' => 1, 'label' => 'Opzione 1'],
        ['value' => 2, 'label' => 'Opzione 2'],
    ]);

    // Numerico
    $html .= $this->createNumberInput('COL0007', 'Quantità', true);

    return $html;
}

Step 4: Opzionale — Aggiungere File di Configurazione

Per pagine complesse, creare un file config.json nella cartella della pagina:

{
    "component": {
        "moduleName": "Nome Modulo",
        "cardTitle": "Titolo",
        "cardDescription": "Descrizione",
        "submitText": "CONFERMA"
    },
    "elixForms": {
        "inputs": {
            "codiceFiscale": "COL0009"
        },
        "outputs": {
            "campo1": "COL0001",
            "campo2": "COL0002"
        }
    }
}

Caricare nel PHP:

$config = json_decode(file_get_contents(__DIR__ . '/config.json'), true);

$page = new NomePaginaPage($config['component']);
echo $page->render();

Step 4.1: Pagine Interattive e Chiamate Asincrone (AJAX)

Se la pagina richiede autocompletamento o interattività (es. ricerca contratti):

1. Proxy Script PHP Locale

Per non esporre credenziali sensibili (API Key, Basic Auth) al client, creare sempre uno script proxy locale (es. search-contratti.php) che:

  • Riceve i dati dal client.
  • Esegue la chiamata protetta tramite HttpClient.
  • Valida con json_decode che la risposta sia JSON valido prima di inviarla.
  • Risponde con 500 e un JSON d'errore pulito in caso di eccezioni.

2. Risoluzione Percorso URL in JavaScript

Il server integrato PHP non esegue il redirect automatico per aggiungere lo slash alla fine delle cartelle. In JavaScript, calcolare sempre la base directory dinamica per supportare URL sia con che senza slash finale o con index.php esplicito:

var baseDir = window.location.pathname;
if (!baseDir.endsWith('/') && !baseDir.endsWith('.php')) {
    baseDir += '/';
}
var lastSlash = baseDir.lastIndexOf('/');
var dir = baseDir.substring(0, lastSlash + 1);

var url = dir + 'search-contratti.php?term=' + encodeURIComponent(term);

3. Parsing Sicuro degli Errori HTTP (Fetch)

Non eseguire direttamente response.json() su risposte d'errore (500/404) o non-JSON per evitare il crash Unexpected token '<'. Utilizzare la tecnica del response.text():

fetch(url)
    .then(function(response) {
        return response.text().then(function(text) {
            var data = null;
            try {
                data = JSON.parse(text);
            } catch (e) {
                // Risposta non JSON (es. HTML d'errore del server)
            }

            if (!response.ok) {
                var errMsg = (data && data.message) ? data.message :
                             (data && data.error) ? data.error :
                             ('Errore API: ' + response.status + ' ' + response.statusText);
                throw new Error(errMsg);
            }

            if (data === null) {
                throw new Error('Risposta del server non in formato JSON.');
            }

            return data;
        });
    })

Step 5: Testing Locale

Per testare le pagine localmente, è necessario avviare il server web dalla cartella radice php/ (in modo che la cartella common/ sia accessibile correttamente):

Opzione 1: PHP CLI Server locale

cd php
php -S localhost:8080

Aprire nel browser:

http://localhost:8080/<nome-pagina>/?RWE2_MODULE_ID=123&RWE2_REQUEST_ID=456&COL0002=test&COL0015=3

Opzione 2: Docker

Dalla root del repository, eseguire:

docker run --rm -p 8080:8080 -v "${PWD}/php:/app" -w /app php:8.2-cli php -S 0.0.0.0:8080

Aprire nel browser:

http://localhost:8080/<nome-pagina>/?RWE2_MODULE_ID=123&RWE2_REQUEST_ID=456&COL0002=test&COL0015=3

Step 6: Deploy su Apache

  1. Caricare la cartella php/ (o la singola cartella della pagina) sul server Apache
  2. Assicurarsi che Apache abbia mod_php o php-fpm configurato
  3. La pagina sarà accessibile via URL diretto (es. https://server.example.com/php/nome-pagina/)
  4. elixForms reindirizza l'utente alla pagina passando i parametri in query string

Struttura Finale

php/<nome-pagina>/
├── index.php         ← Entry point e classe pagina
└── config.json       ← Opzionale: configurazione separata

Checklist Nuova Pagina PHP

  • Cartella creata in php/<nome-pagina>/
  • index.php con declare(strict_types=1) e namespace
  • Classe che estende ElixFormsComponent
  • createCustomFormFields() sovrascritta con i campi corretti
  • Proprietà di configurazione impostate correttamente
  • require_once __DIR__ . '/../common/ElixFormsComponent.php'
  • Test locale con php -S o Docker
  • Verifica che i campi form producano l'HTML corretto
  • Verifica che i parametri obbligatori vengano letti da $_GET