EntityGenerator
Generates an entity in one of two conventions — see {@see Flavor} — auto-detected per app root by {@see ConventionDetector} (override with `GenerationContext`'s `flavor` option, e.g. `--flavor=runtime`), mirroring exactly how {@see ControllerGenerator} picks its convention: - **Legacy**: a Doctrine entity from the `--fields` DSL following the framework's conventions (strict types, id + uuid via {@see \Milpa\Support\UuidGenerator}, typed accessors, enum-as-string columns, ManyToOne relations). `doctrine/orm` is an optional dependency of `milpa/devtools` (see `composer.json`'s `suggest`) — this is the only path that needs it, and {@see generate()} fails fast with {@see DoctrineAvailability::MESSAGE} when it is not installed, instead of emitting a file the host cannot actually use. - **Runtime**: a plain `final readonly class` implementing `milpa/data`'s `Milpa\Data\EntityInterface` (`id()`/`toArray()`/`fromArray()`, no Doctrine attributes) — the `milpa/runtime` + skeleton convention. An orphaned entity class has nothing to persist it, so this path ALSO wires a booting plugin whose `boot()` builds the entity's repository from the app's `storage` config via `Milpa\Data\RepositoryFactory` (driver `file|sqlite|mysql|memory` — the backend is one config line; defaults to a JSON file under `var/` so zero config still persists) and registers it into the DI container — a minimal `PluginInterface` implementation is generated alongside the entity when the target plugin area doesn't exist yet, and an EXISTING plugin gets the registration MATERIALIZED into it — marker anchor first, structural splice second — see {@see self::wireRepository()}; only a file that cannot be parsed falls back to guidance, naming the reason.
EntityGenerator::__construct()
public function __construct(Milpa\DevTools\Make\FieldParser $parser = new FieldParser(), Milpa\DevTools\Make\StubRenderer $renderer = new StubRenderer(), Milpa\DevTools\Make\ConventionDetector $detector = new ConventionDetector(), ?bool $doctrineAvailable = null, Milpa\DevTools\Make\MarkerInserter $markers = new MarkerInserter(), Milpa\DevTools\Make\PluginSurgeon $surgeon = new PluginSurgeon()):Parameters
| Name | Type | Description |
|---|---|---|
| $parser | Milpa\DevTools\Make\FieldParser | |
| $renderer | Milpa\DevTools\Make\StubRenderer | |
| $detector | Milpa\DevTools\Make\ConventionDetector | |
| $doctrineAvailable | (bool | null) | override for testing; `null` (the default) auto-detects via {@see DoctrineAvailability::isAvailable()} — checked LAZILY, only inside {@see generateLegacy()}, so a bare `new EntityGenerator()` used for the RUNTIME path never triggers Doctrine autoloading (mirrors the guarantee {@see ControllerGenerator}'s runtime path already has). |
| $markers | Milpa\DevTools\Make\MarkerInserter | |
| $surgeon | Milpa\DevTools\Make\PluginSurgeon |
EntityGenerator::name()
public function name(): stringThe `<what>` token this generator answers to: `'entity'`.
EntityGenerator::generate()
public function generate(Milpa\DevTools\Make\GenerationContext $context): Milpa\DevTools\Make\GenerationResultRenders the entity (+ repository wiring for runtime) per the detected/overridden {@see Flavor}.
Parameters
| Name | Type | Description |
|---|---|---|
| $context | Milpa\DevTools\Make\GenerationContext |