Darstellung
Entitlements und Feature Gating
Features werden nie über den Plan geprüft.
php
// verboten
if ( $plan === 'business' ) {}
if ( $is_pro ) {}
if ( AD_FORMS_PRO ) {}
// so
$entitlements->allows( 'payments.stripe' );EntitlementManager ist die einzige Autorität:
php
$entitlements->allows( string $feature ): bool;
$entitlements->denies( string $feature ): bool;
$entitlements->require( string $feature ): void; // wirft NotEntitledException
$entitlements->all(): array;Free-Baseline plus signierte Entitlements. Unlicensed, revoked, expired, suspended und unverifizierbar landen alle auf Free – nie auf „nichts“ und nie auf „alles“.
Eigene Feldtypen gaten
required_entitlements() steht auf AbstractField, nicht auf FieldInterface. Ein Add-on, das das Interface direkt implementiert, bleibt kompatibel und deklariert einfach keine Requirements.
php
final class SignatureField extends \Dingfelder\AdForm\Fields\AbstractField {
public function type(): string {
return 'signature';
}
/**
* @return list<string>
*/
public function required_entitlements(): array {
return array( 'fields.advanced', 'fields.signature' );
}
}Einmal deklarieren reicht: Palette, REST-Katalog, Definition-Scanner, Save-Gate und Action-Runner lesen dieselbe Methode.
Eigene Actions gaten
Dasselbe Muster auf AbstractAction. Der Runner prüft vor ad_form_before_action. Eine verweigerte Action wird geloggt und übersprungen – der gespeicherte Entry bleibt.
Module
php
add_action(
'ad_form_register_gated_modules',
function ( \Dingfelder\AdForm\Licensing\Enforcement\ModuleGate $gate ): void {
$gate->register( 'my-addon', array( 'integrations.mailchimp' ) );
}
);Core-Module-IDs (elementor, gutenberg, payments.stripe, …) können Add-ons nicht umdefinieren.
REST-Verweigerung
php
return $this->deny_feature( 'payments.stripe' );Antwort:
json
{
"code": "feature_not_entitled",
"message": "Dieses Feature ist in deinem aktuellen Tarif nicht enthalten.",
"data": {
"status": 403,
"data": {
"success": false,
"code": "feature_not_entitled",
"feature": "payments.stripe",
"required_plan": "pro_plus",
"upgrade_url": "https://dashboard.andredingfelder.com/products/ad-forms"
}
}
}Was Add-ons nicht dürfen
Es gibt bewusst keinen Filter, der Entitlements, die Feature-Registry oder den Lizenzstatus umschreiben kann. Beobachtung über ad_form_feature_denied ist erlaubt, Override nicht.
Siehe FEATURE_MATRIX.md und adr/0004.