Skip to content

Static Generation: Definitions, Naming & Exclusions ​

Reference for how the static files a Moodle plugin needs (db/access.php, db/caches.php, db/services.php, db/messages.php, db/hooks.php, db/events.php and the generated event classes, db/tasks.php) are produced from typed definitions. Verified against middag-php-moodle main@6aae04d on 2026-11-04.

Who does what ​

PieceWhere
Typed definition classes (@api, final readonly)This adapter, src/Definition/
Declaring definitionsThe consumer's extensions (modules)
Collecting, rendering and writing the filesBuild tooling outside this package

Every definition implements Definition\Contract\DefinitionInterface:

MethodPurpose
toMoodleArray(string $plugin_name)The entry exactly as Moodle expects it in the generated file
isCompatible(string $moodle_version)Applies the definition's min_moodle / max_moodle range
getName()The key the entry is written under

Definition classes ​

DefinitionTargetDeclared by the extension throughMain fields
CacheDefinitiondb/caches.phpgetCacheDefinitions()name, mode (CacheMode, default application), simple_keys, simple_data
CapabilityDefinitiondb/access.phpgetCapabilities()name, archetypes, type (CapabilityType), context (ContextLevel), risk (CapabilityRisk), clone_from
ServiceDefinitiondb/services.php ($functions)getServiceDefinitions()name, classname, type (read/write), method, description, ajax, services, capabilities
WebServiceDefinitiondb/services.php ($services)getWebServiceDefinitions()name, shortname, functions, enabled, restricted_users
MessageDefinitiondb/messages.phpgetMessageDefinitions()name, popup, email (MessagePermission)
HookDefinitiondb/hooks.phpgetHookDefinitions()hook_class, callback, priority; min_moodle defaults to '4.3'
EventDefinitiondb/events.php and classes/event/*getEventDefinitions()name, crud, edulevel (EventEdulevel), objecttable, description
FileAreaDefinitionNot generated; read at request timegetFileAreaDefinitions()name, context_level, handler, supports_preview, description; see File Areas
CheckDefinitionNot generated; collected at runtime for lib.php callbacks(consumer-defined)name, classname, type (CheckType)
LangDefinitionA managed block inside lang/<locale>/<plugin>.phpPassed explicitly to the generator (framework-layer catalogs, not extensions)key, strings (locale ⇒ string, en required)

Every definition also carries min_moodle / max_moodle.

Tasks ​

Scheduled tasks are declared with the framework's #[Schedule] attribute (Middag\Framework\Bus\Attribute\Schedule) on the task class. Support\TaskDefinitionBuilder::build() is the canonical statement of how a Schedule maps onto a db/tasks.php row; tooling that cannot require this package re-implements the mapping and pins parity against it. The legacy plugin also accepted a get_task_definitions() method as a compatibility path.

Naming ​

Capabilities and file areas share one convention, implemented by getQualifiedName():

ExtensionCapabilityFile area
core or none{plugin}:{name} (for example local/example:manage){name} (for example attachments)
Any other{plugin}:{extension}_{name} (for example local/example:ecommerce_manage){extension}_{name} (for example customdocs_templates)

Here {plugin} is the frankenstyle name with _ replaced by /. External functions are named {plugin_name}_{name} (ServiceDefinition::getQualifiedName()). Generated event classes are \{plugin_name}\event\{extension}_{name}, with no extension prefix for core (EventDefinition::getEventClassname()); see Event Observation.

Generation ​

The generator sorts entries by name, so diffs stay predictable and a file that changes for an unrelated reason is easy to spot, and it writes idempotently (unchanged input leaves files untouched). It is not part of this package. The legacy plugin drove it through one consolidated entry point, php cli/build.php --statics [target] [--basedir=.] [--dry-run], which replaced the per-target scripts build_tasks.php and build_events.php (removed without a compatibility shim).

Outside the pipeline ​

PathHow it is maintained
db/install.xmlBy hand (XMLDB)
db/upgrade*.php, db/install.phpBy hand, delegating to the adapter (Persistence\UpgradeHelper, Database\Schema\XmldbSchemaAdapter); the consumer may offer before/after install hooks to its extensions (the legacy plugin exposed extend_local_middag_install_before / _after)
lang/By hand, except the managed block rendered from LangDefinition catalogs; hand-written strings outside the block are preserved
Admin settingsNot generated: the same typed-definition pattern, resolved at runtime by SettingsResolver; see Settings & Config Keys
File-area routingNot generated: resolved at request time; see File Areas

Enforcement state ​

ClauseState
One typed definition per static kindcoded — the Definition/ classes; review decides new kinds
Generated files are never edited by handplanned — no check in this package
Capability and file-area namingcoded — getQualifiedName() on the definitions
Settings and file-area routing stay out of generationplanned — architectural choice, no check

Decision record: MDL-016 in middag-php-moodle/docs/decisions.

MIDDAG © 2015-2026