PHPackages                             equites/core - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. equites/core

ActiveLibrary[Framework](/categories/framework)

equites/core
============

Core framework

v1.1.0(4mo ago)128.3kPHPPHP &gt;=8.3CI failing

Since Oct 4Pushed 4mo ago1 watchersCompare

[ Source](https://github.com/LausEquites/Core)[ Packagist](https://packagist.org/packages/equites/core)[ RSS](/packages/equites-core/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (9)Versions (5)Used By (0)

Core PHP framework
==================

[](#core-php-framework)

A lightweight, modular framework focused on keeping things simple while providing the essentials for building APIs and apps.

This repository contains the Core runtime (routing, controllers, ActiveRecord, config, etc.) and a minimal example app showing how to wire it up.

General
-------

[](#general)

### File structure (recommended for apps using Core)

[](#file-structure-recommended-for-apps-using-core)

- app/ — application code
- app/backend/ — backend services (API, domain, DB access)
- app/frontend/ — frontend assets/app
- app/public/ — public web root (web server document root)

Backend
-------

[](#backend)

The backend framework is LausEquites/Core (this repo). Your application code lives in your own repository; it consumes Core as a dependency and follows the structure and conventions below.

Project file structure (backend)
--------------------------------

[](#project-file-structure-backend)

- config/ — configuration files (e.g., routing structure.xml)
- db/ — Phinx database migrations
- NAMESPACE/ — your application namespace root
    - NAMESPACE/Controllers/ — controllers
    - NAMESPACE/Models/ — models

See the example app under the example/ directory for a minimal working setup.

Controllers
-----------

[](#controllers)

### Controller basics

[](#controller-basics)

Controllers are linked to routes declared in an XML file (config/structure.xml). The XML is hierarchical with a root element mapping to the path /. The router resolves controllers by walking this tree.

- In your bootstrap, define the root class namespace for controllers. In the example app:
    - Router::loadRoutes('config/structure.xml')
    - Router::setNameSpace('Controllers')
    - See example/index.php
- Each XML element name maps to a class under the configured namespace. Child elements can use a different namespace via attributes.

Supported XML attributes:

- child-ns — the class namespace for child elements (can be nested)
- params — comma-separated parameters that become part of the path (available to controller methods)

Example XML:

```

```

Path to class resolution:

- / -&gt; NAMESPACE\\Controllers\\Root
- /api -&gt; NAMESPACE\\Controllers\\Api
- /api/login -&gt; NAMESPACE\\Controllers\\Login
- /api/users -&gt; NAMESPACE\\Controllers\\Users
- /api/users/settings -&gt; NAMESPACE\\Controllers\\Users\\Settings

### Controller classes

[](#controller-classes)

If your controller extends Core\\Controller\\Json, you can return any data; the Json controller will set the Content-Type and JSON-encode non-string responses.

HTTP method dispatch:

- The method used to call the endpoint (GET, POST, PATCH, etc.) determines the method invoked on the resolved controller class.
- If the route defines params, the method name will have \_PARAMS appended.

Example: GET /api/users resolves to NAMESPACE\\Controllers\\Users::GET

Lifecycle hooks:

- preServe(): called on all classes in the request path before the main method. Use this to enforce auth, short-circuit requests, or populate properties for later use.

Errors:

- Throw Core\\Exceptions\\External for API errors. The exception code is used as the HTTP status code. Messages for 5xx (&gt;= 500) are not returned to the client.

### Controller methods

[](#controller-methods)

- Use $this-&gt;getParameter(name) or $this-&gt;getParameters() to access path params.
- Use $this-&gt;getRouterParameter(name) for router parameters.

Example
-------

[](#example)

A minimal example is provided under example/:

- example/config/structure.xml — route structure
- example/index.php — bootstraps the router and sets the namespace
- example/Controllers — sample controllers including a JSON controller example

Quick start (from example/):

```
$router = Core\Router::getInstance();
$router->loadRoutes('config/structure.xml');
$router->setNameSpace('Controllers');
$router->run();
```

Core\\Router reference
----------------------

[](#corerouter-reference)

The Core\\Router is a minimal XML-driven router that maps request URIs to controller classes and dispatches them.

What it does:

- Loads a hierarchical XML (structure.xml) mirroring the URL path.
- Splits REQUEST\_URI into segments and walks the XML accordingly.
- Resolves controller class names from XML element names under a configured root namespace.
- Supports attributes on XML elements:
    - child-ns: append this namespace segment for all child elements under the current node.
    - params: comma-separated parameter names. Subsequent URI segments will be consumed into these names in order.
- Instantiates controllers found along the traversed path (if the class exists) and calls their optional preServe() before dispatch.
- Injects router parameters into each instantiated controller via setRouterParameters(array $params) and marks per-controller owned params via setOwnRouterParameters(array $names). This enables GET\_PARAMS/POST\_PARAMS, etc., on controllers that own params.
- Calls serve() on the final controller and echoes its return value. If you extend Core\\Controller\\Json, the output will be JSON with appropriate headers.

404 behavior:

- If a URI segment does not match a node and no pending param is defined for that position, the router throws an Exception with message starting with "404 -".

Path inspection:

- getPath(): returns an array of matched node names and parameter tokens (e.g., \["api", ":userId", "settings"\]). Useful for logging/debugging.

Wiring:

- loadRoutes(string $path): path to your structure.xml.
- setNameSpace(string $namespace): root controller namespace, e.g., "Controllers".
- run(): performs the routing and dispatch for the current request.

Core\\Controller reference
--------------------------

[](#corecontroller-reference)

The Core\\Controller class is the lightweight base used by the router to invoke your controller methods.

Key responsibilities:

- Parse the JSON request body once and expose it via getParameters() and getParameter(name, default).
- Expose router parameters (from config/structure.xml) via getRouterParameters() and getRouterParameter(name, default).
- Dispatch to a method named after the HTTP verb (GET, POST, PATCH, DELETE, ...). If the controller declares that it owns route params, the method name will include the suffix \_PARAMS.
- Throw Core\\Exceptions\\External with status 501 when a verb method is not implemented.

Request body handling:

- The request body is read from php://input and decoded as JSON into an object (stdClass).
- getParameters(): returns the whole object (or null if absent).
- getParameter($name, $default = null): returns a single property or the provided default.

Router parameters:

- getRouterParameters(): returns all router params as an associative array.
- getRouterParameter($name, $default = null): returns a single router param value or the default/null.
- setRouterParameters(array $params): used by the router to inject params for the current request.

Owning parameters and \_PARAMS dispatch:

- setOwnRouterParameters(string\[\] $names): declare which router parameters are considered this controller’s own.
- getOwnRouterParameters(): returns only the subset of router params owned by this controller.
- When own params are set, serve() will resolve to methods like GET\_PARAMS, POST\_PARAMS, etc., if they exist.

Dispatch semantics:

- serve(): determines the target method from $\_SERVER\['REQUEST\_METHOD'\] and the \_PARAMS suffix (if own params are set), then invokes it. If the method does not exist, an External exception is thrown with code 501.

Error handling:

- Throw Core\\Exceptions\\External for client/server errors. Its code is used as the HTTP status. For 5xx errors the message is not exposed to clients.

Tip: If you extend Core\\Controller\\Json, non-string return values from your action methods will be JSON-encoded automatically and the Content-Type: application/json header will be set.

Core\\Controller\\Json reference
--------------------------------

[](#corecontrollerjson-reference)

Core\\Controller\\Json is a convenience base class for building JSON APIs.

What it does:

- Sets the HTTP header Content-Type: application/json for you.
- If your action returns a non-string (array, object, scalar), the result is JSON-encoded automatically.
- If your action returns a string, it is returned as-is (no extra encoding), giving you full control when needed.

Usage:

```
use Core\\Controller;

class Users extends Controller\\Json
{
    public function GET()
    {
        // Will be encoded to {"ok":true,"time":1699999999}
        return ['ok' => true, 'time' => time()];
    }

    public function POST()
    {
        // You can also return a pre-encoded string if you need custom options
        return json_encode(['ok' => true], JSON_PRETTY_PRINT);
    }
}
```

Error helper:

- Json::getErrorObject($error): returns an stdClass with a single property error that you can use for consistent error payloads. Example: return self::getErrorObject('Invalid token'); // -&gt; {"error":"Invalid token"}

How it works:

- Json::serve() calls parent::serve() (Core\\Controller::serve()), then sets the JSON header and encodes non-string outputs.
- Combine with Core\\Exceptions\\External to control HTTP error codes from your actions.

Core\\ActiveRecord reference
----------------------------

[](#coreactiverecord-reference)

Core\\ActiveRecord is a lightweight base for simple table-backed models. Subclass it and define:

- protected static $\_table: the database table name.
- protected static $\_typeMap: optional map of field =&gt; type to control IO conversions.

Supported $\_typeMap types:

- dt or datetime: values are Carbon instances in UTC in PHP; stored as 'Y-m-d H:i:s'.
- json or json-object: values are stdClass in PHP; JSON-encoded on write.
- json-assoc: values are associative arrays; JSON-encoded on write.
- bit: values are bound as integers (0/1) when writing (useful for tinyint/bit).
- default/null: no special conversion.

Loading records:

- protected static getById($id): returns a single instance or false when not found.
- protected static getByIdMulti(array $ids): returns an array of instances (possibly empty).
- protected static getBySql(string $sql, array $params = \[\]): returns an array of instances.
- protected static getBySqlSingle(string $sql, array $params = \[\]): first instance or false.

Hydration/mapping:

- public static createFromArray($data): creates an instance and assigns only properties that exist on the subclass. Applies $\_typeMap conversions when populating fields (Carbon for dt/datetime; json\_decode for json/json-object/json-assoc).

Change tracking and persistence:

- protected function set(string $field, $value): assigns the value and marks the field as modified.
- protected function save():
    - If no fields are modified, returns true immediately.
    - If id is set, performs UPDATE on $\_table with only modified fields.
    - If id is not set, performs INSERT with only modified fields and sets id from lastInsertId().
- Parameter binding honors $\_typeMap via bindParams():
    - dt: converted to UTC 'Y-m-d H:i:s'.
    - bit: bound as integer (PDO::PARAM\_INT).
    - json/json-object/json-assoc: json\_encode before binding (throws External on failure).
    - Booleans are normalized to 0/1 automatically.

Notes:

- All times are treated as UTC. When saving Carbon instances, timezone is normalized to UTC.
- Validation, uniqueness, relations, and complex querying are intentionally out of scope for this minimal base; implement these in your subclass or service layer as needed.

Core\\Config reference
----------------------

[](#coreconfig-reference)

Core\\Config provides a lazy-loading accessor for your application configuration.

What it does:

- On first access, loads APP\_ROOT . '/backend/config/config.php'.
- Caches the loaded config for the lifetime of the request.
- Supports configs returned as either an associative array or an stdClass.

Expected bootstrap:

- Define APP\_ROOT in your app bootstrap so it points to your application root.

Config file format (example):

```
