Repository navigation
3.6.8
Full Changelog: 3.6.6...3.6.8
Version 3.6.8 brings a major cleanup across Luminova’s core. Many parts were renamed, optimized, or fixed, and several new helper classes were added, including Password, String, and the improved error-handling system. The template view engine and the core exception layer also received substantial tuning.
Default HTTP error templates now support grouped pages using 4xx.php and 5xx.php, replacing the old 404.php and 500.php pattern.
Fixes
Routing System
Fixed an issue where routes defined with HTTP HEAD method were incorrectly returning 404 errors.
New Features
HTTP Controller Methods
HTTP controller routable methods can now return Psr\Http\Message\ResponseInterface, Luminova\Interface\ViewResponseInterface, or the traditional int.
Example
Using Luminova\Template\Response class.
use Luminova\Attributes\Route;
use Luminova\Http\Message\Response;
use Psr\Http\Message\ResponseInterface;
#[Route('/api/hello', methods: ['GET'])]
public function hello(): ViewResponseInterface
{
return new Response('Hello world', 200);
}Routing System
Added a new pattern method to define and manage custom URI segment placeholders.
This allows you to create reusable patterns for route parameters, improving maintainability and reducing repetition of patterns.
// In App\Application::onCreate()
Router::pattern('slug', '[a-z0-9-]+');
// In App\Controllers
#[Luminova\Attributes\Route('/blog/(:slug)', methods: ['GET'])]
public function blog(string $slug): int
{
// Handle blog route using the slug value
}Note:
Once defined, theslugpattern can be reused across multiple routes, ensuring consistent validation.
Password Helper
A new Password helper has been added to handle all password-related operations in one place.
Now:
use Luminova\Security\Password;
$hash = Password::hash('pass');
Password::verify('pass', $hash);
// Additional utilities:
Password::rehash('pass', $hash);
Password::strength('pass');
Password::isCompromised('pass');
// and more...Before:
Crypter::password('pass');
Crypter::isPassword('pass', 'hash');Proxy Helper
A dedicated Proxy helper is now available for checking and validating HTTP/SOCKS proxies.
Now:
use Luminova\Utility\Proxy;
$proxy = '';
Proxy::validate($proxy);
Proxy::ping($proxy);
// and more...String Helper
A new Str helper provides object-based string manipulation features.
Now:
use Luminova\Utility\String\Str;
$str = Str::of('peter');
echo $str->length(); // 5
echo $str->toUpperCase()
->trim(); // PETER
// and more...Backend Session Class
The Session class now supports role-based access control, with methods for finer-grained permission management:
-
roles(array $roles)
Assign user roles to the session. -
getRoles(): array
Retrieve all roles currently stored in the session. -
guard(array $roles, int $mode = Session::GUARD_ANY, ?callable $onDenied = null): bool
Validate roles against access rules. Returnstrueif access is denied (fail-fast pattern),falseif access is granted. -
toSessionId(string $id, string $algo = 'sha256')
Convert a string into a valid PHP session ID.Example:
Convert a system identifier into a valid PHP session ID for persistent CLI logins.
use Luminova\Command\Terminal; use Luminova\Sessions\Session; $sid = Session::toSessionId(Terminal::getSystemId());
Supported Guard Modes:
Session::GUARD_ANY(default): Access granted if at least one role matches.Session::GUARD_ALL: Access granted only if all roles match.Session::GUARD_EXACT: Access granted only if all and only the specified roles match.Session::GUARD_NONE: Access granted only if none of the roles are present.
Example:
if ($session->guard(['admin', 'moderator'], Session::GUARD_ALL)) {
throw new AccessDenied('Insufficient privileges.');
}PHP Route Attribute
A new $aliases property has been added to the Route attribute to define multiple alternative URI patterns for the same controller method.
Before (using multiple attributes)
Previously, to map several URIs to the same method, you had to repeat the Route attribute:
// /app/Controllers/Http/ExampleController.php
use Luminova\Attributes\Route;
#[Route('/', methods: ['GET'])]
#[Route('/home', methods: ['GET'])]
#[Route('/default', methods: ['GET'])]
#[Route('/dashboard', methods: ['GET'])]
public function home(): int
{
return $this->view('index');
}Now (using aliases)
You can achieve the same result with a single attribute, improving readability and reducing duplication:
// /app/Controllers/Http/ExampleController.php
use Luminova\Attributes\Route;
#[Route('/', methods: ['GET'], aliases: [
'/home',
'/default'
'/dashboard'
])]
public function home(): int
{
return $this->view('index');
}PHP Prefix Attribute
The Prefix attribute now supports a new $exclude property that allows you to specify URI prefixes to exclude from controller matching. This removes the need for complex negative-lookahead patterns.
Before (manual regex exclusions)
// /app/Controllers/Http/MainController.php
use Luminova\Attributes\Prefix;
#[Prefix(pattern: '/(?!api(?:/|$)|admin(?:/|$)).*')]
class MainController extends Controller
{
}Now (using the built-in exclude list)
// /app/Controllers/Http/MainController.php
use Luminova\Attributes\Prefix;
#[Prefix(pattern: '/(:base)', exclude: [
'api',
'admin'
])]
class MainController extends Controller
{
}Full Changes documentation.