Plugin Annotations & Plugin Context

The Festi Framework provides a dedicated workbench layer (separate package: festi-workbench) responsible for reflection and codebase analysis of plugin method annotations. This layer parses and synchronizes metadata into the system, allowing system plugins to register URL rules, areas, sections, and permissions based on plugin definitions.

This package is intended for project preparation and compilation steps rather than runtime execution. It analyzes annotations and compiles the necessary configuration ahead of time, reducing runtime overhead.

Historically, annotation definitions are done through PHPDoc comments. The current workbench implementation reads PHPDoc only; native PHP Attributes are not supported yet. When Attributes support is added, they will provide better type safety and tooling.

This workbench package is also intended as a foundation for building IDE extensions (e.g. PHPStorm, Visual Studio Code) for autocompletion, validation, navigation, and developer tooling using the same metadata.

  • When it runs: At plugin install or save in the Plugins UI, not on every request. Annotations are not applied on the fly; a sync step is required after changes.

PluginContext

Role: Represents a single plugin’s identity and path. It is the context given to PluginAnnotations when parsing that plugin.

Where it’s used: In the workbench when iterating over plugins (e.g. during install/sync). You construct a context with the plugin name and its base path; the workbench then uses it to locate the plugin class and pass it to PluginAnnotations.

What it provides: Plugin name, base path, system-flag, version, and lazy access to the plugin instance. See the class PHPDoc in festi-workbench for the full API.

PluginAnnotations

Role: Parses PHPDoc annotations from a plugin’s method docblocks and can sync the result into an ISystemObject (e.g. the system plugin object that holds URL rules, areas, sections).

Where it’s used: In the workbench during the same install/sync flow. You create it with a PluginContext, call parse() (optionally with extra annotation names for plugins that define custom ones), then call sync() with the target system object. The framework’s Workbench wires this so that adding or saving a plugin in the Plugins UI triggers parse + sync.

What it provides:

  • Built-in annotations (what you can put on plugin methods):
  • @area — URL area(s) for the method (e.g. default, admin).
  • @urlRule — Regex pattern for URL routing.
  • @section — Section name and permission mask. Format: @section <sectionName>|<mask>. mask is one of: read (2), write (4), exec (6); default is exec if omitted.

  • Workflow: parse() runs reflection and returns a ParsedAnnotationsResult (annotations + per-method MethodInfo). sync() takes that result and pushes it into the given ISystemObject (e.g. registering areas, URL rules, sections). You must call parse() before sync().

  • Extended annotations: Plugins (e.g. RPC) can pass additional annotation names into parse() so that custom annotations are also collected. The result then exposes which methods have which annotations and their values—useful for custom tooling or code generation.

For method signatures, return types, and detailed behaviour of ParsedAnnotationsResult and MethodInfo, use the generated API docs or the PHPDoc on the classes in festi-workbench.