PHPackages                             estebansmolak19/crud-service-generator - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. estebansmolak19/crud-service-generator

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

estebansmolak19/crud-service-generator
======================================

A PHP package to automatically generate CRUD service classes — Un package PHP pour générer automatiquement des classes de service CRUD.

2.x-dev(2mo ago)15[2 PRs](https://github.com/EstebanSmolak19/crud-service-generator/pulls)MITPHPPHP ^8.4CI passing

Since May 14Pushed 1mo agoCompare

[ Source](https://github.com/EstebanSmolak19/crud-service-generator)[ Packagist](https://packagist.org/packages/estebansmolak19/crud-service-generator)[ Docs](https://github.com/EstebanSmolak19/crud-service-generator)[ GitHub Sponsors](https://github.com/EstebanSmolak19)[ RSS](/packages/estebansmolak19-crud-service-generator/feed)WikiDiscussions main Synced 3w ago

READMEChangelogDependencies (13)Versions (11)Used By (0)

CRUD Service Generator — Documentation
======================================

[](#crud-service-generator--documentation)

**CRUD Service Generator** is a Laravel package that automates the creation of robust, secure and configurable CRUD services, based on **PHP 8 Attributes** and a built-in **Audit** system.

---

📦 Installation
--------------

[](#-installation)

```
composer require estebansmolak19/crud-service-generator

php artisan vendor:publish --tag="crud-service-generator-config"
php artisan vendor:publish --tag="crud-service-generator-migrations"
php artisan migrate
```

---

💡 Model Architecture — Double Inheritance
-----------------------------------------

[](#-model-architecture--double-inheritance)

```
php artisan generate:model
```

The package synchronizes your models with the database without ever overwriting your code.

FileRole`App\Models\Base\BaseArret.php`Auto-generated — **overwritten** on every sync`App\Models\Arret.php`Your file — generated **once only**, free to modify```
// ✅ App\Models\Arret.php — add your methods here, safely
class Arret extends BaseArret
{
    public function isAdmin(): bool
    {
        return true;
    }
}
```

---

🔧 Commands
----------

[](#-commands)

### `php artisan make:service`

[](#php-artisan-makeservice)

Generates a service and its associated components.

OptionEffect*(none)*Generates an empty service`--crud`Generates a service with CRUD methods`--controller`Generates a service + API controller`--all`Generates everything: **CRUD Service + CRUD Controller + Routes + Resource**```
# Minimal CRUD service
php artisan make:service ArretService --crud

# Generate everything at once
php artisan make:service ArretService --all
```

With `--all`, the generator asks a few interactive questions:

- The associated model (e.g. `Arret`)
- The controller name
- The route prefix (e.g. `arrets` → generates `GET /arrets`, `POST /arrets`, etc.)

Routes are automatically added in `routes/service_generator.php`.

### Other commands

[](#other-commands)

CommandDescription`php artisan make:attribute MyAttribute`Generates an attribute interceptor`php artisan generate:model`Synchronizes models with the DB`php artisan config:apply`Applies the configuration file`php artisan p:help`Displays the full command guide---

🏗️ Anatomy of a CRUD Service
----------------------------

[](#️-anatomy-of-a-crud-service)

```
class ArretService extends CrudServiceBase implements IFillableContract, HasSqlOverrides
{
    // 🔴 REQUIRED — forgetting this line throws a LogicException at startup
    // role: filters columns exposed via API
    protected array $fillable = ['nom', 'latitude', 'longitude'];

    // Options available via HasCrudConfiguration (all optional)
    protected bool  $audit   = true;             // Enables audit logs
    protected array $orderBy = ['nom' => 'ASC']; // Default sort
    protected int   $perPage = 15;               // Pagination

    public function __construct(Arret $model)
    {
        parent::__construct($model);
    }

    public function permissions(): array
    {
        return [
            'create'  => [IsAuthenticated::class],
            'update'  => [IsAuthenticated::class],
            'destroy' => [IsAuthenticated::class, IsAdmin::class],
            // Missing keys = public access (e.g. 'all', 'find')
        ];
    }
}
```

---

📋 CRUD Methods
--------------

[](#-crud-methods)

MethodParametersDescription`all()`—Returns all records, paginated according to `$perPage``find($id)``mixed $id`Returns a record by ID — `404` if not found`create($data)``array $data`Creates a record, logs if `$audit = true``update($id, $data)``mixed $id`, `array $data`Updates, logs `old_values` / `new_values` if audit`destroy($id)``mixed $id`Deletes, logs before deletion if audit, returns `bool`---

🔒 The Attribute System
----------------------

[](#-the-attribute-system)

Attributes allow you to attach logic (security, validation...) to a method or an entire service, **without polluting the business logic**.

Before each call, the package automatically inspects the declared attributes and executes them in order. If an attribute calls `abort()`, execution stops immediately.

### Included attribute: `IsAuthenticated`

[](#included-attribute-isauthenticated)

Blocks with an `HTTP 401` if the user is not logged in.

```
// A. Via permissions() — for standard CRUD methods (all, find, create, update, destroy)
public function permissions(): array
{
    return [
        'create'  => [IsAuthenticated::class],
        'destroy' => [IsAuthenticated::class, IsAdmin::class], // All must pass
    ];
}

// B. Via PHP 8 Attribute — for your custom methods
#[IsAuthenticated]
#[IsAdmin]
public function exportData(): array { ... }
```

### Creating your own Attribute

[](#creating-your-own-attribute)

```
php artisan make:attribute IsAdmin
```

```
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
class IsAdmin implements ServiceAttributeContract
{
    public function handle(object $service, string $method, array &$params): void
    {
        // $service → instance of the called service
        // $method  → name of the intercepted method (e.g. 'create')
        // &$params → passed arguments, modifiable by reference

        if (!auth()->user()?->is_admin) {
            abort(403, "Access restricted to administrators.");
        }
    }
}
```

You can also pass parameters to your attribute:

```
#[IsRole('super-admin')]
public function deleteAll(): void { ... }

// In the attribute
class IsRole implements ServiceAttributeContract
{
    public function __construct(private string $role)
    {
        // $this->role being the parameter initialized in the constructor.
    }

    public function handle(object $service, string $method, array &$params): void
    {
        if (!auth()->user()?->hasRole($this->role)) {
            abort(403);
        }
    }
}
```

---

📋 Audit System and Logs
-----------------------

[](#-audit-system-and-logs)

Enable audit in your service:

```
protected bool $audit = true;
```

Every `create`, `update`, `destroy` action is automatically recorded in `crud_service_logs`:

ColumnDescriptionExample`user_id`Who acted`7``event`Action type`update``auditable_type`Model class`App\Models\Arret``auditable_id`Record ID`42``old_values`Snapshot before (JSON)`{"nom":"Gare Nord"}``new_values`Snapshot after (JSON)`{"nom":"Gare du Nord"}`---

💾 SQL Overrides (Views and Procedures)
--------------------------------------

[](#-sql-overrides-views-and-procedures)

For complex architectures, you can bypass Eloquent.

### SQL Views

[](#sql-views)

```
// The all() and find() methods will read from this view rather than the table with Eloquent
protected ?string $sqlViewName = 'vue_arrets_avec_ligne';
```

⚠️ The view **must** expose the column defined in `$primaryKey` (default `id`) for `find()` to work.

### Stored Procedures

[](#stored-procedures)

```
// Delegate create / update / destroy to SQL procedures
protected ?string $sqlCreateProcedure = 'sp_create_arret';
protected ?string $sqlUpdateProcedure = 'sp_update_arret';
protected ?string $sqlDeleteProcedure = 'sp_delete_arret';
```

---

👥 Credits
---------

[](#-credits)

- [EstebanSmolak19](https://github.com/EstebanSmolak19)

📄 License
---------

[](#-license)

The MIT License (MIT).

---

---

CRUD Service Generator — Documentation
======================================

[](#crud-service-generator--documentation-1)

**CRUD Service Generator** est un package Laravel qui automatise la création de services CRUD robustes, sécurisés et configurables, basé sur les **Attributs PHP 8** et un système d'**Audit** intégré.

---

📦 Installation
--------------

[](#-installation-1)

```
composer require estebansmolak19/crud-service-generator

php artisan vendor:publish --tag="crud-service-generator-config"
php artisan vendor:publish --tag="crud-service-generator-migrations"
php artisan migrate
```

---

💡 Architecture des Modèles — Double Héritage
--------------------------------------------

[](#-architecture-des-modèles--double-héritage)

```
php artisan generate:model
```

Le package synchronise vos modèles avec la base de données sans jamais écraser votre code.

FichierRôle`App\Models\Base\BaseArret.php`Généré automatiquement — **écrasé** à chaque sync`App\Models\Arret.php`Votre fichier — généré **une seule fois**, libre à modifier```
// ✅ App\Models\Arret.php — ajoutez vos méthodes ici, en toute sécurité
class Arret extends BaseArret
{
    public function isAdmin(): bool
    {
        return true;
    }
}
```

---

🔧 Commandes
-----------

[](#-commandes)

### `php artisan make:service`

[](#php-artisan-makeservice-1)

Génère un service et ses composants associés.

OptionEffet*(aucune)*Génère un service vide`--crud`Génère un service avec les méthodes CRUD`--controller`Génère un service + contrôleur API`--all`Génère la totale : **Service CRUD + Controller CRUD + Routes + Resource**```
# Service CRUD minimal
php artisan make:service ArretService --crud

# Tout générer d'un coup
php artisan make:service ArretService --all
```

Avec `--all`, le générateur vous pose quelques questions interactives :

- Le modèle associé (ex: `Arret`)
- Le nom du contrôleur
- Le préfixe de route (ex: `arrets` → génère `GET /arrets`, `POST /arrets`, etc.)

Les routes sont ajoutées automatiquement dans `routes/service_generator.php`.

### Autres commandes

[](#autres-commandes)

CommandeDescription`php artisan make:attribute MonAttribut`Génère un intercepteur d'attribut`php artisan generate:model`Synchronise les modèles avec la BDD`php artisan config:apply`Applique le fichier de configuration`php artisan p:help`Affiche le guide complet des commandes---

🏗️ Anatomie d'un Service CRUD
-----------------------------

[](#️-anatomie-dun-service-crud)

```
class ArretService extends CrudServiceBase implements IFillableContract, HasSqlOverrides
{
    // 🔴 OBLIGATOIRE — oublier cette ligne lève une LogicException au démarrage
    // rôle : filtre des colonnes exposées en API
    protected array $fillable = ['nom', 'latitude', 'longitude'];

    // Options disponibles via HasCrudConfiguration (toutes optionnelles)
    protected bool  $audit   = true;             // Active les logs d'audit
    protected array $orderBy = ['nom' => 'ASC']; // Tri par défaut
    protected int   $perPage = 15;               // Pagination

    public function __construct(Arret $model)
    {
        parent::__construct($model);
    }

    public function permissions(): array
    {
        return [
            'create'  => [IsAuthenticated::class],
            'update'  => [IsAuthenticated::class],
            'destroy' => [IsAuthenticated::class, IsAdmin::class],
            // Les clés absentes = accès public (ex: 'all', 'find')
        ];
    }
}
```

---

📋 Méthodes CRUD
---------------

[](#-méthodes-crud)

MéthodeParamètresDescription`all()`—Retourne tous les enregistrements, paginé selon `$perPage``find($id)``mixed $id`Retourne un enregistrement par ID — `404` si introuvable`create($data)``array $data`Crée un enregistrement, logue si `$audit = true``update($id, $data)``mixed $id`, `array $data`Met à jour, logue `old_values` / `new_values` si audit`destroy($id)``mixed $id`Supprime, logue avant suppression si audit, retourne `bool`---

🔒 Le Système d'Attributs
------------------------

[](#-le-système-dattributs)

Les attributs permettent d'attacher de la logique (sécurité, validation...) sur une méthode ou un service entier, **sans polluer la logique métier**.

Avant chaque appel, le package inspecte automatiquement les attributs déclarés et les exécute dans l'ordre. Si un attribut fait un `abort()`, l'exécution s'arrête immédiatement.

### Attribut inclus : `IsAuthenticated`

[](#attribut-inclus--isauthenticated)

Bloque avec un `HTTP 401` si l'utilisateur n'est pas connecté.

```
// A. Via permissions() — pour les méthodes CRUD standards (all, find, create, update, destroy)
public function permissions(): array
{
    return [
        'create'  => [IsAuthenticated::class],
        'destroy' => [IsAuthenticated::class, IsAdmin::class], // Tous doivent passer
    ];
}

// B. Via Attribut PHP 8 — pour vos méthodes personnalisées
#[IsAuthenticated]
#[IsAdmin]
public function exportData(): array { ... }
```

### Créer votre propre Attribut

[](#créer-votre-propre-attribut)

```
php artisan make:attribute IsAdmin
```

```
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
class IsAdmin implements ServiceAttributeContract
{
    public function handle(object $service, string $method, array &$params): void
    {
        // $service → instance du service appelé
        // $method  → nom de la méthode interceptée (ex: 'create')
        // &$params → arguments passés, modifiables par référence

        if (!auth()->user()?->is_admin) {
            abort(403, "Accès réservé aux administrateurs.");
        }
    }
}
```

Vous pouvez également passer des paramètres à votre attribut :

```
#[IsRole('super-admin')]
public function deleteAll(): void { ... }

// Dans l'attribut
class IsRole implements ServiceAttributeContract
{
    public function __construct(private string $role)
    {
        // $this->role étant le paramètre initialisé dans le constructeur.
    }

    public function handle(object $service, string $method, array &$params): void
    {
        if (!auth()->user()?->hasRole($this->role)) {
            abort(403);
        }
    }
}
```

---

📋 Système d'Audit et Logs
-------------------------

[](#-système-daudit-et-logs)

Activez l'audit dans votre service :

```
protected bool $audit = true;
```

Chaque action `create`, `update`, `destroy` est enregistrée automatiquement dans `crud_service_logs` :

ColonneDescriptionExemple`user_id`Qui a agi`7``event`Type d'action`update``auditable_type`Classe du modèle`App\Models\Arret``auditable_id`ID de l'enregistrement`42``old_values`Snapshot avant (JSON)`{"nom":"Gare Nord"}``new_values`Snapshot après (JSON)`{"nom":"Gare du Nord"}`---

💾 Surcharges SQL (Vues et Procédures)
-------------------------------------

[](#-surcharges-sql-vues-et-procédures)

Pour les architectures complexes, vous pouvez court-circuiter Eloquent.

### Vues SQL

[](#vues-sql)

```
// Les méthodes all() et find() liront depuis cette vue plutôt que la table avec Eloquent
protected ?string $sqlViewName = 'vue_arrets_avec_ligne';
```

⚠️ La vue **doit** exposer la colonne définie dans `$primaryKey` (par défaut `id`) pour que `find()` fonctionne.

### Procédures Stockées

[](#procédures-stockées)

```
// Déléguer create / update / destroy à des procédures SQL
protected ?string $sqlCreateProcedure = 'sp_create_arret';
protected ?string $sqlUpdateProcedure = 'sp_update_arret';
protected ?string $sqlDeleteProcedure = 'sp_delete_arret';
```

---

👥 Credits
---------

[](#-credits-1)

- [EstebanSmolak19](https://github.com/EstebanSmolak19)

📄 License
---------

[](#-license-1)

The MIT License (MIT).

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance90

Actively maintained with recent releases

Popularity5

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity43

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 ~0 days

Total

8

Last Release

68d ago

Major Versions

v0.1.6-beta → 2.x-dev2026-05-18

### Community

Maintainers

![](https://www.gravatar.com/avatar/b8b2357638459371d60359d493c3b33f8fcfd2aef5345a124f3f7ebca755592d?d=identicon)[Elpokopipok](/maintainers/Elpokopipok)

---

Top Contributors

[![EstebanSmolak19](https://avatars.githubusercontent.com/u/184782113?v=4)](https://github.com/EstebanSmolak19 "EstebanSmolak19 (34 commits)")

---

Tags

laravelEstebanSmolak19crud-service-generator

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/estebansmolak19-crud-service-generator/health.svg)

```
[![Health](https://phpackages.com/badges/estebansmolak19-crud-service-generator/health.svg)](https://phpackages.com/packages/estebansmolak19-crud-service-generator)
```

###  Alternatives

[spatie/laravel-pdf

Create PDFs in Laravel apps

1.0k4.8M48](/packages/spatie-laravel-pdf)[codewithdennis/filament-select-tree

The multi-level select field enables you to make single selections from a predefined list of options that are organized into multiple levels or depths.

330530.5k30](/packages/codewithdennis-filament-select-tree)[rawilk/profile-filament-plugin

Profile &amp; MFA starter kit for filament.

3914.8k](/packages/rawilk-profile-filament-plugin)

PHPackages © 2026

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