From d4863766993ff24d2d245984c7861e35fc1a9384 Mon Sep 17 00:00:00 2001 From: Phil Bennett Date: Thu, 14 Mar 2024 08:59:03 +0000 Subject: [PATCH] Add ability to ensure inflection only happens once per object if defined --- src/Inflector/Inflector.php | 23 ++++++++++++++++++++--- tests/Inflector/InflectorTest.php | 22 ++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/Inflector/Inflector.php b/src/Inflector/Inflector.php index 29bb49a..fd7203a 100644 --- a/src/Inflector/Inflector.php +++ b/src/Inflector/Inflector.php @@ -18,15 +18,24 @@ class Inflector implements ArgumentResolverInterface, InflectorInterface */ protected $callback; + protected array $inflected = []; + public function __construct( protected string $type, - protected $methods = [], - protected $properties = [], - ?callable $callback = null + ?callable $callback = null, + protected bool $oncePerMatch = false, + protected array $methods = [], + protected array $properties = [], ) { $this->callback = $callback; } + public function oncePerMatch(): InflectorInterface + { + $this->oncePerMatch = true; + return $this; + } + public function getType(): string { return $this->type; @@ -64,6 +73,10 @@ public function setProperties(array $properties): InflectorInterface public function inflect(object $object): void { + if (true === $this->oncePerMatch && in_array($object, $this->inflected, true)) { + return; + } + $properties = $this->resolveArguments(array_values($this->properties)); $properties = array_combine(array_keys($this->properties), $properties); @@ -81,5 +94,9 @@ public function inflect(object $object): void if ($this->callback !== null) { call_user_func($this->callback, $object); } + + if (true === $this->oncePerMatch) { + $this->inflected[] = $object; + } } } diff --git a/tests/Inflector/InflectorTest.php b/tests/Inflector/InflectorTest.php index ed2a9a7..195631a 100644 --- a/tests/Inflector/InflectorTest.php +++ b/tests/Inflector/InflectorTest.php @@ -149,4 +149,26 @@ public function setBar($bar): void $inflector->inflect($foo); $this->assertSame($bar, $foo->bar); } + + public function testInflectorOnlyInflectsOncePerMatch(): void + { + $foo = new class { + public int $count = 0; + public function tick(): void + { + $this->count++; + } + }; + + $bar = new class { + }; + + $inflector = new Inflector('Type'); + $inflector->oncePerMatch(); + $inflector->invokeMethod('tick', []); + + $inflector->inflect($foo); + $inflector->inflect($foo); + $this->assertSame(1, $foo->count); + } }