Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] Serialization of primitive types #853

Closed
jvahldick opened this issue Jan 12, 2018 · 7 comments
Closed

[Question] Serialization of primitive types #853

jvahldick opened this issue Jan 12, 2018 · 7 comments

Comments

@jvahldick
Copy link

I've a similar case described in the issue #631
I am trying to convert a boolean into a string, but it never reaches the defined method.

I saw these issues (#631, #610), but I couldn't really make it work.

$serializer = JMS\Serializer\SerializerBuilder::create()
    ->addMetadataDir(__DIR__ . '/src/Resources/metadata', 'Namespace\\Model')
    ->setDebug(true)
    ->addDefaultHandlers()
    ->configureHandlers(function(JMS\Serializer\Handler\HandlerRegistry $registry) {
        $registry->registerSubscribingHandler(new 
        $registry->registerSubscribingHandler(new \Namespace\Handler \BooleanToStringHandler());
    })
    ->build()
;
class BooleanToStringHandler implements SubscribingHandlerInterface
{
    public static function getSubscribingMethods()
    {
        return [
            [
                'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
                'format' => 'json',
                'type' => 'boolean',
                'method' => 'serializeBooleanToString',
            ],
        ];
    }

    public function serializeBooleanToString(JsonSerializationVisitor $visitor, $value, array $type, Context $context)
    {
        // not reached
    }
}
Example:
  properties:
    active:
      type: boolean

I found the solution adding a SerializationVisitor, but I don't think it is the ideal solution for that.
Am I doing something wrong here?

@goetas
Copy link
Collaborator

goetas commented Jan 12, 2018

you cant define hadlers for native types.

you have to

Example:
  properties:
    active:
      type: MY_boolean

and define a handler for MY_boolean

@goetas goetas closed this as completed Jan 12, 2018
@jvahldick
Copy link
Author

@goetas I've tried it, but it throws an error

ReflectionException: Class custom_boolean does not exist in /.../jms/metadata/src/Metadata/MetadataFactory.php on line 167

@goetas
Copy link
Collaborator

goetas commented Jan 12, 2018

class BooleanToStringHandler implements SubscribingHandlerInterface
{
    public static function getSubscribingMethods()
    {
        return [
            [
                'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
                'format' => 'json',
                'type' => 'custom_boolean',
                'method' => 'serializeBooleanToString',
            ],
        ];
    }

    public function serializeBooleanToString(JsonSerializationVisitor $visitor, $value, array $type, Context $context)
    {
        // not reached
    }
}

is your handler defined as this? attention to custom_boolean

@jvahldick
Copy link
Author

Yes, it is.

@jvahldick
Copy link
Author

I managed to fix the problem, but I guess it is a bug. The behavior of my system which throws the exception is basically what is described below.

$string = '{property:false}';
$object = $serializer->deserialize($string, Object::class, 'json');

$object->property = true;
$serializer->serialize($api, 'json');

I fixed the problem adding the deserialization to the handler.

public static function getSubscribingMethods()
{
    return [
        [
            'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
            'format' => 'json',
            'type' => 'custom_boolean',
            'method' => 'serializeBooleanToString',
        ],
        [
            'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
            'format' => 'json',
            'type' => 'custom_boolean',
            'method' => 'deserializeBooleanToString',
        ],
    ];
}

public function serializeBooleanToString(JsonSerializationVisitor $visitor, $value, array $type, Context $context)
{
    return (true === $value)
        ? 'true'
        : 'false'
    ;
}

public function deserializeBooleanToString(JsonDeserializationVisitor $visitor, $value, array $type, Context $context)
{
    return $visitor->visitBoolean($value, $type, $context);
}

@jvahldick
Copy link
Author

jvahldick commented Jan 12, 2018

@goetas you can check it in https://github.com/jvahldick/jms-error-issue-853
PHP version 7.1.12

Changing it to the code below, it works.

public static function getSubscribingMethods()
{
    return [
        [
            'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
            'format' => 'json',
            'type' => 'custom_boolean',
            'method' => 'serializeBooleanToString',
        ],
        [
            'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
            'format' => 'json',
            'type' => 'custom_boolean',
            'method' => 'deserializeBooleanToString',
        ],
    ];
}

public function serializeBooleanToString(JsonSerializationVisitor $visitor, $value, array $type, Context $context)
{
    return (true === $value)
        ? 'true'
        : 'false'
    ;
}

public function deserializeBooleanToString(JsonDeserializationVisitor $visitor, $value, array $type, Context $context)
{
    return $visitor->visitBoolean($value, $type, $context);
}

@goetas
Copy link
Collaborator

goetas commented Jan 13, 2018

in your repo, you are deserializing a custom type but you have defined only the serialization handler (not the de-serialization). that's the reason of the error you are getting

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants