191 lines
7.2 KiB
Markdown
191 lines
7.2 KiB
Markdown
---
|
|
name: elixforms-php-common-library
|
|
description: >
|
|
Documentazione della libreria condivisa PHP common/ del progetto elixForms.
|
|
Descrive la classe base ElixFormsComponent, i metodi factory per i campi form,
|
|
ElixFormsElement per il layout, QueryParamHelper per i query parameter,
|
|
e il pattern di ereditarietà per creare pagine custom.
|
|
Attiva questa skill quando lavori sui componenti PHP condivisi, crei nuovi tipi di campo,
|
|
modifichi la classe base, o integri con la piattaforma elixForms in PHP.
|
|
---
|
|
|
|
# Libreria Common PHP elixForms
|
|
|
|
## Panoramica
|
|
|
|
La cartella `php/common/` contiene la libreria condivisa PHP usata da tutte le pagine custom PHP. È basata su **Bootstrap Italia + HTML nativo** e implementa un sistema di form con campi dinamici, analogo alla libreria React in `react/common/`.
|
|
|
|
## Architettura delle Classi
|
|
|
|
```
|
|
ElixFormsComponent (classe astratta, PHP 8.0+)
|
|
└── SceltaCarrieraPage (classe concreta, in scelta-carriera/index.php)
|
|
└── [AltrePageCustom] (classi concrete nelle sotto-cartelle)
|
|
```
|
|
|
|
### Namespace
|
|
|
|
Tutte le classi usano il namespace PSR-4:
|
|
```php
|
|
namespace ElixForms\Common;
|
|
```
|
|
|
|
Le pagine importano con:
|
|
```php
|
|
require_once __DIR__ . '/../../vendor/autoload.php';
|
|
use ElixForms\Common\ElixFormsComponent;
|
|
```
|
|
|
|
## File della Libreria
|
|
|
|
### `ElixFormsComponent.php` (Classe Base Astratta)
|
|
|
|
Equivalente di `ElixFormsComponentAbstract.tsx` in React.
|
|
|
|
#### Proprietà
|
|
|
|
```php
|
|
protected array $properties; // Equivalente di IElixFormsComponentProperties
|
|
```
|
|
|
|
Chiavi supportate in `$properties`:
|
|
| Chiave | Tipo | Obbligatorio | Descrizione |
|
|
|---|---|---|---|
|
|
| `moduleName` | string | Sì | Nome del modulo nel breadcrumb |
|
|
| `cardTitle` | string | Sì | Titolo della card principale |
|
|
| `userDisplayName` | string | No | Nome utente nell'header |
|
|
| `headerTitle` | string | No | Titolo sotto il breadcrumb |
|
|
| `headerHeroImageSrc` | string | No | URL immagine hero |
|
|
| `cardDescription` | string | No | Descrizione nella card |
|
|
| `alertInfoTitle` | string | No | Titolo alert informativo |
|
|
| `alertInfoMessage` | string | No | Messaggio alert informativo |
|
|
| `instructionsTitle` | string | No | Titolo istruzioni |
|
|
| `instructionsMessage` | string | No | Messaggio istruzioni |
|
|
| `submitText` | string | No | Testo bottone submit (default: 'INVIA') |
|
|
| `additionalFieldsJson` | string | No | JSON schema per campi dinamici |
|
|
| `isDarkTheme` | bool | No | Tema scuro (riservato per uso futuro) |
|
|
|
|
#### Metodi Factory (Campi Form)
|
|
|
|
| Metodo | Tipo Campo | HTML Output |
|
|
|---|---|---|
|
|
| `createTextInput($name, $label, $required)` | Testo | `<input type="text">` |
|
|
| `createTextAreaInput($name, $label, $required)` | Textarea | `<textarea>` |
|
|
| `createNumberInput($name, $label, $required)` | Numerico | `<input type="number">` |
|
|
| `createBooleanInput($name, $label, $required)` | Booleano (Sì/No) | Radio buttons |
|
|
| `createRadioInput($name, $label, $options, $required)` | Radio | Radio buttons |
|
|
| `createCheckboxInput($name, $label, $options)` | Checkbox multipli | Checkboxes + hidden |
|
|
| `createDropdownInput($name, $label, $options, $required)` | Dropdown | `<select>` |
|
|
| `createHiddenInput($name)` | Nascosto | `<input type="hidden">` |
|
|
|
|
#### Metodi Estensibili (Override)
|
|
|
|
```php
|
|
// Campi custom del form — OBBLIGATORIO sovrascrivere
|
|
protected function createCustomFormFields(): string { return ''; }
|
|
|
|
// Contenuto extra prima del form
|
|
protected function renderExtraContentPre(): string { return ''; }
|
|
|
|
// Contenuto extra dopo il form
|
|
protected function renderExtraContentPost(): string { return ''; }
|
|
```
|
|
|
|
#### Metodo Principale
|
|
|
|
```php
|
|
public function render(): string
|
|
```
|
|
|
|
Genera l'HTML **completo** della pagina (`<!DOCTYPE html>` ... `</html>`), includendo:
|
|
- `<head>` con CSS Bootstrap Italia e design system UniPR
|
|
- Header con logo UniPR e nome utente
|
|
- Breadcrumb
|
|
- Card con alert, istruzioni, form e campi
|
|
- Footer "powered by elixForms"
|
|
- Script JS per checkbox
|
|
|
|
### `ElixFormsElement.php` (Wrapper Layout)
|
|
|
|
Genera il layout a due colonne per ogni campo form:
|
|
|
|
```php
|
|
$element = new ElixFormsElement($labelHtml, $inputHtml, $separator);
|
|
echo $element->render();
|
|
```
|
|
|
|
Output HTML:
|
|
```html
|
|
<div class="row mb-3 align-items-start">
|
|
<div class="col-12 col-md-4">
|
|
<div class="text-md-end pe-md-3 mt-2">{label}</div>
|
|
</div>
|
|
<div class="col-12 col-md-8">
|
|
{input}
|
|
</div>
|
|
</div>
|
|
```
|
|
|
|
### `QueryParamHelper.php` (Utility Query String)
|
|
|
|
Classe statica per leggere parametri dalla query string `$_GET`:
|
|
|
|
```php
|
|
QueryParamHelper::getCheckedFromQuery('COL0006'); // int[] (checkbox, valori separati da virgola)
|
|
QueryParamHelper::getOptionFromQuery('COL0015'); // ?int (radio/dropdown)
|
|
QueryParamHelper::getBooleanFromQuery('COL0004'); // ?bool (boolean)
|
|
QueryParamHelper::getDecodedTextFromQuery('COL0002'); // ?string (testo URL-decoded)
|
|
```
|
|
|
|
### `HttpClient.php` (Utility Richieste HTTP REST)
|
|
|
|
Adapter applicativo basato su Guzzle per effettuare chiamate HTTP server-to-server sicure verso Web Service esterni (es. endpoint contratti). Accetta un `GuzzleHttp\\ClientInterface` opzionale nel costruttore per consentire mocking e test senza traffico di rete:
|
|
|
|
```php
|
|
use ElixForms\Common\HttpClient;
|
|
|
|
$client = new HttpClient([
|
|
'X-Api-Key' => 'chiave-api-custom',
|
|
'Accept' => 'application/json'
|
|
]);
|
|
$client->setBasicAuth('username', 'password');
|
|
$client->setTimeout(10); // timeout in secondi
|
|
|
|
// Richiesta GET
|
|
$response = $client->get('http://api-endpoint/cerca', [
|
|
'parametro1' => 'valore1'
|
|
]);
|
|
```
|
|
|
|
**Best Practices gestite da HttpClient:**
|
|
- **Timeout**: Gestione dei timeout di connessione ed esecuzione per evitare blocchi infiniti del server Apache.
|
|
- **Sicurezza delle credenziali**: Permette di eseguire chiamate server-side mantenendo chiavi API e password nascoste al browser del client.
|
|
- **Error Handling**: Se il server remoto restituisce codici HTTP diversi da 20x (es. 404, 500), solleva una `RuntimeException` contenente il codice di stato generico senza includere nel messaggio d'errore l'eventuale payload della risposta (es. tag HTML dell'errore di Apache) per motivi di sicurezza ed integrità del JSON finale.
|
|
|
|
## Differenze rispetto alla versione React
|
|
|
|
| Aspetto | React | PHP |
|
|
|---|---|---|
|
|
| **Rendering** | Client-side (JSX → DOM) | Server-side (PHP → HTML) |
|
|
| **State** | `this.state` + `this.setState()` | Valori da `$_GET` (stateless) |
|
|
| **Checkbox sync** | React state + hidden input | JS client-side + hidden input |
|
|
| **Build** | Vite → single bundle JS | Nessuna build necessaria |
|
|
| **CSS** | Iniettato nel JS | `<link>` tags nell'HTML |
|
|
| **Output** | Singolo file `.js` | File `.php` serviti da Apache |
|
|
|
|
## Parametri Obbligatori elixForms
|
|
|
|
Gestiti automaticamente come hidden inputs dalla classe base:
|
|
- `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`
|
|
|
|
## Note Importanti
|
|
|
|
- Il form fa POST a `https://procedure.unipr.it/rwe2/ComeBackToElixAndSave`
|
|
- L'encoding charset è `ISO-8859-1` per compatibilità con il backend
|
|
- Gli ID dei campi form **non devono mai essere manipolati** (vedi AGENTS.md)
|
|
- L'ID dell'hidden input dei checkbox e dei mandatory fields ha suffisso `_hidden`
|
|
- I checkbox usano un attributo `data-param` e uno script JS per sincronizzare il valore con l'hidden input
|