christiankerl / ckWebServicePlugin

Build SOAP and WSDL based web services with symfony 1.x.
MIT License
11 stars 5 forks source link

Doctrine Relations properties are lost during tests #3

Closed vbourdeix closed 12 years ago

vbourdeix commented 13 years ago

When using ckDoctrinePropertyStrategy on model with relations, for example Blog which have Posts, which have comments. When you give a parameter of type Blog which contains some posts and comments data, it is not in the final object in the request object. Only members of Blog are preserved.

Failing test :

$options = array( 'classmap' => array( 'Blog' => 'ckGenericObjectAdapter_Blog', 'Post' => 'ckGenericObjectAdapter_Post', 'Comment' => 'ckGenericObjectAdapter_Comment', 'PostArray' => 'ckGenericArray', 'CommentArray' => 'ckGenericArray' ), );

$blog = new Blog(); $blog->setName("a blog");

$post = new Post(); $post->setDescription("first post");

$comment = new Comment(); $comment->setDescription("a comment"); $comments = new Doctrine_Collection("Comment"); $comments->add($comment); $post->setComments($comments);

$posts = new Doctrine_Collection("Post"); $posts->add($post);

$blog->setPosts($posts);

$c = new ckTestSoapClient($options);

$c->createBlog($blog) ->isFaultEmpty() ->is("name", "a blog") ->is(".Posts.0.description", "a comment");

christiankerl commented 13 years ago

Can you post the result of:

<?php

var_dump($c->__getLastRequest());
var_dump($c->__getLastResponse());
vbourdeix commented 13 years ago
<?php
var_dump($c->__getLastRequest());

gives

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://testsoap/">
  <SOAP-ENV:Header/>
  <SOAP-ENV:Body>
    <ns1:createBlog>
      <blog>
        <id/>
        <name>a blog</name>
        <Posts>
          <item>
            <id/>
            <blogid/>
            <description/>
            <Comments>
              <item>
                <id/>
                <postid>1</postid>
                <description/>
              </item>
            </Comments>
          </item>
        </Posts>
      </blog>
    </ns1:createBlog>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

and

<?php
var_dump($c->__getLastResponse());

gives

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://testsoap/">
  <SOAP-ENV:Body>
    <ns1:createBlogResponse>
      <result>
        <id/>
        <name>a blog</name>
        <Posts>
          <item>
            <id/>
            <blogid>1</blogid>
            <description></description>
            <Comments>
              <item>
                <id/>
                <postid>1</postid>
                <description></description>
              </item>
            </Comments>
          </item>
        </Posts>
      </result>
    </ns1:createBlogResponse>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

What I don't understand is that before

<?php
$this->lastResult = parent::__soapCall($method, $parameters, array(), $this->getRequestHeaders(), $this->responseHeaders);

in the __call method of ckTestSoapClient.class.php, the following code

<?php
die(var_dump($parameters[0]->toArray()));

But after the soapcall a

<?php
die(var_dump($this->lastResult->getObject()->toArray()));

shows that the data is lost

christiankerl commented 13 years ago

as you can see in the xml of the request the comment's description is not transferred to the server

<Comments>
    <item>
        <id/>
        <postid>1</postid>
        <description></description>
    </item>
</Comments>

btw. the classmapping with ckGenericArray and ckGenericObjectAdapter_* is not working on the client side. Therefore, you can't use the Doctrine classes at the client side. Try it with plain PHP classes and arrays at the client side. Define classes for Blog, Post, Comment which have public properties corresponding to the ones of your Doctrine classes. In the classmap map Blog, Post and Comment to the names of your new classes:

<?php

class Blog
{
    public $id;
    public $name;
    // ...
}

class Post
{
    // ...
}

class Comment
{
    // ...
}

$options = array(
    'classmap' => array('Blog' => 'Blog', 'Post' => 'Post', 'Comment' => 'Comment')
);