PHPackages                             escolalms/model-fields - 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. escolalms/model-fields

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

escolalms/model-fields
======================

Escola LMS model-fields extension.

0.1.1(1y ago)1193.8k↓24%5MITPHPPHP &gt;=8.0CI passing

Since Mar 3Pushed 8mo ago1 watchersCompare

[ Source](https://github.com/EscolaLMS/model-fields)[ Packagist](https://packagist.org/packages/escolalms/model-fields)[ RSS](/packages/escolalms-model-fields/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (7)Versions (32)Used By (5)

Model Fields
============

[](#model-fields)

[![swagger](https://camo.githubusercontent.com/bf46f50926ef796b1bb0b6e41af746af52ff3aacdffb0533450f3b614a7334a2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f63756d656e746174696f6e2d737761676765722d677265656e)](https://escolalms.github.io/model-fields/)[![codecov](https://camo.githubusercontent.com/5edcdf1acd4aa0f936eae69aff900a7be8550354cb78a74026b1247e1cdc12db/68747470733a2f2f636f6465636f762e696f2f67682f4573636f6c614c4d532f6d6f64656c2d6669656c64732f6272616e63682f6d61696e2f67726170682f62616467652e7376673f746f6b656e3d4e52414e34523841475a)](https://codecov.io/gh/EscolaLMS/model-fields)[![phpunit](https://github.com/EscolaLMS/model-fields/actions/workflows/test.yml/badge.svg)](https://github.com/EscolaLMS/model-fields/actions/workflows/test.yml)[![downloads](https://camo.githubusercontent.com/a44ddeb7dba45af43090decaf6d70bd4fda33a380c617e40c7b39bfd0c26c512/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6573636f6c616c6d732f6d6f64656c2d6669656c6473)](https://packagist.org/packages/escolalms/model-fields)[![downloads](https://camo.githubusercontent.com/875e787434f13d9201fac1168ac8c352fd76ecdeee4f4eafbc040902e3acbc9e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6573636f6c616c6d732f6d6f64656c2d6669656c6473)](https://packagist.org/packages/escolalms/model-fields)[![downloads](https://camo.githubusercontent.com/2865545b014a9283409685a7d72430a7628dfcd93c5f3f63d97724f0ce6d9e56/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6573636f6c616c6d732f6d6f64656c2d6669656c6473)](https://packagist.org/packages/escolalms/model-fields)[![Maintainability](https://camo.githubusercontent.com/d410e86a9ee647d8dfc2b476b3c50f6f7b29ce0947555ea38b02dbc9b1d3cc02/68747470733a2f2f6170692e636f6465636c696d6174652e636f6d2f76312f6261646765732f32343138343539613032626266363432323533652f6d61696e7461696e6162696c697479)](https://codeclimate.com/github/EscolaLMS/model-fields/maintainability)[![Test Coverage](https://camo.githubusercontent.com/dd969440aebaa92195b642d934e409d1c2bd04a547b36b7d7c3b066789dad76a/68747470733a2f2f6170692e636f6465636c696d6174652e636f6d2f76312f6261646765732f32343138343539613032626266363432323533652f746573745f636f766572616765)](https://codeclimate.com/github/EscolaLMS/model-fields/test_coverage)[![Mutation testing badge](https://camo.githubusercontent.com/1a0e47111f9d87d191a311b64c434916fb68a69a2b1ef3686c0af0aba3a8fb1c/68747470733a2f2f696d672e736869656c64732e696f2f656e64706f696e743f7374796c653d666c61742675726c3d687474707325334125324625324662616467652d6170692e737472796b65722d6d757461746f722e696f2532466769746875622e636f6d2532464573636f6c614c4d532532466d6f64656c2d6669656c64732532466d61696e)](https://dashboard.stryker-mutator.io/reports/github.com/EscolaLMS/model-fields/main)

What does it do
---------------

[](#what-does-it-do)

This package allows you to add unlimited extra primitive fields to any model.

Types of fields that can be user

- booleandoc
- number
- varchar
- text
- json

Details documentation is provided as an example

Installing
----------

[](#installing)

- `composer require escolalms/model-fields`
- `php artisan migrate`
- `php artisan db:seed --class="EscolaLms\ModelFields\Database\Seeders\PermissionTableSeeder"`

Database
--------

[](#database)

The package allows to add additional fields by creating special meta description values that are saved in database.

Next to metadata descriptions there are values that works with the meta description.

Below are examples of how matadata and values are stored in database

`model_fields_metadata` table sample rows

idcreated\_atupdated\_atnametyperulesextradefaultclass\_typevisibility21472022-03-03 12:10:052022-03-03 12:10:05descriptiontext\["required","string","max:255"\]NULLlorem ipsumEscolaLms\\ModelFields\\Tests\\Models\\User121482022-03-03 12:10:052022-03-03 12:10:05interested\_in\_testsboolean\["required","boolean"\]NULL1EscolaLms\\ModelFields\\Tests\\Models\\User121492022-03-03 12:10:052022-03-03 12:10:05titlevarchar\["required","string","max:255"\]NULLEscolaLms\\ModelFields\\Tests\\Models\\User121502022-03-03 12:10:052022-03-03 12:10:05consentsjson\["required","json"\]NULL\[\]EscolaLms\\ModelFields\\Tests\\Models\\User121512022-03-03 12:10:052022-03-03 12:10:05extra\_pointsnumber\["required","integer"\]NULL123EscolaLms\\ModelFields\\Tests\\Models\\User121532022-03-03 12:11:052022-03-03 12:11:05extra\_descriptiontext\["required","string","max:255"\]NULLlorem ipsumEscolaLms\\ModelFields\\Tests\\Models\\User1`model_fields_values` table sample rows

idcreated\_atupdated\_atnamevalueclass\_typeclass\_id14322022-03-03 12:17:422022-03-03 12:17:42consents{"consent1":true,"consent2":false}EscolaLms\\ModelFields\\Tests\\Models\\User145814332022-03-03 12:17:422022-03-03 12:17:42extra\_points1000EscolaLms\\ModelFields\\Tests\\Models\\User145814362022-03-03 12:17:422022-03-03 12:17:42descriptionzzzEscolaLms\\ModelFields\\Tests\\Models\\User145814382022-03-03 12:17:422022-03-03 12:17:42interested\_in\_teststrueEscolaLms\\ModelFields\\Tests\\Models\\User1458See [tests](tests) folder as rows above are generated from the tests.

Example
-------

[](#example)

The best documentation operates on live example so here it is.

Assuming you have User Model

```
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected $table = 'users';
    protected $fillable = ['first_name', 'last_name', 'email'];
    protected $appends = ['foo'];
    public function getFooAttribute()
    {
        return 'bar';
    }
}
```

In order to add extra fields to user model you would need to create new columns in user table with migration and add those fields. This is a standard way of handling this issue, but this package introduces new one.

### Option 1. Extending Model

[](#option-1-extending-model)

This option replaces `Illuminate\Database\Eloquent\Model` with `EscolaLms\ModelFields\Models\Model`

```
use EscolaLms\ModelFields\Models\Model;

class User extends Model
{
    protected $table = 'users';
    protected $fillable = ['first_name', 'last_name', 'email'];
    protected $appends = ['foo'];
    public function getFooAttribute()
    {
        return 'bar';
    }
}
```

### Option 2. Trait in Model.

[](#option-2-trait-in-model)

This option uses `EscolaLms\ModelFields\Traits\ModelFields` instead of extending class;

```
use Illuminate\Database\Eloquent\Model;
use EscolaLms\ModelFields\Traits\ModelFields;

class User extends Model
{
    use ModelFields;

    protected $table = 'users';
    protected $fillable = ['first_name', 'last_name', 'email'];
    protected $appends = ['foo'];
    public function getFooAttribute()
    {
        return 'bar';
    }
}

}
```

Basically that all the steps you need to allow model to be extendable.

### Defining new fields on selected Model.

[](#defining-new-fields-on-selected-model)

Now lets create new field meta description. We'll be adding new field to user, called `description` which will be long text.

```
use EscolaLms\ModelFields\Facades\ModelFields;

ModelFields::addOrUpdateMetadataField(
    User::class, // Model class that we want to extents
    'description', // name of new field
    'text', // type of new field
    'lorem ipsum', // default value
    ['required', 'string', 'max:255'] // validation rules
);
```

Interface of this method is as follows

```
use EscolaLms\ModelFields\Models\Metadata;

public function addOrUpdateMetadataField(string $class_type, string $name, string $type, string $default = '', array $rules = null, $visibility = 1  'to be or not to be',
];

$user = User::create(array_merge([
    'first_name' => 'John',
    'last_name' => 'Deo',
    'email' => 'john@email.com',
], $extraAttributes));

$user = User::find($user->id);

assert($user->description === $extraAttributes['description']);
```

That's all, your user model is ready to be extended. You can get and set attributes as they were created standard way.

```
 $extraAttributes = [
    'description' => 'aaa',
    'interested_in_tests' => false,
    'aaaa' => 'aaaa', // this will not be saved as is neither in model attributes nor in extra fields
    'consents' => ['consent1' => true, 'consent2' => false]
];

$user = User::create(array_merge([
    'first_name' => 'aaa',
    'last_name' => 'aaa',
    'email' => 'aaa@email.com',
], $extraAttributes));

$user->fill(['a' => 'nb']);  // this will not be saved as is neither in model attributes nor in extra fields

$user = User::find($user->id); // fetch user from database

assert($user->description === $extraAttributes['description']);
assert($user->interested_in_tests === $extraAttributes['interested_in_tests']);
assert($user->consents === $extraAttributes['consents']);
assert($user->aaaa === null);

$user->description = 'abc';
$user->interested_in_tests = true;
$user->save();

$user = User::find($user->id); // fetch user from database

assert($user->description === 'abc');
assert($user->interested_in_tests === true);

$user->update([
    'description' => 'zzz',
    'interested_in_tests' => false
]);

$user = User::find($user->id);  // fetch user from database

assert($user->description === 'zzz');
assert($user->interested_in_tests === false);
```

### Resources and fields visibility

[](#resources-and-fields-visibility)

Using resources is simple, look at the following example

```
namespace EscolaLms\ModelFields\Tests\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;
use EscolaLms\ModelFields\Tests\Models\User;
use EscolaLms\ModelFields\Facades\ModelFields;
use EscolaLms\ModelFields\Enum\MetaFieldVisibilityEnum;

class UserResource extends JsonResource
{
    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function toArray($request)
    {
        return [
            'id' => $this->user->id,
            'first_name' => $this->user->first_name,
            'last_name'  => $this->user->last_name,
            'email' => $this->user->email,
            ...ModelFields::getExtraAttributesValues($this->user, MetaFieldVisibilityEnum::PUBLIC) //  MetaFieldVisibilityEnum::PUBLIC === 1
        ];
    }
}
```

Note. In php 7.4 user `array_merge` instead of spread `...` operator.

Look at the visibility field in example above. Package allows to define visibility of the meta fields. Here we're defining 2 fields, one is public, second admin only.

```
use EscolaLms\ModelFields\Facades\ModelFields;
use EscolaLms\ModelFields\Facades\ModelFields;

ModelFields::addOrUpdateMetadataField(
    User::class,
    'title',
    'varchar',
    '',
    ['required', 'string', 'max:255']
);

ModelFields::addOrUpdateMetadataField(
    User::class,
    'admin_secret',
    'varchar',
    'super_secret',
    ['required', 'string', 'max:255'],
    MetaFieldVisibilityEnum::ADMIN
);
```

Now we can have 2 endpoints one that list user with public fields, other with visible to admin only.

```
namespace EscolaLms\ModelFields\Tests\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;
use EscolaLms\ModelFields\Tests\Models\User;
use EscolaLms\ModelFields\Facades\ModelFields;
use EscolaLms\ModelFields\Enum\MetaFieldVisibilityEnum;

class UserResource extends JsonResource
{
    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function toArray($request)
    {
        return [
            'first_name' => $this->user->first_name,
            'last_name'  => $this->user->last_name,
            'email' => $this->user->email,
            ...ModelFields::getExtraAttributesValues($this->user, MetaFieldVisibilityEnum::PUBLIC)
        ];
    }
}
```

Now let's see how Admin Resource would look like.

```
namespace EscolaLms\ModelFields\Tests\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;
use EscolaLms\ModelFields\Tests\Models\User;
use EscolaLms\ModelFields\Facades\ModelFields;
use EscolaLms\ModelFields\Enum\MetaFieldVisibilityEnum;

class UserAdminResource extends JsonResource
{
    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function toArray($request)
    {
        return [
            'id' => $this->user->id,
            'first_name' => $this->user->first_name,
            'last_name'  => $this->user->last_name,
            'email' => $this->user->email,
            ...ModelFields::getExtraAttributesValues($this->user, MetaFieldVisibilityEnum::ADMIN | MetaFieldVisibilityEnum::PUBLIC)
        ];
    }
}
```

`MetaFieldVisibilityEnum::ADMIN | MetaFieldVisibilityEnum::PUBLIC` is a [Flagged/Bitwise Enum](https://github.com/BenSampo/laravel-enum#flaggedbitwise-enum). `MetaFieldVisibilityEnum` is just a proposal - you can use as many permissions as you like yet defining values you must use powers of 2, like.

```
    const ReadComments      = 1  ['required', 'string'],
            'email' => ['required', 'unique:users'],
            ...ModelFields::getFieldsMetadataRules(User::class)
        ];
    }
}
```

In php 7.4 user `array_merge` instead of spread `...` operator.

Endpoints
---------

[](#endpoints)

All the endpoints are defined in [![swagger](https://camo.githubusercontent.com/bf46f50926ef796b1bb0b6e41af746af52ff3aacdffb0533450f3b614a7334a2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f63756d656e746174696f6e2d737761676765722d677265656e)](https://escolalms.github.io/model-fields/).

Tests
-----

[](#tests)

Run `./vendor/bin/phpunit` to run tests. See [tests](tests) folder as it's quite good staring point as documentation appendix.

Test details [![codecov](https://camo.githubusercontent.com/5edcdf1acd4aa0f936eae69aff900a7be8550354cb78a74026b1247e1cdc12db/68747470733a2f2f636f6465636f762e696f2f67682f4573636f6c614c4d532f6d6f64656c2d6669656c64732f6272616e63682f6d61696e2f67726170682f62616467652e7376673f746f6b656e3d4e52414e34523841475a)](https://codecov.io/gh/EscolaLMS/model-fields) [![phpunit](https://github.com/EscolaLMS/model-fields/actions/workflows/test.yml/badge.svg)](https://github.com/EscolaLMS/model-fields/actions/workflows/test.yml)

Events
------

[](#events)

This package does not dispatch any events.

Listeners
---------

[](#listeners)

This package does not listen for any events

How to use this on frontend.
----------------------------

[](#how-to-use-this-on-frontend)

### Admin panel

[](#admin-panel)

All the endpoints defined in [![swagger](https://camo.githubusercontent.com/bf46f50926ef796b1bb0b6e41af746af52ff3aacdffb0533450f3b614a7334a2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f63756d656e746174696f6e2d737761676765722d677265656e)](https://escolalms.github.io/model-fields/) are for admin panel.

There is native component you can use to implement this in [admin panel](https://github.com/EscolaLMS/Admin/tree/main/src/components/ModelFields) for any model that allows extending

```

```

Example in admin panel

**List of user model fields**

[![List of user model fields](docs/list.png "List of user model fields")](docs/list.png)

**Creating/editing model field**

[![Creating/editing model field](docs/edit.png "Creating/editing model field")](docs/edit.png)

### Front Application

[](#front-application)

See example above how to extend controllers to CRUD model fields to give model

Permissions
-----------

[](#permissions)

Permissions are defined in [seeder](packages/model-fields/database/seeders/PermissionTableSeeder.php)

Roadmap. Todo. Troubleshooting.
-------------------------------

[](#roadmap-todo-troubleshooting)

- `firstOrCreate` doesn't work when passing extra attributes

###  Health Score

43

—

FairBetter than 91% of packages

Maintenance51

Moderate activity, may be stable

Popularity34

Limited adoption so far

Community22

Small or concentrated contributor base

Maturity55

Maturing project, gaining track record

 Bus Factor2

2 contributors hold 50%+ of commits

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

Total

26

Last Release

486d ago

PHP version history (2 changes)0.0.1PHP &gt;=7.4

0.1.0PHP &gt;=8.0

### Community

Maintainers

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

---

Top Contributors

[![qunabu](https://avatars.githubusercontent.com/u/214608?v=4)](https://github.com/qunabu "qunabu (13 commits)")[![mako321](https://avatars.githubusercontent.com/u/59456825?v=4)](https://github.com/mako321 "mako321 (12 commits)")[![HerbertIV](https://avatars.githubusercontent.com/u/62691459?v=4)](https://github.com/HerbertIV "HerbertIV (7 commits)")[![daVitekPL](https://avatars.githubusercontent.com/u/58150098?v=4)](https://github.com/daVitekPL "daVitekPL (4 commits)")[![dyfero](https://avatars.githubusercontent.com/u/59400506?v=4)](https://github.com/dyfero "dyfero (2 commits)")[![dicani0](https://avatars.githubusercontent.com/u/58490533?v=4)](https://github.com/dicani0 "dicani0 (2 commits)")[![pa-cholek](https://avatars.githubusercontent.com/u/5345420?v=4)](https://github.com/pa-cholek "pa-cholek (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/escolalms-model-fields/health.svg)

```
[![Health](https://phpackages.com/badges/escolalms-model-fields/health.svg)](https://phpackages.com/packages/escolalms-model-fields)
```

###  Alternatives

[wireui/wireui

TallStack components

1.8k1.3M16](/packages/wireui-wireui)[livewire/volt

An elegantly crafted functional API for Laravel Livewire.

4205.3M84](/packages/livewire-volt)[ramonrietdijk/livewire-tables

Dynamic tables for models with Laravel Livewire

21147.4k](/packages/ramonrietdijk-livewire-tables)

PHPackages © 2026

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