PHPackages                             ivanbaric/sanigen - 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. [Validation &amp; Sanitization](/categories/validation)
4. /
5. ivanbaric/sanigen

ActiveLibrary[Validation &amp; Sanitization](/categories/validation)

ivanbaric/sanigen
=================

Declarative sanitization and attribute generators for Eloquent models.

v1.6.0(1mo ago)01MITPHPPHP ^8.2

Since Jul 17Pushed 1mo agoCompare

[ Source](https://github.com/IvanBaric/sanigen)[ Packagist](https://packagist.org/packages/ivanbaric/sanigen)[ RSS](/packages/ivanbaric-sanigen/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (7)Dependencies (10)Versions (8)Used By (0)

Sanigen
=======

[](#sanigen)

[![Latest Version on Packagist](https://camo.githubusercontent.com/9e0e7636b8c0d3ab561ceb02adde60de05506417e908df296c14bafe515da31d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6976616e62617269632f73616e6967656e2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/ivanbaric/sanigen)[![Total Downloads](https://camo.githubusercontent.com/1479c2a565ab68ea14173c303f9911e1b5d00197c9499f70df20900c1207dd7a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6976616e62617269632f73616e6967656e2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/ivanbaric/sanigen)[![License](https://camo.githubusercontent.com/98b1a5a382f97b8f0a5fae3ba8a32032f9ce1bf07b9bc5590903f3d82d57cb23/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6976616e62617269632f73616e6967656e2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/ivanbaric/sanigen)

Sanigen provides declarative sanitization and attribute generators for Eloquent models, so teams can keep input cleanup consistent without repeating pipelines across models.

Quick Start
-----------

[](#quick-start)

```
composer require ivanbaric/sanigen
```

Recommended: publish the config file.

```
php artisan vendor:publish --provider="IvanBaric\Sanigen\SanigenServiceProvider" --tag="config"
```

Define aliases in `config/sanigen.php`, then reuse the same defaults across your models.

```
'aliases' => [
    'text' => 'strip_html|strip_scripts|strip_emoji|strip_newlines|trim|squish',
    'title' => 'strip_html|strip_scripts|strip_emoji|strip_newlines|trim|squish|lower|ucfirst',
    'ascii' => 'strip_html|strip_scripts|strip_emoji|strip_newlines|trim|squish|ascii',
    'email' => 'trim|lower|email',
    'url' => 'trim|strip_newlines|strip_scripts|url',
    'slug' => 'trim|lower|slug',
    'decimal' => 'trim|decimal',
    'phone' => 'trim|phone_clean',
];
```

Sanigen gives you two model properties:

- `$sanitize`: applies sanitizer aliases from `config/sanigen.php`
- `$generate`: fills empty attributes on `creating` using generator rules

```
use Illuminate\Database\Eloquent\Model;
use IvanBaric\Sanigen\Traits\Sanigen;

class Post extends Model
{
    use Sanigen;

    protected $fillable = ['name', 'description', 'email', 'website', 'slug', 'price', 'phone'];

    protected array $sanitize = [
        'name' => 'title',
        'description' => 'text',
        'email' => 'email',
        'website' => 'url',
        'slug' => 'slug',
        'price' => 'decimal',
        'phone' => 'phone',
    ];

    protected array $generate = [
        'slug' => 'slugify:name',
        'uuid' => 'uuid',
        'owner_id' => 'user:id',
        'team_id' => 'user:current_team_id',
    ];
}
```

```
$post = Post::create([
    'name' => '  alert(1)my FIRST post  ',
    'description' => 'alert(1)Hello world',
    'email' => ' USER@EXAMPLE.COM ',
    'website' => 'example.com',
    'price' => ' EUR 1,234.56 ',
    'phone' => ' +1 (123) 456-7890 ',
]);
```

Result:

```
[
    'uuid' => '550e8400-e29b-41d4-a716-446655440000',
    'owner_id' => 1,
    'team_id' => 42,
    'name' => 'My first post',
    'description' => 'Hello world',
    'email' => 'user@example.com',
    'website' => 'https://example.com',
    'slug' => 'my-first-post',
    'price' => '1234.56',
    'phone' => '+11234567890',
]
```

Available Aliases
-----------------

[](#available-aliases)

- `text`: generic cleaned text
- `title`: cleaned title-style text
- `ascii`: cleaned ASCII-only text
- `email`: normalized email
- `url`: normalized URL
- `slug`: slug-ready value
- `decimal`: normalized decimal number
- `phone`: normalized phone number

Class-Level Attributes
----------------------

[](#class-level-attributes)

Besides model properties, you can use class-level attributes:

```
use IvanBaric\Sanigen\Attributes\Generate;
use IvanBaric\Sanigen\Attributes\Sanitize;

#[Sanitize([
    'name' => 'title',
    'description' => 'text',
    'email' => 'email',
])]
#[Generate([
    'slug' => 'slugify:name',
    'uuid' => 'uuid',
])]
class Post extends Model
{
    use Sanigen;
}
```

Rule priority is:

1. explicit model properties (`$sanitize`, `$generate`)
2. class-level attributes (`#[Sanitize]`, `#[Generate]`)
3. config defaults (`sanitize_defaults`, `generate_defaults`)

Full Reference
--------------

[](#full-reference)

Built-in sanitizersSanitizerDescriptionExample`trim`Removes whitespace from beginning and end`" Hello "` -&gt; `"Hello"``lower`Converts to lowercase`"Hello"` -&gt; `"hello"``upper`Converts to uppercase`"hello"` -&gt; `"HELLO"``ucfirst`Capitalizes first character`"hello"` -&gt; `"Hello"``squish`Normalizes whitespace to single spaces`"Hello   World"` -&gt; `"Hello World"``strip_newlines`Removes all line breaks`"Line 1\nLine 2"` -&gt; `"Line 1Line 2"``strip_html`Removes all HTML tags`"Hello"` -&gt; `"Hello"``strip_tags`Removes HTML tags except allowed ones`"Hello"` -&gt; `"Hello"``strip_scripts`Removes script-bearing markup, inline JS handlers, dangerous protocols, and suspicious JS patterns`"alert(1)Hello"` -&gt; `"Hello"``strip_emoji`Removes emoji characters`"Hello 👋 World 🌍"` -&gt; `"Hello  World "``alpha`Keeps only letters`"Hello123"` -&gt; `"Hello"``alnum`Keeps only letters and numbers`"Hello123!"` -&gt; `"Hello123"``alpha_dash`Keeps letters, numbers, hyphens, underscores`"Hello-123_!"` -&gt; `"Hello-123_"``ascii`Keeps only ASCII characters`"cafe ć"` -&gt; `"cafe "``digits`Keeps only digits`"Price: $123.45"` -&gt; `"12345"``decimal`Keeps decimal number characters and normalizes separators`"1,234.56 €"` -&gt; `"1234.56"``email`Sanitizes email addresses`" USER@EXAMPLE.COM "` -&gt; `"user@example.com"``phone_clean`Sanitizes phone numbers`"(123) 456-7890"` -&gt; `"+1234567890"``url`Ensures URLs have a protocol`"example.com"` -&gt; `"https://example.com"``slug`Creates a URL-friendly slug`"Hello World"` -&gt; `"hello-world"`Built-in generatorsGeneratorPurposeExample`uuid`UUID v4`550e8400-e29b-41d4-a716-446655440000``uuid:v7`UUID v7`018f0f4b-9c3a-7c3e-9d9a-2c3c4b5a6d7e``uuid:v8`UUID v8`018f0f4b-9c3a-8c3e-9d9a-2c3c4b5a6d7e``ulid`ULID`01J3Z3N6K2Z9N0R2Z7T1W5Y8QG``autoincrement`next numeric value`1` -&gt; `2` -&gt; `3``unique_string:length`unique random string`unique_string:8` -&gt; `A1B2C3D4``random_string:length`random string`random_string:16` -&gt; `aZ2kLm9Qp0xYt1uV``slugify:field`unique slug from another field`slugify:title` -&gt; `my-post-title``slugify:field,date`unique slug with date suffix`slugify:title,date` -&gt; `my-post-title-27-03-2026``slugify:field,uuid`unique slug with UUID suffix`slugify:title,uuid` -&gt; `my-post-title-550e8400-e29b-41d4-a716-446655440000``carbon:+7 days`Carbon date from a modifier`carbon:+7 days` -&gt; `2026-04-03 12:00:00``user:property`authenticated user property`user:id` -&gt; `1`, `user:email` -&gt; `user@example.com`Custom sanitizersScaffold a sanitizer class:

```
php artisan make:sanitizer Username
php artisan make:sanitizer Admin/TitleClean --force
```

```
namespace App\Sanitizers;

use IvanBaric\Sanigen\Sanitizers\Contracts\Sanitizer;

class UsernameSanitizer implements Sanitizer
{
    public function apply(string $value): string
    {
        return strtolower(trim($value));
    }
}
```

Register it:

```
use IvanBaric\Sanigen\Registries\SanitizerRegistry;

SanitizerRegistry::register('username', \App\Sanitizers\UsernameSanitizer::class);
```

Use it:

```
protected $sanitize = [
    'username' => 'username',
];
```

Custom generatorsScaffold a generator class:

```
php artisan make:generator Slug
php artisan make:generator Content/Slug --force
```

```
namespace App\Generators;

use IvanBaric\Sanigen\Generators\Contracts\GeneratorContract;

class CouponCodeGenerator implements GeneratorContract
{
    public function generate(string $field, object $model): mixed
    {
        return 'SALE-' . strtoupper(str()->random(8));
    }
}
```

Register it:

```
use IvanBaric\Sanigen\Registries\GeneratorRegistry;

GeneratorRegistry::register('coupon_code', \App\Generators\CouponCodeGenerator::class);
```

Use it:

```
protected $generate = [
    'code' => 'coupon_code',
];
```

Resanitize Existing Rows
------------------------

[](#resanitize-existing-rows)

Warning: this command updates existing database records. Run it on a backup-aware deployment path and test it on staging first.

```
php artisan sanigen:resanitize "App\Models\Post" --chunk=200
```

Production Notes
----------------

[](#production-notes)

```
return [
    'enabled' => true,
    'missing_sanitizer' => 'throw',
    'aliases' => [
        'text' => 'strip_html|strip_scripts|strip_emoji|strip_newlines|trim|squish',
        'title' => 'strip_html|strip_scripts|strip_emoji|strip_newlines|trim|squish|lower|ucfirst',
        'ascii' => 'strip_html|strip_scripts|strip_emoji|strip_newlines|trim|squish|ascii',
        'email' => 'trim|lower|email',
        'url' => 'trim|strip_newlines|strip_scripts|url',
        'slug' => 'trim|lower|slug',
        'decimal' => 'trim|decimal',
        'phone' => 'trim|phone_clean',
    ],
    'allowed_html_tags' => '',
    'encoding' => 'UTF-8',
    'max_strip_scripts_input_length' => 32768,
    'sanitize_defaults' => [],
    'generate_defaults' => [],
];
```

Spatie Translatable Support
---------------------------

[](#spatie-translatable-support)

Sanigen works with Spatie Laravel Translatable because translatable attributes are stored as arrays and Sanigen sanitizes each scalar item individually.

Limitations
-----------

[](#limitations)

Sanigen only runs when data goes through an Eloquent model instance.

Tests
-----

[](#tests)

```
composer test
```

License
-------

[](#license)

MIT. See [LICENSE.md](LICENSE.md).

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance90

Actively maintained with recent releases

Popularity1

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~42 days

Recently: every ~63 days

Total

7

Last Release

47d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/8364e79aacbf982a433dbe7f978eacd6987572355a0cf762d69a35a7c4b73e72?d=identicon)[IvanBaric](/maintainers/IvanBaric)

---

Top Contributors

[![IvanBaric](https://avatars.githubusercontent.com/u/6261128?v=4)](https://github.com/IvanBaric "IvanBaric (21 commits)")

---

Tags

laravellaravel-frameworklaravel-packagelaravel12

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/ivanbaric-sanigen/health.svg)

```
[![Health](https://phpackages.com/badges/ivanbaric-sanigen/health.svg)](https://phpackages.com/packages/ivanbaric-sanigen)
```

###  Alternatives

[spatie/laravel-honeypot

Preventing spam submitted through forms

1.6k6.0M60](/packages/spatie-laravel-honeypot)[proengsoft/laravel-jsvalidation

Validate forms transparently with Javascript reusing your Laravel Validation Rules, Messages, and FormRequest

1.1k2.3M49](/packages/proengsoft-laravel-jsvalidation)[stevebauman/purify

An HTML Purifier / Sanitizer for Laravel

5325.6M19](/packages/stevebauman-purify)[axlon/laravel-postal-code-validation

Worldwide postal code validation for Laravel and Lumen

3853.3M1](/packages/axlon-laravel-postal-code-validation)[sunspikes/clamav-validator

Custom Laravel 5 anti-virus validator for file uploads.

3651.8M3](/packages/sunspikes-clamav-validator)[laravel-validation-rules/credit-card

Validate credit card number, expiration date, cvc

2412.2M5](/packages/laravel-validation-rules-credit-card)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
