Skip to content

Commit

Permalink
Allow undefined property handler to return a string to override varia…
Browse files Browse the repository at this point in the history
…ble name

This lets us add e.g. camel case mapping handlers.

Resolves: #198
Resolves: #183
Resolves: #150
Resolves: #149
Resolves: #29
  • Loading branch information
reinfi authored and cweiske committed Jan 21, 2023
1 parent 1a93f1c commit cd83947
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 2 deletions.
22 changes: 22 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,28 @@ __ http://php.net/manual/en/language.types.callable.php
$jm->undefinedPropertyHandler = 'setUndefinedProperty';
$jm->map(...);
Or if you would let JsonMapper handle the setter for you, you can return a string
from the ``$undefinedPropertyHandler`` which will be used as property name.

.. code:: php
/**
* Handle undefined properties during JsonMapper::map()
*
* @param object $object Object that is being filled
* @param string $propName Name of the unknown JSON property
* @param mixed $jsonValue JSON value of the property
*
* @return void
*/
function fixPropName($object, $propName, $jsonValue)
{
return ucfirst($propName);
}
$jm = new JsonMapper();
$jm->undefinedPropertyHandler = 'fixPropName';
$jm->map(...);
Missing properties
------------------
Expand Down
12 changes: 10 additions & 2 deletions src/JsonMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,18 +177,26 @@ public function map($json, $object)
. ' in object of type ' . $strClassName
);
} else if ($this->undefinedPropertyHandler !== null) {
call_user_func(
$undefinedPropertyKey = call_user_func(
$this->undefinedPropertyHandler,
$object, $key, $jvalue
);

if (is_string($undefinedPropertyKey)) {
list($hasProperty, $accessor, $type, $isNullable)
= $this->inspectProperty($rc, $undefinedPropertyKey);
}
} else {
$this->log(
'info',
'Property {property} does not exist in {class}',
array('property' => $key, 'class' => $strClassName)
);
}
continue;

if (!$hasProperty) {
continue;
}
}

if ($accessor === null) {
Expand Down
52 changes: 52 additions & 0 deletions tests/NameMappingTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

declare(strict_types=1);

use PHPUnit\Framework\TestCase;

require_once 'JsonMapperTest/Simple.php';

class NameMappingTest extends TestCase
{
public function testItSetKeysIfReturnedByUndefinedPropertyHandler(): void
{
$jm = new JsonMapper();
$jm->undefinedPropertyHandler = function (
JsonMapperTest_Simple $object,
string $key,
$value
): string {
return lcfirst(
str_replace(
' ', '', ucwords(str_replace(array('_', '-'), ' ', $key))
)
);
};

/** @var JsonMapperTest_Simple $sn */
$sn = $jm->map(
json_decode('{"hyphen_value": "abc"}'),
new JsonMapperTest_Simple()
);

self::assertSame('abc', $sn->hyphenValue);
}

public function testItDoesNotMapKeyIfUndefinedPropertyHandlerDoesNotReturnValue(): void
{
$jm = new JsonMapper();
$jm->undefinedPropertyHandler = function (
JsonMapperTest_Simple $object,
string $key,
$value
): void {};

/** @var JsonMapperTest_Simple $sn */
$sn = $jm->map(
json_decode('{"hyphen_value": "abc"}'),
new JsonMapperTest_Simple()
);

self::assertNull($sn->hyphenValue);
}
}

0 comments on commit cd83947

Please sign in to comment.