Voor ontwikkelaars
Modules bouwen
Modulemanifests, ontdekking, registratiecontracten, afhankelijkheden, migraties en levenscyclus.
Op deze pagina
Een Module beheert een optioneel domein
Gebruik een Module voor een optionele commercefunctie met eigen domeinregels en gegevensopslag. Voorraad, abonnementen, digitale levering, evenementen en provisioning zijn voorbeelden. Gebruik een Extension voor een provideradapter of een bijdrage aan een bestaand uitbreidingspunt. Presentatie hoort in een Theme.
Het publieke toegangspunt in Core staat in Modules/Contracts/Module.php:
interface Module
{
public function id(): string;
public function register(ModuleContext $context): void;
}
ModuleContext staat bewust los van Livewire-markup en CSS. Via deze context registreer je capabilities, rechten, navigatie, accountbijdragen, routes en listeners. Een Module mag een Livewire-scherm leveren, maar het domeintoegangspunt hoeft geen schermcomponent te zijn.
Genereer een ontwikkelskelet
Voer vanuit Core eerst de configuratie voor een bestaande sibling-repository in:
AGOVENA_OPTIONAL_PACKAGES_PATH=../optional-packages
php artisan agovena:make-module workshop
Het ID begint met een letter en gebruikt kleine letters en cijfers, gescheiden door enkele koppeltekens. De generator schrijft module.json, src/WorkshopModule.php en src/WorkshopServiceProvider.php. Een bestaand doel wordt geweigerd tenzij je --force opgeeft. Gebruik die vlag alleen als je de gegenereerde bestanden daadwerkelijk wilt overschrijven.
Controleer het manifest vóór installatie. De huidige generator schrijft agovena: "^0.1", terwijl Core in config/agovena.php platformversie 0.0.1 aangeeft. De gegenereerde compatibiliteitsvoorwaarde is een uitgangspunt, geen garantie dat deze bij je checkout past. Stel de voorwaarde in op versies die je werkelijk ondersteunt en test.
Zonder geldige optional-packages-configuratie valt de generator terug op modules/ binnen Core. Runtime-ontdekking scant die terugvalmap niet automatisch. Gebruik bij voorkeur de sibling-repository of configureer de juiste bovenliggende map in extra_module_paths. Maak van first-party packages geen permanente Core-submappen.
Bronnen: MakeModuleCommand, ScaffoldingGenerator en platformconfiguratie.
Manifestcontract
Het Downloads-manifest is een concreet voorbeeld:
{
"id": "downloads",
"name": "Downloads",
"version": "1.0.0",
"description": "Downloadable file assets and customer entitlements after payment.",
"author": "Agovena",
"agovena": "^0.0.1",
"group": "commerce",
"provider": "Agovena\\Modules\\Digital\\DigitalServiceProvider",
"dependencies": []
}
| Veld | Betekenis in de runtime |
|---|---|
id, name, provider |
Verplicht voor ontdekking; provider is een PHP-klassenaam |
version |
Packageversie, standaard 0.0.0 |
description |
Beschrijving, standaard leeg |
agovena |
Platformvoorwaarde volgens Composer, standaard * |
dependencies |
Lijst met andere Module-ID's, geen versievoorwaarden |
author |
Auteurslabel, standaard Agovena |
group |
Groep in de catalogus, standaard other |
autoload.psr-4 |
Optionele koppeling van namespaces aan relatieve mappen |
De runtime bepaalt het bestandspad van het manifest. Een manifestveld path doet dat niet. Zonder PSR-4-configuratie leidt ontdekking de namespace af van provider en gebruikt het src/ als die map bestaat. Geef een eigen namespace expliciet op, bijvoorbeeld "Acme\\Workshop\\": "src/". Prefixes moeten eindigen op een backslash. De autoloader negeert relatieve paden met ...
Bronnen: Availability-capabilityreferentie, ModuleManifest en PackageAutoload.
Provider en domeinregistratie
Een gebruikelijke provider erft van Laravel ServiceProvider en biedt module(): Module. Laravel gebruikt register(): void voor servicebindings. Het afzonderlijke domeinobject gebruikt register(ModuleContext $context) voor Agovena-bijdragen. Combineer deze onverenigbare methodesignatures niet in één klasse.
De Core availability-provider bindt het ProductStock-contract en registreert de listeners voor fysieke voorraad. Optionele packages gebruiken dezelfde contracten via expliciete integratiepunten; ze leveren inventory niet zelf:
$this->app->singleton(ProductStock::class, CatalogProductStock::class);
Event::listen(OrderPlacing::class, AssertStockBeforeOrderPlacing::class);
Event::listen(OrderCreated::class, ReserveStockWhenOrderCreated::class);
Event::listen(OrderCancelled::class, RestockWhenOrderCancelled::class);
Dit fragment komt uit AvailabilityServiceProvider en AvailabilityCapability. Physical commerce gebruikt dit gedeelde Core availability-contract; het is geen optioneel package.
Contextmethoden en routegrenzen
| Contextmethode | Bijdrage |
|---|---|
moduleId() |
ID van de huidige package |
admin() |
Adminregistratie voor rechten en UI-contracten |
capabilities() |
Registratie van productcapabilities |
customerAccountNav($item) |
Navigatie in de klantomgeving |
customerAccountOverview($id, $factory, $sort) |
Klantgebonden overzichtskaart |
listen($event, $listener) |
Luisteren naar een Core- of Module-event |
adminRoutes($callback) |
/admin, naamprefix admin., medewerkersmiddleware |
customerRoutes($callback) |
/account, naamprefix customer., ingelogde en geverifieerde klant |
apiRoutes($callback) |
/api/v1, naamprefix api.v1., Sanctum, limieten en tokenbevoegdheden |
Een navigatierecht vervangt de autorisatie van een scherm of handeling niet. De Admin-routehelper voegt webauthenticatie, rechtensynchronisatie en admin.access toe. Packageacties moeten hun eigen relevante rechten blijven controleren.
Module-API-routes gebruiken de Core-koppeling tussen routenamen en abilities. De ondersteunde prefixes na api.v1. zijn subscriptions., services., downloads., digital-secrets. en event-tickets.. Een nieuwe willekeurige prefix weigert bearer-verzoeken totdat de Core-mapping bewust wordt uitgebreid. Zie ModuleContext en authenticatie.
Ontdekking en levenscyclus
ModuleManager doorzoekt eerst de opslag voor geïnstalleerde packages, daarna de optional-repository en vervolgens extra paden. Elke root bevat submappen met module.json. Het eerste gevonden ID wint.
- Ontdekken: manifests lezen en autoloading registreren. Dit schakelt de package niet in.
- Installeren: platformcompatibiliteit en vindbaarheid van afhankelijkheden controleren, een uitgeschakeld installatierecord maken en migraties uitvoeren. Afhankelijkheden worden niet automatisch geïnstalleerd.
- Inschakelen: installatie en ingeschakelde afhankelijkheden vereisen, openstaande migraties uitvoeren, status opslaan, de provider registreren en het Modulecontract eenmaal per managerruntime aanroepen.
- Uitschakelen: de Module en afhankelijke Modules uitschakelen, evenals Extensions die daarop steunen. Tabellen en gegevens blijven behouden. Nieuw gestarte runtimes registreren de uitgeschakelde Module niet meer.
- Upgraden:
migrateInstalled()verwerkt openstaande migraties voor geïnstalleerde Modules, ook als ze uitgeschakeld zijn. - Verwijderen: het installatierecord weghalen zonder domeingegevens te wissen.
purgeData: truewordt geweigerd, want generiek opschonen is niet geïmplementeerd.
Bewaar packagemigraties in database/migrations. Gebruik de manager- en upgradeflow in plaats van aan te nemen dat een schakelaar of het verwijderen van een map schemawijzigingen terugdraait.
Controleer een Modulewijziging
Schrijf tests voor ontdekking, capabilityregistratie en gegevensbehoud van optionele packages. Core-capabilities zoals availability, physical commerce en recurring billing worden rechtstreeks in Core getest en worden niet via ModuleManager ingeschakeld.
php artisan test tests/Feature/ModuleRuntimeTest.php
php artisan test tests/Feature/ModuleMatrixTest.php
ModuleRuntimeTest controleert dat Inventory-voorraad buiten products staat, afneemt bij bestellen, in het geteste scenario niet overschreden kan worden en uitschakelen overleeft. Gebruik bijdragen en testen voor de volledige controleflow.