Update: Fixed some stupid typo’s in the documentation.
I’ve published my SOAP Datasource on Github, you can find the sourcecode in the ‘soapsource‘ repository.
SoapSource allows you to connect with SOAP servers that support Wsdl. I also started implementing functionality for non Wsdl SOAP servers, but I don’t think I will continue on this.
SoapSource now supports non wsdl servers also, you can add ‘uri’ and ‘location’ parameters to your datasource configuration now.
In order to use the Datasource you will need to have PHP5 installed with the SOAP extension.
Here’s how you use it:
Copy the soap_source.php file to your app/models/datasources/ directory
Add a configuration to your database.php in app/config/
var $soap = array(
‘datasource’ => ‘soap’,
‘wsdl’ => ‘http://localhost/soapservice.wsdl’, // wsdl mode
‘location’ => ”, // Required for non wsdl mode
‘uri’ => ” // Required for non wsdl mode
);Then in your model set:
var $useDbConfig = ‘soap’;
var $useTable = false;
And you’re ready to go.
In your controller you can now use
$this->Model->query(‘SoapMethod’, array(‘mySoapParams’));
or
$this->Model->SoapMethod(array(‘mySoapParams’));
Hey, spiffy!
This is almost exactly the API I had envisioned for this stuff, right down to the use of query() and custom methods. Good job on figuring out all the DataSource API stuff.
Thanks a lot nate!
Any chance we’ll see something like this in Cake in the future? I noticed there’s a soap class in the 2.x sandbox.
Hi,
that’s the component for working with soap in CakePHP I was looking for: simple to integrate, simple to use. Great work so far. But it doesn’t work for me… :-(
I downloaded the soap_source.php, added this wsdl-url in the database.php
http://www.thomas-bayer.com/names-service/soap?wsdl
and called this code in my test_controller.php:
$this->Test->query(‘getCountries’, array());
pr($this->Test);
exit();
If I understand this right, I should get an array with country-names.
It doesn’t work – there is no array of country-names – and I don’t get any error-message.
The webservice itself works, I tested it with soapUI 2.5.
The extension for php_soap.dll is activated in php.ini and both options are shown as ‘enabled’ in phpinfo.php
I am working on my local machine at localhost:8080.
Do you have any ideas what could be my mistake? Could you also please tell what format the params in the array must have if I have any?
Greetings,
Ricky
Ricky,
First of all to output the result you should use something like:
$result = $this->Test->query(’getCountries’, array());
pr($result);
exit();
If you use wsdl, you can just pass the parameters in the correct order in the params array. The soap extension will take care of the rest.
Hope this helps
Hi again!
I’m sorry, but there is still no result. :-(
Could you please try it with this WSDL and if it was successful, mail me your code? Perhaps I’ve did something basically wrong and am searching on the wrong place…
Ah, I forget to say: I use the newest CakePHP-Version available: 1.2.0.7962.
Thanks a lot and happy new year!
Greetings,
Ricky
After reading through this article, I just feel that I really need more info. Could you suggest some more resources please?
http://www.php.net/soap
good luck
Hi,
After reading your article, I tried to implement the SoapSource to a web application that I have to develop for my work. My WebApp is like a directory of documents. And the Documents belong to User. The model User is a DataSource from another WebApp. I have to load the users information from a SOAP webservice called getLiteMemberList.
How could I use your code ? I tried to implement it but, I have this error:
Fatal error: Call to undefined method SoapSource::calculate() in ###\cake\libs\model\model.php on line 2015
Thanks for the work. I have set up the code as you showed but when I make a call to the API I get the following error:
SOAP Error: Function (“QuerySub”) is not a valid method for this service [APP\models\datasources\soap_source.php, line 201]
I know for a fact that this method exists as I use it in my own SOAP class.
Any suggestions you can offer would be appreciated.
Thanks.
Forget my last message. I was in error.
Ok now I have discovered a problem. When I send a transaction to my API I have specific field names for the data. Your class seems to be overwriting these. Here is my set up:
function view($id = null)
{
// http://www.pagebakers.nl/2008/12/18/soapsource-a-soap-client-datasource-for-cakephp/
//$this->Subscriber->id = $id;
$this->TransactionParams = array();
$this->TransactionParams['loginName'] = ‘XXX’;
$this->TransactionParams['loginPassword'] = ‘XXX’;
$this->TransactionParams['orgName'] = ‘Solo Field Dev’;
$this->TransactionParams['transaction']['id'] = ‘cake_test’;
$this->TransactionParams['transaction']['wait'] = ’0′;
$this->TransactionParams['transaction']['version'] = ’3.2′;
$this->TransactionParams['transaction']['TransactionCommandList'] = array();
$this->TransactionParams['transaction']['TransactionCommandList']['QuerySub']['SubscriberId'] = 456;
$this->set(‘subscriber’, $this->Subscriber->query(‘SendTransaction’, $this->TransactionParams ));
}
Here is the Resulting XML:
client6065
Solo Field Dev
id
cake_test
wait
0
version
3.2
TransactionCommandList
QuerySub
SubscriberId
456
As you can see the fields names are wiped and replaced with Param(n)
Am I doing something wrong?
XML
client6065
Solo Field Dev
id
cake_test
wait
0
version
3.2
TransactionCommandList
QuerySub
SubscriberId
456
Sorry man I cant seem to post the XML. But essentially I need to know why the field names are overwritten.
Thanks
I changed the following line in your class:
$result = $this->client->__soapCall($method, $queryData);
to:
$result = $this->client->sendTransaction($queryData);
I am interested in serializing and then caching the response as is offered in the nuSOAP library, where would I start? Or would I have been luck just starting from scratch with nuSOAP?
@Sean, well you could use my code as a start, replace the standard SoapClient code with the nuSOAP class’ methods
[...] http://www.pagebakers.nl/…t-datasource-for-cakephp/ [...]
Hi,
Followed all the steps.
Calling a webservice like this:
$response = $this->Employee->query(‘getAuthorisation’, array(‘john’, ‘password1′));
(I’ve tried many, many notations, varieties)
In my webservice console i see that the webservice getAuthorisation is called, but no parameters are passed along!
When i print the value of $method and $queryData right before the webservice in soap_source.php is called i get this:
string(16) “getAuthorisation”
array(2) {
[0]=>
string(4) “john”
[1]=>
string(4) “password1″
}
Somehow the parameters are not accepted/passed along at some later point!
If anyone can help me out here, would be greatly appreciated!!
I am having a problem adding attributes and was wondering if you could shed some light. I have pasted below a portion of XSD that defines the section I am working with as well as the PHP I am using to create the structure. Right before sendTransaction I can see the params are there but they are not getting converted to XML.
−
−
−
public function AddUpdateServices($subscriber_id, $actions)
{
$this->add_transaction_id(‘AddUpdateSub’);
$command = array();
$command['AddUpdateSub']['SubscriberId'] = $subscriber_id;
$command['AddUpdateSub']['ServiceList']['replace'] = ‘yes’;
foreach($actions['DeleteSubService'] as $service_name)
{
$service = array();
$service['action'] = ‘delete’;
$service['ServiceName'] = $service_name;
$command['AddUpdateSub']['ServiceList'][]->Service = $service;
}
foreach($actions['AddUpdateSubService'] as $service_name)
{
$service = array();
$service['action'] = ‘add’;
$service['ServiceName'] = $service_name;
$command['AddUpdateSub']['ServiceList'][]->Service = $service;
}
$this->add_command_to_transaction($command);
return $this->formatResult($this->query(‘SendTransaction’,$this->TransactionParams));
}
Steven, can you paste a print_r of $this->TransactionParams ?
Calls make to getRequest and getResponse after query do not output anything. Am I missing something here?
By the way my debug level is set to 2 so I would assume this line in the SoapSource class -
$options = array(‘trace’ => Configure::read(‘debug’) > 0);
would set the trace option to ‘true’ and therefore enable output from __getLastRequest / __getLastResponse.
@Ian unfortunately you can’t call those methods directly from your controller currently