Hello Sharepoint, Meet PHP

(2009)

I am not a huge fan of Sharepoint, but we are starting to use it at work and it does do certain things well.

Trying to make Sharepoint do something non-obvious can be a lot of fun, especially on a slow day.

So I was trying to create a simple feedback form that would be stored by Sharepoint as a List. While this is well within Sharepoint's capabilities, it ends up being kind of a pain. You end up either creating a custom WebPart or designing something in InfoPath or writing ASP code. None of these options really appeals to me, mostly because I don't know much about Sharepoint and I don't have priviledges to deploy code on the server. Luckily most of the Sharepoint API is exposed through Web Services. Just make a PHP-backed webpage, produce the XML and fire it off to Sharepoint - no problem, right?

Unfortunately, this is easier said than done. SOAP is typically an all-or-nothing proposition. You don't “kind of” get a response, you either get success or an opaque error message.

I spent the better part of a morning piecing this together from a zillion blog posts. There are two big tricks - getting the XML right and using NTLM authentication.

This code sample requires the NuSOAP library for PHP - you could also do it with PHP's native SOAP I suppose. You will need to have a fairly recent version of CURL to get the NTLM authentication.

<?php
/* Requires the NuSOAP library */
require_once('lib/nusoap.php');

/*  Your username and password, separated by a colon
 Domain may be optional, depending on your setup */
$auth = "domainusername:password";

/*  Location of the Lists.asmx file
 If the list is in a subsite, the subsite must be in the path */
$wsdl = "http://domain.com/some-site/some-subsite/_vti_bin/Lists.asmx?WSDL";

/*  GUID of the list */
$guid = "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}";

/* Setup NuSOAP
Sharepoint requires NTLM Authorization
You need a fairly recent version of CURL installed for this */
$client = new soapclient($wsdl, true);
$client->setCredentials("","","ntlm");
$client->setCurlOption(CURLOPT_USERPWD, $auth);

/*  XML for the request, add extra Fields as necessary */
$xml =
'
<UpdateListItems xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<listName>'.$guid.'</listName>
<updates>
<Batch>
<Method ID="1" Cmd="New">
<Field Name="Title">My Title</Field>
<Field Name="ABC">My Value</Field>
</Method>
</Batch>
</updates>
</UpdateListItems>
';

/* Invoke the Web Service */
$result = $client->call('UpdateListItems', $xml);

/* Check for Errors */
if(isset($fault)) {
echo("<h2>Error</h2>". $fault);
}

/* Debugging Info */
echo("<h2>Request</h2>" . htmlspecialchars($client->request, ENT_QUOTES));
echo("<h2>Response</h2>" . htmlspecialchars($client->response, ENT_QUOTES));
echo("<h2>Debug</h2>" . htmlspecialchars($client->debug_str, ENT_QUOTES));

unset($client);
?>

That's pushing data into Sharepoint. You can also pull data using the GetListItems Web Service. The code is basically the same with different XML.