31 januari, 2012

PHP: Solution: Access Websitepanel 1.2.0 Hosting API with PHP nusoap - AddUser error - Object reference not set to an instance of an object

Swedish/svenska
Notis: Denna artikel är skriven på engelska för att det är många utländska prorgrammerare som har problem med Websitepanel och dess API. Därför bestämde jag att skriva den på engelska, dels för att hjälpa mig själv och att dela med mig av kunskapen om hur jag löste problemet till alla som söker efter en lösning på problemet.


Some words about this article
I wrote this article/guide because I'm developing a PHP API for Websitepanel using NuSOAP instead of PHP SOAP extension, and I encountered big problems yesterday and this morning. I want to share my solution and show everyone how I solved it.

The problem
When you use PHP to add a new user with the API function AddUser in esUsers.asmx then most of you will encounter problems and get an error like the following:

Object reference not set to an instance of an object

I pulled my hair, I read the specification, I read examples, I googled for a solution but every solution I found was someone saying he/she solved it by switching to PHP's SOAP extension and not using NuSOAP, and they didn't even publish the solution in code. Why oh why. This made it even more difficult. And I'm not the kind of guy that asks questions i forums - I search before I ask.

Debugging
I tried to output NuSOAP debugging information but that was a smack in the face - too much information and it almost looks the same everywhere, and I don't know where to look. A bit further down in the output I saw some trail of what could be wrong, but I already knew that one parameter was not valid, because it was not working. So continuing with the documentation...

Documentation
What about the documentation for the API, you say? It's kind of incomplete and only has a small working example and including information about how to add a new user but not how to use it in code. The documentation only describes the parameters and their values.

Solution?
I found the solution and I could not believe it - it was so simple but at the same time very unclear and frustrating. I should also say that UserExists works without any problems.

Here is code that does not work and almost everyone that tried to solve this in forums on the Internet used the following code.

PHP:
$param = array(
'OwnerId' => "1", // Owner of the account
'RoleId' => "3", // User
'StatusId' => "1", // Active
'IsDemo' => "false",
'IsPeer' => "false",
'Username' => "testuser",
'Password' => "123456abc!",
'Firstname' => "Testfirst",
'Lastname' => "Testlast",
'Email' => "test@test.com",
);

// This code does NOT work!!
$wsp->call('AddUser', array('parameters' => $param),
'http://smbsaas/websitepanel/enterpriseserver',
'http://smbsaas/websitepanel/enterpriseserver/AddUser');
But then I read the specs one more time slowly and focusing on the documentation at the same time. Then I noticed what was wrong.

Here is the SOAP XML specification:
<s:element name="AddUser">
<s:complextype>
<s:sequence>
<s:element minoccurs="0" maxoccurs="1" name="user" type="tns:UserInfo">
<s:element minoccurs="1" maxoccurs="1" name="sendLetter" type="s:boolean">
</s:element></s:element></s:sequence>
</s:complextype>
</s:element>
Can you see that there are 2 named parameters called "user" and "sendLetter"? That means that the call to AddUser requires a multidimensional array, where the index named "user" shall be assigned the array that contains the user details.

In the documentation it says the following:
"All other fields of the 'user' parameter are optional.
Also you may decide to set 'sendLetter' parameter to 'true' if you would like to send user registration notification."

I first thought that the user details array also could include an index called sendLettter but now I know that it should be completly separate.

Ok, here is the solution
The following code does the trick :)

PHP:
$param = array(
'OwnerId' => "1", // Owner of the account
'RoleId' => "3", // User
'StatusId' => "1", // Active
'IsDemo' => "false",
'IsPeer' => "false",
'Username' => "testuser",
'Password' => "123456abc!",
'Firstname' => "Testfirst",
'Lastname' => "Testlast",
'Email' => "test@test.com",
);

// SOLUTION: Create multidimensional array as
// parameter to follow the SOAP XML specification
$user = array(
'user' => $param
// 'sendLetter' => true
);

// This code DOES work!!
$wsp->call('AddUser', array('parameters' => $user),
'http://smbsaas/websitepanel/enterpriseserver',
'http://smbsaas/websitepanel/enterpriseserver/AddUser');
Perfect!

In my Websitepanel Audit log I saw the following information:
Information 1/31/2012 9:19 AM 9:19 AM User Add test1 adminuser

I hope that you really get this working. And have a nice day

Happy programming

// Waschman

Välkomna till bloggen

Välkomna ska ni vara kära besökare. Jag skriver om IT för att det är kul och för att jag vill dela med mig av information och kunskap. Jag försöker hålla bloggen så kategoriserad som möjligt för att ni enklare ska hitta intressanta länkar och artiklar.