Zimbra offers Open Source email server software and shared calendar for Linux and the Mac
Go Back   Zimbra :: Forums > Zimbra Collaboration Suite > Developers

Welcome to the Zimbra :: Forums!
Welcome, if you would like to post a comment please register. We also encourage you to explore all things Zimbra with our team and members of the community.

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old 04-28-2010, 09:57 AM
Moderator
 
Posts: 7,911
Default [SOLVED] PHP SOAP XML Decode

Is there a easy way in PHP to decode the XML that comes back from a SOAP request into reference arrays ?
Code:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><context xmlns="urn:zimbra"><change token="12345"/></context></soap:Header><soap:Body><SearchResponse more="0" sortBy="dateDesc" offset="0" xmlns="urn:zimbraMail"><cn fileAsStr="Contact, Test" id="206622" rev="558980" d="1272466487000" sf="1272466487000" l="7"><a n="lastName">Contact</a><a n="company">A Nice Company</a><a n="workPhone">12345</a><a n="firstName">Test</a><a n="jobTitle">Some Fun Job</a></cn></SearchResponse></soap:Body></soap:Envelope>
Using a PHP function I found it turns the above SOAP XML response into the following array which is pretty hard to work on
Code:
Array
(
    [a] => Array
        (
            [0] => Contact
            [1] => A Nice Company
            [0_attr] => Array
                (
                    [n] => lastName
                )

            [1_attr] => Array
                (
                    [n] => company
                )

            [2] => 12345
            [2_attr] => Array
                (
                    [n] => workPhone
                )

            [3] => Test
            [3_attr] => Array
                (
                    [n] => firstName
                )

            [4] => Some Fun Job
            [4_attr] => Array
                (
                    [n] => jobTitle
                )

        )

)
Any pointers would be gratefully appreciated; even if the response is switch to JSON instead of XML.
__________________
Reply With Quote
  #2 (permalink)  
Old 04-28-2010, 05:46 PM
Outstanding Member
 
Posts: 703
Default

For PHP, JSON is a whole lot easier and less of a headache. Results will come back to you already in an associative array.
Reply With Quote
  #3 (permalink)  
Old 04-29-2010, 02:41 AM
Moderator
 
Posts: 7,911
Default

Thanks ... would you care to share a little bit of code for how to construct a JSON request in PHP please ?
__________________
Reply With Quote
  #4 (permalink)  
Old 04-29-2010, 05:19 AM
Moderator
 
Posts: 7,911
Default

Krishopper, I tried something like this
Code:
$params = array ('Header','context','_jsns' => 'urn:zimbraAccount','Body','AuthRequest','_jsns' => 'urn:zimbra','account' => 'uxbod@domain.com','preauth' => 'timestamp=' . "$timestamp" . '" expires="0"' . $preauthToken);

        try
        {
                $zimbraSession = $client->__soapCall(NULL, json_encode($params), NULL);

        } catch (SoapFault $exception) { echo "Failed : $exception\n\n"; }
Though it falls in a heap due to the second element of the soapCall requiring an array. A little example would be very appreciative please ?
__________________
Reply With Quote
  #5 (permalink)  
Old 04-29-2010, 02:14 PM
Outstanding Member
 
Posts: 703
Default

I have a larger Zimbra class that I created, but am not quite ready to share with the world, so here are bits and pieces to get an AuthTok and create an account. Hope it helps.

Code:
$adminUser = "user@host.com";
$adminPass = "password";
$adminServer = "zenoss.example.com";

// Auth to the server and get auth token
$data = array(
    "Header" => array(
        "_jsns" => "urn:zimbra",
        "session" => null,
    ),
    "Body" => array(
        "AuthRequest" => array(
            "_jsns" => "urn:zimbraAdmin",
            "name" => $adminUser,
            "password" => $adminPass,
        ),
    ),
);

$ret = dorequest($data);
$authtok = $ret['authToken'][0]['_content'];


    /********************************************************************
     * Zimbra: CreateAccountRequest
     * arr = array(
     *     'name' => email address to create
     *    'password' => password to set on new account
     * );
     */

function zimbra_CreateAccountRequest($authtok, $arr) {
    $data = array(
         "Header" => array(
              "context" => array(
                   "_jsns" => "urn:zimbra",
                   "authToken" => array(
                        "_content" => $authtok,
                   ),
              ),
         ),
         "Body" => array(
              "CreateAccountRequest" => array(
                   "_jsns" => "urn:zimbraAdmin",
              ),
         ),
    );

    foreach ($arr as $key => $val) {
        if ($key == 'a') {
            $data['Body']['CreateAccountRequest'][$key] = $val;
        } else {
            $data['Body']['CreateAccountRequest'][$key] = 
                array('_content' => $val);
        }
    }
    
    print_r($data);
    $acct = array();
    $rv = $dorequest($data);
    return $rv;
}



function dorequest($data, $admin=true, $strip=true) {
    $js = json_encode($data);
    $url = ($admin ?
        sprintf("https://%s:7071/service/admin/soap/", $adminServer) :
        sprintf("https://%s/service/soap/", $adminServer)
    );

    $ch = curl_init();

    $options = array(
        CURLOPT_URL => $url,
        CURLOPT_POST => 1,
        CURLOPT_POSTFIELDS => $js,
        CURLOPT_HEADER => false,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_RETURNTRANSFER => true,
    );

    curl_setopt_array($ch, $options);
    $output = curl_exec($ch);
    curl_close($ch);

    if ($output === false) { print curl_error($ch); }

    $outputarr = json_decode($output);
    $arr = $this->object2array($outputarr);

    if (!$strip) { return $arr; }
    $arr = array_shift($arr['Body']);
    return $arr;

}
Reply With Quote
  #6 (permalink)  
Old 04-30-2010, 01:33 AM
Moderator
 
Posts: 7,911
Default

Krishopper, many thanks for that I believe I am so close now! When formatting the preauth using a non admin account I am ending up with an array that looks like
Code:
Array
(
    [Header] => Array
        (
            [_jsns] => urn:zimbraAccount
        )

    [Body] => Array
        (
            [AuthRequest] => Array
                (
                    [_jsns] => urn:zimbraAccount
                    [account] => uxbod@domain.com
                    [preauth timestamp=1272612560000 expires=0] => Array
                        (
                            [_content] => 525b9ace76ac211077032e404c695b93ff00ee12
                        )

                )

        )

)
Does that looks right ? I know that if you were doing it via XML the preauth field should look like
Code:
<preauth timestamp="1272612560000" expires="0">525b9ace76ac211077032e404c695b93ff00ee12</preauth>
And I am thinking that my array for JSON encoding is not quite right yet ?
__________________
Reply With Quote
  #7 (permalink)  
Old 04-30-2010, 02:38 AM
Moderator
 
Posts: 7,911
Default

Worked it out Krishopper, and using curl is definately a better option than SoapClient! Thank you so so much for your help it has been very appreciated
__________________
Reply With Quote
  #8 (permalink)  
Old 04-30-2010, 06:51 AM
Outstanding Member
 
Posts: 703
Default

No problem - and CURL + JSON does make it a whole heck of a lot easier in PHP. It almost seems too easy. I fought with SOAP+PHP for a while and then noticed that Zimbra supported JSON after reading soap.txt and soap-admin.txt in the doc directory, gave it a try, and was on my happy way.
Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes


Similar Threads

Why Join?

Registering let's you ask questions, makes it easier to search, displays any files attached to posts, and notifies you about replies.

blog.zimbra.com




 

SEO by vBSEO ©2011, Crawlability, Inc.