Skip to content

Commit 04a9649

Browse files
committed
Fix handling CallbackBinding when key is contained in JSON fields
As previously the CallbackBindings where moved into a separate property in the ClassBindings class, they need to be called independently of the keys being present in the JSON fields, because the hasBindings method doesn't check the separate callbackBindings class property. When iterating over the JSON fields check for registered CallbackBinding, so it doesn't execute handleRaw() unnecessarily before the CallbackBinding is handled below.
1 parent 4d470f6 commit 04a9649

File tree

3 files changed

+39
-5
lines changed

3 files changed

+39
-5
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [4.0.2] - 2020-10-15
8+
### Fixed
9+
- Another issue where CallbackBinding wasn't handled.
10+
711
## [4.0.1] - 2020-10-15
812
### Fixed
913
- Still handle CallbackBinding when property name doesn't match a JSON fieldname.

src/ClassBindings.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public function decode(array $data, $instance)
5050
$binding = $this->bindings[$fieldName];
5151
$property = Property::create($instance, $this->bindings[$fieldName]->property());
5252
$this->handleBinding($binding, $property, $data);
53-
} else {
53+
} elseif (!$this->hasCallbackBinding($fieldName)) { // callback bindings are handled below
5454
if ($this->jsonDecoder->shouldAutoCase()) {
5555
$property = $this->autoCase($fieldName, $instance);
5656

@@ -67,10 +67,8 @@ public function decode(array $data, $instance)
6767
}
6868

6969
foreach ($this->callbackBindings as $propertyName => $binding) {
70-
if (!in_array($propertyName, $jsonFieldNames)) {
71-
$property = Property::create($instance, $propertyName);
72-
$this->handleBinding($binding, $property, $data);
73-
}
70+
$property = Property::create($instance, $propertyName);
71+
$this->handleBinding($binding, $property, $data);
7472
}
7573

7674
return $instance;
@@ -104,6 +102,11 @@ public function hasBinding($property)
104102
return array_key_exists($property, $this->bindings);
105103
}
106104

105+
public function hasCallbackBinding(string $propertyName): bool
106+
{
107+
return array_key_exists($propertyName, $this->callbackBindings);
108+
}
109+
107110
/**
108111
* validates and executes the found binding on the given property.
109112
*

tests/ClassBindingsTest.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,20 @@ public function it_registers_a_binding()
2626
$this->assertTrue($classBindings->hasBinding('field'));
2727
}
2828

29+
/** @test */
30+
public function it_registers_a_callback_binding()
31+
{
32+
$classBindings = new ClassBindings(new JsonDecoder());
33+
34+
$this->assertFalse($classBindings->hasBinding('field'));
35+
$this->assertFalse($classBindings->hasCallbackBinding('field'));
36+
37+
$classBindings->register(new CallbackBinding('field', function () {}));
38+
39+
$this->assertFalse($classBindings->hasBinding('field'));
40+
$this->assertTrue($classBindings->hasCallbackBinding('field'));
41+
}
42+
2943
/** @test */
3044
public function it_fails_to_register_a_not_compatible_binding_class()
3145
{
@@ -57,6 +71,19 @@ public function bind($jsonDecoder, $jsonData, $property)
5771
$classBindings->decode(['firstname' => 'John'], new Person());
5872
}
5973

74+
/** @test */
75+
public function it_executes_callback_bindings_when_property_name_is_contained_in_json_fields()
76+
{
77+
$classBindings = new ClassBindings(new JsonDecoder());
78+
$classBindings->register(new CallbackBinding('firstname', function ($data) {
79+
return $data['firstname'] . ' Doe';
80+
}));
81+
82+
$person = $classBindings->decode(['firstname' => 'John'], new Person());
83+
84+
$this->assertEquals('John Doe', $person->firstname());
85+
}
86+
6087
/** @test */
6188
public function it_executes_callback_bindings_when_property_name_is_not_contained_in_json_fields()
6289
{

0 commit comments

Comments
 (0)