How to create a custom JMSSerializen handler for base types like strings or arrays? The goal would be to (de)serialize some properties in non-default ways. For example to specify that one array property should be deserialized to a CSV string instead to a default JSON array or one string string property to to an encrypted / encoded string, etc.
While creating such a handler for a custom class was no problem, I struggle to do the same for base types.
class SyncableEntityHandler implements SubscribingHandlerInterface {
public static function getSubscribingMethods() {
return [
[
'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
'format' => 'json',
'type' => 'SomeClass',
'method' => 'serializeSomeClassToJson',
],
[
'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
'format' => 'json',
'type' => 'SomeClass',
'method' => 'deserializeSomeClassFromJson',
],
];
}
public function serializeSomeClassToJson(JsonSerializationVisitor $visitor, AbstractSyncableEntity $entity, array $type, Context $context) {
...
}
public function deserializeSomeClassFromJson(JsonDeserializationVisitor $visitor, $entityGuid, array $type, Context $context) {
...
}
}
class OtherClass {
/*
* @JMS\Type("SomeClass")
*/
protected $someProperty;
/*
* @JMS\Type("array")
*/
protected $serializeToDefaultArray;
/*
* @JMS\Type("csv_array") // How to do this?
*/
protected $serializeToCSVString;
}
While I can create a handler with 'type' => 'array' to change the (de)serializiation of all arrays, I do not know to only select some arrays.
I already thought about using getters and setters instead (e.g. getPropertyAsCsvString() and setPropertyFromCsvString()). While this would work with custom classes, I would like to serialize some third-party classes as well where I specify the serialization options not with annotations but in .yaml files. Adding getter and setters to these classes is not (easily) possible. Additionally creating these getters and setters would add a lot of overhead.
So, is there a way to create and specify special handlers for some properties?
The implementation is quite straightforward:
Then just annotate your property with
@JMS\Type("csv_array")and register the handler.Note that using
explodeandimplodedoes not escape the input so you may want to use something like league/csv instead.