Routing & URL Schemas
The Routing Engine (router.php) is the backbone of Pragma CMS. It acts as a comprehensive middleware pipeline that processes the request, enforces security, resolves the language, and executes the controller, all without querying the database for route matching.
Anatomy of a Pragma URL
TEXT
<https://domain.com> / fr / blog / tech / my-article ? utm_source=twitter
\\________________/ \\_/ \\______________________/ \\__________________/
BASE_URL Lang Route Path Query String
- Language Prefix: Extracted automatically if it matches an active language code. Exceptions like
/apior/adminbypass this requirement. - Route Path: The exact path mapped against the cached routes.
The Security Pipeline
Before any controller is executed, the router fortifies the HTTP response:
- CSRF Generation: A cryptographically secure 32-byte hexadecimal CSRF token is attached to the session.
- Dynamic CSP (Content Security Policy): The router generates a unique
nonce($GLOBALS['csp_nonce']) for the current request. This nonce must be used to execute any inline<script>tags, rendering XSS attacks virtually impossible. - Strict Headers: Injects
X-Content-Type-Options: nosniff,X-Frame-Options: SAMEORIGIN, and strict Referrer policies. - Cache Control: Forces
no-cache, must-revalidateto ensure dynamic HTML is never stale, while safely delegating asset caching (304 Not Modified) to the browser.
The High-Performance Cache Matching
Pragma CMS compiles all active routes into a highly optimized PHP array stored in storage/cache/routes/{langCode}.php. This eliminates the need for expensive database lookups on every page load.
The Validation Process:
- Regex Conversion: The router converts user-friendly patterns (e.g.,
blog/{slug}) into native Regular Expressions. - HTTP Method Check: Rejects mismatches (e.g., POST requests on a GET-only route).
- Strict Dynamic Validation: If a route utilizes dynamic placeholders (
{slug}), the router verifies the extracted value against theContentTypeManagerto ensure the entity actually exists. This prevents collisions between identical route structures (e.g., distinguishing/products/my-itemfrom/blog/my-item).
Parameter Injection & Execution
Once the route is fully validated:
- The target controller file is resolved using
resolveCascadingPath()(allowing Site overrides over Core files). - The extracted URL parameters are safely injected directly into the
$_GETsuperglobal. - The
$page->currentRouteobject is populated, giving the developer immediate access to the route's handle, parameters, and Main Content Type context.