crumbls/subscriptions v2.0.1
Creating and attaching
Create a feature
use Crumbls\Subscriptions\Models\Feature;
$users = Feature::create([
'name' => 'Users',
'slug' => 'users',
]);
The slug is what you'll reference everywhere else (recordFeatureUsage('users'), canUseFeature('users'), middleware can-use-feature:users). Keep it short, kebab-case, and stable -- changing it later requires a data migration.
name is translatable JSON via spatie/laravel-translatable.
Attach to plans with per-plan values
$basic->features()->attach($users, ['value' => '5']);
$pro->features()->attach($users, ['value' => '50']);
$ent->features()->attach($users, ['value' => '999999']);
The value is stored as a string on the plan_features pivot. The library coerces it to int when checking limits and to bool when used as a feature flag.
Boolean features (on/off)
For features that are either present or absent (SSL, custom branding, white-label, priority support):
$ssl = Feature::create(['name' => 'SSL', 'slug' => 'ssl']);
$basic->features()->attach($ssl, ['value' => 'false']);
$pro->features()->attach($ssl, ['value' => 'true']);
Then check with canUseFeature:
if ($sub->canUseFeature('ssl')) {
// enable SSL
}
true, non-zero numbers, and any non-empty string other than 'false' / '0' count as enabled.
Quota features (numeric limits)
For features with a count: users, API calls, projects, GB.
$apiCalls = Feature::create([
'name' => 'API Requests',
'slug' => 'api-requests',
'resettable_period' => 1,
'resettable_interval' => 'month',
]);
$pro->features()->attach($apiCalls, ['value' => '10000']);
canUseFeature('api-requests') returns true while used < value. See Usage tracking for the consumption side.
Sort order on the pivot
The pivot has its own sort_order so you can control how features appear on a single plan's pricing card without affecting their order on other plans:
$pro->features()->attach($users, ['value' => '50', 'sort_order' => 10]);
$pro->features()->attach($apiCalls, ['value' => '10k', 'sort_order' => 20]);
$pro->features()->attach($ssl, ['value' => 'true','sort_order' => 30]);
Detaching
Detaching removes the feature from the plan but keeps the feature definition for use on other plans:
$basic->features()->detach($ssl);
Existing subscriptions on the basic plan immediately lose access to ssl. canUseFeature('ssl') returns false.
Soft deletes
Features use soft deletes. A deleted feature stays out of new attachments and reports false for canUseFeature everywhere it was attached. Restore with $feature->restore().