Complete Changelog (v3.6.8 and Later)
Property | Value |
---|---|
Version Code | 3.6.8 |
Version Name | Hermes |
Published | 2024-08-28 06:36:16 |
Updated | 2025-08-28 06:36:16 |
In version 3.6.8, Luminova received broad optimizations and fixes across its core modules. We also introduced Monitor, the new error handling system. The view engine’s template rendering and core exception handling mechanisms have been significantly optimized as well.
Default HTTP error view templates can now use 4xx.php
and 5xx.php
instead of 404.php
and 500.php
to handle grouped HTTP error pages.
Fixes
Added in Version 3.6.8
Routing System
Fixed an issue where routes defined with HTTP HEAD
method were incorrectly returning 404 errors.
New Features
Added in Version 3.6.8
Base HTTP Controller
Introduced a new protected $view
property, giving controllers direct access to a lazily initialized instance of Luminova\Template\View
for template management.
$this->view->view('home')->render();
// Or directly from the application class
$this->app->view->view('home')->render();
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\Interface\ViewResponseInterface;
#[Route('/api/hello', methods: ['GET'])]
public function hello(): ViewResponseInterface
{
return response()->content([
'message' => 'Hello world'
]);
}
With middleware authentication:
If you want to return default content when middleware fails, otherwise return STATUS_ERROR
:
use Luminova\Attributes\Route;
use Luminova\Interface\ViewResponseInterface;
#[Route('/api/(:root)', methods: ['ANY'], middleware: Route::HTTP_BEFORE_MIDDLEWARE)]
public function middleware(): ViewResponseInterface|int
{
if (OK) {
return STATUS_SUCCESS;
}
return response()->failed()->content(
['message' => 'Access denied'],
['Content-Type' => 'application/json']
);
}
Using Psr\Http\Message\ResponseInterface
to return default content when middleware fails.
When middleware fails, set response status code to 500
, this way the routing system will terminate execution immidiatly.
use Luminova\Attributes\Route;
use Luminova\Http\Message\Response;
#[Route('/api/(:root)', methods: ['ANY'], middleware: Route::HTTP_BEFORE_MIDDLEWARE)]
public function middleware(): Response|int
{
if (OK) {
return STATUS_SUCCESS;
}
$body = json_encode(['message' => 'Access denied']);
return new Response(
$body,
500, // Indicate that middleware has failed
['Content-Type' => 'application/json']
);
}
Routing System
Added a new pattern
method to define and manage custom URI segment placeholders.This allows you 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, the
slug
pattern can be reused across multiple routes, ensuring consistent validation.
Core Error Monitoring System
Added Luminova\Errors\Monitor
for advanced error detection and Luminova\Errors\Message
for structured error messages. This system improves how Luminova applications detect and respond to critical issues.
Exception Error Codes
Added Luminova\Exceptions\Code
to centralize exception and error codes. Key methods include:
getName
– Retrieve a descriptive name for an error code.has
– Check if an error or exception code is recognized.
Abstract Base Exception Class
Introduce new methods:
getDescription
- Return a formatted exception message without any private file path included.isCode
method for conveniently checking if the current exception code matches one or more codes.
Example:
use Luminova\Exceptions\Code;
use Luminova\Exceptions\AppException;
use Luminova\Exceptions\RuntimeExcption;
try {
throw new RuntimeExcption('Error', Code::NOT_SUPPORTED);
} catch (AppException $e) {
if ($e->isCode(Code::DATABASE_ERROR)) {
// Handle single code
}
if ($e->isCode([Code::NOT_ALLOWED, Code::NOT_SUPPORTED])) {
// Handle multiple codes
}
}
Template View Class
The Luminova\Template\View
class now includes additional methods:
info
– Get metadata about a template file without rendering.exists
– Check if a template file exists without rendering.setUriPathDepth
– Configure the relative URI parent directory depth.
These method can be used directly inside template files:
hasOption
– Check if a context option is available in the view.isExported
– Check if a property is exported to the template scope.getExports
– Retrieve all exported properties available to the template.getExport
– Retrieve a specific property exported to the template scope.getOptions
– Get all context options for the view.getOption
– Retrieve a single context option by name.getTemplate
– Get the resolved or specified template filename.getStatusCode
– Get the HTTP status code used during rendering.
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. Returnstrue
if access is denied (fail-fast pattern),false
if 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:
#[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:
#[Route('/', methods: ['GET'], aliases: [
'/home',
'/default'
'/dashboard'
])]
public function home(): int {
return $this->view('index');
}
Global Helper Functions
Added new global helper functions for improved response handling:
redirect
– Sends an HTTP redirect using the currentResponse
instance.Supports bothLocation
andRefresh
headers and automatically terminates execution after sending.Example:
Luminova\Funcs\redirect(string $uri, ?string $method = null, int $status = 302);
abort
– Terminates execution and sends an error response with the specified HTTP status code.Useful for rejecting invalid requests or handling unexpected conditions globally.Example:
Luminova\Funcs\abort(int $status = 500, string $message = '', array $headers = []);
back
– Redirects the client to the previous page using theHTTP_REFERER
header,falling back to/
if no referrer is available.Example:
Luminova\Funcs\back(?string $method = null, int $status = 302);
Here’s a beginner-friendly, optimized version of your documentation:
Optimization and Enhancements
Updated in Version 3.6.8
Template View Class
The Luminova\Template\View
class has been improved to make template rendering faster, safer, and easier to use.
Key improvements:
- Lazy Loading – The View class is no longer a trait inside the CoreApplication. It is now loaded only when needed, which improves performance.
- Protected Scope – Templates cannot directly access private properties or methods of the View class. This keeps your data safe and prevents accidental changes.
- Consistent Rendering – Isolated rendering is strictly enforced. When not isolated,
$self
behaves exactly like$this
, making template code predictable and easier to read.
Tip for beginners:Think of the View class as a separate workspace for your templates.It only exposes what is meant to be used in templates and keeps everything else private. This prevents errors and keeps your code clean.
Session::login
The login()
method now supports role assignment at the time of authentication:
$session->login(roles: ['admin', 'editor']);
This eliminates the need for separate role setup after login and ensures consistent session initialization.
Schema Sturucture Data Generator
The Luminova\Seo\Schema
class has been optimized to improved performance and introduced new structure of schema definition, making it easier to extend and manager.
Luminova\Funcs::import
The global import()
function now supports passing variables into the imported file’s scope:
Luminova\Funcs\import('path/to/file.php', scope: ['name' => 'Peter']);
// Inside path/to/file.php:
echo $name; // Peter
Outgoing HTTP Request Helper Class (Network
)
- Added support for static method calls (
get()
,post()
,postAsync()
) to simplify HTTP requests without manually creating client objects. - Introduced
Network::config(...)
for defining default settings (base_uri
, headers, timeout). Configuration is locked after first setup to prevent changes. Improved error handling:
- Clear
BadMethodCallException
is thrown when a static method is called incorrectly (e.g., missing URL with nobase_uri
configured).
- Clear
Example:
use Luminova\Http\Network;
// Configure default settings
Network::config([
'base_uri' => 'https://api.example.com/',
'timeout' => 10,
'headers' => ['Accept' => 'application/json']
]);
// Static requests
$response = Network::get('user/42/profile');
// Async
Network::postAsync('users', ['json' => ['name' => 'Alice']])
->then(function(Response $response){
//...
});
Without Default Configuration:
Static methods also work without pre-configured defaults — simply pass the full URL and any request options directly:
use Luminova\Http\Network;
$response = Network::get('https://api.example.com/user/42/profile', [
'timeout' => 10,
'headers' => ['Accept' => 'application/json']
]);
Error Exception Class
The Luminova\Exceptions\ErrorException
class has been updated to match PHP’s native ErrorException
behavior.You can now pass the error severity, file, and line number directly when creating an instance:
new Luminova\Exceptions\ErrorException(
$message,
$code = Code::ERROR,
$severity = 1,
$file = null,
$line = null,
$previous = null
);
Error Controller Interface
The Luminova\Interface\ErrorHandlerInterface
now requires an abstract method onTrigger()
for custom HTTP status code handling. This method is called when:
- no default error handler is defined, or
Luminova\Routing\Router::trigger(xxx)
is explicitly invoked.
Example:
// /app/Errors/Controllers/ErrorController.php
public static function onTrigger(Application $app, int $status = 404, array $arguments = []): int
{
$template = match ($status) {
500 => '5xx',
// Add more custom templates per status code
default => '4xx'
};
return $app->view->view($template)->render(
['data' => $arguments],
$status
);
}
Dynamic URI Segment Placeholders
Improved placeholder matching and added new built-in types for cleaner route definitions:
(:uuid)
– matches valid UUID values.(:username)
– matches usernames containing letters, numbers, dots, underscores, or hyphens.(:version)
– matches version numbers such as1.0
,2.5.3
, or similar.
These placeholders make your routes easier to read and automatically validate the expected format of each URI segment.
Renamed
Renamed in Version 3.6.8
Update all references to these namespaces:
Luminova\Http\Client\Curl
→Luminova\Http\Client\Novio
Luminova\Core\**
→Luminova\Foundation\*
Luminova\Arrays\ArrayUtil
→Luminova\Utils\Collections\Arr
Luminova\Arrays\Listify
→Luminova\Utils\Collections\Listify
Routing System Error Handler
Setting error handler in routing system:
Luminova\Routing\Router::setErrorListener()
→ UseLuminova\Routing\Router::onError()
Exceptions
Luminova\Exceptions\*::getFilteredMessage()
→ UseLuminova\Exceptions\*::getDescription()
URI Parent Depth
Setting URL and assets parent directory depth:
Luminova\Template\View::setAssetDepth(N)
→ UseLuminova\Template\View::setUriPathDepth(N)
Route Attribute Constants
Attribute Route class middleware constants renamed for clarity:
Luminova\Attributes\Route::BEFORE_MIDDLEWARE
→ UseLuminova\Attributes\Route::HTTP_BEFORE_MIDDLEWARE
Luminova\Attributes\Route::AFTER_MIDDLEWARE
→ UseLuminova\Attributes\Route::HTTP_AFTER_MIDDLEWARE
Luminova\Attributes\Route::GLOBAL_MIDDLEWARE
→ UseLuminova\Attributes\Route::CLI_GLOBAL_MIDDLEWARE
Luminova\Attributes\Route::GUARD_MIDDLEWARE
→ UseLuminova\Attributes\Route::CLI_GROUP_MIDDLEWARE
Structured Data Generator
Schema class methods renamed for consistency:
Luminova\Seo\Schema::setConfig()
→ UseLuminova\Seo\Schema::setObject()
Luminova\Seo\Schema::getSchema()
→ UseLuminova\Seo\Schema::toJsonLd()
Luminova\Seo\Schema::getMeta()
→ UseLuminova\Seo\Schema::getHeadTags()
Luminova\Seo\Schema::getMutable()
→ UseLuminova\Seo\Schema::getObject()
Luminova\Seo\Schema::getGraph()
→ UseLuminova\Seo\Schema::getJsonLdString()
Luminova\Seo\Schema::getScript()
→ UseLuminova\Seo\Schema::getJsonLdScript()
Deprecated
Deprecated in Version 3.6.8
Sitemap Generator Command
The sitemap command now allows passing arguments to override default configurations.You can also exclude URLs using patterns, built-in placeholders, or even custom defined placeholders.
- Deprecated:
php novakit generate:sitemap
- Use instead:
php novakit sitemap
Changes
Changed in Version 3.6.8
Exception Codes Reference
Exception codes are now centralized in a dedicated Code
class.Update your exception constructors to reference codes from Luminova\Exception\Code
instead of individual exception classes.
Before:
use Luminova\Exception\RuntimeException;
throw new RuntimeException('Message', RuntimeException::INVALID);
After:
use Luminova\Exception\Code;
use Luminova\Exception\RuntimeException;
throw new RuntimeException('Message', Code::INVALID);
Routing System Error Trigger
The routing error trigger method is now private.Replace calls to triggerError()
with trigger()
.
Before:
$router->triggerError($code);
After:
$router->trigger($code);
Core Error Handling
The Luminova\Errors\ErrorHandler
class has been replaced with Luminova\Errors\Monitor
.Update references to use the new class and correct method names.
Before:
use Luminova\Errors\ErrorHandler;
ErrorHandler::*;
// Resolve error code to name
ErrorHandler::getErrorName(...);
// Deprecated error trigger
ErrorHandler::depreciate(...);
After:
use Luminova\Errors\Monitor;
Monitor::*;
// Resolve error code to name
Luminova\Exception\Code::getName(...);
// Deprecated error trigger (correct spelling)
Monitor::deprecate(...);
Note: The method is now correctly named
deprecate
, replacing the misspelleddepreciate
.