Writing Magento plugins without conflicts using Bricklayer check-class and plugin-list

Just enough checks to write a Magento plugin that does not fight with the ones already there.

Plugins are cheap to write and easy to get wrong. Your plugin works on a clean install, then on the real store it runs in the wrong order, its around plugin never calls $proceed because someone else’s around plugin returned early, or the class You targeted is not even the class being used because a preference rewrote it.

None of that is visible in Your module’s source. It is the merged DI config of every installed module, resolved at runtime. That is exactly what Bricklayer exposes.

The tools

Tool Parameters Returns
check-class className (required) plugins, DI configuration and preferences for the class, in one call
plugin-list className (required), method all plugins (interceptors) for a class, optionally for one method
di-configuration className (required), area (global, frontend, adminhtml) preferences, plugins and virtual types for a class or interface
preference-list interface all preference rewrites, optionally filtered
event-list eventName, area events and their observers

Start with check-class. It is the combined pre-check, one call instead of three:

check-class className=Magento\Catalog\Api\ProductRepositoryInterface

The response has plugins, di_configuration and preferences keys, plus a _skill_hint pointing to the matching development-context category.

Need only one method? Narrow it down:

plugin-list className=Magento\Catalog\Api\ProductRepositoryInterface method=save

Plugins declared for one area only? Check the area You are targeting, the default is global:

di-configuration className=Magento\Checkout\Model\Session area=frontend

Thinking about an observer instead? See what already listens:

event-list eventName=catalog_product_save_after

Workflow

  1. development-context category=plugin - plugin patterns; its _next_steps sends the agent to check-class
  2. check-class className=<target> - what already plugs into the class, what rewrites it
  3. If a preference replaces the class, decide: plugin the interface, or the class actually in use
  4. Pick a sortOrder that places Your plugin where You want it relative to the existing ones
  5. development-context category=coding-standards, then write di.xml and the plugin
  6. Run setup:di:compile. Bricklayer notices generated/metadata/global.php changed and reinitializes itself on the next call, so a second plugin-list shows Your plugin in the chain

The last step is the one people skip. Checking after the change is how You confirm the plugin is registered for the right method and in the right order.

  • Want this enforced? Add a row to .bricklayer/decision-matrix.md, e.g. “Adding a plugin | check-class | development-context category=plugin”
  • Override the bundled plugin guideline with Your house rules in .bricklayer/skills/plugin/SKILL.md

Start coding!

Source: GitHub · Introspection tools wiki