Commerce Development: PHP, Modules, Dependency Injection, Plugins
Object manager and DI
Magento's object manager builds classes from di.xml. Understand constructor injection versus the discouraged ObjectManager::getInstance(). Know argument types: string, number, boolean, array, and object (with shared="false" for non-shared instances). Virtual types let you configure a named variant of a class without subclassing.
Plugins in depth
A plugin targets a public method of a class or interface. before methods receive original arguments and return modified arguments (or null to skip); around methods receive the callable $proceed and must return the result; after methods receive the result and can return a modified value. Plugins cannot intercept final classes/methods, static methods, or non-public methods. Order is controlled by sortOrder and the plugin list in di.xml; plugins on interfaces apply to implementations resolved through that interface.
Events, observers, and cron
Events are dispatched via the event manager; observers cannot change return values, making them suitable for side effects. Cron jobs are declared in crontab.xml with a group and schedule; know that cron group configuration lives in config.xml. Console commands are declared in di.xml under Magento\Framework\Console\CommandList.
Traps
- A plugin on a method that is itself called internally (not via DI proxy) will not fire.
- around plugins that forget to call $proceed break functionality.
- Assuming after plugins can change arguments; they cannot.
- Registering a plugin on a final method silently fails.
Worked example
To log every product save: create a plugin on ProductRepositoryInterface::save with a before method that logs $product->getSku(), declared in etc/di.xml with a type node for the interface. Because the repository is resolved through the interface, the plugin fires for all implementations.