From e9af0d13414285c012c4b213d78909258402b291 Mon Sep 17 00:00:00 2001
From: Bart Jaskulski <bjaskulski@protonmail.com>
Date: Fri, 27 Sep 2024 12:05:50 +0200
Subject: [PATCH] feat: add support for passing additional options to handlers

Signed-off-by: Bart Jaskulski <bjaskulski@protonmail.com>
---
 src/Binding/Definition.php                    |  3 +++
 src/Binding/Definition/CallableDefinition.php |  9 ++++++++
 src/Binding/Definition/HookableDefinition.php | 18 ++++++++++++---
 src/Binding/Definition/UnknownDefinition.php  | 15 ++++++++++---
 src/Binding/DefinitionFactory.php             |  8 +++----
 src/Binding/Loader/ArrayDefinitions.php       | 22 ++++++++++++++-----
 6 files changed, 59 insertions(+), 16 deletions(-)

diff --git a/src/Binding/Definition.php b/src/Binding/Definition.php
index 7184bf5..6e0594c 100644
--- a/src/Binding/Definition.php
+++ b/src/Binding/Definition.php
@@ -13,4 +13,7 @@ interface Definition {
 
 	/** @return T */
 	public function value();
+
+	/** @return mixed */
+	public function option( string $name );
 }
diff --git a/src/Binding/Definition/CallableDefinition.php b/src/Binding/Definition/CallableDefinition.php
index 9bf3774..5ceb6d0 100644
--- a/src/Binding/Definition/CallableDefinition.php
+++ b/src/Binding/Definition/CallableDefinition.php
@@ -15,12 +15,17 @@ class CallableDefinition implements Definition {
 	/** @var callable */
 	private $callable;
 
+	/** @var array<string, mixed> */
+	private array $options;
+
 	public function __construct(
 		callable $callable,
 		?string $hook = null,
+		array $options = []
 	) {
 		$this->callable = $callable;
 		$this->hook     = $hook;
+		$this->options  = $options;
 	}
 
 	public function hook(): ?string {
@@ -30,4 +35,8 @@ class CallableDefinition implements Definition {
 	public function value() {
 		return $this->callable;
 	}
+
+	public function option( string $name ) {
+		return $this->options[ $name ] ?? null;
+	}
 }
diff --git a/src/Binding/Definition/HookableDefinition.php b/src/Binding/Definition/HookableDefinition.php
index 286d9ba..fe3cf80 100644
--- a/src/Binding/Definition/HookableDefinition.php
+++ b/src/Binding/Definition/HookableDefinition.php
@@ -9,18 +9,22 @@ use WPDesk\Init\Binding\Definition;
 /** @implements Definition<class-string<Hookable>> */
 class HookableDefinition implements Definition {
 
-	/** @var ?string */
-	private $hook;
+	private ?string $hook;
 
 	/** @var class-string<Hookable> */
-	private $hookable;
+	private string $hookable;
+
+	/** @var array<string, mixed> */
+	private array $options;
 
 	public function __construct(
 		string $hookable,
 		?string $hook = null,
+		array $options = []
 	) {
 		$this->hook     = $hook;
 		$this->hookable = $hookable;
+		$this->options  = $options;
 	}
 
 	public function hook(): ?string {
@@ -30,4 +34,12 @@ class HookableDefinition implements Definition {
 	public function value() {
 		return $this->hookable;
 	}
+
+	/**
+	 * @param string $name
+	 * @return mixed
+	 */
+	public function option( string $name ) {
+		return $this->options[ $name ] ?? null;
+	}
 }
diff --git a/src/Binding/Definition/UnknownDefinition.php b/src/Binding/Definition/UnknownDefinition.php
index 3ee808e..e238d9b 100644
--- a/src/Binding/Definition/UnknownDefinition.php
+++ b/src/Binding/Definition/UnknownDefinition.php
@@ -15,12 +15,17 @@ class UnknownDefinition implements Definition {
 	/** @var mixed */
 	private $value;
 
+	/** @var array<string, mixed> */
+	private array $options;
+
 	public function __construct(
 		$value,
-		?string $hook = null
+		?string $hook = null,
+		array $options = []
 	) {
-		$this->value = $value;
-		$this->hook     = $hook;
+		$this->value   = $value;
+		$this->hook    = $hook;
+		$this->options = $options;
 	}
 
 	public function hook(): ?string {
@@ -30,4 +35,8 @@ class UnknownDefinition implements Definition {
 	public function value() {
 		return $this->value;
 	}
+
+	public function option( string $name ) {
+		return $this->options[ $name ] ?? null;
+	}
 }
diff --git a/src/Binding/DefinitionFactory.php b/src/Binding/DefinitionFactory.php
index 5b66072..dc38268 100644
--- a/src/Binding/DefinitionFactory.php
+++ b/src/Binding/DefinitionFactory.php
@@ -10,15 +10,15 @@ use WPDesk\Init\Binding\Definition\UnknownDefinition;
 
 class DefinitionFactory {
 
-	public function create( $value, ?string $hook ): Definition {
+	public function create( $value, ?string $hook, array $options = [] ): Definition {
 		if ( is_string( $value ) && class_exists( $value ) && is_subclass_of( $value, Hookable::class, true ) ) {
-			return new HookableDefinition( $value, $hook );
+			return new HookableDefinition( $value, $hook, $options );
 		}
 
 		if ( is_callable( $value ) ) {
-			return new CallableDefinition( $value, $hook );
+			return new CallableDefinition( $value, $hook, $options );
 		}
 
-		return new UnknownDefinition( $value, $hook );
+		return new UnknownDefinition( $value, $hook, $options );
 	}
 }
diff --git a/src/Binding/Loader/ArrayDefinitions.php b/src/Binding/Loader/ArrayDefinitions.php
index 865b0a3..aa30bbe 100644
--- a/src/Binding/Loader/ArrayDefinitions.php
+++ b/src/Binding/Loader/ArrayDefinitions.php
@@ -16,7 +16,7 @@ class ArrayDefinitions implements BindingDefinitions {
 	/** @var DefinitionFactory */
 	private $factory;
 
-	public function __construct( array $bindings, ?DefinitionFactory $factory = null) {
+	public function __construct( array $bindings, ?DefinitionFactory $factory = null ) {
 		$this->bindings = $bindings;
 		$this->factory  = $factory ?? new DefinitionFactory();
 	}
@@ -28,8 +28,18 @@ class ArrayDefinitions implements BindingDefinitions {
 	private function normalize( iterable $bindings ): iterable {
 		foreach ( $bindings as $key => $value ) {
 			if ( is_array( $value ) ) {
-				foreach ( $value as $unit ) {
-					yield $this->create( $unit, $key );
+				if ( isset( $value['handler'] ) ) {
+					// Single item with handler
+					yield $this->create( $value['handler'], $key, $value );
+				} else {
+					// Multiple items
+					foreach ( $value as $unit ) {
+						if ( is_array( $unit ) && isset( $unit['handler'] ) ) {
+							yield $this->create( $unit['handler'], $key, $unit );
+						} else {
+							yield $this->create( $unit, $key );
+						}
+					}
 				}
 			} else {
 				yield $this->create( $value, $key );
@@ -38,10 +48,10 @@ class ArrayDefinitions implements BindingDefinitions {
 	}
 
 	/**
-     * @param mixed $value
+	 * @param mixed $value
 	 * @param int|string $hook
 	 */
-	private function create( $value, $hook ): Definition {
-		return $this->factory->create( $value, is_int( $hook ) ? null : $hook );
+	private function create( $value, $hook, array $options = [] ): Definition {
+		return $this->factory->create( $value, is_int( $hook ) ? null : $hook, $options );
 	}
 }
-- 
GitLab