PHP/SOAP dont create desired xml request - php

I am trying to use a WSDL web service with php/soap. And it always gives a deserializing error which is exactly:
Error in deserializing body of request message for operation 'Test'. OperationFormatter encountered an invalid Message body. Expected to find node type 'Element' with name 'Test' and namespace ''. Found node type 'Element' with name 'parameters' and 'namespace'
When I test the WSDL source with WcfTestClient software nothing goes wrong and it returns with desired results.
When I compare the request XML which created by SOAP and XML which created by WcfTestClient software, I see that difference may be the problem. It seem like something wrong with namespace and prefixes, but I don't know how to solve it, or maybe it is something else causes the problem.
The request XMLs is this: http://pastebin.com/eysnG89F.
In case you need PHP code, this is the code I am using.
try{
$soap_options = array(
'soap_version' => SOAP_1_1,
'cache_wsdl' => WSDL_CACHE_NONE,
'trace' => TRUE
);
$soap = new SoapClient(
'http://url.to/web/service.svc?wsdl', $soap_options
);
$a = $soap->Test(
array("login" =>
array(
"FirmaId" => 15,
"KullaniciAdi" => "Asdf",
"Parola" => "Xyxy",
)
)
);
var_dump($a);
} catch (Exception $e) {
var_dump($e);
}

I cant find the exact cause and solution but this seems like working.
First, when you give object instead of array for the wsdl method, you can get rid of item, value nodes. Node will be created by object name
$a = $soap->Test(
(object)array("login" =>
(object)array(
"FirmaId" => 15,
"KullaniciAdi" => "Asdf",
"Parola" => "Xyxy",
)
)
);
After that i realized an < parameters> node instead of < WsdlMethod> node created in request xml. With overriding __doRequest method and replacing strings, can get rid this problem but still cant see the response. Need to wrap < wsdlMethodResponse> node with < parameter> via str_replace and finally get desired response.
As i said this may be a temporary solution. But working for me :)

Related

How to create Items in Podio using podio-php?

Podio's API documentation differs from podio-php's when it comes to creating new Items.
Based on Podio's tutorial, I would have to format each value according to its type, whereas podio-php describes using PodioItemFieldCollection to handle that for you. I prefer the latter option, but I keep getting this error:
Invalid value "1" (string): Not a valid option
I don't see much difference in my code versus the example given by podio-php. What's causing this error?
$fields = new PodioItemFieldCollection(array(
new PodioTextItemField(array("external_id" => "my-text-field", "values" => "FooBar")),
new PodioProgressItemField(array("external_id" => "my-number-field", "values" => 75))
));
$atts = array(
'app' => new PodioApp($app_id),
'fields' => $fields
);
$item = new PodioItem($atts);
No errors caught up to here. But when I try to save...
$response = $item->save();
Invalid value "1" (string): Not a valid option
The $app_id was being passed in as a string. I've had this issue now with a few different ID values returned in an API response. I explicitly cast the value as an integer and the error went away:
$atts = array(
'app' => new PodioApp((int)$app_id),
'fields' => $fields
);

PHP Soap - SOAP-ERROR: Encoding: object hasn't 'checkConnectivityRequest' property

I'm having a problem getting a particular SOAP call to work -most of them work fine, but this one is giving me a headache.
The WSDL is http://fibre.venus.ispwebhost.com/FibreClassTest/colt.wsdl, and the request I am generating is:
$result = $soap->checkConnectivity(
array('checkConnectivityRequest' =>
array(
'requestType' => 'SITE',
'requestMode' => array(
'requestId' => date("Ymdhis"),
'siteAddress' => array(
'postalZipCode' => $this->postcode,
'connectivityType' => 'COLT FIBRE',
'bandwidth' => '2M',
),
)
)
)
);
However I'm getting a SOAP error back (which I believe means it's not even passing it to the web service), so not sure if I'm mis-reading the WSDL?
Thanks!
If you search in the content of http://fibre.venus.ispwebhost.com/FibreClassTest/colt.wsdl you will notice that there is not wsdl:operation named checkConnectivityRequest. The closest i saw was checkConnectivity so, try to replace checkConnectivityRequest with checkConnectivity and let me know.
Happy coding

PHP SOAP WSDL How to call soap action with the same method name

I have WSDL which returns me function list which is included below
[0] => ExternalCacheAccessRsp service(ExternalCacheAccessReq $parameters)
[1] => PingRsp service(PingReq $parameters)
[2] => SystemInfoRsp service(SystemInfoReq $parameters)
[3] => TimeRsp service(TimeReq $parameters)
How I can call PingReq function by
__soapCall()
When I am trying to call __soapCall('service') it returns me first method
"ExternalCacheAccessReq"
Thank you for your answer but both solutions are incorrect for this case.
In the first case Soap returns that I didn't pass attribute "CacheName" which is obligatory for "ExternalCacheAccessRsp" (first method).
In the second solution I have message that method "PingRsp" is not valid. The valid method is "service", but as you see on the top all methods have name "service".
The only way to do this is writing the XML request manually and sending by the method SoapClient::__doRequest.
Take a look at my answer here: stackoverflow.com/a/51099774/6783224
Given a SoapClient like:
$serviceUrl = 'your service address';
$client = new SoapClient($serviceUrl, array(
'trace' => true,
'soap_version' => SOAP_1_2,
'encoding' => 'UTF-8')
);
You can call your method like:
$client->PingRsp($parameters);
Best regards!
Your web service method is overloaded and so you should set the input parameters as specified by PingReq. The only way the server can distinguish between which overload you want is by the format and structure of the input parameters. You can examine the WSDL to see what the structure of PingReq is.
$client = new SoapClient('http://wsdl'); // <-- enter your wsdl url
// set $params as defined by your WSDL for the `PingReq` structure.
$params = array(
'param1' => 'one',
'param2' => 'two'
);
$response = $client->service($params);

CakePHP SoapClient drops fields?

My app uses CakePHP (2.2.5) to get data from a SOAP server. I put logging into the SoapSource.php connector to see the XML returned and to display the array returned:
$result = $this->client->__soapCall($method, array('parameters' => $tParams));
Logger::write('SOAP Last Response', $this->client->__getLastResponse(), 3, 'transaction');
Logger::write('SOAP Last Response Object', print_r($result, TRUE), 3, 'transaction');
But what I'm seeing in the log is that two (recently-added) fields present in the XML are missing from the array, specifically, the last two before the RPList (formatted here but otherwise verbatim):
<transactionResult>
<id>test</id>
<resultCode>0</resultCode>
<ReadScheduledRecordingsRsp>
<RecordingDefinitionList>
<RecordingDefinition>
<RDId>d8c16d8f-67c6-469a-83c3-d51d8f8859a9</RDId>
<Title>The Young and the Restless</Title>
<SeriesId>4422</SeriesId>
<KeepUntil>SpaceIsNeeded</KeepUntil>
<StartPadSeconds>0</StartPadSeconds>
<EndPadSeconds>0</EndPadSeconds>
<Frequency>EveryDay</Frequency>
<KeepAtMost>0</KeepAtMost>
<Priority>23</Priority>
<ShowType>Any</ShowType>
<AirtimeDomain>SpecificTime</AirtimeDomain>
<ChannelDomain>SpecificChannel</ChannelDomain>
<RPList>
...
Followed by:
ARRAY
(
[transactionResult] => stdClass Object
(
[id] => test
[resultCode] => 0
[ReadScheduledRecordingsRsp] => stdClass Object
(
[RecordingDefinitionList] => stdClass Object
(
[RecordingDefinition] => Array
(
[0] => stdClass Object
(
[RDId] => d8c16d8f-67c6-469a-83c3-d51d8f8859a9
[Title] => The Young and the Restless
[SeriesId] => 4422
[KeepUntil] => SpaceIsNeeded
[StartPadSeconds] => 0
[EndPadSeconds] => 0
[Frequency] => EveryDay
[KeepAtMost] => 0
[Priority] => 23
[ShowType] => Any
[RPList] => stdClass Object
(
...
I'm guessing I just forgot or didn't know to do something, but I don't know what. It's just very suspicious that the two fields that don't work are the two that were just added, but I can't find any place where the fields are enumerated.
The WSDL doesn't specify any fields at all, just that there will be a bunch of data inside a transactionResult.
In the connect call, the options likewise don't specify any fields.
It all worked fine until the back-end added those two fields, and it all still works fine, except that I can't see the 2 new fields in the object.
Any ideas?
It would be nice to see the XML for RPList. What version of PHP/libxml?
Have you actually validated the XML returned by __getLastResponse()?
It sounds to me like your using WSDL mode for the client but your WSDL file lacks precision. Try using a WSDL which actually describes the data being served up by the API.
Am I understanding that the $result object when dumped lists RPList but the value is not what you expect? If so you might be able to get away with adding the SOAP_SINGLE_ELEMENT_ARRAYS option to the clients constructor: new SoapClient($wsdl, array('features' => SOAP_SINGLE_ELEMENT_ARRAYS));. That's a long shot though. Need to see WSDL and full output from __getLastResponse().
Any errors? Try wrapping the call like so:
try {
$client = new SoapClient ('http://yoursite.com?WSDL',
array("trace" => 1,
"exceptions" => true,
"cache_wsdl" => WSDL_CACHE_NONE,
"features" => SOAP_SINGLE_ELEMENT_ARRAYS)
);
$result = $client->SomeMethod($data);
} catch (SoapFault $exception) {
var_dump($exception);
} catch (Exception $exception) {
var_dump($exception);
}
Short of fixing the WSDL/XML response your workaround seems like the best solution.

jQuery.parseJSON fails to parse valid json

load : function() {
var mastery = $('div.mastery.trees');
this.object = $.parseJSON($('a.json.data', mastery).text());
console.log(this.object);
}
this fails silently (unless i add a try/catch block around parseJSON) regardless of the content of the json data (the data i want to use - see below - or even just some very simple test data)
actual data
{"points":{"allowed":30,"current":0,"offense":0,"defense":0,"utility":0},"current":{"offense":{},"defense":{},"utility":{}},"trees":{"offense":{"Deadliness":{"max":3,"req":""},"Cripple":{"max":1,"req":""},"Plentiful_Bounty":{"max":1,"req":""},"Archmages_Savvy":{"max":3,"req":""},"Sorcery":{"max":4,"req":{"offense":4}},"Alacrity":{"max":4,"req":{"offense":4}},"Burning_Embers":{"max":1,"req":{"offense":8}},"Archaic_Knowledge":{"max":1,"req":{"offense":8,"Sorcery":4}},"Sunder":{"max":3,"req":{"offense":8}},"Offensive_Mastery":{"max":2,"req":{"offense":8}},"Brute_Force":{"max":3,"req":{"offense":12}},"Lethality":{"max":3,"req":{"offense":16}},"Improved_Rally":{"max":1,"req":{"offense":16}},"Havoc":{"max":1,"req":{"offense":20}}},"defense":{"Menders_Faith":{"max":1,"req":""},"Resistance":{"max":3,"req":""},"Preservation":{"max":1,"req":""},"Hardiness":{"max":3,"req":""},"Strength_of_Spirit":{"max":3,"req":{"defense":4,"Resistance":3}},"Evasion":{"max":4,"req":{"defense":4}},"Defensive_Mastery":{"max":2,"req":{"defense":8}},"Nimbleness":{"max":1,"req":{"defense":8,"Evasion":4}},"Harden_Skin":{"max":3,"req":{"defense":8,"Hardiness":3}},"Veterans_Scars":{"max":4,"req":{"defense":12}},"Willpower":{"max":1,"req":{"defense":12}},"Ardor":{"max":3,"req":{"defense":16}},"Reinforce":{"max":1,"req":{"defense":16}},"Tenacity":{"max":1,"req":{"defense":20}}},"utility":{"Spatial_Accuracy":{"max":1,"req":""},"Good_Hands":{"max":3,"req":""},"Perseverance":{"max":3,"req":""},"Haste":{"max":1,"req":""},"Awareness":{"max":4,"req":{"utility":4}},"Expanded_Mind":{"max":4,"req":{"utility":4}},"Greed":{"max":1,"req":{"utility":8}},"Meditation":{"max":3,"req":{"utility":8}},"Utility_Mastery":{"max":2,"req":{"utility":8}},"Insight":{"max":1,"req":{"utility":8}},"Quickness":{"max":3,"req":{"utility":12}},"Blink_of_an_Eye":{"max":1,"req":{"utility":12}},"Intelligence":{"max":3,"req":{"utility":16}},"Mystical_Vision":{"max":1,"req":{"utility":16}},"Presence_of_the_Master":{"max":1,"req":{"utility":20}}}}}
test data
{"json":1}
jsonlint.com tells me both of these data-sets are valid json so why wont it parse properly?
all the data comes from a php array thats converted via json_encode()
return array(
"points" => array( // for js
"allowed" => 30,
"current" => 0,
"offense" => 0,
"defense" => 0,
"utility" => 0,
),
"current" => array( // for js
"offense" => new stdClass,
"defense" => new stdClass,
"utility" => new stdClass,
),
"trees" => array(
"offense" => $offense, // the trees
"defense" => $defense,
"utility" => $utility,
),
);
been staring at it for a while and just cant see where the error would be coming from
does anyone have any ideas?
From your question:
a simple mistake being overlooked that i only picked up on when
checking the console.log as suggested by JamWaffles
the gist of it is this; var mastery is picking up 2 divs (the parent
that i want and the direct child which i dont) - and as both are
parents to the json data.. thats where the duplication comes from
silly
thanks jamwaffles!

Categories