Friday, April 19, 2013

How to get all Calendar Names for a Zimbra Mail user using SOAP


I came across such a requirement while working on a project which uses Zimbra Mail Server ( version 7.0 ). I spent hours searching for a proper example or documentation on how to do this.In spite of spending so many hours i couldn't find any proper example at all. However i managed to find out how to do this by trial and error method. So i thought it would be good to share how i did it with all.

Note: Soap extension should be enabled in your web server.

Now you can try the following code to get list of all calendars in a user account.


 <?php  
      function xml2array ( $xmlObject, $out = array () )  
      {  
           foreach ( (array) $xmlObject as $index => $node )  
                $out[$index] = ( is_object ( $node ) ) ? xml2array ( $node ) : $node;  
           return $out;  
      }  
   $client = new SoapClient(null,  
     array(  
       'location' => "YOUR ZIMBRA SOAP URL",  
       'uri' => "urn:zimbraAccount",  
       'trace' => 1,  
       'exceptions' => 1,  
       'soap_version' => SOAP_1_1,  
       'style' => SOAP_RPC,  
       'use' => SOAP_LITERAL  
     )  
   );  
   echo "Client Built<br>";  
      //Provide username (eg. mm@zimbra.testdomain.com) and password       
      $var = new SoapVar('<account by="name">mm@zimbra.testdomain.com</account><password>mmr123c</password>', XSD_ANYXML);            
      $params = array(  
                $var,  
                );                 
   echo "Params built<br>";  
   try {  
     echo "Creating header<br>";  
     $soapHeader = new SoapHeader(  
           'urn:zimbraAccount',  
           'context'  
           );  
     echo "Authorizing<br>";      
     $result = $client->__soapCall(  
           "AuthRequest",   
           $params,   
           null,  
           $soapHeader  
     );  
     echo "Authorized<br>";    
           $authToken=$result['authToken'];  
     //print_r($result);  
                try {  
                     echo "Trying to get Folders<br>";  
                     $soapHeader = new SoapHeader(  
                                    'urn:zimbraMail',  
                                    'context',  
                                         new SoapVar(  
                                              '<ns1:context><format type="xml" /></ns1:context>',  
                                              XSD_ANYXML  
                                         )                                     
                                    );  
                     $result = $client->__soapCall(  
                                    "GetFolderRequest",   
                                    array(''),   
                                    array('uri' => 'urn:zimbraMail'),  
                                    $soapHeader  
                     );  
                     echo "Got folder info<br>";    
                     $xml = new SimpleXMLElement($client->__getLastResponse());  
                     $xml->registerXPathNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');  
                     $body = $xml->xpath('//soap:Body');  
                     $xml->registerXPathNamespace('zimbra', 'urn:zimbraMail');  
                     $GetFolderResponse = $xml->xpath('//soap:Body/zimbra:GetFolderResponse');  
                     $folder = $GetFolderResponse[0]->folder;  
                     $folder->registerXPathNamespace('zimbra', 'urn:zimbraMail');  
         $appointments = $folder->xpath('zimbra:folder[@view="appointment"]');  
                     $links = $folder->xpath('zimbra:link[@view="appointment"]');  
                     //print_r($appointments);  
                     //print_r($links);  
                     $appointments = xml2array ( $appointments, $out = array () );  
                     $links = xml2array ( $links, $out = array () );  
                     echo "<pre/>";  
                     print_r($appointments);  
                     print_r($links);  
                     //echo htmlentities($client->__getLastRequest()) . "<br><br>";  
         //echo htmlentities($client->__getLastResponse()) . "<br><br>";  
                } catch (SoapFault $exception) {  
                     echo "exception caught while trying to fetch Folder info<br><br>";  
                     //echo htmlentities($client->__getLastRequest()) . "<br><br>";  
                  // echo htmlentities($client->__getLastRequestHeaders()) . "<br><br>";  
                  // echo htmlentities($client->__getLastResponseHeaders()) . "<br><br>";  
                     echo htmlentities($client->__getLastResponse()) . "<br><br>";  
                     //echo $exception . "<br><br>";  
                }  
   } catch (SoapFault $exception) {  
     echo "exception caught while trying to authorize<br><br>";  
     //echo htmlentities($client->__getLastRequest()) . "<br><br>";  
     // echo htmlentities($client->__getLastRequestHeaders()) . "<br><br>";  
     //echo htmlentities($client->__getLastResponseHeaders()) . "<br><br>";  
     echo htmlentities($client->__getLastResponse()) . "<br><br>";  
     //echo $exception . "<br><br>";  
   }  
 ?>  

3 comments:

Unknown said...
This comment has been removed by the author.
Unknown said...

Ty for sharing.

Tim said...

I'm trying to pass the required s and e parameters for the GetFreeBusyRequest method, but when I add them inline, such as

$result = $client->__soapCall(
'GetFreeBusyRequest s="000", e="000"',
... );

I get an error that the method is missing the closing ">." Where/how do I properly pass these additional parameters?

Thanks for sharing your work, and any help you might be able to offer on this.