Luminova Framework

Complete Changelog (v3.6.8 and Later)

PropertyValue
Version Code3.6.8
Version NameHermes
Published2024-08-28 06:36:16
Updated2025-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(): arrayRetrieve all roles currently stored in the session.

  • guard(array $roles, int $mode = Session::GUARD_ANY, ?callable $onDenied = null): boolValidate roles against access rules. Returns true 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 current Response instance.Supports both Location and Refresh 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 the HTTP_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:

  1. Lazy Loading – The View class is no longer a trait inside the CoreApplication. It is now loaded only when needed, which improves performance.
  2. Protected Scope – Templates cannot directly access private properties or methods of the View class. This keeps your data safe and prevents accidental changes.
  3. 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 no base_uri configured).

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 as 1.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\CurlLuminova\Http\Client\Novio
  • Luminova\Core\**Luminova\Foundation\*
  • Luminova\Arrays\ArrayUtilLuminova\Utils\Collections\Arr
  • Luminova\Arrays\ListifyLuminova\Utils\Collections\Listify

Routing System Error Handler

Setting error handler in routing system:

  • Luminova\Routing\Router::setErrorListener()Use Luminova\Routing\Router::onError()

Exceptions

  • Luminova\Exceptions\*::getFilteredMessage()Use Luminova\Exceptions\*::getDescription()

URI Parent Depth

Setting URL and assets parent directory depth:

  • Luminova\Template\View::setAssetDepth(N)Use Luminova\Template\View::setUriPathDepth(N)

Route Attribute Constants

Attribute Route class middleware constants renamed for clarity:

  • Luminova\Attributes\Route::BEFORE_MIDDLEWAREUse Luminova\Attributes\Route::HTTP_BEFORE_MIDDLEWARE
  • Luminova\Attributes\Route::AFTER_MIDDLEWAREUse Luminova\Attributes\Route::HTTP_AFTER_MIDDLEWARE
  • Luminova\Attributes\Route::GLOBAL_MIDDLEWAREUse Luminova\Attributes\Route::CLI_GLOBAL_MIDDLEWARE
  • Luminova\Attributes\Route::GUARD_MIDDLEWAREUse Luminova\Attributes\Route::CLI_GROUP_MIDDLEWARE

Structured Data Generator

Schema class methods renamed for consistency:

  • Luminova\Seo\Schema::setConfig()Use Luminova\Seo\Schema::setObject()
  • Luminova\Seo\Schema::getSchema()Use Luminova\Seo\Schema::toJsonLd()
  • Luminova\Seo\Schema::getMeta()Use Luminova\Seo\Schema::getHeadTags()
  • Luminova\Seo\Schema::getMutable()Use Luminova\Seo\Schema::getObject()
  • Luminova\Seo\Schema::getGraph()Use Luminova\Seo\Schema::getJsonLdString()
  • Luminova\Seo\Schema::getScript()Use Luminova\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 misspelled depreciate.