Compare commits
5 Commits
1.0.10
...
refactor_r
| Author | SHA1 | Date | |
|---|---|---|---|
| 230476e8e5 | |||
| d5871ed8e7 | |||
| ad6e07c76d | |||
| 06310d9eb9 | |||
| f679d0b20e |
21
README.md
21
README.md
@@ -6,13 +6,20 @@ NovaconiumPHP is a high-performance PHP framework designed with inspiration from
|
|||||||
|
|
||||||
Pronounced: Noh-vah-koh-nee-um
|
Pronounced: Noh-vah-koh-nee-um
|
||||||
|
|
||||||
Packagist: https://packagist.org/packages/4lt/novaconium
|
* Packagist: https://packagist.org/packages/4lt/novaconium
|
||||||
Master Repo: https://git.4lt.ca/4lt/novaconium
|
* Master Repo: https://git.4lt.ca/4lt/novaconium
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
Novaconium is heavly influenced by docker, but you can use composer outside of docker.
|
Novaconium is designed to be developed primarily using Docker. Instead of relying on tools installed directly on your system, common development tasks are executed inside containers:
|
||||||
You can [learn more about how novaconium works with composer](https://git.4lt.ca/4lt/novaconium/src/branch/master/docs/Install-Composer-On-Debian.md).
|
|
||||||
|
* Composer runs inside a Docker container rather than on your host machine
|
||||||
|
* Apache / PHP are served from containers instead of your local environment
|
||||||
|
* Sass compilation is also handled within a container
|
||||||
|
|
||||||
|
As long as you have Docker installed, you can use the full development environment without installing additional dependencies on your system.
|
||||||
|
|
||||||
|
You can [learn more about how novaconium works with composer](https://git.4lt.ca/4lt/novaconium/src/branch/master/docs/Composer.md).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
PROJECTNAME=novaproject;
|
PROJECTNAME=novaproject;
|
||||||
@@ -24,9 +31,9 @@ docker run --rm --interactive --tty --volume ./novaconium/:/app composer:latest
|
|||||||
cp -R novaconium/vendor/4lt/novaconium/skeleton/. .;
|
cp -R novaconium/vendor/4lt/novaconium/skeleton/. .;
|
||||||
|
|
||||||
# Edit .env
|
# Edit .env
|
||||||
# pwgen -cnsB1v 12 root password
|
# pwgen -cnsB1v 12 # root password
|
||||||
# pwgen -cnsB1v 12 mysql user password (need in both config and env)
|
# pwgen -cnsB1v 12 # mysql user password (need in both config and env)
|
||||||
# pwgen -cnsB1v 64 framework key (need in config)
|
# pwgen -cnsB1v 64 # framework key (need in config)
|
||||||
# Edit novaconium/App/config.php
|
# Edit novaconium/App/config.php
|
||||||
|
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ Update novaconium with composer in docker: ```docker run --rm --interactive --tt
|
|||||||
|
|
||||||
## Install Composer natively on Debian
|
## Install Composer natively on Debian
|
||||||
|
|
||||||
Assuming you have nala installed:
|
Assuming you have nala installed (otherwise use apt-get):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo nala install curl php-cli php-mbstring git unzip
|
sudo nala install curl php-cli php-mbstring git unzip
|
||||||
|
|||||||
101
docs/Router.md
Normal file
101
docs/Router.md
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
# Router
|
||||||
|
|
||||||
|
`Novaconium\Router` resolves the current HTTP request to a controller file, based on a route table defined in PHP config files. It supports exact-match routes and simple parameterized routes (e.g. `/users/{id}`).
|
||||||
|
|
||||||
|
## How it works
|
||||||
|
|
||||||
|
On construction, the router runs through this pipeline:
|
||||||
|
|
||||||
|
1. **Load routes** — merges framework-level routes with app-level routes.
|
||||||
|
2. **Prepare path** — normalizes `REQUEST_URI` into a clean path string.
|
||||||
|
3. **Prepare query** — parses the query string into an array.
|
||||||
|
4. **Determine request type** — `get` or `post`.
|
||||||
|
5. **Find controller** — matches the path against the route table.
|
||||||
|
6. **Resolve controller file** — turns the matched controller string into an actual file path, falling back to a 404 controller if needed.
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
| Property | Type | Description |
|
||||||
|
|---|---|---|
|
||||||
|
| `$routes` | array | Combined route table (framework + app routes), keyed by path pattern. |
|
||||||
|
| `$query` | array | Parsed query string parameters. |
|
||||||
|
| `$path` | string | Normalized request path. |
|
||||||
|
| `$controller` | string | Resolved controller identifier (e.g. `Users/show` or `NOVACONIUM/Errors`). |
|
||||||
|
| `$controllerPath` | string | Absolute file path to the controller. |
|
||||||
|
| `$parameters` | array | Named parameters extracted from a parameterized route match. |
|
||||||
|
| `$requestType` | string | `'get'` or `'post'`. |
|
||||||
|
|
||||||
|
## Route table format
|
||||||
|
|
||||||
|
Routes are defined as an associative array, keyed by URL path. Each entry maps HTTP methods to a controller string:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$routes = [
|
||||||
|
'/' => [
|
||||||
|
'get' => 'Home/index',
|
||||||
|
],
|
||||||
|
'/users/{id}' => [
|
||||||
|
'get' => 'Users/show',
|
||||||
|
],
|
||||||
|
'/login' => [
|
||||||
|
'get' => 'Auth/loginForm',
|
||||||
|
'post' => 'Auth/login',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
Controller strings starting with `NOVACONIUM` are resolved against the framework's controller directory (e.g. `NOVACONIUM/Errors` → `FRAMEWORKPATH/controllers/Errors.php`); all other controller strings are resolved against the app's controller directory (`BASEPATH/App/controllers/`).
|
||||||
|
|
||||||
|
## Matching behavior
|
||||||
|
|
||||||
|
### 1. Exact match
|
||||||
|
|
||||||
|
The router first checks for an exact match between `$this->path` and a key in `$this->routes`. If found, and the current request type has a handler defined, that controller is returned immediately.
|
||||||
|
|
||||||
|
### 2. Parameterized match
|
||||||
|
|
||||||
|
If no exact match is found, the router scans the route table for patterns containing `{`. For each candidate:
|
||||||
|
|
||||||
|
- The **static prefix** of the pattern (everything before the first `{`) must prefix-match the current path.
|
||||||
|
- The pattern and the path must have the **same number of `/`-separated segments**.
|
||||||
|
|
||||||
|
The first route pattern satisfying both conditions is treated as the match — the router does not keep searching for a "better" match after this point, even if the matched route turns out to have no handler for the current request method (see [Known quirks](#known-quirks) below).
|
||||||
|
|
||||||
|
Once a candidate route is selected, the router walks its segments looking for the first `{param}` segment, extracts the corresponding path segment into `$this->parameters[paramName]`, and returns immediately with the controller for the current request type.
|
||||||
|
|
||||||
|
### 3. No match
|
||||||
|
|
||||||
|
If neither an exact nor a parameterized match is found, `$this->controller` is set to `'404'`, and `setRouteFile()` will fail to find a corresponding controller file, triggering the 404 fallback described below.
|
||||||
|
|
||||||
|
## Controller file resolution (`setRouteFile`)
|
||||||
|
|
||||||
|
Given the resolved `$this->controller` string:
|
||||||
|
|
||||||
|
1. If it starts with `NOVACONIUM`, look in `FRAMEWORKPATH/controllers/`.
|
||||||
|
2. Otherwise, look in `BASEPATH/App/controllers/`.
|
||||||
|
3. If the file exists, use it.
|
||||||
|
4. If not, fall back to `BASEPATH/App/controllers/404.php` if it exists.
|
||||||
|
5. Otherwise, fall back to the framework's built-in `FRAMEWORKPATH/controllers/404.php`.
|
||||||
|
|
||||||
|
## Known quirks
|
||||||
|
|
||||||
|
These behaviors exist in the current implementation and are preserved intentionally for backward compatibility — they're documented here so they aren't mistaken for bugs during future changes.
|
||||||
|
|
||||||
|
- **Only the first `{param}` in a route pattern is captured.** If a route pattern has multiple parameters (e.g. `/users/{id}/posts/{postId}`), only `id` is extracted into `$this->parameters`; `postId` is never processed, because the matching loop returns as soon as it finds the first parameter segment.
|
||||||
|
- **The first prefix+segment-count match wins, even without a method handler.** If a parameterized route's static prefix and segment count match the request, but that route has no handler defined for the current request type (e.g. the route only defines `get` but the request is `post`), the router still commits to that route and returns `null` as the controller (which then falls through to the 404 controller). It does **not** continue searching for another route that might have a valid handler.
|
||||||
|
- **No support for trailing wildcard or optional segments.** Segment counts must match exactly between the pattern and the path; there's no support for `*` or optional `{param?}` style segments.
|
||||||
|
|
||||||
|
## Debugging
|
||||||
|
|
||||||
|
Call `$router->debug()` to dump the resolved path, controller path, extracted parameters, and full route table as an HTML table, then halt execution via `die()`. Intended for development use only.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```php
|
||||||
|
$router = new \Novaconium\Router();
|
||||||
|
|
||||||
|
include $router->controllerPath;
|
||||||
|
|
||||||
|
// Inside the controller, access route parameters via:
|
||||||
|
$router->parameters['id'];
|
||||||
|
```
|
||||||
@@ -1,12 +1,10 @@
|
|||||||
# Sample Docker Compose
|
# Sample Docker Compose
|
||||||
services:
|
services:
|
||||||
corxn:
|
corxn:
|
||||||
image: 4lights/corxn:6.0.0
|
image: 4lights/corxn:8.5.3
|
||||||
ports:
|
ports:
|
||||||
- "8000:80"
|
- "8000:80"
|
||||||
volumes:
|
volumes:
|
||||||
- "/etc/timezone:/etc/timezone:ro"
|
|
||||||
- "/etc/localtime:/etc/localtime:ro"
|
|
||||||
- ./novaconium:/data
|
- ./novaconium:/data
|
||||||
- ./data/logs:/var/log/apache2 # Optional Logs
|
- ./data/logs:/var/log/apache2 # Optional Logs
|
||||||
- "./logs:/data/logs"
|
- "./logs:/data/logs"
|
||||||
@@ -29,8 +27,6 @@ services:
|
|||||||
MYSQL_USER: novaconium
|
MYSQL_USER: novaconium
|
||||||
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
|
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
|
||||||
volumes:
|
volumes:
|
||||||
- "/etc/timezone:/etc/timezone:ro"
|
|
||||||
- "/etc/localtime:/etc/localtime:ro"
|
|
||||||
- ./data/db:/var/lib/mysql
|
- ./data/db:/var/lib/mysql
|
||||||
networks:
|
networks:
|
||||||
- internal
|
- internal
|
||||||
@@ -49,9 +45,6 @@ services:
|
|||||||
- PMA_USER=root
|
- PMA_USER=root
|
||||||
- PMA_PASSWORD=${MYSQL_ROOT_PASSWORD}
|
- PMA_PASSWORD=${MYSQL_ROOT_PASSWORD}
|
||||||
- UPLOAD_LIMIT=200M
|
- UPLOAD_LIMIT=200M
|
||||||
volumes:
|
|
||||||
- "/etc/timezone:/etc/timezone:ro"
|
|
||||||
- "/etc/localtime:/etc/localtime:ro"
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
proxy:
|
proxy:
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// ini_set('display_errors', 1);
|
// ini_set('display_errors', 1);
|
||||||
|
|
||||||
// Define the base path where the website is running from
|
// Define the base path where the website is running from
|
||||||
define('BASEPATH', dirname(__DIR__, 1));
|
define('BASEPATH', dirname(__DIR__));
|
||||||
|
|
||||||
// Load Composer's autoload file to handle class autoloading
|
// Load Composer's autoload file to handle class autoloading
|
||||||
require BASEPATH . '/vendor/autoload.php';
|
require BASEPATH . '/vendor/autoload.php';
|
||||||
|
|||||||
216
src/Router.php
216
src/Router.php
@@ -1,5 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Novaconium;
|
namespace Novaconium;
|
||||||
|
|
||||||
class Router {
|
class Router {
|
||||||
public $routes = [];
|
public $routes = [];
|
||||||
public $query = [];
|
public $query = [];
|
||||||
@@ -10,120 +11,185 @@ class Router {
|
|||||||
public $requestType = 'get';
|
public $requestType = 'get';
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
$this->routes = $this->loadRoutes();
|
$this->routes = $this->loadRoutes();
|
||||||
$this->path = $this->preparePath();
|
$this->path = $this->preparePath();
|
||||||
$this->query = $this->prepareQuery();
|
$this->query = $this->prepareQuery();
|
||||||
$this->requestType = $this->getRequestType();
|
$this->requestType = $this->getRequestType();
|
||||||
$this->controller = $this->findController();
|
$this->controller = $this->findController();
|
||||||
$this->controllerPath = $this->setRouteFile();
|
$this->controllerPath = $this->setRouteFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge framework routes with app-defined routes (app routes can override framework routes).
|
||||||
|
*/
|
||||||
private function loadRoutes() {
|
private function loadRoutes() {
|
||||||
require_once( \FRAMEWORKPATH . '/config/routes.php');
|
require_once(\FRAMEWORKPATH . '/config/routes.php');
|
||||||
// Check if Path exists
|
|
||||||
if (file_exists(\BASEPATH . '/App/routes.php')) {
|
|
||||||
require_once( \BASEPATH . '/App/routes.php');
|
|
||||||
}
|
|
||||||
$routes = array_merge((array)$routes, (array)$framework_routes);
|
|
||||||
|
|
||||||
return $routes;
|
if (file_exists(\BASEPATH . '/App/routes.php')) {
|
||||||
|
require_once(\BASEPATH . '/App/routes.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_merge((array)$routes, (array)$framework_routes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize the request path: strip query string, trailing slash, and anything after "&".
|
||||||
|
*/
|
||||||
private function preparePath() {
|
private function preparePath() {
|
||||||
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
|
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
|
||||||
|
|
||||||
//homepage
|
|
||||||
if ($path === '/') {
|
if ($path === '/') {
|
||||||
return $path;
|
return $path;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove empty directory path
|
$path = rtrim($path, '/');
|
||||||
$path = rtrim($path, '/'); // remove trailing slash
|
|
||||||
|
|
||||||
//remove anything after and including ampersand
|
|
||||||
$path = preg_replace('/&.+$/', '', $path);
|
$path = preg_replace('/&.+$/', '', $path);
|
||||||
|
|
||||||
return $path;
|
return $path;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function prepareQuery() {
|
private function prepareQuery() {
|
||||||
$parsedUri = parse_url($_SERVER['REQUEST_URI']);
|
$parsedUri = parse_url($_SERVER['REQUEST_URI']);
|
||||||
$queryArray = [];
|
$queryArray = [];
|
||||||
|
|
||||||
if (isset($parsedUri['query'])) {
|
if (isset($parsedUri['query'])) {
|
||||||
parse_str($parsedUri['query'], $queryArray);
|
parse_str($parsedUri['query'], $queryArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $queryArray;
|
return $queryArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getRequestType() {
|
private function getRequestType() {
|
||||||
// is the requewst a get or post?
|
return empty($_POST) ? 'get' : 'post';
|
||||||
if (empty($_POST)) {
|
|
||||||
return 'get';
|
|
||||||
} else {
|
|
||||||
return 'post';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve the current path to a controller string.
|
||||||
|
* First tries an exact match, then falls back to matching parameterized
|
||||||
|
* routes like "/users/{id}".
|
||||||
|
*/
|
||||||
private function findController() {
|
private function findController() {
|
||||||
|
$exactMatch = $this->findExactMatch();
|
||||||
// one to one match
|
if ($exactMatch !== null) {
|
||||||
if (array_key_exists($this->path, $this->routes)) {
|
return $exactMatch;
|
||||||
if (!empty($this->routes[$this->path][$this->requestType])) {
|
|
||||||
return $this->routes[$this->path][$this->requestType];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->routes as $key => $value) {
|
$paramMatch = $this->findParameterizedMatch();
|
||||||
// Check if key contains a curly bracket, if not continue. We already checked above.
|
if ($paramMatch !== null) {
|
||||||
if (!strpos($key, '{')) continue;
|
return $paramMatch;
|
||||||
|
|
||||||
// Remove everything after the curly bracket, from key
|
|
||||||
$keyPath = substr($key, 0, strpos($key, '{'));
|
|
||||||
|
|
||||||
//see if keyPath matches the first characters of $this->path, only the first characters have to match
|
|
||||||
if (strpos($this->path, $keyPath) === 0) {
|
|
||||||
|
|
||||||
// We have a potential match. Now check if the parameter count is equal
|
|
||||||
$keyParams = explode('/', $key);
|
|
||||||
$pathParams = explode('/', $this->path);
|
|
||||||
$keyParamCount = count($keyParams);
|
|
||||||
$pathParamCount = count($pathParams);
|
|
||||||
if ($keyParamCount === $pathParamCount) {
|
|
||||||
for ($i=0; $i < $pathParamCount; $i++) {
|
|
||||||
if (strpos($keyParams[$i], '{') !== false) {
|
|
||||||
$keyParams[$i] = substr($keyParams[$i], 1, -1);
|
|
||||||
$this->parameters[$keyParams[$i]] = $pathParams[$i];
|
|
||||||
return $this->routes[$key][$this->requestType];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return '404';
|
return '404';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks if the file exists, sets file path
|
private function findExactMatch() {
|
||||||
|
if (array_key_exists($this->path, $this->routes)
|
||||||
|
&& !empty($this->routes[$this->path][$this->requestType])
|
||||||
|
) {
|
||||||
|
return $this->routes[$this->path][$this->requestType];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loop over parameterized routes (those containing "{") looking for the
|
||||||
|
* first one whose static prefix matches the path AND whose segment count
|
||||||
|
* matches. As soon as such a route is found, control is handed off to
|
||||||
|
* extractControllerFromMatch(), which returns immediately (even with a
|
||||||
|
* `null` controller) -- this mirrors the original code's behavior of
|
||||||
|
* stopping the search on the first prefix+segment-count match, rather
|
||||||
|
* than continuing on to try other candidate routes.
|
||||||
|
*/
|
||||||
|
private function findParameterizedMatch() {
|
||||||
|
foreach ($this->routes as $routePattern => $methods) {
|
||||||
|
// Only parameterized routes (containing "{") are relevant here;
|
||||||
|
// plain routes were already checked in findExactMatch().
|
||||||
|
if (strpos($routePattern, '{') === false) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->routeMatchesPath($routePattern)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->segmentCountsMatch($routePattern)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Original behavior: once we find a route with a matching prefix
|
||||||
|
// and segment count, we commit to it -- even if it turns out
|
||||||
|
// there's no handler for the current request method.
|
||||||
|
return $this->extractControllerFromMatch($routePattern, $methods);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Quick check: does the static portion of the route pattern (everything
|
||||||
|
* before the first "{") prefix-match the current path?
|
||||||
|
*/
|
||||||
|
private function routeMatchesPath($routePattern) {
|
||||||
|
$staticPrefix = substr($routePattern, 0, strpos($routePattern, '{'));
|
||||||
|
|
||||||
|
return strpos($this->path, $staticPrefix) === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function segmentCountsMatch($routePattern) {
|
||||||
|
$patternSegments = explode('/', $routePattern);
|
||||||
|
$pathSegments = explode('/', $this->path);
|
||||||
|
|
||||||
|
return count($patternSegments) === count($pathSegments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts named parameters into $this->parameters and returns the
|
||||||
|
* controller for the current request type (or null if that method
|
||||||
|
* isn't defined for this route).
|
||||||
|
*
|
||||||
|
* Matches the original quirk: only the FIRST "{param}" segment found
|
||||||
|
* gets added to $this->parameters, and the method returns right away --
|
||||||
|
* any additional "{param}" segments later in the pattern are never
|
||||||
|
* processed. This is preserved as-is rather than "fixed", since
|
||||||
|
* behavior should stay unchanged.
|
||||||
|
*/
|
||||||
|
private function extractControllerFromMatch($routePattern, $methods) {
|
||||||
|
$patternSegments = explode('/', $routePattern);
|
||||||
|
$pathSegments = explode('/', $this->path);
|
||||||
|
|
||||||
|
foreach ($patternSegments as $i => $segment) {
|
||||||
|
if (strpos($segment, '{') !== false) {
|
||||||
|
$paramName = substr($segment, 1, -1); // strip { }
|
||||||
|
$this->parameters[$paramName] = $pathSegments[$i];
|
||||||
|
|
||||||
|
return $methods[$this->requestType] ?? null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve the controller string to an actual file path, falling back to a 404 controller.
|
||||||
|
*/
|
||||||
private function setRouteFile() {
|
private function setRouteFile() {
|
||||||
|
|
||||||
if (str_starts_with($this->controller, 'NOVACONIUM')) {
|
if (str_starts_with($this->controller, 'NOVACONIUM')) {
|
||||||
$trimmed = substr($this->controller, strlen('NOVACONIUM/'));
|
$trimmed = substr($this->controller, strlen('NOVACONIUM/'));
|
||||||
$cp = \FRAMEWORKPATH . '/controllers/' . $trimmed . '.php';
|
$controllerPath = \FRAMEWORKPATH . '/controllers/' . $trimmed . '.php';
|
||||||
} else {
|
} else {
|
||||||
$cp = \BASEPATH . '/App/controllers/' . $this->controller . '.php';
|
$controllerPath = \BASEPATH . '/App/controllers/' . $this->controller . '.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_exists($cp)) {
|
if (file_exists($controllerPath)) {
|
||||||
return $cp;
|
return $controllerPath;
|
||||||
} else {
|
|
||||||
//Check if 404 exits
|
|
||||||
if (file_exists( \BASEPATH . '/App/controllers/404.php')) {
|
|
||||||
return \BASEPATH . '/App/controllers/404.php';
|
|
||||||
} else {
|
|
||||||
return \FRAMEWORKPATH . '/controllers/404.php';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (file_exists(\BASEPATH . '/App/controllers/404.php')) {
|
||||||
|
return \BASEPATH . '/App/controllers/404.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
return \FRAMEWORKPATH . '/controllers/404.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function debug() {
|
public function debug() {
|
||||||
@@ -134,9 +200,7 @@ class Router {
|
|||||||
echo '<tr><th>Parameters</th><td><pre>' . print_r($this->parameters, true) . '</pre></td></tr>';
|
echo '<tr><th>Parameters</th><td><pre>' . print_r($this->parameters, true) . '</pre></td></tr>';
|
||||||
echo '<tr><th>Routes</th><td><pre>' . print_r($this->routes, true) . '</pre></td></tr>';
|
echo '<tr><th>Routes</th><td><pre>' . print_r($this->routes, true) . '</pre></td></tr>';
|
||||||
echo '</table></div>';
|
echo '</table></div>';
|
||||||
|
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,5 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Novaconium\Logger;
|
||||||
|
use Novaconium\Session;
|
||||||
|
use Novaconium\MessageHandler;
|
||||||
|
use Novaconium\Database;
|
||||||
|
use Novaconium\Post;
|
||||||
|
use Novaconium\Redirect;
|
||||||
|
use Novaconium\Router;
|
||||||
|
|
||||||
|
$db = null;
|
||||||
|
$post = null;
|
||||||
|
|
||||||
// --- Load Config ---
|
// --- Load Config ---
|
||||||
if (file_exists(\BASEPATH . '/App/config.php')) {
|
if (file_exists(\BASEPATH . '/App/config.php')) {
|
||||||
require_once \BASEPATH . '/App/config.php';
|
require_once \BASEPATH . '/App/config.php';
|
||||||
@@ -11,7 +22,6 @@ require_once \FRAMEWORKPATH . '/src/functions.php';
|
|||||||
require_once \FRAMEWORKPATH . '/src/twig.php';
|
require_once \FRAMEWORKPATH . '/src/twig.php';
|
||||||
|
|
||||||
// --- Logging ---
|
// --- Logging ---
|
||||||
use Novaconium\Logger;
|
|
||||||
$log = new Logger(\BASEPATH . $config['logfile'], $config['loglevel']);
|
$log = new Logger(\BASEPATH . $config['logfile'], $config['loglevel']);
|
||||||
|
|
||||||
// --- Twig Data Array ---
|
// --- Twig Data Array ---
|
||||||
@@ -21,35 +31,29 @@ $data['matomo_url'] = $config['matomo_url'] ?? '';
|
|||||||
$data['matomo_id'] = $config['matomo_id'] ?? '0';
|
$data['matomo_id'] = $config['matomo_id'] ?? '0';
|
||||||
|
|
||||||
// --- Session ---
|
// --- Session ---
|
||||||
use Novaconium\Session;
|
|
||||||
$session = new Session();
|
$session = new Session();
|
||||||
$data['token'] = $session->get('token');
|
$data['token'] = $session->get('token');
|
||||||
$data['username'] = $session->get('username');
|
$data['username'] = $session->get('username');
|
||||||
|
|
||||||
// --- Messages ---
|
// --- Messages ---
|
||||||
use Novaconium\MessageHandler;
|
|
||||||
$messages = new MessageHandler($session->flash('messages'));
|
$messages = new MessageHandler($session->flash('messages'));
|
||||||
foreach (['error', 'notice'] as $key) {
|
foreach (['error', 'notice'] as $key) {
|
||||||
$data[$key] = $messages->showMessages($key);
|
$data[$key] = $messages->showMessages($key);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Database ---
|
// --- Database ---
|
||||||
use Novaconium\Database;
|
|
||||||
if (!empty($config['database']['host'])) {
|
if (!empty($config['database']['host'])) {
|
||||||
$db = new Database($config['database']);
|
$db = new Database($config['database']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- POST Wrapper ---
|
// --- POST Wrapper ---
|
||||||
use Novaconium\Post;
|
|
||||||
if (!empty($_POST)) {
|
if (!empty($_POST)) {
|
||||||
$post = new Post($_POST);
|
$post = new Post($_POST);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Redirect Handler ---
|
// --- Redirect Handler ---
|
||||||
use Novaconium\Redirect;
|
|
||||||
$redirect = new Redirect();
|
$redirect = new Redirect();
|
||||||
|
|
||||||
// --- Router ---
|
// --- Router ---
|
||||||
use Novaconium\Router;
|
|
||||||
$router = new Router();
|
$router = new Router();
|
||||||
require_once $router->controllerPath;
|
require_once $router->controllerPath;
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
>
|
>
|
||||||
|
|
||||||
{# STYLESHEET #}
|
{# STYLESHEET #}
|
||||||
<link rel="stylesheet" href="/css/main.css">
|
<link rel="stylesheet" href="/css/novaconium.css">
|
||||||
|
|
||||||
{# highlight.js #}
|
{# highlight.js #}
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user