PHPackages                             thomas-brillion/use-it - 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. thomas-brillion/use-it

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

thomas-brillion/use-it
======================

Easy to use Laravel Features, Abilities, Usages and Consumptions

v0.3.1(1y ago)120MITPHPPHP ^8.1|^8.2|^8.3

Since May 6Pushed 1y ago1 watchersCompare

[ Source](https://github.com/w99910/use-it)[ Packagist](https://packagist.org/packages/thomas-brillion/use-it)[ Fund](https://buy.stripe.com/eVa4hXaHdc0t1Nu144)[ GitHub Sponsors](https://github.com/w99910)[ RSS](/packages/thomas-brillion-use-it/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (6)Versions (14)Used By (0)

Use-It - Features, Abilities, Usages and Consumptions
=====================================================

[](#use-it---features-abilities-usages-and-consumptions)

[![preview](preview.png)](preview.png)

Table Of Contents
-----------------

[](#table-of-contents)

- [Introduction](#introduction)
- [Concept](#concept)
- [Installation](#installation)
- [Usage](#usage)
- [Middleware](#middleware)
- [SoftDeletes](#softdeletes)
- [Custom Models](#using-custom-models)
- [Testing](#testing)
- [Bug Report](#bug-report)
- [License](#license)
- [Funding](#funding)

> `FeatureGroup` is introduced `v0.2.0`. It is similar to `Role` in `roles-permissions` concept. You can assign multiple `features` to the `feature-group` and then those features will be automatically attached to the user if user is given access to that `feature-group`.

Introduction
------------

[](#introduction)

While there are many packages in Laravel like Laravel Pennant (for feature flags) and Spatie Permission (for managing user permissions and roles), I would like to create a feature that is not only an ability or permission but also a consumable one.

For example, I want to make an ability feature called "can-post" so users can create posts. Also, I'm thinking of a consumable feature called "storage" for using storage in the app. I plan to have different levels of usage for " storage," like "100GB storage" or "1TB storage."

Concept
-------

[](#concept)

In this system, we have four main database models:

- Feature: This model handles the creation of features.
- Ability: It manages interactions with ability-based features.
- Usage: This model tracks the usage of quantity-based features.
- Consumption: Responsible for managing the consumption of a usage.
- FeatureGroup: Responsible for handling feature groups

When you create a new feature, you can grant a user access to that feature. Depending on the type of feature—whether it's an ability or a usage—a corresponding ability or usage record will be generated. You can then test this ability or usage by using the feature name.

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

[](#installation)

- ### Install via composer

    [](#install-via-composer)

```
composer require thomas-brillion/use-it
```

- ### Setting up migrations

    [](#setting-up-migrations)

Publish the migration presets.

```
php artisan vendor:publish --tag=use-it-migrations
```

Note: If you are using `feature group` on different table other than `users`, please create a pivot table and change the table in the relationship such as

```
public function featureGroups(): BelongsToMany
{
   return $this->belongsToMany(ThomasBrillion\UseIt\Support\ModelResolver::getFeatureGroupModel(), 'your_pivot_table_name');
}
```

Please consult [laravel documentation](https://laravel.com/docs/11.x/eloquent-relationships#many-to-many) for more details.

- ### Setting up your model

    [](#setting-up-your-model)

Implement either `ThomasBrillion\UseIt\Interfaces\CanUseFeature` or `ThomasBrillion\UseIt\Interfaces\CanUseFeatureGroup` interface in your model class and either include `ThomasBrillion\UseIt\Traits\CanUseIt` trait or resolve the interface on your own.

> It is not mandatory to implement `ThomasBrillion\UseIt\Interfaces\CanUseFeatureGroup` interface if you don't want to use feature group.

```
use ThomasBrillion\UseIt\Interfaces\CanUseFeature;

class User implements CanUseFeature {
   use CanUseIt;
   ...
}
```

Usage
-----

[](#usage)

- ### Create Features

    [](#create-features)

In order to create feature, you can use `create` method of `FeatureService` service.

There are two types of features: `Ability` and `Quantity`.

> Note: Feature name must be unique.

```
ThomasBrillion\UseIt\Services\FeatureService::create(
   name: 'post',
   description: 'create a post',
   type: \ThomasBrillion\UseIt\Support\Enums\FeatureType::Ability,
   meta: [],
   disabled: false
)
```

- ### Grant User to Feature

    [](#grant-user-to-feature)

Use `grantFeature` method of `FeatureService`.

- If feature is `Ability` type, `Ability` record will be created for user.

```
$user = User::first(); // or any eloquent model which either uses `CanUseIt` trait or implements `CanUseFeature` interface.

ThomasBrillion\UseIt\Services\FeatureService::of($user)->grantFeature('post', expireAt:  new DateTime('1year'))
```

- if feature is `Quantity` type, `Usage` record will be created. You need pass third parameter as `maximum_value` of feature, optionally fourth parameter as `level` and fifth parameter as `meta`.

```
$user = User::first(); // or any eloquent model which either uses `CanUseIt` trait or implements `CanUseFeature` interface.

ThomasBrillion\UseIt\Services\FeatureService::create(
   name: 'storage',
   description: 'use storage',
   type: \ThomasBrillion\UseIt\Support\Enums\FeatureType::Quantity,
   meta: [],
   disabled: false
)
ThomasBrillion\UseIt\Services\FeatureService::of($user)->grantFeature(feature: 'storage', expireAt:  new DateTime('1year'), total: 100, level: 0)

// granting multiple features
ThomasBrillion\UseIt\Services\FeatureService::of($user)->grantFeatures(['storage','post'], expireAt:  new DateTime('1month'), total: 100, level: 0)
```

> Note: You can create multiple usages of same feature with different maximum values and level. When usage is consumed, higher level usage will try to be consumed first.

- ### Checking if user can use feature

    [](#checking-if-user-can-use-feature)

You can use

- `canUseFeature` to check if user can use **all** of provided feature/s.

```
$user = User::first(); // or any eloquent model which either uses `CanUseIt` trait or implements `CanUseFeature` interface.

$user->canUseFeature('post');

$user->canUseFeature('storage', amount:1000);

$user->canUseFeature('upload,storage', amount: 1000);

$user->canUseFeature(['upload', 'storage'], amount: 1000);
```

- `canUseAnyFeature to check if user can use **any** of provided feature/s. You can pass either comma-separated string or string or array.

```
$user = User::first(); // or any eloquent model which either uses `CanUseIt` trait or implements `CanUseFeature` interface.

$user->canUseAnyFeature('post');

$user->canUseAnyFeature('post,upload,comment');

$user->canUseAnyFeature(['post','upload','comment'], amount:1000);
```

- ### Consuming usable feature

    [](#consuming-usable-feature)

Use `try` method of `FeatureService`. Pass `feature_name` as first parameter and `amount` as second parameter if feature is quantitative type.

If feature is `Quantity` type, `Consumption` model object will be returned upon successful process. otherwise, following errors will be thrown depending on the condition.

- `Cannot find usages for the feature` if feature is not found
- `Usage is expired` if user has expired access to the feature
- `Usage is out of limit` if user has consumed all available amount.

```
$user = User::first(); // or any eloquent model which either uses `CanUseIt` trait or implements `CanUseFeature` interface.

$featureService = new ThomasBrillion\UseIt\Services\FeatureService($user);

ThomasBrillion\UseIt\Services\FeatureService::create(
   name: 'storage',
   description: 'create a post',
   type: \ThomasBrillion\UseIt\Support\Enums\FeatureType::Quantity,
)

ThomasBrillion\UseIt\Services\FeatureService::of($user)->grantFeature('storage',  expireAt: new DateTime('1year'), total: 1000 );

$user->try('storage', amount: 10);
```

- ### Disable/Enable Feature

    [](#disableenable-feature)

You can toggle accessiblity to the feature.

```
$user = User::first(); // or any eloquent model which either uses `CanUseIt` trait or implements `CanUseFeature` interface.

ThomasBrillion\UseIt\Services\FeatureService::create(
   name: 'storage',
   description: 'use storage',
   type: \ThomasBrillion\UseIt\Support\Enums\FeatureType::Quantity,
)

ThomasBrillion\UseIt\Services\FeatureService::disableFeature('storage');

ThomasBrillion\UseIt\Services\FeatureService::enableFeature('storage');
```

- ### Revoking access to feature

    [](#revoking-access-to-feature)

You can revoke access to feature using `revokeToFeature` method of `FeatureService` class.

```
$user = User::first(); // or any eloquent model which either uses `CanUseIt` trait or implements `CanUseFeature` interface.

$featureService = new ThomasBrillion\UseIt\Services\FeatureService($user);

ThomasBrillion\UseIt\Services\FeatureService::create(
   name: 'post',
   description: 'create a post',
   type: \ThomasBrillion\UseIt\Support\Enums\FeatureType::Ability,
)

ThomasBrillion\UseIt\Services\FeatureService::of($user)->grantFeature('post', expireAt:  new DateTime('1month'));

$user->canUseFeature('post'); // true

ThomasBrillion\UseIt\Services\FeatureService::of($user)->revokeToFeature('post');
$user->canUseFeature('post'); // false
```

- ### Getting current usages of a feature

    [](#getting-current-usages-of-a-feature)

```
$user = User::first(); // or any eloquent model which either uses `CanUseIt` trait or implements `CanUseFeature` interface.

$user->getConsumableUsagesOfFeature('post'); // return collection of usages
```

- ### Getting all usages of a feature

    [](#getting-all-usages-of-a-feature)

```
$user = User::first(); // or any eloquent model which either uses `CanUseIt` trait or implements `CanUseFeature` interface.

$user->getAllUsagesOfFeature('post'); // return collection of usages
```

- ### Getting the current consumable usage of a feature

    [](#getting-the-current-consumable-usage-of-a-feature)

```
$user = User::first(); // or any eloquent model which either uses `CanUseIt` trait or implements `CanUseFeature` interface.

$user->getCurrentUsageOfFeature('post');
```

- ### Getting consumptions of a feature

    [](#getting-consumptions-of-a-feature)

```
$user = User::first(); // or any eloquent model which either uses `CanUseIt` trait or implements `CanUseFeature` interface.

$user->getConsumptionsOfFeature('post'); // return array of consumptions with key as usage id
```

- Feature Group
    -------------

    [](#feature-group)

A feature group is a logical grouping of features, offering a centralized way to access and revoke features instead of interacting with a feature manually.

- Creating feature group

```
$featureGroup = ThomasBrillion\UseIt\Models\FeatureGroup::create(
        'premium-plan',
        'gives access to premium features'
);
```

- Create new features or add existing features to feature group

I recommand you to set preset data for `Quantity` type feature such as `total` or `expireInSeconds`.

```
$fourTeamMembersFeature = FeatureService::create('mini-team', 'add four team members', FeatureType::Quantity, total: 4, expireInSeconds: 60 * 60 * 24 * 30);

FeatureGroupService::addFeatures($featureGroup, [
        $fourTeamMembersFeature,
        'can-post'
]);
```

- Grant user to that feature group.

```
$user = User::first();

FeatureGroupService::of($user)->grantFeatureGroup('premium-plan');

expect($user->canUseFeature('mini-team', 1))->toBeTrue();
expect($user->canUseFeature('can-post'))->toBeTrue();
```

- Checking if user has feature group

```
$user->hasFeatureGroup('premium-plan'); // return boolean.
```

- Revoke feature group

```
FeatureGroupService::of($user)->revokeFeatureGroup('premium-plan');
```

- Middleware
    ----------

    [](#middleware)

In Laravel, `ThomasBrillion\UseIt\Http\Middlewares\CanUseFeatureMiddleware` is automatically registered in service provider. You can use it in your route by using middleware alias `can-use-feature` and `can-use-any-feature` by passing the feature name as first parameter.

```
Route::post('/post',[ExampleAction::class,'post'])->middleware('can-use-feature:post');
```

You can provide multiple feature names by separating with comma.

```
Route::post('/post',[ExampleAction::class,'post'])->middleware('can-use-feature:post,comment,upload');

Route::post('/post',[ExampleAction::class,'post'])->middleware('can-use-any-feature:post,comment');
```

> Note: To check if user can consume usage of feature, you need to pass `amount` input in the request.

```
https://example-laravel.test/post?amount=12

```

- Routing
    -------

    [](#routing)

Routes are disabled by default. In order to enable it, you can either

- set the `routes` config as `true` or
- call this static method `\ThomasBrillion\UseIt\Http\Controllers\UseItController::routes();` inside your route file ( eg `routes/web.php` )

There are two end-points provided by this package.

- Checking if user can use feature - `/use-it/can/{feature}`In order to check if the feature can be consumed a certain amount, pass query parameters - `amount` in the request.

    ```
    /use-it/can/post?amount=100

    ```
- Trying the feature - `/use-it/try/{feature}`In order to consume the feature, pass query parameters - `amount` and `meta` (optional) in the request.

    ```
    /use-it/try/post?amount=100

    ```
- SoftDeletes
    -----------

    [](#softdeletes)

In order to enable `SoftDelete` feature, you can [extend the models](#using-custom-models) and follow [laravel soft-delete instructions](https://laravel.com/docs/11.x/eloquent#soft-deleting).

You also need to add `deleted_at` column in your migration. You can publish migrations using

```
php artisan vendor:publish --tag=use-it
```

- Using Custom Models
    -------------------

    [](#using-custom-models)

You can change `Feature`, `Ability`, `Usage` and `Consumption` models by either providing custom models in config file or registering it before using it.

Your custom model must implement corresponding interface.

- feature: `ThomasBrillion\UseIt\Interfaces\Models\FeatureInterface`
- featureGroup: `ThomasBrillion\UseIt\Interfaces\Models\FeatureGroupInterface`
- ability: `ThomasBrillion\UseIt\Interfaces\Models\AbilityInterface`
- usage: `ThomasBrillion\UseIt\Interfaces\Models\UsageInterface`
- consumption: `ThomasBrillion\UseIt\Interfaces\Models\ConsumptionInterface`
- #### Method A: Config File

    [](#method-a-config-file)

```
// configs/use-it.php
[
    'routes' => false,

    'models' => [

        // Change your custom model here
        'feature' => MyCustomFeatureModel::class,

        'feature-group' => \ThomasBrillion\UseIt\Models\FeatureGroup::class,

        'ability' => \ThomasBrillion\UseIt\Models\Ability::class,

        'usage' => \ThomasBrillion\UseIt\Models\Usage::class,

        'consumption' => \ThomasBrillion\UseIt\Models\Consumption::class,
    ]
];
```

- #### Method B: Manually Register Using Resolver

    [](#method-b-manually-register-using-resolver)

You can either register your custom model using `ThomasBrillion\UseIt\Support\ModelResolver`.

```
use ThomasBrillion\UseIt\Support\ModelResolver;

ModelResolver::registerModel('feature', MyCustomFeature::class);
```

Testing
-------

[](#testing)

`composer run test`

Bug Report
----------

[](#bug-report)

Please kindly create an issue or pull request.

License
-------

[](#license)

The MIT LICENSE.

Funding
-------

[](#funding)

Consider [supporting me](https://github.com/sponsors/w99910) or letting me know if you have any freelance projects or remote job opportunities available.

Please consider supporting me to continue contribution of open-source libraries.

###  Health Score

29

—

LowBetter than 59% of packages

Maintenance38

Infrequent updates — may be unmaintained

Popularity8

Limited adoption so far

Community7

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

Recently: every ~3 days

Total

13

Last Release

619d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/8cc3500e43c9d8366ea5b2b974176026c785ee56a3f93445a5262f155e9d37c9?d=identicon)[zawlintun](/maintainers/zawlintun)

---

Top Contributors

[![w99910](https://avatars.githubusercontent.com/u/65523475?v=4)](https://github.com/w99910 "w99910 (12 commits)")

---

Tags

laravelabilitiesfeaturesusagesConsumptions

###  Code Quality

TestsPest

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/thomas-brillion-use-it/health.svg)

```
[![Health](https://phpackages.com/badges/thomas-brillion-use-it/health.svg)](https://phpackages.com/packages/thomas-brillion-use-it)
```

###  Alternatives

[yajra/laravel-datatables-oracle

jQuery DataTables API for Laravel

4.9k33.8M339](/packages/yajra-laravel-datatables-oracle)[barryvdh/laravel-ide-helper

Laravel IDE Helper, generates correct PHPDocs for all Facade classes, to improve auto-completion.

14.9k123.0M687](/packages/barryvdh-laravel-ide-helper)[spatie/laravel-enum

Laravel Enum support

3655.4M31](/packages/spatie-laravel-enum)[psalm/plugin-laravel

Psalm plugin for Laravel

3274.9M308](/packages/psalm-plugin-laravel)[datomatic/nova-enum-field

A Laravel Nova PHP 8.1 enum field with filters

20134.2k](/packages/datomatic-nova-enum-field)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)

PHPackages © 2026

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