- Gli elenchi tengono ricerca, filtri e ordinamento nell'indirizzo (#[Url]); la pagina c'era già. - I link verso schede e operazioni (data-ritorno) portano ?da= con la pagina di partenza, o il da già ricevuto: si risale all'origine (elenco -> scheda -> Rientra -> elenco filtrato). - Ritorno::valida accetta solo percorsi interni: niente rimandi esterni. - Trait RicordaRitorno: redirect dopo il salvataggio, Annulla e "Torna indietro" usano la pagina di partenza. Senza da, tutto come prima. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
50 lines
1.6 KiB
PHP
50 lines
1.6 KiB
PHP
<?php
|
|
|
|
namespace App\Support;
|
|
|
|
/**
|
|
* La pagina da cui è partito un percorso, per tornarci dopo un'operazione.
|
|
*
|
|
* I link che aprono una scheda o un'operazione portano `?da=<percorso>`
|
|
* (lo aggiunge resources/js/app.js ai link con data-ritorno): il percorso
|
|
* della pagina di partenza con i suoi filtri, o il `da` che quella pagina
|
|
* aveva già ricevuto, così si risale sempre all'origine. Elenco → scheda →
|
|
* Rientra → conferma riporta all'elenco filtrato.
|
|
*
|
|
* Si accettano solo percorsi interni ("/territori?zona=3"): un indirizzo
|
|
* completo o "//altro.sito" farebbe del parametro un rimando verso l'esterno.
|
|
*/
|
|
final class Ritorno
|
|
{
|
|
public const PARAM = 'da';
|
|
|
|
/** L'URL a cui tornare, o null se il valore non è un percorso interno valido. */
|
|
public static function valida(mixed $percorso): ?string
|
|
{
|
|
if (! is_string($percorso) || $percorso === '' || strlen($percorso) > 2000) {
|
|
return null;
|
|
}
|
|
|
|
if (! str_starts_with($percorso, '/')
|
|
|| str_starts_with($percorso, '//')
|
|
|| str_contains($percorso, '\\')
|
|
|| preg_match('/[\x00-\x1F\x7F]/', $percorso)) {
|
|
return null;
|
|
}
|
|
|
|
// Le richieste interne di Livewire non sono pagine.
|
|
$path = (string) parse_url($percorso, PHP_URL_PATH);
|
|
if ($path === '' || str_starts_with($path, '/livewire')) {
|
|
return null;
|
|
}
|
|
|
|
return url($percorso);
|
|
}
|
|
|
|
/** Il ritorno indicato dalla richiesta corrente (?da=…), se valido. */
|
|
public static function daRichiesta(): ?string
|
|
{
|
|
return self::valida(request()->query(self::PARAM));
|
|
}
|
|
}
|