jump to navigation

Complex Types – 2 February 17, 2006

Posted by rossoft in CakePHP.
trackback

Working more on complex types. Now you can describe a complex type simply telling the name of the model. Automatically the webservice checks the model and defines the variable in the xsd.
I  have updated the controller class

A more complete example:

<?php
vendor(‘nusoap/web_services_controller’);
class ArticulosServicesController extends WebServicesController
{
    var $name=’ArticulosServices’;
    var $uses=array(‘Articulo’,’Familia’);
   
    var $api=array(
            ‘add’=>array (    ‘doc’=>’agregar articulo’,
                            ‘input’=>array(‘codigo’=>’xsd:string’,
                                            ‘nombre’=>’xsd:string’,
                                            ‘precio’=>’xsd:float’)),
               ‘browse’=>array(‘doc’=>’precio articulo’,                                      
                             ‘output’=>array(‘return’=>’Array_Articulos’)),

               ‘read’=>array(‘doc’=>’lee todos los campos de un articulo’,                                      
                            ‘output’=>array(‘return’=>’Articulo’)),

               ‘read2’=>array(‘doc’=>’lee algunos campos de un articulo’,                                      
                            ‘output’=>array(‘return’=>’Articulo2’)),

                                           
               ‘precio’=>array(‘doc’=>’precio articulo’,
                                ‘input’=>array(‘codigo’=>’xsd:string’),
                             ‘output’=>’xsd:integer’)
                );
    var $complexTypes=array(
                ‘Array_Articulos’=>array(‘array’=>’MyArticulo’),
                ‘MyArticulo’=>array(‘struct’=>array(
                            ‘codigo’=>’xsd:string’,
                            ‘nombre’=>’xsd:string’,
                            ‘precio’=>’xsd:float’)),
                ‘Articulo’=>array(‘model’=>’Articulo’),
                ‘Articulo2’=>array(    ‘model’=>’Articulo’,
                                        ‘fields’=>array(‘codigo’,’nombre’,’precio_pvp’=>’precio’,’descripcion’))               
                );
                   
    function add($codigo,$nombre,$precio)
    {
        $data[‘Articulo’][‘codigo’]=$codigo;
        $data[‘Articulo’][‘nombre’]=$nombre;
        $data[‘Articulo’][‘precio_pvp’]=$precio;
        $this->Articulo->save($data);
    }
   
   
    /**
     * returns the price of one article
     */
    function precio($codigo)
    {       
        $data=$this->Articulo->findAll(“Articulo.codigo =’$codigo'”);
        if ($data)
        {
            return $data[0][‘Articulo’][‘precio_pvp’];
        }
        else
        {
            return new soap_fault(‘Client’,”,’Este artículo no existe.’,”);
        }
       
    }

    /**
     * retuns one array of custom struct type
     */   
    function browse()
    {
        $ret=array();
        $data=$this->Articulo->findAll();
        foreach ($data as $art)
        {
            $ret[]=array(‘codigo’=>$art[‘Articulo’][‘codigo’],
                                         ‘nombre’=>$art[‘Articulo’][‘nombre’],
                                         ‘precio’=>$art[‘Articulo’][‘precio_pvp’]);
                         
        }       
        return $ret;            
    }
   
    /**
     * return one element of model Articulo
     */
    function read($codigo)
    {
        $ret=array();
        $data=$this->Articulo->findAll(“Articulo.codigo=’$codigo'”,null,null,50,1,0);
        return $data[0][‘Articulo’];
    }   

    /**
     * return one element of model Articulo
     * (it will return only certain columns of it)
     * precio_pvp column is renamed to precio
     */
    function read2($codigo)
    {
        $ret=array();
        $data=$this->Articulo->findAll(“Articulo.codigo=’$codigo'”,null,null,50,1,0);
        $data[0][‘Articulo’][‘precio’]=$data[0][‘Articulo’][‘precio_pvp’];
        unset($data[0][‘Articulo’][‘precio_pvp’]);
        return $data[0][‘Articulo’];
    }   
       
}

?>

Advertisements

Comments»

1. martin - February 21, 2006

Ive download new web_service_controller and there are notice complexTypes not found, in source there are not complexTypes but complexType (bug?) ive changed that, and after adding some array complex there are error in wsdl “namespace not defined”

2. rossoft - February 21, 2006

Thanks for your feedback, I’ve uploaded new version renaming var $complexType to var $complexTypes (nothing else has changed). This only fixes the notice, nor the “namespace not defined”. If you can send me your controller, I will study it for fixing.

3. rossoft - February 25, 2006

I have fixed some bugs like “XXX has no namespace!”.
Now you can generate the WSDL in two ways: mycontroller?wsdl or mycontroller/wsdl

4. Ryan - October 27, 2006

This is awesome, but what if I want to do the following (would it be possible?)

I want to create my controller classes, but I want that one controller to handle both the http transactions, as well as the webservice transactions.

So if someone were to go to http://www.whatever.com/controller/action in their browser it would work just fine, displaying the appropriate template, but if they were to go to http://www.whatever.com/webservice/controller/action it would call the same action in the controllers file, and would return the appropriate soap call.

I would just like to minimize re-writing the same code, to do the exact same thing.

Thanks (email me back if possible!)

5. Franck - January 18, 2007

Hello,

I have tried it with the latest version of cake 1.1.12.4205, and I keep having warning and no response, I mean the date are not transmitted back.
The warning concerns session/php line 146 / 147 mainly also I needed to add the type ‘string’ => ‘xsd:string’ and ‘integer’ => ‘xsd:integer’ to the array in the webservices_controller ..
I am sure it’s something stupid, but I cana’t figure out what..

6. Franck - January 18, 2007

well I figure out for the warnings, but still can’t get any data back from the webservice
If someone has an idea of what I can do to bring more information, I get the infos 🙂
Thanks

7. Erich - January 25, 2007

I’ve managed to get this working, although something is really wrong with the generated WSDL file:

When the soap action gets called, it returns the content of the application home page.

8. Erich - January 25, 2007

I’ve managed to get this working, although something is really wrong with the generated WSDL file:

When the soap action gets called, it returns the content of the application home page, as defined in the soap:address.

9. Erich - January 25, 2007

What a pain…

<service name=”Leads”>
<port name=”LeadsPort” binding=”tns:LeadsBinding”>
<soap:address location=”http://192.168.1.24/app/webroot/index.php”/>
</port>
</service>

10. Franck - January 25, 2007

I managed to get it works, I have modified the Webservice_controllers in order to take in account ‘exclude_fields’ as well as ‘fields’, also added some $var CommonExclude definition if you want to exclude variable in models that are always there (ie : created, modified)..

I have also amended the BuildComplextypes, to be able to do this in a structure :
‘tstl’ => array(‘struct’ => array(array(‘model’ => ‘Applicant’,
exclude_fields’ => array(‘isvalid’, ‘title’))
‘Addr’ => ‘alladdr’))

That allow to add a model in a structure without having to make another “array”, very usefull for some realtions such as
parent
– child
– child
where in output you do not want to “move” the data for each occurence..

I can send it to Ross to check if I have done too many mistakes, or anyone who wants to play with..

Ciao

11. ianh - March 14, 2007

I have this working really well for fairly simple structures but got stuck on more complex structures; let me explain:

In the $api var on this page, there is a browse function that returns an array of articles ‘Array_Articulos’. In the $complexTypes var this translates to meaning an array of ‘MyArticulo’s with the struct defined thereafter. So far this works brilliantly.

What I am now trying to do is to return an array of associated objects within MyArticluo (e.g. tags). I have gotten as far as making the $complexType definition like this:

‘MyArticulo’=>array(’struct’=>array(
‘codigo’=>’xsd:string’,
‘nombre’=>’xsd:string’,
‘precio’=>’xsd:float’,
‘array’=>’Tags’)),
‘Tags’=>array(‘struct’=>array(
‘id’ => ‘xsd:integer’)),

I then get stuck figuring out how to format the results from a findAll() query to match. Doing a var_dump on my returned data I find the MyArticulo data gets returned just fine, except the array which comes back null.

Any ideas would be very welcome. Unfortunately there are people chopping down trees right outside my office today so not the best environment to focus!

12. bobby - June 13, 2007

have we got the way to call with wsdl file


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: