PHPackages                             ghebby/laravel-hfm - 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. ghebby/laravel-hfm

ActiveLibrary

ghebby/laravel-hfm
==================

A laravel packe aimed to reduce verbose and repetiteve code in the application by generatinc it at runtime starting from a simple Array declaration in the Models.

v1.0.0(5y ago)013MITPHPPHP ^7.2

Since Jan 3Pushed 5y ago1 watchersCompare

[ Source](https://github.com/anatolieGhebea/laravel-hfm)[ Packagist](https://packagist.org/packages/ghebby/laravel-hfm)[ Docs](https://github.com/anatolieghebea/laravel-hfm)[ RSS](/packages/ghebby-laravel-hfm/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (2)Dependencies (4)Versions (3)Used By (0)

draft
=====

[](#draft)

#### UNSTABLE

[](#unstable)

A simple Laravel packge to help DRY your code
=============================================

[](#a-simple-laravel-packge-to-help-dry-your-code)

[![Latest Version on Packagist](https://camo.githubusercontent.com/662bad93b2affb01f34287d921b63071ce40d009f580004ac3fef77ffea8d63a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6768656262792f6c61726176656c2d68666d2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/ghebby/laravel-hfm)[![GitHub Tests Action Status](https://camo.githubusercontent.com/c31b73de201c800bf3ffc810ce716b2184ef02c5b816b4957bdc5b534a087de0/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f776f726b666c6f772f7374617475732f616e61746f6c69654768656265612f6c61726176656c2d68666d2f72756e2d74657374733f6c6162656c3d7465737473)](https://github.com/anatolieGhebea/laravel-hfm/actions?query=workflow%3ATests+branch%3Amaster)[![Total Downloads](https://camo.githubusercontent.com/aa0e113b77ff736d519dc0fc29eb159ce913c51db5880651b1bc630cdc04a60d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6768656262792f6c61726176656c2d68666d2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/ghebby/laravel-hfm)

This packe aims to reduce verbose and repetiteve code in the application by generatinc it at runtime starting from a simple Array declaration in the Model.

> This is an opinionated approach, so make sure it suits your project guide lines before using it.

Installation
------------

[](#installation)

1. This package publishes a config/laravel-hfm.php file. If you already have a file by that name, you must rename or remove it.
2. You can install the package via composer:

```
composer require ghebby/laravel-hfm
```

3. Optional: The service provider will automatically get registered. Or you may manually add the service provider in your config/app.php file:

```
'providers' => [
    // ...
    Ghebby\LaravelHfm\LaravelHfmServiceProvider::class,
];
```

4. You should publish the config/laravel-hfm.php config file with:

```
php artisan vendor:publish --provider="Ghebby\LaravelHfm\LaravelHfmServiceProvider" --tag="config"
```

5. If you want to customize the views for the UI helper functions, then run

```
php artisan vendor:publish --provider="Ghebby\LaravelHfm\LaravelHfmServiceProvider" --tag="views"
```

to bublish them in `resources/views/vendor/laravel-hfm/`

Usage
-----

[](#usage)

Defining a Field Map on the Model may have a lot of benifits in terms of code duplication, making it easier and faster to develop trivil parts of the application.

**Let's see a short example.**Model name: *company*Model fileds:

- id
- name
- fiscal\_code
- email
- phone
- description
- address
- city
- zip
- country

#### Tipical approach

[](#tipical-approach)

In a tipical situation in the model `Company.php` we will have something like this

```
namespace App\Models;

class Company extends Model
{
    protected $table = 'companies';

    protected $fillable = ['name', 'fiscal_code', '...'];
    // OR
    protected $guarded = ['id'];

}
```

On the CompanyController we will have something like

```
namespace App\Http\Controllers;

class CompanyController extends Controller
{

    // [...]

    public function create(Request $request)
    {
        //
        return view('company.create');
    }

    public function store(Request $request)
    {
        // before persisting the data n DB you must validate it.
        // thus writing validation rules is a mandatory action
        // and it might look like this.
        $validaData = $request->validate(
            [
                'name' => 'string|max:255|required',
                'fiscal_code' => 'string|max:255|required',
                'email' => 'email|max:255|required',
                'phone' => 'string|max:255|nullable',
                //....
            ]
        );

        Company::create($validaData);

        return redirect()->route('company.index');
    }

    public function edit(Request $request, $id)
    {
        //
        $company = Company::findOrFail($id);

        return view('company.edit')->with('company', $company);
    }

    public function update(Request $request, $id)
    {
        // before persisting the data n DB you must validate it.
        // thus writing validation rules is a mandatory action
        // and it might look like this.
        $validaData = $request->validate(
            [
                'name' => 'string|max:255|required',
                'fiscal_code' => 'string|max:255|required',
                'email' => 'email|max:255|required',
                'phone' => 'string|max:255|nullable',
                //....
            ]
        );

        $company = Company::findOrFail($id);
        $company->update($validaData);

        return redirect()->route('company.index');
    }

    // [...]
}
```

On the view side a tipical situation may be

```
//[....]

    @csrf

            Name

            Fiscal Code

        // [...]

            Country

    Create

//[....]
```

I hope it's easy to see the problem. If for some reason a constraint is change we will need to fix the code in a few places:

- in controller@store -&gt; validationRules
- in controller@update -&gt; validationRules
- in view.create -&gt; fields
- in view.edit -&gt; fields

#### Using this package

[](#using-this-package)

The package provides:

- a Contract Interface to be implemented by the model
- a HfmTrait that contains the most used methods for manipolating the Field Map
- a HfmConst and HfmHelper which gets autoloaded on app boot, in order to define the cosnstants
- a few view helper functions which have the ability to generate a UI given a FieldMap

Let's how the code changes when sing this package:

Model `Company.php`

```
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

use Ghebby\LaravelHfm\Traits\FieldsMapTrait;
use Ghebby\LaravelHfm\Contracts\FieldsMapContract;

class Company extends Model implements FieldsMapContract
{
    use FieldsMapTrait;

    protected $table = 'companies';

    protected $fillable = ['name', 'fiscal_code', '...'];
    // OR
    protected $guarded = ['id'];

    /**
     * Returns the DB fields for the model.
     * This map is used to automatically the create/update form
     */
    public static function getFieldsMap() {

        $fields = [
            'id' => [ FLD_LABEL => 'Id', FLD_UI_CMP => CMP_TEXT,  FLD_DATA_TYPE => DT_INT, FLD_LENGTH => 11 , FLD_FLT_COND => 'LIKE', FLD_PRIMARY => true,  FLD_REQUIRED => false ] ,
            'name' => [ FLD_LABEL => 'Company name', FLD_UI_CMP => CMP_TEXT,  FLD_DATA_TYPE => DT_TEXT, FLD_LENGTH => 255 , FLD_FLT_COND => 'LIKE', FLD_REQUIRED => true ] ,
            'fiscal_code' => [ FLD_LABEL => 'Fiscal Code', FLD_UI_CMP => CMP_TEXT,  FLD_DATA_TYPE => DT_TEXT, FLD_LENGTH => 255 , FLD_FLT_COND => 'LIKE', FLD_REQUIRED => true ] ,
            'email' => [ FLD_LABEL => 'E-mail', FLD_UI_CMP => CMP_TEXT,  FLD_DATA_TYPE => DT_TEXT, FLD_LENGTH => 255 , FLD_FLT_COND => 'LIKE', FLD_REQUIRED => true ] ,
            'phone' => [ FLD_LABEL => 'Phone', FLD_UI_CMP => CMP_TEXT,  FLD_DATA_TYPE => DT_TEXT, FLD_LENGTH => 50 , FLD_FLT_COND => 'LIKE', FLD_REQUIRED => false ],
            'description'=> [ FLD_LABEL => 'Description',FLD_UI_CMP => CMP_TEXT_AREA,  FLD_DATA_TYPE => DT_TEXT_AREA, FLD_LENGTH => -1, FLD_FLT_COND => 'LIKE', FLD_REQUIRED => false ] ,
            'address' => [ FLD_LABEL => 'Address', FLD_UI_CMP => CMP_TEXT,  FLD_DATA_TYPE => DT_TEXT, FLD_LENGTH => 255 , FLD_FLT_COND => 'LIKE', FLD_REQUIRED => true ],
            'city' => [ FLD_LABEL => 'City', FLD_UI_CMP => CMP_TEXT,  FLD_DATA_TYPE => DT_TEXT, FLD_LENGTH => 100 , FLD_FLT_COND => 'LIKE', FLD_REQUIRED => true ],
            'zip' => [ FLD_LABEL => 'zip', FLD_UI_CMP => CMP_TEXT,  FLD_DATA_TYPE => DT_TEXT, FLD_LENGTH => 10 , FLD_FLT_COND => '=', FLD_REQUIRED => true ],
            'country' => [ FLD_LABEL => 'Country', FLD_UI_CMP => CMP_TEXT,  FLD_DATA_TYPE => DT_TEXT, FLD_LENGTH => 100 , FLD_FLT_COND => 'LIKE', FLD_REQUIRED => true ],
        ];

        return $fields;
    }

}
```

On controller

```
namespace App\Http\Controllers;

class CompanyController extends Controller
{

    // [...]

    public function create(Request $request)
    {
        //
        $fields = Company::getFieldsMap();

        if( isset($fields['id']) ){
            // when creating a new entry, id field in required normaly.
            unset($fields['id']);
        }

        return view('company.create')->with('fields', $fields);
    }

    public function store(Request $request)
    {

        $rules = Company::getDefaultValidationRules();
        // $rules is an array of validation rules for each field in the field map,
        // which nakes it very easy to override or integrate rules, example
        // $rules['fiscal_code'][] = 'min:10'; // addd a constraint for min number of char
        // unset($rules['email']); // this will prevent the validator method to set the key value pair for 'email' in $validaData

        $validaData = $request->validate($rules);

        Company::create($validaData);

        return redirect()->route('company.index');
    }

    public function edit(Request $request, $id)
    {
        //
        $company = Company::findOrFail($id);
        $fields = Company::getFieldsMap();

        return view('company.edit')->with('company', $company)->with('fields', $fields);
    }

    public function update(Request $request, $id)
    {

        $rules = Company::getDefaultValidationRules();
        $validaData = $request->validate($rules);

        $company = Company::findOrFail($id);
        $company->update($validaData);

        return redirect()->route('company.index');
    }

    // [...]
}
```

On the view side

```
//[....]

    @csrf

        @if( count($fileds) > 0 )
            // if you have published and customized the UI helper functions, use this
            @include('vendor.anatolieghebea.laravel-hfm.helpers._standardForm', ['stdFields' => $fileds])

            // if using the package default helper functions
            @include('laravel-hfm::helpers._standardForm', ['stdFields' => $fileds])
        @endif

    Create

//[....]
```

```
//[....]

    @csrf

        @if( count($fileds) > 0 )
            // if you have published and customized the UI helper functions, use this
            @include('vendor.anatolieghebea.laravel-hfm.helpers._standardForm', ['stdFields' => $fileds, 'mainModel' => $company, 'op' => 'edit'])

            // if using the package default helper functions
            @include('laravel-hfm::helpers._standardForm', ['stdFields' => $fileds, 'mainModel' => $company, 'op' => 'edit'])
        @endif

    Save

//[....]
```

With this approach we centralized the source of truth in the application, if we change the label for the filed `name` in Company.php it will propagete to all the views that relies on the `_standardForm` helper function.

If in the Field Map on the filed `fiscal_code` the attribute `required` is set to FALSE, the change will immediately affect the store and update methods in Controller and also the required attribute on the input field.

### Adding removing fields

[](#adding-removing-fields)

Adding or removing a field to an Model entity, is just the mater of adding o removing a line in the `getFieldMap()` of the model.

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Anatolie Ghebea](https://github.com/anatolieGhebea)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

22

—

LowBetter than 22% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity5

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity49

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

Total

2

Last Release

1942d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/39d7ee00eda72c95b2d6b4aa917308c406d8cdbf0c9e32839d7d909a61e5091d?d=identicon)[ghebby](/maintainers/ghebby)

---

Top Contributors

[![anatolieGhebea](https://avatars.githubusercontent.com/u/11662026?v=4)](https://github.com/anatolieGhebea "anatolieGhebea (29 commits)")

---

Tags

ghebbyanatolieghebealaravel-hfm

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/ghebby-laravel-hfm/health.svg)

```
[![Health](https://phpackages.com/badges/ghebby-laravel-hfm/health.svg)](https://phpackages.com/packages/ghebby-laravel-hfm)
```

###  Alternatives

[bezhansalleh/filament-shield

Filament support for `spatie/laravel-permission`.

2.8k2.9M88](/packages/bezhansalleh-filament-shield)[illuminate/console

The Illuminate Console package.

12944.1M5.1k](/packages/illuminate-console)[timokoerber/laravel-one-time-operations

Run operations once after deployment - just like you do it with migrations!

6481.7M11](/packages/timokoerber-laravel-one-time-operations)[vormkracht10/laravel-mails

Laravel Mails can collect everything you might want to track about the mails that has been sent by your Laravel app.

24149.7k](/packages/vormkracht10-laravel-mails)[wnx/laravel-sends

Keep track of outgoing emails in your Laravel application.

200427.3k](/packages/wnx-laravel-sends)[illuminate/process

The Illuminate Process package.

44699.5k65](/packages/illuminate-process)

PHPackages © 2026

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