memran / marwa-entity
Fluent Entity Builder and validation library. define once, protect everywhere.
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/memran/marwa-entity
Requires
- php: >=8.2
- psr/container: ^2.0
- psr/http-factory: ^1.0
- psr/http-message: ^2.0
- psr/http-server-handler: ^1.0
- psr/http-server-middleware: ^1.0
Requires (Dev)
- phpunit/phpunit: ^11.0
This package is auto-updated.
Last update: 2025-11-04 11:17:55 UTC
README
Define once. Protect everywhere.
A lightweight, framework-agnostic entity schema and validation library for PHP 8.2+
used across the Marwa ecosystem โ powering request validation, form building, and database migrations.
๐ Overview
Marwa\Entity lets you define your application data structure once and reuse it safely across:
- โ Validation (for HTTP requests, CLI inputs, API payloads, etc.)
- ๐งฑ Entity schema definition (with metadata, UI hints, and type safety)
- ๐งพ Migration builders (generate portable table specs from your schema)
- ๐งฐ Form builders (for Twig, Blade, or any UI layer)
- ๐ Future support: load schemas from YAML / JSON definition files.
Itโs part of the Marwa Framework ecosystem, but fully standalone and PSR-compatible.
๐ง Philosophy
Define once, use everywhere.
Instead of repeating validation logic across models, forms, and migrations,
you define your entity schema once and reuse it safely in:
| Layer | Uses |
|---|---|
| marwa/request | Validates PSR-7 requests with the same schema |
| marwa/view | Builds Twig forms from uiSpec() |
| marwa/migration | Generates database migrations via migrationSpec() |
๐ฆ Installation
composer require memran/marwa-entity
Requirements:
* PHP 8.2 or higher
* PSR-4 autoloading enabled (Composer handles this)
Basic Exam
use Marwa\Entity\Entity\EntitySchema; use Marwa\Entity\Entity\Entity; use Marwa\Entity\Validation\Validator; use Marwa\Entity\Validation\Rules\{Required, Min}; use Marwa\Entity\Support\Sanitizers; // 1๏ธโฃ Define your entity schema $schema = EntitySchema::make('users'); $schema->string('name') ->label('Full Name') ->rule(new Required(), new Min(3)) ->sanitize(Sanitizers::trim()); $schema->string('email') ->label('Email Address') ->rule(new Required()) ->sanitize(Sanitizers::trim(), Sanitizers::lower()) ->meta('unique', true) ->meta('widget', 'email'); $schema->boolean('is_active') ->label('Active?') ->meta('default', true); // 2๏ธโฃ Validate & sanitize input data $validator = new Validator(); $entity = new Entity($schema, $validator); $input = [ 'name' => ' Emran ', 'email' => ' TEST@EXAMPLE.com ', 'is_active' => '1', ]; try { $validated = $entity->hydrate($input); print_r($validated); } catch (\InvalidArgumentException $e) { echo $e->getMessage(); }
Output
Array
(
[name] => Emran
[email] => test@example.com
[is_active] => 1
)
Core Concepts
| Concept | Class | Purpose |
|---|---|---|
| Entity Schema | EntitySchema | Blueprint of all fields |
| Field | Field | Single field definition (type, label, rules, sanitizers) |
| Validator | Validator | Evaluates schema rules and builds error bags |
| Rules | Rules* | Pluggable validation rules (Required, Min, Unique, etc.) |
| ErrorBag | Validation\ErrorBag | Collects validation messages |
| Sanitizers | Support\Sanitizers | Built-in input cleaners |
| Entity | Entity | Executes validation, sanitization, and casting |
Rule System
Add rules fluently:
$schema->string('password') ->rule(new Required(), new Min(8));
Built-in rules:
| Rule | Purpose |
|---|---|
| Required | Value must be present |
| StringRule | Must be a string |
| IntegerRule | Must be an integer |
| Min,Max | Numeric or string length checks |
| Email, Regex | Format checks |
| InArray | Must match one of the given values |
| Unique, Exists | Custom callable checks (framework-agnostic) |
โ Unique and Exists are callback-based โ you pass your own closure to query DB or API.
Sanitizers
Sanitizers are lightweight closures applied before validation.
use Marwa\Entity\Support\Sanitizers; $schema->string('username') ->sanitize(Sanitizers::trim(), Sanitizers::lower());
Built-in: trim() lower() stripTags(array $allowed = [])
You can define your own:
$schema->string('slug')->sanitize(fn($v)=>str_replace(' ','-',strtolower($v)))
Example: Migration Spec
print_r($schema->migrationSpec());
Output:
[ 'name' => [ 'type' => 'string', 'enum' => null, 'nullable' => false, 'index' => false, 'unique' => false, 'default' => null, 'precision' => null, 'scale' => null ], 'email' => [ 'type' => 'string', 'enum' => null, 'nullable' => false, 'index' => false, 'unique' => true, 'default' => null, 'precision' => null, 'scale' => null ] ]
Integration Examples
โ In a PSR-7 Request Library
// marwa/request $form = new UserStoreRequest($request, $userEntity); $data = $form->validated(); // uses Marwa\Entity internally
๐งฑ In a Migration Library
$table->applyEntitySpec($schema->migrationSpec());
๐จ In a View Library
$fields = $schema->uiSpec(); // used by Twig macro to build form
๐ฎ Roadmap
* JSON / YAML schema loading (auto via SchemaFactory)
* Rule registration via container or config
* Localization & message translation
* Typed casting customization
* Nested entity relationships
* Advanced schema introspection
โ๏ธ License
Released under the MIT License. ยฉ 2025 Mohammad Emran
๐ Acknowledgments
Built with โค๏ธ by the Marwa Open Source Team for developers who love clarity, reusability, and DX-first design.