Skip to content

Commit b7415a8

Browse files
authored
Merge pull request #33 from zumba/undeclared-property-mode
Allowing to change the undeclared property unserialization mode
2 parents ae83475 + e5d55b6 commit b7415a8

File tree

3 files changed

+104
-2
lines changed

3 files changed

+104
-2
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ script:
1717
- if [ $TRAVIS_PHP_VERSION = '7.0' ]; then vendor/bin/phpunit --coverage-clover build/logs/clover.xml; else vendor/bin/phpunit; fi
1818

1919
after_success:
20-
- if [ $TRAVIS_PHP_VERSION = '7.0' ]; then php vendor/bin/coveralls; fi
20+
- if [ $TRAVIS_PHP_VERSION = '7.0' ]; then php vendor/bin/php-coveralls; fi

src/JsonSerializer/JsonSerializer.php

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Zumba\JsonSerializer;
44

5+
use InvalidArgumentException;
56
use ReflectionClass;
67
use ReflectionException;
78
use SplObjectStorage;
@@ -20,6 +21,10 @@ class JsonSerializer
2021
const KEY_UTF8ENCODED = 1;
2122
const VALUE_UTF8ENCODED = 2;
2223

24+
const UNDECLARED_PROPERTY_MODE_SET = 1;
25+
const UNDECLARED_PROPERTY_MODE_IGNORE = 2;
26+
const UNDECLARED_PROPERTY_MODE_EXCEPTION = 3;
27+
2328
/**
2429
* Storage for object
2530
*
@@ -64,6 +69,13 @@ class JsonSerializer
6469
*/
6570
protected $customObjectSerializerMap;
6671

72+
/**
73+
* Undefined Attribute Mode
74+
*
75+
* @var integer
76+
*/
77+
protected $undefinedAttributeMode = self::UNDECLARED_PROPERTY_MODE_SET;
78+
6779
/**
6880
* Constructor.
6981
*
@@ -200,6 +212,27 @@ public function unserialize($value)
200212
return $this->unserializeData($data);
201213
}
202214

215+
/**
216+
* Set unserialization mode for undeclared class properties
217+
*
218+
* @param integer $value One of the JsonSerializer::UNDECLARED_PROPERTY_MODE_*
219+
* @return self
220+
* @throws InvalidArgumentException When the value is not one of the UNDECLARED_PROPERTY_MODE_* options
221+
*/
222+
public function setUnserializeUndeclaredPropertyMode($value)
223+
{
224+
$availableOptions = [
225+
static::UNDECLARED_PROPERTY_MODE_SET,
226+
static::UNDECLARED_PROPERTY_MODE_IGNORE,
227+
static::UNDECLARED_PROPERTY_MODE_EXCEPTION
228+
];
229+
if (!in_array($value, $availableOptions)) {
230+
throw new InvalidArgumentException('Invalid value.');
231+
}
232+
$this->undefinedAttributeMode = $value;
233+
return $this;
234+
}
235+
203236
/**
204237
* Parse the data to be json encoded
205238
*
@@ -431,7 +464,16 @@ protected function unserializeObject($value)
431464
$propRef->setAccessible(true);
432465
$propRef->setValue($obj, $this->unserializeData($propertyValue));
433466
} catch (ReflectionException $e) {
434-
$obj->$property = $this->unserializeData($propertyValue);
467+
switch ($this->undefinedAttributeMode) {
468+
case static::UNDECLARED_PROPERTY_MODE_SET:
469+
$obj->$property = $this->unserializeData($propertyValue);
470+
break;
471+
case static::UNDECLARED_PROPERTY_MODE_IGNORE:
472+
break;
473+
case static::UNDECLARED_PROPERTY_MODE_EXCEPTION:
474+
throw new JsonSerializerException('Undefined attribute detected during unserialization');
475+
break;
476+
}
435477
}
436478
}
437479
if (method_exists($obj, '__wakeup')) {

tests/JsonSerializerTest.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,66 @@ public function testSerializationUndeclaredProperties()
375375
$this->assertSame('value', $obj->sub->key);
376376
}
377377

378+
/**
379+
* Test undeclared properties setter (valid)
380+
*
381+
* @return void
382+
*/
383+
public function testSetUnserializeUndeclaredPropertyModeValid() {
384+
$value = $this->serializer->setUnserializeUndeclaredPropertyMode(JsonSerializer::UNDECLARED_PROPERTY_MODE_SET);
385+
$this->assertSame($value, $this->serializer);
386+
}
387+
388+
/**
389+
* Test undeclared properties setter (invalid)
390+
*
391+
* @return void
392+
*/
393+
public function testSetUnserializeUndeclaredPropertyModeInvalid() {
394+
$this->setExpectedException('InvalidArgumentException');
395+
$value = $this->serializer->setUnserializeUndeclaredPropertyMode('bad value');
396+
}
397+
398+
/**
399+
* Test unserialization of undeclared properties in SET mode
400+
*
401+
* @return void
402+
*/
403+
public function testUnserializeUndeclaredPropertySet() {
404+
$this->serializer->setUnserializeUndeclaredPropertyMode(JsonSerializer::UNDECLARED_PROPERTY_MODE_SET);
405+
406+
$serialized = '{"@type":"stdClass","sub":{"@type":"stdClass","key":"value"}}';
407+
$obj = $this->serializer->unserialize($serialized);
408+
$this->assertInstanceOf('stdClass', $obj->sub);
409+
$this->assertSame('value', $obj->sub->key);
410+
}
411+
412+
/**
413+
* Test unserialization of undeclared properties in IGNORE mode
414+
*
415+
* @return void
416+
*/
417+
public function testUnserializeUndeclaredPropertyIgnore() {
418+
$this->serializer->setUnserializeUndeclaredPropertyMode(JsonSerializer::UNDECLARED_PROPERTY_MODE_IGNORE);
419+
420+
$serialized = '{"@type":"stdClass","sub":{"@type":"stdClass","key":"value"}}';
421+
$obj = $this->serializer->unserialize($serialized);
422+
$this->assertFalse(isset($obj->sub));
423+
}
424+
425+
/**
426+
* Test unserialization of undeclared properties in EXCEPTION mode
427+
*
428+
* @return void
429+
*/
430+
public function testUnserializeUndeclaredPropertyException() {
431+
$this->serializer->setUnserializeUndeclaredPropertyMode(JsonSerializer::UNDECLARED_PROPERTY_MODE_EXCEPTION);
432+
433+
$this->setExpectedException('Zumba\Exception\JsonSerializerException');
434+
$serialized = '{"@type":"stdClass","sub":{"@type":"stdClass","key":"value"}}';
435+
$obj = $this->serializer->unserialize($serialized);
436+
}
437+
378438
/**
379439
* Test serialize with recursion
380440
*

0 commit comments

Comments
 (0)