views:

185

answers:

5

The problem:
I am about to develop a Drupal site for a company that stores a lot of data in a sharepoint environment (products, recipes etc...). I need to get that information into my Drupal system somehow. Preferably saving it as drupal nodes.
That information will also be edited/added in the sharepoint system, so on top of just saving the data to drupal it will also have to check for updates on a regular basis.

One idea for a solution is using some sort of web-service to retrieve data, but i have no idea of how that would be done in drupal.

So my question(s) is: Has anyone done anything like this, if so how, or does anyone have any suggestions to how one would go about doing this?

Any answers would be highly appreciated.

/Anders

+1  A: 

Sharepoint saves data in an MS SQL database, right? A coworker of mine wrote up a good outline of the process we used in moving data from MS SQL to Drupal.

Scott Reynen
A: 

You could definitely talk to it via web services. We have connected a Drupal site into MS Great Plains before.

Kevin
+2  A: 

I strongly recommend taking a close look at the FeedAPI module and it's extensions.

I've used it successfully:

  • 'out-of-the-box' for node creation from RSS feeds
  • with slight modifications for node creation from the contents of a Webservice
  • as a blueprint/example for a custom module implementation that creates nodes from the content of another Webservice (some very special needs there that called for a custom solution)

If, as it sounds, you have some control over the way the sharepoint data gets exposed, you should be able to use FeedAPI successfully without any modifications at all, but maybe you'll need to implement your own parser extension (again, check the additional modules already written to extend FeedAPI for examples, if not solutions).

Henrik Opel
Good suggestion. I tried the upgraded version of FeedAPI (just called Feeds), and it's almost exactly what i was looking for. The only problem is that i need it to parse an XML feed. It handles RSS/atom and CSV, but not XML. If you (or anyone) knows a way to get it to create nodes from an XML, that would help me so much. Thank you very much anyway. /Anders
andersandersson666
@andersandersson666: RSS and ATOM feeds are XML already, so you're not looking for a way to create nodes 'from XML in general', but rather to create nodes 'from XML according to the schema of your Webservice output'. That's what my last paragraph is aiming at - you could either try to configure your sharepoint server to offer the content in a format that FeedAPI understands, or you'll need to implement a custom parser plug-in for the FeedAPI module that 'understands/translates' the XML currently offered by your Webservice.
Henrik Opel
A: 

SharePoint by default exposes webservices. If you have access to the items in the SharePoint website , you should also be able to access them by using the webservices. Keep in mind to pass the correct user credentials when accessing the webservices from code.

If you only need readaccess in Drupal you can also use rss feeds. It might be a bit harder with rss feeds to filter, sort or find a specific item.

Reading directly from the database is not recommended since Microsoft does not guarantee that the dataschema wil remain the same between software updates.

W0ut
+1  A: 

We have done this on many web services we have set up, and will soon be doing this for Sharepoint as well. As you say, you can get the data in XML. So you just need to 1) Retrieve the XML data 2) Parse the XML data 3) Return the now readable data in a block in Drupal

For 1 you need to open any firewall access and provide a publicly readable XML feed or set it only accessible by the IP of the Drupal server or some other authentication mechanism. For 2PHP gives you many options on how to parse the XML. We created one module to handle the XML service, and then we call it from another module which handles the display, theme, etc. Below I'll provide first an example of two functions from the XML module, and then an example of how you might use it in another module.

Here is from the XML module.

/**
 * Retrieving XML data from the URL
 * 
 * @param $url
 *    The url to retrieve the data
 * @param $replace_special_characters
 *   Replace special character to HTML format
 *   
 * @return parse result as struct 
 */
function xmlservice_parse($url, $replace_special_characters = FALSE) {
    $http_contents = drupal_http_request($url);
    if (!isset($http_contents->data)) {
        throw new RuntimeException("Cannot get contents from the URL");
    }//if

    if($replace_special_characters)
        $http_contents_data = str_replace('&','&', $http_contents->data);
    else
        $http_contents_data = $http_contents->data;

    $xml_parser = xml_parser_create();
    xml_parse_into_struct($xml_parser, $http_contents_data, $result);
    xml_parser_free($xml_parser);

    return $result;
}

/**
 * Retrieving XML data as Dom document from the URL
 * 
 * @param $url
 *    The url to retrieve the data
 * @param $replace_special_characters
 *   Replace special character to HTML format
 * 
 * @return result as Dom Document
 */
function xmlservice_parse_to_dom($url, $replace_special_characters = FALSE) {
    $http_contents = drupal_http_request($url);
    if (isset($http_contents->error)) {
        throw new RuntimeException($http_contents->error);
    }//if
    if (!isset($http_contents->data)) {
        throw new RuntimeException("Cannot get contents from the URL");
    }//if

    if($replace_special_characters){
        $http_contents_data = str_replace('&','&', $http_contents->data);
    }//if
    else{
        $http_contents_data = $http_contents->data;
    }//else

    $dom_document = new DomDocument;
    /* load htmlinto object */
    $dom_document->loadXML($http_contents_data);
    /* discard white space */
    $dom_document->preserveWhiteSpace = false;

    return $dom_document;
}

Then just write your code to create a block. If you don't know how to do that, check out http://www.nowarninglabel.com/home/creating-a-new-custom-module-in-drupal-6 which creates a simple block. Then for the content you can just call one of the above functions on a XML document, for instance $content = xml_service_parse('http://sharepoint.example.com/some/thing/feed.xml');

If you want to parse into a node, you could just use the XML function but instead use node_save() to programmatically create a node: http://api.drupal.org/api/function/node_save I haven't looked too much at the Sharepoint services available yet, but you could probably just parse the XML into a dom document like shown above and then do a loop through it creating a node for each XML node that matches your criteria.

And if you wanted more of the work done for

Hope that was helpful. Feel free to ask for more detail.

nowarninglabel