Salt la conținut

Rutare

Sistemul de rutare din Leto este construit în jurul clasei RoutesCollector, care expune metode fluente pentru definirea rutelor.

Definirea rutelor

Rutele se definesc în metoda routes() a clasei aplicației sau a modulelor:

namespace App;

use App\Controllers\HelloController;
use App\Controllers\FormController;
use Leto\AppBuilder\Application;
use Leto\Routing\RoutesCollector;

class App extends Application
{
    public function routes(RoutesCollector $route): void
    {
        $route->get('/', [HelloController::class, 'hello']);
        $route->post('/submit', [FormController::class, 'submit']);
        $route->put('/update/{id}', [UpdateController::class, 'update']);
        $route->delete('/delete/{id}', [DeleteController::class, 'delete']);
    }
}
Folosește mereu use Leto\AppBuilder\Application; și extends Application. Dacă scrii extends Leto\AppBuilder\Application fără backslash într-un fișier cu namespace App;, PHP caută clasa în App\Leto\AppBuilder\Application și primești o eroare de clasă inexistentă.

Parametri de rută

Un segment între acolade ({id}, {slug}) devine un parametru dinamic:

$route->get('/users/{id}', [UserController::class, 'show']);
$route->get('/posts/{slug}', [PostController::class, 'view']);

Cum citești parametrii în controller

Parametrii rutei ajung în controller după nume: {id} din URL se leagă de argumentul $id al metodei (contează numele, nu poziția). Nu trebuie să faci nimic special, doar declară argumentul:

namespace App\Controllers;

use Leto\Http\Response;

class UserController
{
    public function show(int $id): Response
    {
        $user = User::find($id);

        return new Response(['user' => $user]);
    }
}

Aceiași parametri sunt disponibili și pe request()->attributes (ex: request()->attributes->get('id')), util când nu vrei să-i declari ca argumente.

Rute numite

Al treilea argument al metodelor get()/post()/etc. dă rutei un nume, ca să poți genera URL-ul mai târziu fără să hardcodezi path-ul:

// Definește o rută numită
$route->get('/users/{id}', [UserController::class, 'show'], 'users.show');

// Generează URL-ul cu funcția globală route()
$url = route('users.show', ['id' => 5]);  // https://exemplu.com/users/5

Grupuri de rute

group() aplică un prefix comun (și, opțional, middleware comun) unui set de rute, ca să nu repeți path-ul de bază:

$route->group('/admin', function (RoutesCollector $route) {
    $route->get('/', [AdminController::class, 'dashboard']);      // /admin/
    $route->get('/users', [AdminController::class, 'users']);     // /admin/users
})->middleware(AuthMiddleware::class);

Constrângeri și prioritate

where() restrânge un parametru la un regex, iar priority() decide ce rută câștigă când mai multe se potrivesc:

$route->get('/posts/{id}', [PostController::class, 'show'])
      ->where(['id' => '\d+'])   // {id} acceptă doar cifre
      ->priority(10);            // prioritate mai mare = verificată prima

Middleware

Rutele pot avea middleware atașat:

$route->get('/admin', [AdminController::class, 'dashboard'])
      ->middleware(AuthMiddleware::class);

Interfața middleware:

use Closure;
use Leto\Http\Redirect;
use Leto\Http\Request;
use Leto\Routing\MiddlewareInterface;

class AuthMiddleware implements MiddlewareInterface
{
    public function handle(Request $request, Closure $next)
    {
        if (!isset($_SESSION['user'])) {
            return new Redirect('/login');
        }
        return $next($request);
    }
}

Managerul de rute

RoutesManager coordonează încărcarea rutelor din toate modulele aplicației. Fiecare modul își înregistrează rutele prin propria metodă routes().