Warning: Illegal string offset '_imagedir' in /home/cakephpf/public_html/lofiversion/index.php on line 545

Warning: Illegal string offset '_emodir' in /home/cakephpf/public_html/lofiversion/index.php on line 546
CakePHP UnOfficial Community Forum > SOAP with Cake - A simple solution
Help - Search - Member List - Calendar
Full Version: SOAP with Cake - A simple solution
CakePHP UnOfficial Community Forum > Tutorials Galore

francky06l
I did work with SOAP and cake a while ago using cake 1.1. I did receive maybe PM for sharing code, and decided to re factor the code for cake 1.2.
The solution described is largely based on Rossoft work and nusoap project (for the PHP4 compatibility).

There are two parts, a Cake application acting as a server and serving request as SOAP request. Then a sample client that demonstrate the request to the SOAP server (actually this can be any Soap server).

The server.

The idea is to use one controller that will act and handle all the soap request. In this controller we will describe the SOAP "services" as well as their input/output data.
The nusoap vendor should be placed in the vendors/nusoap folder and it contains
- the refactored nusoap files (necessary for PHP4 and renamed for compatibility with PHP5)
- a base controller called "WebServicesController", derived from AppCOntroller and handling our soap request.
(check later for downloading the vendors/nusoap files).

Let's say we want our controller being "servers", we will then declare it as follow :

[php]
App::import('Vendor', 'WebServicesController');

class ServersController extends WebServicesController
{
var $name = 'Servers';
var $uses = array('Person');
var $autoRender = false;
var $api=array(
'simpletest' => array('doc' => 'Simple test, gets an integer from input, return integer * 2',
'input' => array('appid' => 'xsd:integer'),
'output' => array('return' => 'xsd:integer')),
'sumtest' => array('doc' => 'Sum test, gets 2 integer return the sum',
'input' => array('int1' => 'xsd:integer', 'int2' => 'xsd:integer'),
'output' => array('return' => 'xsd:integer')),
)

// simpletest, just get an integer and return it's double

function simpletest($inp)
{
return $inp * 2;
}

// get 2 integers and return the sum

function sumtest()
{
$v = func_get_args();
if(count($v) != 2)
$this->_soap_server->fault(20, '', 'Wrong number of parameters passed, Expected 2');
else
return array_sum($v);
}
}
[/php]

Note that the uses is there just for the testing application (available in download). The important parts in this controller:

- autoRender = false, this is important since anything rendered as "html" will make the SOAP xml inconsistent.
- api, these are our handled soap services. Api get 3 parameters: "doc", "input", "output". The api keys of the array are matching a method of our controller, these methods handle the data part.
  • doc, a short description of the service
  • input, the input parameters service. The data received by the method can be simple (as described) or complex (see below)
  • output, usually a "return" statement that contains either a simple type or a complex type (see below)
Complex type.

The complex type are described by the class variable $complexType as follow :

[php]
var $complexTypes = array('twoint' => array('struct' => array('int1' => 'xsd:integer',
'int2' => 'xsd:integer')),
'intarray' => array('array' => 'xsd:integer'),
'fullperson' => array('model' => 'Person'),
'cleanfullperson' => array('model' => 'Person', 'ignoreFields' => array('created', 'modified')),

'firstnameperson' => array('model' => 'Person', 'onlyFields' => array('firstname')),

'firstnamepersonservertime' => array('struct' => array(array('model' => 'Person', 'onlyFields' => array('firstname')),
'servertime' => 'xsd:string')),
'allpersons' => array('array' => 'fullperson'),
'allpersonsfirstname' => array('array' => 'firstnameperson'),
);
[/php]

few tips:

Complex have a name, then a type "array", "struct" and I have added "model". This will build up the SOAP data part par method. Then a method can get or return a complex type or nested complex type:

[php]
'getallpersons' => array('doc' => 'Retrieve All Person records',
'output' => array('return' => 'allpersons')),
[/php]

Note that for model, I have added the "ignoreFields" property and "onlyFields", this can be usefull if you want to restrict only few name of a model, or only include few names of the model.

The sample code attached (soapserver) is full of example and contains a database for testing (only 3 records). The DB script is located in the zip file as well.
After installing the sample, type "http://localhost/soapserver/servers" in a browser, that should list a description of all methods exposed by the server.

The client part

In order to query a soap server, I did a small component. The client also needs the vendors/nusoap folder. However it does not use the WebservicesController.

To make a request to a SOAP server, a client should include
[php]
var $components = array('soap');
[/php]
To handle a SOAP request, this would be done as follow :
[php]
function testsoap()
{
$url = Configure::read('SoapServer');
$func = 'simpletest';

$snd = array('appid' => 15);
$data = $this->soap->client($url, $func, $snd, false);
$this->_renderResult($data);
$this->set('data',$data);
}
[/php]

This is extract from the client sample application (attached as zip). Be sure to set the correct "SoapServer" url in the core/config.php file.

The rest is quite straight forward. Check the code, and the samples handled by the client (the name is matching the server methods). I did not optimize all code, since it's for demo purpose.

Running the server sample application

- The application are running on cake1.2 from the SVN branch (should work with the official Beta release)
- Unzip the nusoap.zip in the vendors directory
- Unzip the soapserver.zip to create your soapserver application.
- create a database (default is tutusoap), there is a SQL script in the zip
- Adjust your DB host/user/password in /config/database.php
- try to call your application using the controller "servers" in a browser.

Running the client sample application

- Unzip the nusoap.zip in vendors (can be already done if vendors is as cake level)
- Unzip the soapclient.zip to create the soapclient application.
- edit the /config/config.php and change the SoapServer parameter to fit your soap server location.
- access your soap client application, it routes directly to an home made home page (derived from the cake core). The client does not need database, just ignore the warning about database config not found.

Here are the files. Remarks, comments are welcome.
WyriHaximus
Hi do you have a working download link to the soaptuto.zip? All I get is jibrish when I click the attached file link.
ronaldmaas
Don't click on the link. Try "right-click" and choose "Save As" from the drop down menu. Works for me.


ronald
WyriHaximus
QUOTE (ronaldmaas @ Oct 18 2008, 08:33 AM)
Don't click on the link. Try "right-click" and choose "Save As" from the drop down menu. Works for me.


ronald

Hmmm aparently only IE can download it properly both firefox and chrome seem to misunderstand it.
bipul
Thanks a Helped a Lot,


Its working but got Hactic error
I spended among 5-6 hrs but not resolved Please suggest my mistake.
What i have done is just added all the require files in their places and at one point Forum says open server in a browser it ran well but when I clicked on WSDL
which means my URL was like this http://localhost/myproject/Servers?wsdl

and in browser I gives this error


XML Parsing Error: XML or text declaration not at start of entity
Location: http://localhost/myproject/Servers?wsdl
Line Number 1, Column 2: <?xml version="1.0" encoding="ISO-8859-1"?>
-^

I navigated all the files
i.e vendor/nusoap/nusoap.php
vendor/nusoap/web_services_controller.php
controller/services_controller.php
and component/soap.php

But No Luck
please help.
Thanks sad.gif
francky06l
Strange you use this encoding, I suggest you use UTF-8 instead.
This error append when you have a trailiing space or a space at a beginning of a file.
arehf
Thanks a lot.

I was able to test this on soapUI but somehow when I try to connect it in .Net it fails.

What do you think is the problem?
sparkdev
Hi,
I am not able to download the attached sample code from the post. Could you please me it down-loadable.

With regards

This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2014 Invision Power Services, Inc.
Lo-Fi 1.1 iDS Beta, Originally written by Matt,
re-written by Shaun Harrison, Layer 04.com, for pre IPB2.0 versions.