Pennant Feature Configuration
Declare required settings for Pennant features, prevent incomplete activation, and link administrators to the correct configuration page.
Some feature flags need more than an on/off value. They may depend on credentials, identifiers, mappings, or other application settings before they can operate safely.
Tempr supports these prerequisites through feature configuration providers. A provider:
- Reports the human-readable names of any missing requirements.
- Links administrators to the page where those values are managed.
- Prevents the feature from being activated while requirements are missing.
- Makes an already-enabled feature behave as inactive if its required configuration is later removed.
Features without a registered configuration provider continue to behave like normal Pennant flags.
Administrator Experience
In the Config panel's Features resource, a feature with registered requirements displays:
- Ready when all required values are present.
- Missing configuration when one or more values are absent. Hover over the badge to see their names.
- A Configure action linking to the feature's settings page.
Trying to enable an incomplete feature displays the missing requirements and leaves the flag disabled.
Add Requirements Backed By Spatie Settings
Create a provider that extends SpatieSettingsFeatureConfiguration:
<?php
namespace App\Features\Configuration;
use App\Filament\Pages\ManageExampleIntegration;
use App\Settings\ExampleIntegrationSettings;
class ExampleIntegrationConfiguration extends SpatieSettingsFeatureConfiguration
{
protected function settingsClass(): string
{
return ExampleIntegrationSettings::class;
}
protected function requiredSettings(): array
{
return [
'account_id' => 'Account ID',
'mappings.default_item_id' => 'Default item mapping',
];
}
public function settingsUrl(): string
{
return ManageExampleIntegration::getUrl(panel: 'config');
}
}
The keys returned by requiredSettings() use dot notation against the settings class's toArray() output. A value is considered missing when it is null, an empty string, or an empty array. Boolean false and numeric 0 are treated as configured values.
Register the provider in config/pennant-manager.php using the feature's stable Pennant name:
use App\Features\Configuration\ExampleIntegrationConfiguration;
use App\Features\ExampleIntegrationEnabled;
'configurations' => [
ExampleIntegrationEnabled::NAME => ExampleIntegrationConfiguration::class,
],
Use the feature's Pennant name, such as integration.example, as the map key. Do not use the feature class name as the key.
Add Custom Requirements
Not every prerequisite belongs in Spatie Settings. For example, readiness may depend on a database record or an established OAuth connection. Implement FeatureConfiguration directly when the requirement needs custom logic:
<?php
namespace App\Features\Configuration;
use App\Contracts\Features\Configuration\FeatureConfiguration;
class ExampleConnectionConfiguration implements FeatureConfiguration
{
public function __construct(private readonly ConnectionBroker $connectionBroker) {}
public function missingRequirements(): array
{
return $this->connectionBroker->isConnected()
? []
: ['Connected account'];
}
public function settingsUrl(): string
{
return ManageExampleConnection::getUrl(panel: 'config');
}
}
Providers are resolved through Laravel's container, so constructor injection is supported.
Runtime Behavior
App-owned global flags extend GlobalFeature. Its active() method requires both conditions to be true:
- Pennant stores the feature as enabled.
- The registered configuration provider reports no missing requirements.
Calling the feature class's activate() method throws a LogicException listing missing requirements when setup is incomplete.
if (ExampleIntegrationEnabled::active()) {
// The flag is enabled and its required configuration is present.
}
ExampleIntegrationEnabled::activate();
Use the feature class methods for application checks and programmatic activation. Direct calls to Feature::activate() bypass the configuration assertion, although GlobalFeature::active() will still report the feature as inactive while requirements are missing.
Testing A Provider
Provider coverage should verify:
- Each missing value produces the expected administrator-facing label.
- Valid falsey values such as
falseor0are accepted when appropriate. - The settings URL points to a page the intended administrator can access.
- The feature cannot activate while requirements are missing.
- The feature becomes active after requirements are satisfied.
Run the focused feature configuration tests with:
php artisan test --compact tests/Unit/FeatureConfigurationManagerTest.php tests/Unit/FeatureFlagsTest.php
Implementation Reference
| Concern | Location |
|---|---|
| Provider contract | app/Contracts/Features/Configuration/FeatureConfiguration.php |
| Provider registry and assertions | app/Features/Configuration/FeatureConfigurationManager.php |
| Spatie Settings base provider | app/Features/Configuration/SpatieSettingsFeatureConfiguration.php |
| Runtime feature gating | app/Features/GlobalFeature.php |
| Pennant Manager status and actions | app/Filament/Resources/Features/FeatureResource.php |
| Provider registration | config/pennant-manager.php |