Ga naar inhoud

Request lifecycle & routing

De webshop heeft drie afzonderlijke ingangspoorten voor HTTP-verkeer, elk met een eigen lifecycle. Dit document beschrijft hoe een request binnenkomt, verwerkt wordt en antwoord krijgt.


Overzicht: vier ingangspoorten

Ingangspoort Bestand Gebruik
Storefront (pagina's) _www/index.php Alle paginaverzoeken van klanten
AJAX / inline-API _www/api.php Asynchrone verzoeken vanuit de browser (_f-parameter)
Externe publieke API _api/index.php Externe koppelingen (EDI, voertuigdata, klantorders)
Admin control panel _cp/index.php Interne Slim 4-app op admin.atraxion.com

1. Storefront — _www/index.php

Stap-voor-stap lifecycle

sequenceDiagram
    participant Browser
    participant index as _www/index.php
    participant bootstrap as bootstrap.php
    participant config as _core/config/config.php
    participant router as _core/config/router.php (Slim)
    participant slim as Slim 4 App
    participant handler as NotFoundHandler
    participant legacy as atx\Router
    participant ctrl as atx\...Controller
    participant view as atx\...View

    Browser->>index: HTTP GET /nl/producten/...
    index->>bootstrap: require bootstrap.php
    bootstrap->>bootstrap: vendor/autoload, constants, Sentry-init, sessie
    index->>index: offline-check (is_offline()) → exit indien offline
    index->>index: PATH_INFO bepalen uit REQUEST_URI
    index->>config: require appconfig/config.php
    config->>config: initLogin / UserController (sessie-check)
    config->>router: require _core/router.php → router()
    router->>slim: AppFactory::create() + middleware-stack
    slim->>slim: addRoutingMiddleware, FirewallMiddleware, GatedChannelMiddleware, ...
    slim->>slim: routeMatch?
    alt Route gevonden (Slim-route)
        slim->>ctrl: Slim-controller (Atraxion\...\ of Odoo\Controller\...)
        ctrl-->>Browser: PSR-7 Response
    else Route niet gevonden (HttpNotFoundException)
        slim->>handler: FallthroughHandler → NotFoundHandler
        handler->>handler: analyze(request): PATH_INFO → PageDAO::getTemplate()
        handler->>legacy: atx\Router::route(template, action, params, PageDef)
        legacy->>legacy: dispatchPage() → dispatchRoute() → legacy fallback
        legacy->>ctrl: atx\...(Page/Web)Controller::execAction()
        ctrl->>view: atx\...View::execAction()
        view-->>Browser: HTML-response (output-buffering)
    end

Gedetailleerde stappen

1. _www/index.php (regels 1–48)

  • :3require __DIR__ . '/appconfig/bootstrap.php' — laadt vendor-autoload, constanten, Sentry en sessie.
  • :5–8Offline-check via is_offline(true) — indien offline: Atraxion\load_page('offline') en exit. (Vóór PATH_INFO, want een offline shop mag niets parsen.)
  • :10–14PATH_INFO bepalen uit REQUEST_URI als het niet al door de webserver is gezet.
  • Rootpagina (/) leidt door naar de standaardtaal: redirect(sprintf('/%s/', get_user_locale())) (_www/index.php:17–19).
  • require_once __DIR__ . '/appconfig/config.php' — laadt de verdere routering.

2. _www/appconfig/config.php

  • Laadt opnieuw bootstrap.php (idempotent) en daarna APP_CORE_PATH . '/config/config.php'.

3. _core/config/config.php (regels 1–19)

  • Registreert een globale fouthandler.
  • Voert sessie-initialisatie uit: UserController::execAction('initLogin') — controleert de ingelogde status en laadt klantcontext.
  • require APP_CORE_PATH . '/router.php' — start de eigenlijke routering.

4. _core/router.php (regels 1–4)

Dit is een dunne shim:

$router = require APP_CORE_PATH . '/config/router.php';
$router();

Het laadt _core/config/router.php, dat een anonieme functie teruggeeft, en roept die onmiddellijk aan.

5. _core/config/router.php — Slim 4 app + middleware

Hier wordt de eigenlijke Slim 4-applicatie opgebouwd (_core/config/router.php:9–146):

  • AppFactory::create(null, $container) — container is de ServiceRegistry-container.
  • Middleware-stack — Slim 4 voert middleware in LIFO-volgorde uit (last added = outermost). Volgorde van buiten naar binnen (_core/config/router.php:128–135):
  • OfflineMiddleware — offline-pagina (buitenste laag, toegevoegd als laatste op regel 135)
  • InjectUserMiddleware — klant in context injecteren
  • StickyTwoFactorMiddleware — 2FA-sessiecontrole
  • GatedChannelMiddleware — channel-toegangscontrole (mini-shop-licentie)
  • RoutingMiddleware — Slim-routing
  • FirewallMiddleware — IP-based blokkering
  • BodyParsingMiddleware — JSON/form-body-parsing
  • FlushEntitiesMiddleware — flush Doctrine-entities na request (binnenste laag, toegevoegd als eerste op regel 128)

  • Expliciete Slim-routes (voorbeelden) — controllers komen uit meerdere namespaces:

  • GET|POST /exchangeAtraxion\Exchange\Controller\ExchangeController (Pay.nl callback) — router.php:87
  • GET|POST /two-factorAtraxion\Authentication\Controller\AuthenticationControllerrouter.php:89
  • GET /api/search/{term}Atraxion\Front\Controller\Api\SiteSearchControllerrouter.php:67
  • GET /{_locale}/errors/404Atraxion\Front\Controller\ErrorController::error404router.php:17
  • GET /api/products/synchroniseOdoo\Controller\ProductPricesControllerrouter.php:58–60
  • GET /api/suppliers/{id}/synchroniseOdoo\Controller\ProductStockControllerrouter.php:63
  • /distributors/orders/*Atraxion\Front\Controller\DistributorControllerrouter.php:98–102
  • /order-documents/*Atraxion\Front\Controller\DocumentPortalControllerrouter.php:107–125
  • /api/vehicle-brands/*Atraxion\Model\Vehicle\Controller\MakesController / ModelsControllerrouter.php:69–77

  • Error-handler: FallthroughHandler (src/Atraxion/Front/Handler/FallthroughHandler.php) is de werkelijke default error handler — delegeert naar NotFoundHandler alleen bij HttpNotFoundException; overige exceptions gaan door naar Slim's ingebouwde default error handler (router.php:137–143).

6. FallthroughHandlerNotFoundHandler — legacy routing fallback

Wanneer geen Slim-route overeenkomt, vangt FallthroughHandler (src/Atraxion/Front/Handler/FallthroughHandler.php) de HttpNotFoundException op en delegeert naar NotFoundHandler (src/Atraxion/Front/Handler/NotFoundHandler.php). NotFoundHandler:

  • AJAX-request (is_ajax() = true): parst $_REQUEST[AJAX_FUNCTION] (de _f-parameter) op sFunction_sAction-formaat (NotFoundHandler.php:38–43).
  • Pagina-request: parst PATH_INFO → haalt via PageDAO::getTemplate($urlParts[1]) de paginadefinitie op (NotFoundHandler.php:46–81). URL-segmenten op even posities (index 2, 4, …) worden als sleutel/waarde-paren in $_GET/$_POST/$_REQUEST gezet.
  • Roept atx\Router::route($template, $action, $_REQUEST, $oPageDef) aan.

7. atx\Router — custom route-dispatcher

_core/model/classes/atx/Router.php heeft drie dispatching-lagen:

  1. dispatchPage() (Router.php:77–119): als er een $oPageDef is, zoekt het de template-string op. Bestaat er een klasse met die naam? → container->get($template)->execAction($action). Anders: statische pagina via StaticPageController.

  2. dispatchRoute() (Router.php:240–257): zoekt de route in _core/config/routing.php (en _admin/config/routing.php bij admin-context). Gedelegeerd aan de bijbehorende atx\..Controller via container->get($controllerClass)->execAction($action).

  3. Legacy-fallback (Router.php:143–220): raadpleegt _core/controller/config/a_ajaxController.php (AJAX) of a_legacyController.php, laadt het gevonden PHP-bestand via router_dispatchLegacyRoute().

8. Controller → View

atx\Controller::execAction() (_core/controller/classes/atx/Controller.php:397–477):

  • Controleert of de actie in Params() bestaat.
  • Voert de actiemethode uit.
  • Bepaalt automatisch de bijbehorende View-klasse: naam van controller min Controller + View (Controller.php:435–439).
  • Roept $this->view->execAction($action) aan.
  • Bij AJAX-modus ($context->bAjax = true): retourneert JSON via returnJSON().
  • Bij pagina-modus: buffer wordt als HTML uitvoer gestuurd.

2. AJAX / inline-API — _www/api.php

_www/api.php verwerkt asynchrone verzoeken vanuit de browser:

Browser → api.php → bootstrap.php → config.php → _core/router.php (Slim+legacy)

Bijzonderheden:

  • Controleert of $_REQUEST[AJAX_FUNCTION] (= _f) aanwezig is; zo niet: exit(1) (api.php:5–7).
  • Na bootstrap en config.php loopt het request door dezelfde Slim-app en NotFoundHandler als een pagina-request, maar is_ajax() retourneert true.
  • In NotFoundHandler::analyze() wordt dan de _f-waarde geparsed op sFunction_sAction-formaat: explode('_', $_REQUEST[AJAX_FUNCTION]) (NotFoundHandler.php:38–43). Het eerste deel is de route-naam, de rest de actie.
  • De Controller retourneert JSON via returnJSON().

3. Externe publieke API — _api/index.php

_api/index.php is een volledig zelfstandige Slim 4-applicatie, los van de storefront:

Externe client → _api/index.php → bootstrap.php (gedeeld) → Slim 4 App → Controller → JSON

Bijzonderheden (_api/index.php:1–134):

  • Bootstrapt via require __DIR__ . '/../_www/appconfig/bootstrap.php' — deelt dezelfde constanten en ServiceRegistry.
  • Bouwt een eigen Slim\App op met eigen middleware (BodyParsingMiddleware, ClientMiddleware, TrafficRecordingMiddleware).
  • Routes zijn RESTful (geen _f-parameter):
  • POST /edi en POST /tyrestreamEdiController (EDI-orders)
  • GET /vehicle-brands/* → voertuig-API
  • GET|POST /products/* en /orders/* en /invoices/* → klant-API
  • GET /odoo/* → Odoo-API (beveiligd met ApiKeyMiddleware)
  • Eigen JSON-error-handler via ErrorHandlerInterface.
  • Geen gebruik van NotFoundHandler of legacy atx\Router.

Routing-configuratie: named routes (_core/config/routing.php)

De legacy custom router laadt named routes uit _core/config/routing.php. Elke entry koppelt een route-naam aan een controllerklasse:

'wheelsearch' => 'atx\articles\wheels\WheelSearchController',
'tyresearch'  => 'atx\articles\tyres\TyreSearchController',
'cart'        => 'atx\customers\cart\CartController',
'user'        => 'atx\customers\UserController',
// ...

De router definieert drie contexten als infrastructuur: * (publiek), loggedin, en admin (Router.php:15–19). In de praktijk zijn alleen * en admin ingevuld met routes:

  • _core/config/routing.php → uitsluitend '*'-context
  • _admin/config/routing.php → uitsluitend 'admin'-context

De loggedin-context bestaat als sleutel in de routes-array maar er zijn nergens loggedin-routes gedefinieerd. Bij admin-context (checkManage()) worden de routes uit _admin/config/routing.php geladen (Router.php:28–32).


4. Admin control panel — _cp/index.php

_cp/index.php is een volledig zelfstandige Slim 4-applicatie, bereikbaar op admin.atraxion.com (Apache-vhost mapt admin.* naar DocumentRoot _cp/):

Beheerder → _cp/index.php → bootstrap.php (gedeeld) → Slim 4 App → Atraxion\Admin\Controller\... → JSON/Twig

Bijzonderheden:

  • Bootstrapt via require __DIR__ . '/../_www/appconfig/bootstrap.php' — deelt dezelfde constanten, ServiceRegistry en Doctrine-setup met de storefront.
  • Service-providers: Atraxion\Admin\ServiceProvider\{SlimServiceProvider, AdminServiceProvider, ApiServiceProvider}.
  • Controllers in src/Atraxion/Admin/Controller/; Twig-templates in templates/admin/.
  • Geen gebruik van de legacy atx\Router of NotFoundHandler.

Samenvatting: storefront-routing gebruikt Slim én een custom router

De storefront gebruikt Slim 4 als eerste laag: expliciete routes (exchange, API-endpoints, documentenportaal, …) worden door Slim afgehandeld. Controllers komen uit meerdere namespaces (Atraxion\... én Odoo\...). Voor alle overige URLs valt Slim terug via FallthroughHandler op NotFoundHandler, die de legacy atx\Router aanroept. De legacy router zoekt vervolgens in _core/config/routing.php of valt terug op legacy controller-bestanden.

De externe API (_api/) en het admin control panel (_cp/) zijn elk een afzonderlijke Slim 4-app zonder legacy-fallback.


Zie ook: Autoloading & namespaces · Service container & bootstrap · Tech stack