Novell Home

Accessing the Groupwise Web Service using PHP

From Developer Community

By Bill Bodine

Contents

Introduction

This is a follow up article to GroupWise Client Development with Web Services that discussed using Java to access the Groupwise Web Service. In addition to focusing on PHP as the development language, I will try to touch on a few other aspects of using the Groupwise Web Service that I did not discuss in the previous article. I will use PHP5 for the purposes of this article. PHP4 can be used, but to do so you would need to use a 3rd party library like NuSoap to build the Soap packets needed for the Web Service. PHP5 has Soap and other libraries (the PHP5 DOM module for example) that prove to be very useful for developing a Web Service client.

I have built this companion [tutorial] that can be used to see specifically how to ensure that PHP5 is working properly on a SUSE Linux 10 machine. Additionally, the tutorial illustrates the setup of Apache2 and other interesting pieces of software, like tcpmon

Getting Started

PHP5 is installed very simply from the YaST console. The modules that are typically needed are:

  • php5 – this has the core modules
  • php5-devel – might not be as critical as the others, but has useful information libraries and tutorials
  • php5-dom – adds support for the Document Object Module (DOM). DOM is used to work with XML files
  • php5-soap – used to create SOAP clients and servers.
  • php5-zlib – used to read and write gzip compressed files
  • php5-doc – provides documentation for php5

Ordinarily, Apache2 is already installed on most SUSE Linux machines. However, it may be necessary to use the System Runlevel Editor to make sure that it is started when the system is initialized.

The Groupwise Web Service is downloaded from http://forge.novell.com/modules/xfmod/project?gwsoap.


Building the Application

This paper is designed to show how to perform the very simple task of accessing a users mailbox and reading selected mail messages. Future articles will delve in to other topics of interest. To read the users mail box you will need to:

  1. Authenticate to the system
  2. Query the service for the “mailbox” folder
  3. List the items contained by the “mailbox” folder
  4. Display a message for a specific mailbox item.

Authenticating to the Groupwise Web Service.

Following are examples of request and response documents used to perform this task.

loginRequest

<?xml version=”1.0” encoding=”UTF-8”?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV=”http://schemas.xmlsoap.org/soap/envelope/”
				xmlns:ns1=”http://schemas.novell.com/2005/01/GroupWise/methods”
				xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
				xmlns:SOAP-ENC=”http://schemas.xmlsoap.org/soap/encoding/”
				xmlns:ns2=”http://schemas.novell.com/2005/01/Groupwise/types”
				xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
					SOAP-ENV:encodingStyle=”http://schemas.xmlsoap.org/soap/encoding/”>
		<SOAP-ENV:Body>
			<ns1:loginRequest>
				<auth xsi:type=”ns2:PlainText”>
					<username xsi:type=”xsd:string”>demo1</username>
					<password xsi:type=”xsd:string”>ourpassword</password>
				</auth>
				<language xsi:type=”xsd:string”>us</language>
				<version xsi:type=”xsd:decimal”>1.0</version>
				<application xsi:type=”xsd:string”>OurTestApplication</application>
			</ns1:loginRequest>
		</SOAP-ENV:Body>

The only real critical element at this point of time is the <auth> element. For now, the service does not care what values are placed in the <language>, <version>, or the <application> elements. Following is an example of some PHP code snippets that can be used to build the document illustrated above. To view the complete code you can either access the related tutorial on the developer web site or download the accompanying source files.

	
...
	$gwservice = new GroupwiseService ( $_SESSION['location'] );

	/* $userName and $userPassword are retrieved from the user interface */
	$pt = array( “username” => $userName,
		     “password” => $userPassword );

	$lres = $gwservice->loginRequest($pt, “us”, “1.0”,  “OurTestApp”);
	...

GroupwiseService is a class that implements the SOAP calls that will be made to the Groupwise Web Service. The class constructor and loginRequest methods are shown below:

	
...
	class GroupwiseService {
		public $session;
		public $sc;

		public function GroupwiseService($location=”localhost”) {
			$this->sc = new SoapClient( NULL, array(
			“location” => $location,
			“uri” => “http://schemas.novell.com/2005/01/GroupWise/methods”,
			“trace” => true ) );
		}

		public function loginRequest($pt, $language, $version, $application) {
			$login = new SoapVar($pt, SOAP_ENC_OBJECT, “PlainText”, 
				“http://schemas.novell.com/2005/01/Groupwise/types”, “auth” );
			$lang = new SoapVar( $language, XSD_LANGUAGE, NULL, NULL, “language” );
			$ver = new SoapVar($version, XSD_DECIMAL, NULL, NULL, “version” );
			$app = new SoapVar($application, XSD_STRING, NULL, NULL, “application” );

			return $this->sc->__soapCall('loginRequest', array($login, $lang, $ver, $app));
		}
        }

The GroupwiseService constructor above instantiates a new SoapClient object. Notice that a NULL value is passed in as the first value to the constructor, indicating that non-WSDL mode is used. If we were using the WSDL mode for this class, the 'location' and 'uri' values could have come from the wsdl document rather than the command line or some other location. Since we are using non-WSDL mode for our SoapClient object we have used the SoapVar class to hold our data for the various calls.

The critical data used to construct the SoapVar object are: 1)The data value itself, 2)the encoding ID (XSD_STRING, XSD_DECIMAL, etc.), and 3)the element name expected by the Soap Server. The encoding ID is a constant defined within PHP itself. Many variables are able to be defined by well known types like integer, string, decimal, etc. Additionally, the SOAP_ENC_OBJECT is used to identify objects of a unique type. In the case of the loginRequest method the Groupwise server expects a structure passed in that contains the users authentication credentials. The URI that is passed in identifies a schema file that has types defined for a Web Service. This call is referencing a types document (found in the Groupwise NDK as the types.xsd file) that has defined a “PlainText” type. It is as follows:

	<xs:complexType name=”PlainText”>
		<xs:complexContent>
			<xs:extension base=”tns:Authentication”>
				<xs:sequence>
					<xs:element name=”username” type=”xs:string”/>
					<xs:element name=”password” type=”xs:string” minOccurs=”0”/>
				</xs:sequence>
			</xs:extension>
		</xs:complexContent>
	</xs:complexType>

It is by examining this structure that we see that a username and an optional password need to be passed in as values to the “auth” element.

loginResponse

<?xml version=”1.0” encoding=”UTF-8”>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle=”http://schemas/xmlsoap.org/soap/encoding/”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xmlns:SOAP-ENC=”http://schemas.xmlsoap.org/soap/encoding/”
xmlns:xsd=”http://www.w3.org/2001/XMLSchema”
xmlns:SOAP-ENV=”http://schemas.xmlsoap.org/soap/envelope/”>
			<SOAP-ENV:Body>
				<gwm:loginResponse
					xmlns:gwm=”http://schemas.novell.com/2005/01/GroupWise/methods”
					xmlns:gwt=”http://schemas.novell.com/2005/01/GroupWise/types”>
					<gwm:session>HeZ_xABzUnP_abav</gwm:session>
					<gwm:userinfo>
						<gwt:name>Demo1</gwt:name>
						<gwt:email>demo1@dmz1.provo.novell.com</gwt:email>
						<gwt:uuid>26A40000-078F-0000-BA12-12002D004V00</gwt:uuid>
					</gwm:userinfo>
					<gwm:gwVersion>7.0.1</gwm:gwVersion>
					<gwm:build>341</gwm:build>
					<gwm:serverUTCTime>2006-09-21T17:09:34Z</gwm:serverUTCTime>
					<gwm:status>
						<gwt:code>0</gwt:code>
					</gwm:status>
				</gwm:loginResponse>
			</SOAP-ENV:Body>
		</SOAP-ENV:Envelope>

Inspecting the SOAP document above gives you a good idea of the data that is returned from the Groupwise Web Service. The following depicts one of the ways that this data might be parsed and displayed in a table.

...
$lres = $gwservice->loginRequest($pt, “us”, “1.0”, “OurTestApp”);
?>
<table>
<tr>
<td>Username:</td>
<td><?php echo $lres['userinfo']->name; ?></td>
</tr>
<tr>
<td>EMail:</td>
<td><?php echo $lres['userinfo']->email; ?></td>
</tr>
<tr>
<td>Unique User ID:</td>
<td><?php echo $lres['userinfo']->uuid; ?></td>
</tr>
<tr>
<td>Session:</td>
<td><?php  echo $lres['session']; ?></td>
</tr>
<tr>
<td>Groupwise Version:</td>
<td><?php echo $lres['gwVersion']; ?></td>
</tr>
<tr>
<td>Status Return Code:</td>
<td><?php echo $lres['status']->code; ?></td>
</tr>
</table>
<?
...

Querying the service for the 'Mailbox' folder.

There are many folders that may contain items of interest. For this application we will be reading the contents of the “Mailbox” folder. Other folders of interest you may have seen in the Groupwise environment include “Sent Items”, “Notes”, “Calendar”, “Contacts”, etc.

We perform this query since we cannot retrieve the contents of a folder based on the folders name. We need to use it's system “id”. For this example, I will use the getFolderList method to list all the folders that reside below the topmost folder named “folders”. With the results of this query it becomes an easy task to search for the folder name “Mailbox” and to then store the needed “id”. Following is an example of a getFolderListRequest SOAP document and some PHP code that can be used to build the request.

getFolderListRequest

		<?xml version="1.0" encoding="UTF-8"?>
		<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
				xmlns:ns1="http://schemas.novell.com/2005/01/GroupWise/methods" 
				xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
				xmlns:ns2="http://schemas.novell.com/2005/01/GroupWise/types" 
				xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
				xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 
				SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
			<SOAP-ENV:Header>
				<ns2:session>I6Ut18fr0P7vrQz6</ns2:session>
			</SOAP-ENV:Header>
			<SOAP-ENV:Body>
				<ns1:getFolderListRequest>
					<parent xsi:type="xsd:string">folders</parent>
					<view xsi:type="xsd:string"></view>
					<recurse xsi:type="xsd:boolean">1</recurse>
					<imap xsi:type="xsd:boolean">0</imap>
					<nntp xsi:type="xsd:boolean">0</nntp>
				</ns1:getFolderListRequest>
			</SOAP-ENV:Body>
		</SOAP-ENV:Envelope>

In this document you will see a SOAP Header element that did not exist in the login request. Once the client has logged in to the service, each subsequent request must contain the session number in the SOAP Header. When you view the implementation of the getFolderListRequest method in the GroupwiseService class below, you will see how the header is inserted in our example.

Additional elements of note are the <view> element that is used to define those elements the service should send it's response. The idea being that if you really don't want all the information returned from the Web Service, you may insert a string of space delimited element names in the view element and the response will only return those elements. For example, we could put something like <view>id name</view> to be much more restrictive in our response document. The <recursive> element is used to signal whether the service should return the contents of the folder and all its subfolders (true), or just the immediate contents of the folder (false). Likewise, selecting true or false for the <imap> and <nntp> elements indicates if the response document should include imap and nntp messages in addition to the rest of the Groupwise items returned.

	$gwservice->session = $lres['session']; //return in the loginResponse document
	$_SESSION['gwsession'] = $gwservice->session;
	$folderListResponse = $gwservice->getFolderListRequest( “folders”, “”, true, false, false );

The GroupwiseService class implementation of the getFolderListRequest method is:

	public function getFolderListRequest( $sParent, $sView, $bRecurse, $bImap, $bNntp ) {
		$sh = new SoapHeader(“http://schemas.novell.com/2005/01/GroupWise/types”,
					“session”, $this->session );
		$parent = new SoapVar($sParent, XSD_STRING, NULL, NULL, “parent” );
		$view = new SoapVar($sView, XSD_STRING, NULL, NULL, “view” );
		$recurse = new SoapVar($bRecurse, XSD_BOOLEAN, NULL, NULL, “recurse” );
		$imap = new SoapVar($bImap, XSD_BOOLEAN, NULL, NULL, “imap” );
		$nntp = new SoapVar($bNntp, XSD_BOOLEAN, NULL, NULL, “nntp” );
		return $this->sc->__soapCall('getFolderListRequest', 
					array($parent, $view, $recurse, $imap, $nntp), 
					NULL, $sh );
	}

Note the inclusion of the SoapHeader element as was discussed earlier. The response document can be quite large depending on the system queried. Below are a few of the folders returned from a typical query.

getFolderListResponse

		<?xml version="1.0" encoding="UTF-8"?>
		<SOAP-ENV:Envelope 
				SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
				xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 
				xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
				xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
				xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
			<SOAP-ENV:Header/>
			<SOAP-ENV:Body>
				<gwm:getFolderListResponse 
					xmlns:gwm="http://schemas.novell.com/2005/01/GroupWise/methods" 
				xmlns:gwt="http://schemas.novell.com/2005/01/GroupWise/types">
					<gwm:folders>
						<gwt:folder 
						xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
						xsi:type="gwt:SystemFolder">
							<gwt:id>6.dom1.po1.1.0.1.0.1@5</gwt:id>
							<gwt:name>Demo1 User</gwt:name>
							<gwt:modified>2005-9-3T5:17:58Z</gwt:modified>
							<gwt:sequence>0</gwt:sequence>
							<gwt:isSystemFolder>1</gwt:isSystemFolder>
							<gwt:folderType>Root</gwt:folderType>
						</gwt:folder>
						<gwt:folder 
						xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
						xsi:type="gwt:SystemFolder">
							<gwt:id>1391.dom1.po1.100.0.1.0.1@72</gwt:id>
							<gwt:name>Notes</gwt:name>
							<gwt:modified>2006-6-2T5:02:20Z</gwt:modified>
							<gwt:parent>6.dom1.po1.1.0.1.0.1@5</gwt:parent>
							<gwt:sequence>0</gwt:sequence>
							<gwt:isSystemFolder>1</gwt:isSystemFolder>
							<gwt:folderType>Notes</gwt:folderType>
						</gwt:folder>
						<gwt:folder 
						xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
						xsi:type="gwt:SystemFolder">
							<gwt:id>7.dom1.po1.100.0.1.0.1@16</gwt:id>
							<gwt:name>Mailbox</gwt:name>
							<gwt:modified>2006-6-2T5:02:19Z</gwt:modified>
							<gwt:parent>6.dom1.po1.1.0.1.0.1@5</gwt:parent>
							<gwt:count>62</gwt:count>
							<gwt:sequence>2</gwt:sequence>
							<gwt:isSystemFolder>1</gwt:isSystemFolder>
							<gwt:folderType>Mailbox</gwt:folderType>
						</gwt:folder>
						<gwt:folder 
						xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
						xsi:type="gwt:SystemFolder">
							<gwt:id>19.dom1.po1.100.0.1.0.1@30</gwt:id>
							<gwt:name>Sent Items</gwt:name>
							<gwt:modified>2005-6-2T2:13:20Z</gwt:modified>
							<gwt:parent>6.dom1.po1.1.0.1.0.1@5</gwt:parent>
							<gwt:sequence>3</gwt:sequence>
							<gwt:isSystemFolder>1</gwt:isSystemFolder>
							<gwt:folderType>SentItems</gwt:folderType>
						</gwt:folder>
						...

The following PHP code can be used to save off the id of the Mailbox folder:

	...
	if ( $folderListResponse['status']->code == 0 ) {
		foreach ( $folderListResponse['folders']->folder as $folder ) {
			if ( $folder->name == “Mailbox” ) {
				$mailboxID = $folder->id;
				$_SESSION['mailboxid'] = $mailboxID;
				break;
			}
		}
	}
	...

List the items contained by the Mailbox folder

For our application we will build a table that displays three details about the items contained in the Mailbox folder: 1)the message creator, 2)the message subject, 3)the message creation date. Our application will use the getItems method to retrieve the desired information. Here is a typical getItemsRequest document.

getItemsRequest

		<?xml version="1.0" encoding="UTF-8"?>
		<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
				xmlns:ns1="http://schemas.novell.com/2005/01/GroupWise/methods" 
				xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
				xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 
				xmlns:ns2="http://schemas.novell.com/2005/01/Groupwise/types" 
				xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
				SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
			<SOAP-ENV:Header>
				<ns3:session>I6Ut18fr0P7vrQz6</ns3:session>
			</SOAP-ENV:Header>
			<SOAP-ENV:Body>
				<ns1:getItemsRequest>
					<container xsi:type="xsd:string">7.dom1.po1.100.0.1.0.1@16</container>
					<view xsi:type="xsd:string">default</view>
					<element xsi:type="ns2:FilterEntry">
						<op xsi:type="xsd:string">eq</op>
						<field xsi:type="xsd:string">source</field>
						<value xsi:type="xsd:string">received</value>
					</element>
					<item xsi:nil="1" xsi:type="ns2:ItemRefList"/>
					<count xsi:type="xsd:integer">100</count>
				</ns1:getItemsRequest>
			</SOAP-ENV:Body>
		</SOAP-ENV:Envelope>

This request has a few interesting fields. Note, of course, that the session number is included in the SOAP header. Additionally, we are including the <container> value. This is the 'Mailbox' id that was returned in the previous step. The <view> has a value of default, meaning that we just want some the typical attributes that define the item to be returned. Things like the item type, the item id, the creation date, the status of the item (opened, read, forwarded, accepted, etc.) Most specifically the thing to note is that the item message will not be returned. If we wanted the message to also be included we would have listed the value as: <view>default message</view>. Likewise, hidden messages are not returned unless the keyword 'hidden' is included in the view list. The NDK documentation lists other values that may be included in the view element.

In this example we have also included a FilterEntry element. This element is used to further refine what items we would like returned from our search. In our case, we have indicated that all “received” messages should be sent. By looking at the types.xsd document in the NDK, we can see that other options are: sent, draft, and personal. It is also possible to filter on the status of a document. For example, all items can be retrieved if they have been: accepted, completed, delegated, deleted, forwarded, opened, read, etc. This is an effective way to list just those items that are of the most interest to the application user.

The following code was used to generate the getListRequest SOAP document.

	$gwFilter = array(“op” => “eq”, “field” => “source”, “value” => “received” );

	$getItemsResponse = $gwservice->getItemsRequest( $mailboxID, 
								“default”, $gwFilter, null, 100 );

The GroupwiseService class is as follows:

	public function getItemsRequest($sContainer, $sView, $aFilterEntry, $aItems, $iCount) {
		$sh = new SoapHeader(“http://schemas.novell.com/2005/01/GroupWise/types”,
					“session”, $this->session );
		$container = new SoapVar( $sContainer, XSD_STRING, NULL, NULL, “container” );
		$view = new SoapVar($sView, XSD_STRING, NULL, NULL, “view” );
		$filter = new SoapVar($aFilterEntry, SOAP_ENC_OBJECT, “FilterEntry”,
					“http://schemas.novell.com/2005/01/Groupwise/types”, “element” );
		$items = new SoapVar($aItems, SOAP_ENC_OBJECT, “ItemRefList”, 
					“http://schemas.novell.com/2005/01/Groupwise/types”, “item” );
		$count = new SoapVar($iCount, XSD_INTEGER, NULL, NULL, “count” );
		return $this->sc->__soapCall( 'getItemsRequest',
						array($container, $view, $filter, $items, $count ),
						NULL, $sh );
	}

A lot of information is given as a response to this request. Rather than include an entire response document, the following is an example of the elements that are returned.

getItemsResponse

			<items> 
				<item type="Mail"> 
					<id>some id</id> 
					<version>3</version> 
					<modified>2006-09-07T22:44:53Z</modified> 
					<container>some parent container id</container> 
					<created>2006-09-07T21:19:47Z</created> 
					<status> 
						<opened>1</opened> 
						<read>1</read> 
					</status> 
					<source>received</source> 
					<delivered>2006-09-07T21:19:47Z</delivered> 
					<security>Normal</security> 
					<subject>Attachment attached</subject> 
					<distribution> 
						<from> 
							<displayName>Some user</displayName> 
							<email>someUser@here.com</email> 
							<uuid>some user id</uuid> 
						</from> 
						<to>some destination user</to> 
						<sendoptions> 
							<statusTracking>None</statusTracking> 
						</sendoptions> 
					</distribution> 
					<options> 
						<priority>Standard</priority> 
					</options> 
					<hasAttachment>1</hasAttachment> 
					<size>1801</size> 
				</item> 
			</items> 
			<status> 
				<code>0</code> 
			</status> 

The PHP code used to parse this response document is not really any different to how we have done it in the past. Since we have installed the PHP-dom module we are able to parse XML documents as if they are individual class objects.

Display a message for a specific mailbox item.

Now that we have displayed a table listing all the mail messages that we might be interested in, it is time to allow the user to view the actual mail message. The getItem method will be used for this purpose. This method is very similar to the getItems method, with the primary difference being that we are identifying the specific message to return rather than all the messages in a given folder.

getItemRequest

		<?xml version="1.0" encoding="UTF-8"?>
		<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
				xmlns:ns1="http://schemas.novell.com/2005/01/GroupWise/methods" 
				xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
				xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 
				xmlns:ns2="http://schemas.novell.com/2005/01/Groupwise/types" 
				xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
				SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
			<SOAP-ENV:Header>
				<ns3:session>I6Ut18fr0P7vrQz6</ns3:session>
			</SOAP-ENV:Header>
			<SOAP-ENV:Body>
				<ns1:getItemRequest>
					<id xsi:type=”xsd:string”>444447.dom1.po1.100.0.1.0.1@16</container>
					<view xsi:type="xsd:string">default message</view>
				</ns1:getItemsRequest>
			</SOAP-ENV:Body>
		</SOAP-ENV:Envelope>

This request will return everything the getItemsRequest method did previously. It will also return the item's message since we have placed the message identifier in the <view> element. The PHP code for this method is as follows:

	...
	$getItemResponse = $gwservice->getItemRequest( $_GET['id'], “default message” );
	...

The GroupwiseService class for this method is:

	public function getItemRequest( $sId, $sView ) {
		$sh = new SoapHeader( “http://schemas.novell.com/2005/01/GroupWise/types”,
					“session”, $this->session );
		$id = new SoapVar( $sId, XSD_STRING, NULL, NULL, “id” );
		$view = new SoapVar( $sView, XSD_STRING, NULL, NULL, “view” );
		return $this->sc->__soapCall('getItemRequest',
						array($id, $view), NULL, $sh );
	}

The response to this document is very similar to the response for the getItems method. The primary difference here is that we have requested the item's message. So the response document will have the following, in addition to all the elements in the previous response. getItemResponse

		...
		<gwt:message>
			<gwt:part contentType=”text/plain” length=”32”>VGhpcyefieifaIGTasdfe13</gwt:part>
		</gwt:message>
		...

The document is parsed the same way the other documents have been parsed. The primary distinction, however, is that since the message is base64 encoded, we need to decode the message for the user to be able to read it. For this example, the following was used to decode the message:

	...
	<td><?echo base64_decode($mailItem->message->part);?></td>
	...

Summary

The idea of this article is to show how a GroupWise client can be developed using the GroupWise Web Service NDK. PHP was used as the development language and a number of sample XML SOAP documents have been shown to illustrate how the data data needs to be structured as it is transferred to the Web service. Hopefully, even though the example was a simple client that reads email, it will be enough to help anyone who has the documentation see how they might use the other features of the Web Service for a more complete client.

Novell® Making IT Work As One

© 2008 Novell, Inc. All Rights Reserved.