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

dev-main 2025-10-22 11:47 UTC

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.