Skip to content

Commit 8c115df

Browse files
authored
Merge pull request #38 from otsch/bugfix/handle-callback-bindings
Fix handling CallbackBindings
2 parents 3e7d354 + 4d470f6 commit 8c115df

File tree

3 files changed

+42
-5
lines changed

3 files changed

+42
-5
lines changed

CHANGELOG.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ 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.0] - 2002-10-06
7+
## [4.0.1] - 2020-10-15
8+
### Fixed
9+
- Still handle CallbackBinding when property name doesn't match a JSON fieldname.
10+
11+
## [4.0.0] - 2020-10-06
812
### Added
913
- support for magic class properties
1014
- auto casing for json field - class properties mapping
@@ -40,4 +44,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4044

4145
## [2.2.0] - 2019-01-11
4246
### Added
43-
- `JsonDecoder` instance as second parameter to callback function signature for CallbackBindings
47+
- `JsonDecoder` instance as second parameter to callback function signature for CallbackBindings

src/ClassBindings.php

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Exception;
66
use Karriere\JsonDecoder\Bindings\AliasBinding;
7+
use Karriere\JsonDecoder\Bindings\CallbackBinding;
78
use Karriere\JsonDecoder\Bindings\RawBinding;
89
use Karriere\JsonDecoder\Exceptions\InvalidBindingException;
910
use Karriere\JsonDecoder\Exceptions\JsonValueException;
@@ -16,6 +17,11 @@ class ClassBindings
1617
*/
1718
private $bindings = [];
1819

20+
/**
21+
* @var array
22+
*/
23+
private $callbackBindings = [];
24+
1925
/**
2026
* @var JsonDecoder
2127
*/
@@ -32,10 +38,14 @@ public function __construct(JsonDecoder $jsonDecoder)
3238
* @param mixed $instance
3339
*
3440
* @return mixed
41+
*
42+
* @throws JsonValueException
3543
*/
3644
public function decode(array $data, $instance)
3745
{
38-
foreach (array_keys($data) as $fieldName) {
46+
$jsonFieldNames = array_keys($data);
47+
48+
foreach ($jsonFieldNames as $fieldName) {
3949
if ($this->hasBinding($fieldName)) {
4050
$binding = $this->bindings[$fieldName];
4151
$property = Property::create($instance, $this->bindings[$fieldName]->property());
@@ -56,6 +66,13 @@ public function decode(array $data, $instance)
5666
}
5767
}
5868

69+
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+
}
74+
}
75+
5976
return $instance;
6077
}
6178

@@ -68,9 +85,11 @@ public function register($binding)
6885
{
6986
if (!$binding instanceof Binding) {
7087
throw new InvalidBindingException();
88+
} elseif ($binding instanceof CallbackBinding) {
89+
$this->callbackBindings[$binding->property()] = $binding;
90+
} else {
91+
$this->bindings[$binding->jsonField()] = $binding;
7192
}
72-
73-
$this->bindings[$binding->jsonField()] = $binding;
7493
}
7594

7695
/**

tests/ClassBindingsTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Karriere\JsonDecoder\Tests;
44

55
use Karriere\JsonDecoder\Binding;
6+
use Karriere\JsonDecoder\Bindings\CallbackBinding;
67
use Karriere\JsonDecoder\Bindings\FieldBinding;
78
use Karriere\JsonDecoder\ClassBindings;
89
use Karriere\JsonDecoder\Exceptions\InvalidBindingException;
@@ -55,4 +56,17 @@ public function bind($jsonDecoder, $jsonData, $property)
5556

5657
$classBindings->decode(['firstname' => 'John'], new Person());
5758
}
59+
60+
/** @test */
61+
public function it_executes_callback_bindings_when_property_name_is_not_contained_in_json_fields()
62+
{
63+
$classBindings = new ClassBindings(new JsonDecoder());
64+
$classBindings->register(new CallbackBinding('somePropertyName', function () {
65+
return 'yes';
66+
}));
67+
68+
$person = $classBindings->decode(['firstname' => 'John'], new Person());
69+
70+
$this->assertEquals('yes', $person->somePropertyName);
71+
}
5872
}

0 commit comments

Comments
 (0)