friendica-github/doc/StrategyHooks.md
2023-07-26 21:44:31 +02:00

3 KiB

Friendica strategy Hooks

Strategy hooks

This type of hook is based on the Strategy Design Pattern.

A strategy class defines a possible implementation of a given interface based on a unique name. Every name is possible as long as it's unique and not null. Using an empty name ('') is possible as well and should be used as the "default" implementation. To register a strategy, use the ICanRegisterInstance interface.

After registration, a caller can automatically create this instance with the ICanCreateInstances interface and the chosen name.

This is useful in case there are different, possible implementations for the same purpose, like for logging, locking, caching, ...

Normally, a config entry is used to choose the right implementation at runtime. And if no config entry is set, the "default" implementation should be used.

Example

interface ExampleInterface
{
	public function testMethod();
}

public class ConcreteClassA implements ExampleInterface
{
	public function testMethod()
	{
		echo "concrete class A";
	}
}

public class ConcreteClassB implements ExampleInterface
{
	public function testMethod()
	{
		echo "concrete class B";
	}
}

/** @var \Friendica\Core\Hooks\Capability\ICanRegisterStrategies $instanceRegister */
$instanceRegister->registerStrategy(ExampleInterface::class, ConcreteClassA::class, 'A');
$instanceRegister->registerStrategy(ExampleInterface::class, ConcreteClassB::class, 'B');

/** @var \Friendica\Core\Hooks\Capability\ICanCreateInstances $instanceManager */
/** @var ConcreteClassA $concreteClass */
$concreteClass = $instanceManager->create(ExampleInterface::class, 'A');

$concreteClass->testMethod();
// output:
// "concrete class A";

hooks.config.php

To avoid registering all strategies manually inside the code, Friendica introduced the hooks.config.php file.

There, you can register all kind of strategies in one file.

HookType::STRATEGY

For each given interface, a list of key-value pairs can be set, where the key is the concrete implementation class and the value is an array of unique names.

Example

use Friendica\Core\Hooks\Capability\BehavioralHookType as H;

return [
	H::STRATEGY  => [
		ExampleInterface::class => [
			ConcreteClassA::class => ['A'],
			ConcreteClassB::class => ['B'],
		],
	],
];

Addons

The hook logic is useful for decoupling the Friendica core logic, but its primary goal is to modularize Friendica in creating addons.

Therefor you can either use the interfaces directly as shown above, or you can place your own hooks.config.php file inside a static directory directly under your addon core directory. Friendica will automatically search these config files for each activated addon and register the given hooks.