Skip to content

Plugins

Plugins let you modify the input or output of any public method on any class — without replacing the class itself. They’re the fine-grained counterpart to Preferences.

Marko supports two plugin types:

TypeWhen It RunsWhat It Can Do
BeforeBefore the original methodModify input arguments
AfterAfter the original methodModify the return value

A plugin is a plain PHP class with methods that follow a naming convention:

PostRepositoryPlugin.php
<?php
declare(strict_types=1);
namespace App\MyApp\Plugin;
use Marko\Blog\Repository\PostRepository;
class PostRepositoryPlugin
{
/**
* Modify arguments before getPost() is called.
*/
public function beforeGetPost(PostRepository $subject, int $id): array
{
// Log or transform the input
return [$id]; // Return modified arguments as array
}
/**
* Modify the return value after getPost() completes.
*/
public function afterGetPost(PostRepository $subject, array $result): array
{
// Add extra data to the result
$result['retrieved_at'] = time();
return $result;
}
}
  • beforeMethodName — runs before methodName
  • afterMethodName — runs after methodName

The first parameter is always $subject (the original object). For before plugins, remaining parameters match the original method’s signature. Return an array of the (possibly modified) arguments.

For after plugins, the second parameter is the result from the original method. Return the (possibly modified) result.

Plugins are registered in module.php:

module.php
<?php
declare(strict_types=1);
use App\MyApp\Plugin\PostRepositoryPlugin;
use Marko\Blog\Repository\PostRepository;
return [
'plugins' => [
PostRepository::class => [
PostRepositoryPlugin::class,
],
],
];

When multiple plugins target the same method:

  1. All before plugins run (in module priority order)
  2. The original method runs
  3. All after plugins run (in module priority order)

Plugins are ideal for cross-cutting concerns:

  • Adding logging to specific methods
  • Transforming data before it’s saved
  • Adding validation before an action
  • Enriching return values with additional data

If you need to replace the entire behavior, use a Preference instead.