PHPackages                             rpillz/laravel-feature-access - 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. rpillz/laravel-feature-access

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

rpillz/laravel-feature-access
=============================

Feature access for Laravel apps

1.1.1(3y ago)328[3 PRs](https://github.com/RPillz/laravel-feature-access/pulls)MITPHPPHP ^8.0 || ^8.1CI passing

Since Nov 21Pushed 1w ago1 watchersCompare

[ Source](https://github.com/RPillz/laravel-feature-access)[ Packagist](https://packagist.org/packages/rpillz/laravel-feature-access)[ Docs](https://github.com/rpillz/laravel-feature-access)[ GitHub Sponsors](https://github.com/RPillz)[ RSS](/packages/rpillz-laravel-feature-access/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (5)Dependencies (6)Versions (8)Used By (0)

Feature access for Laravel apps
===============================

[](#feature-access-for-laravel-apps)

[![Latest Version on Packagist](https://camo.githubusercontent.com/754ff24c4a0dcd97027747917b877a92027eb86eb4ac368ddd5a733df2713a3e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7270696c6c7a2f6c61726176656c2d666561747572652d6163636573732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/rpillz/laravel-feature-access)[![GitHub Tests Action Status](https://camo.githubusercontent.com/f65f303502227cc4e9ae1a6fb76361293006033c2fa1ced54042aea6ec9ae0d1/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f776f726b666c6f772f7374617475732f7270696c6c7a2f6c61726176656c2d666561747572652d6163636573732f72756e2d74657374733f6c6162656c3d7465737473)](https://github.com/rpillz/laravel-feature-access/actions?query=workflow%3Arun-tests+branch%3Amain)[![GitHub Code Style Action Status](https://camo.githubusercontent.com/290b65f290ab5146a00d62dbc217368ac10759477135437e3a26c5424110f901/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f776f726b666c6f772f7374617475732f7270696c6c7a2f6c61726176656c2d666561747572652d6163636573732f436865636b253230262532306669782532307374796c696e673f6c6162656c3d636f64652532307374796c65)](https://github.com/rpillz/laravel-feature-access/actions?query=workflow%3A%22Check+%26+fix+styling%22+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/9d2436d3d6c7f2d77154b666d48e843b73bea62a6e1a84fbff6330ecab405aa0/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7270696c6c7a2f6c61726176656c2d666561747572652d6163636573732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/rpillz/laravel-feature-access)

Add Plans (eg: Basic, Standard, Pro) and Feature restrictions (eg: Can Make 3 Pages, Can Upload Video) to your Laravel app.

Plans and corresponding features are hard-coded in a config file, but these defaults may be overridden with a database entry for a specific user. (ie: Your special friend who wants all the features, but, like, for free.)

Feature access can be assigned to any model (eg: User, Team) via a trait, which adds properties to use in your app logic, such as $user-&gt;canViewFeature('pictures-of-my-dog')

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

[](#installation)

You can install the package via composer:

```
composer require rpillz/laravel-feature-access
```

**Publish the config file.** This is where your features and tiers are defined.

```
php artisan vendor:publish --tag=feature-access-config
```

**Publish and run migrations.** This will create a *'features'* table for storing access information attached to your models.

```
php artisan vendor:publish --tag=feature-access-migrations
php artisan migrate
```

Basic Usage
-----------

[](#basic-usage)

### 1. Define Features (and Tiers) in the Config

[](#1-define-features-and-tiers-in-the-config)

Start by defining your app features in the *feature-access.php* config file.

This is an example of a feature mapped out in the config file:

```
return [

    'sample-feature' => [ // begin with the feature key name. This is used to request permissions.
        'name' => 'Test Feature', // Human readable name
        'read' => true, // Can read/view items in this feature
        'update' => false, // cannot edit/change/update items
        'create' => false, // cannot create new items
        'destroy' => false, // cannot destroy/delete items
        'limit' => 3, // limit on number of items allowed
        'levels' => [ // Override the base feature permissions with levels or packages (eg: basic, pro, plus)
            'pro' => [ // level/package key
                'name' => 'Extra Stuff!', // human readable name
                'update' => true, // pro level can edit/change/update items
                'create' => true, // pro level can create items
                'limit' => 5, // limit is increased
                // other permissions will default to base feature definition (above)
            ],
        ]
    ],

];
```

The base level of this feature will be the permission used for all users **and guests** unless they have been explicitly granted an upgraded access level, or override.

### 2. Add Trait To Model

[](#2-add-trait-to-model)

In most cases, you would add this trait to your **User** model, which would allow that user to access (or not access) features.

```
use RPillz\FeatureAccess\Traits\HasFeatureAccess;

class User extends Authenticatable
{

    use HasFeatureAccess;

    ...
```

### 3. Add Permission Checks to your App Logic

[](#3-add-permission-checks-to-your-app-logic)

An example, in a blade template, of adding a button to create a new item, only if the current user is allowed to *create* on the feature *sample-feature*.

```
@if(Auth::user()->canCreateFeature('sample-feature'))
    Add New Sample Item
@endif
```

### 4. Grant Higher Access To Users

[](#4-grant-higher-access-to-users)

You can set permission acces for your User (or any model) with the **setFeatureAccess()** method.

```
$user->setFeatureAccess('sample-feature', 'basic'); // give this user 'basic' level access to 'sample-feature' (which does not exist)

$user->setFeatureAccess('sample-feature', 'pro'); // give this user 'pro' level access to 'sample-feature'

$user->setFeatureAccess('sample-feature', 'pro', [ 'update' => false ]); // give this user 'pro' level access to 'sample-feature', but override the default setting to allow edits just for this user.
```

In the first example above, the user is granted *basic* level access to *sample-feature*. However, there is no *basic* level defined in the feature config file. Their permissions for *sample-feature* will default to the basic settings. These same default settings would be used if no level has been explicitly set for a user.

More Usage Options
------------------

[](#more-usage-options)

### Using Team Model

[](#using-team-model)

Your app may make use of Teams (a la Jetstream) in which case you may want to have the **Team** model using this trait, and accessing user permissions via their team.

**Add the *HasFeatureAccess* trait to your Team model.** Now any user on that team will have access to the same features, through the team.

```
Auth::user()->currentTeam->canReadFeature('maple-syrup');
```

This trait can be applied to any Model, or even multiple models if you want to be able apply permissions to both Users and Teams individually. (There is no built-in permission inheritance in such a case, just one or the other.)

### Using Other Models

[](#using-other-models)

You can grant feature access to any model using the *HasFeatureAccess* trait. In most cases, that model would somehow be associated with the authenticated user. However, it could be adapted to other uses:

- On a Tenant or Domain model, which would grant features depending upon the domain through which your app was being accessed.
- On a particular Page or Post to change what features are displayed in the layout.

You can be using this on multiple models within the same app, so you may bend it to your will!

### Methods to Check Permission On Your Model

[](#methods-to-check-permission-on-your-model)

```
$user->canUseFeature('feature-name', 'permission-requested');

// alias functions

$user->canCreateFeature('sample-feature'); // permission-requested = create

$user->canReadFeature('sample-feature'); // permission-requested = read
$user->canViewFeature('sample-feature'); // permission-requested = read

$user->canUpdateFeature('sample-feature'); // permission-requested = update
$user->canEditFeature('sample-feature'); // permission-requested = update

$user->canDestroyFeature('sample-feature'); // permission-requested = destroy
$user->canDeleteFeature('sample-feature'); // permission-requested = destroy

$user->withinFeatureLimit('sample-feature', $user->items->count()); // compares against feature limit
$user->withinFeatureLimit('sample-feature', $user->items->count(), 1); // is there room to add 1 more item?

// or get all the permission data for your model

$user->getFeatureData('sample-feature'); // return array
```

### Using The Facade

[](#using-the-facade)

You can use the Facade methods to check permissions. However, **this only works for the User and/or Team models.** The upside is these will work whether or not a visitor is signed in to an account, and returns base access for guests.

```
FeatureAccess::userCan(string $feature_name, string $permission); // check for permission to 'create', 'read', 'update', or 'destroy'

// shortcut aliases

FeatureAccess::userCanCreate('sample-feature'); // returns boolean true/false

FeatureAccess::userCanRead('sample-feature');
FeatureAccess::userCanView('sample-feature'); // alias of 'read' permission

FeatureAccess::userCanUpdate('sample-feature');
FeatureAccess::userCanEdit('sample-feature'); // alias of 'update' permission

FeatureAccess::userCanDestroy('sample-feature');
FeatureAccess::userCanDelete('sample-feature'); // alias of 'destroy' permission

// it also works for Teams! (a la Jetstream)

FeatureAccess::teamCan(string $feature_name, string $permission);

FeatureAccess::teamCanCreate('sample-feature'); // and all the other aliases as per above
```

If you need to get the full array of current permission access, you can use this:

```
FeatureAccess::userFeature('sample-feature'); // returns array
FeatureAccess::teamFeature('sample-feature'); // returns array
```

### Integrating with Subscriptions (from Cashier, SPark, etc.)

[](#integrating-with-subscriptions-from-cashier-spark-etc)

Rather than creating/updating duplicate database rows to change a user's feature access level, there is a feature to dynamically check the active subscription level for a user, and get the feature permissions accordingly.

This feature must be activated in the *feature-access.php* config file.

```
// Check for active subscription to grant access
'subscriptions' => true,
```

Then you need to add a function on your User model (or Team model, or whatever is using the *HasFeatureAccess* trait) which will return a name corresponding to the appropriate level, as defined in your feature config.

```
public function getFeatureSubscriptionLevel(string $feature_name = null): ?string
    {
        // this logic needs to be customized according to your subscription set-up
        if ($subscription = $this->subscriptions->active()->first()){
            return $subscription->name; // ie: "pro"
        }

        return null;
    }
```

Once you have this set, the subscription will be consulted when returning a User's current feature access.

```
$free_user->canCreateFeature('sample-feature'); //false

$pro_user->canCreateFeature('sample-feature'); //true
```

In order of priority, the user's feature level is first determined by anything saved in the database (by *setFeatureAccesss()* for example), then checking the subscription level (if activated) and finally defaulting to the config file. This means it is possible to upgrade access above and beyond a paid subscription for your VIP users on a case-by-case basis. (technically, you could also downgrade them, you monster!)

Here's an example of the function to go along with Laravel Spark subscriptions.

```
public function getFeatureSubscriptionLevel(string $feature_name = null): ?string
{
    // If you're using Laravel Spark with this model as a Billable.
    // Note: The plan name from Spark is likely capitalized. Make sure it matches your feature-access config level names exactly.
    return $this->sparkPlan()->name ?: null;

}
```

Notice, also, that this function accepts an optional *$feature\_name* argument, which allows you to be more granular in your subscription and logic if needed. (ie: if the subscription to access Pages is different from the subscription to access Blogs)

### Super-Admin Permission

[](#super-admin-permission)

If the current model *property* matches anything in the array, all permission tests will return true. They get to do *everything*.

```
return [

    // grant all access to models which match...
    'super_admin_property' => 'email', // this property...
    'super_admin_access' => [ // to any of these.
        'admin@example.com',
    ],

]
```

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)

- [Ryan Pilling](https://github.com/RPillz)
- [All Contributors](../../contributors)

License
-------

[](#license)

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

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance64

Regular maintenance activity

Popularity10

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity64

Established project with proven stability

 Bus Factor1

Top contributor holds 77% 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 ~107 days

Total

4

Last Release

1362d ago

PHP version history (2 changes)1.0.0PHP ^8.0

1.1.0PHP ^8.0 || ^8.1

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/9386244?v=4)[Ryan](/maintainers/RPillz)[@RPillz](https://github.com/RPillz)

---

Top Contributors

[![RPillz](https://avatars.githubusercontent.com/u/9386244?v=4)](https://github.com/RPillz "RPillz (47 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (8 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (6 commits)")

---

Tags

laravelRPillzlaravel-feature-access

###  Code Quality

TestsPest

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/rpillz-laravel-feature-access/health.svg)

```
[![Health](https://phpackages.com/badges/rpillz-laravel-feature-access/health.svg)](https://phpackages.com/packages/rpillz-laravel-feature-access)
```

###  Alternatives

[spatie/laravel-pdf

Create PDFs in Laravel apps

1.0k4.8M46](/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.

329530.5k29](/packages/codewithdennis-filament-select-tree)[worksome/exchange

Check Exchange Rates for any currency in Laravel.

124603.0k](/packages/worksome-exchange)[stephenjude/laravel-wallet

A simple wallet implementation for Laravel

26611.9k](/packages/stephenjude-laravel-wallet)[rawilk/profile-filament-plugin

Profile &amp; MFA starter kit for filament.

3913.7k](/packages/rawilk-profile-filament-plugin)[tarfin-labs/event-machine

Event-driven state machines for Laravel with event sourcing, type-safe context, and full audit trail.

199.4k](/packages/tarfin-labs-event-machine)

PHPackages © 2026

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