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

XmlKeyValueStore annotation does not seem to deserialize properly #139

Closed
mvriel opened this issue Sep 2, 2013 · 13 comments
Closed

XmlKeyValueStore annotation does not seem to deserialize properly #139

mvriel opened this issue Sep 2, 2013 · 13 comments

Comments

@mvriel
Copy link

mvriel commented Sep 2, 2013

For phpDocumentor we use the JMS Serializer library to convert settings XML files into models. This worked perfectly until we tried to add a key-value store series of parameters to our objects.

The error seems to occur with the following XML (this is actually generated by the serialize method).

<?xml version="1.0" encoding="UTF-8"?>
<template>
  <author><![CDATA[Mike van Riel]]></author>
  <version><![CDATA[1.0.0]]></version>
  <copyright><![CDATA[Mike van Riel 2013]]></copyright>
  <description><![CDATA[

      To improve performance you can add the following to your .htaccess:

      <ifModule mod_deflate.c>
          <filesMatch "\.(js|css|html)$">
              SetOutputFilter DEFLATE
          </filesMatch>
      </ifModule>
  ]]></description>
  <transformations>
    <transformation query="copy" writer="FileIo" source="templates/clean/images" artifact="images">
      <parameters/>
    </transformation>
    <transformation query="copy" writer="FileIo" source="templates/clean/css" artifact="css">
      <parameters/>
    </transformation>
    <transformation query="copy" writer="FileIo" source="templates/clean/js" artifact="js">
      <parameters/>
    </transformation>
    <transformation query="namespace" writer="twig" source="templates/clean/namespace.html.twig" artifact="index.html">
      <parameters/>
    </transformation>
    <transformation query="indexes.namespaces" writer="twig" source="templates/clean/namespace.html.twig" artifact="">
      <parameters/>
    </transformation>
    <transformation query="indexes.classes" writer="twig" source="templates/clean/class.html.twig" artifact="">
      <parameters/>
    </transformation>
    <transformation query="indexes.interfaces" writer="twig" source="templates/clean/interface.html.twig" artifact="">
      <parameters/>
    </transformation>
    <transformation query="indexes.traits" writer="twig" source="templates/clean/class.html.twig" artifact="">
      <parameters/>
    </transformation>
    <transformation query="files" writer="twig" source="templates/clean/file.html.twig" artifact="">
      <parameters/>
    </transformation>
    <transformation query="files" writer="twig" source="templates/clean/file.source.txt.twig" artifact="files/{{path}}.txt">
      <parameters/>
    </transformation>
    <transformation query="" writer="twig" source="templates/clean/reports/markers.html.twig" artifact="reports/markers.html">
      <parameters/>
    </transformation>
    <transformation query="" writer="twig" source="templates/clean/reports/errors.html.twig" artifact="reports/errors.html">
      <parameters/>
    </transformation>
    <transformation query="" writer="twig" source="templates/clean/reports/deprecated.html.twig" artifact="reports/deprecated.html">
      <parameters/>
    </transformation>
    <transformation query="" writer="twig" source="templates/clean/graphs/class.html.twig" artifact="graphs/class.html">
      <parameters/>
    </transformation>
    <transformation query="" writer="Graph" source="Class" artifact="graphs/classes.svg">
      <parameters/>
    </transformation>
  </transformations>
  <parameters>
    <twig-debug><![CDATA[true]]></twig-debug>
  </parameters>
</template>

When I deserialize this XML (see https://github.com/phpDocumentor/phpDocumentor2/blob/develop/src/phpDocumentor/Transformer/Template/Collection.php#L96) with the template model (https://github.com/phpDocumentor/phpDocumentor2/blob/develop/src/phpDocumentor/Transformer/Template.php#L66) I notice that the $parameters property never receives any elements.

Am I doing something wrong or is this an issue with the XmlKeyValueStore annotation/functionality?

@adrienbrault
Copy link
Contributor

I think that XmlKeyValuePairs deserialization support is missing.

@mvriel
Copy link
Author

mvriel commented Sep 2, 2013

@adrienbrault do you know where I can look so I might be able to contribute a fix?

@adrienbrault
Copy link
Contributor

Hum, actually, try to use @Serializer\Type("array<string>") instead of @Serializer\Type("array") first.

@mvriel
Copy link
Author

mvriel commented Sep 2, 2013

I have tried your suggestion but it won't help ..

@mvriel
Copy link
Author

mvriel commented Sep 2, 2013

Ouch, that piece of code is quite in the core of JMS Serializer. That will take some time to digest.

@schmittjoh
Copy link
Owner

This will likely be complicated/impossible as we have no type information for key value pairs in XML (or we need to embed the information into the document).

Another, simpler solution would be to introduce a Parameters object in your code where you can keep the different settings.

@mvriel
Copy link
Author

mvriel commented Sep 2, 2013

I am unable to predict which exact settings are necessary due to the way this is set up; is it possible and what is the easiest way to extract an array of variable keys?

<parameters>
<my-parameter></my-parameter>
<my-random-parameter></my-random-parameter>
</parameters>

I don't mind adding a parameters collection object by the way; those flexible keys are my main requirement

@adrienbrault
Copy link
Contributor

@mvriel Hm, maybe try @Serializer\Type("array<string, string>")

@schmittjoh
Copy link
Owner

Right now, this is not easy in XML as we have no type information for each individual key (to which value should we convert the data, boolean, string, integer, etc.?). You could probably write a listener which extracts the parameters from XML and set them on your object if you know the types.

A more long-term fix in the serializer would be to embed type information:

<parameters>
    <my-parameter type="string">123</my-parameter>
    <my-random-parameter type="boolean">true</my-random-parameter>
</parameters>

Although the caveat here is that you probably don't want the XML to come from input that can be manipulated by a possibly malicious user.

@mvriel
Copy link
Author

mvriel commented Sep 2, 2013

Is the same complexity applicable when I know up front that all keys should be strings?

@schmittjoh
Copy link
Owner

That would make things easier indeed. It is not possible right now as the element name is hard-coded (see https://github.com/schmittjoh/serializer/blob/master/src/JMS/Serializer/XmlDeserializationVisitor.php#L146).

Are you tied to this format, or would something like this work:

<parameters>
    <parameter name="my-parameter">value</parameter>
    <parameter name="my-random-parameter">another value</parameter>
</parameters>

@mvriel
Copy link
Author

mvriel commented Sep 6, 2013

Thanks for all your input; I have decided to go for your last suggestion. I had hoped I would be able to use the former as that would have prevented a BC break but given the limited time I have available I have chosen for this one.

Again, thank you!

@mvriel mvriel closed this as completed Sep 6, 2013
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

3 participants