Results 1 to 10 of 12

Thread: [SOLVED] Simple SOAP Admin Example In PHP

Hybrid View

  1. #1
    Join Date
    Jul 2007
    Location
    Peoria, IL
    Posts
    11
    Rep Power
    8

    Default [SOLVED] Simple SOAP Admin Example In PHP

    I have been reading through the posts like mad and looked all over Google but I can't find a super simple stripped down PHP example of how to add an account to Zimbra via SOAP *with* actual PHP source code. This would be a really great addition to the Wiki that once I get something actually working I would be happy to add to it so other people don't have all the wasted time I have looking for something that just doesn't exist.... Anyway, enough ranting Anyway, I don't know jack about SOAP in PHP and I'm doing my best to guess my way through this with little luck. I'm sure all I am missing is something really silly but I just can't seem to get this working. Can someone please enlighten me as to what I am doing wrong? Thanks in advance!

    Here is my PHP script:
    PHP Code:
    <?PHP
            $client 
    = new SoapClient(NULL,
                    array
                    (
                            
    "location" => "https://mail.myzimbrasever.com/service/soap/",
                            
    "uri"      => "urn:zimbra"
                    
    )
            );

            print(
                    
    $client->__call("AuthRequest",
                            array
                            (
                                    new 
    SoapParam("admin""name"),
                                    new 
    SoapParam("mypass""password")
                            ),
                            array
                            (
                                    
    "uri"           => "urn:zimbra",
                                    
    "soapaction"    => "urn:zimbra#AuthRequest"
                            
    )
                    )
            . 
    "\n");

    ?>
    And here is my completely useless output:
    Code:
    <br />
    <b>Fatal error</b>:  Uncaught SoapFault exception: [HTTP] Could not connect to host in /mnt/Web/htdocs/SOAP/soap.php:22
    Stack trace:
    #0 [internal function]: SoapClient-&gt;__doRequest('&lt;?xml version=&quot;...', 'https://mail.myzim....', 'urn:zimbra#Auth...', 1, 0)
    #1 /mnt/Web/htdocs/SOAP/soap.php(22): SoapClient-&gt;__call('AuthRequest', Array, Array)
    #2 {main}
      thrown in <b>/mnt/Web/htdocs/SOAP/soap.php</b> on line <b>22</b><br />

  2. #2
    Join Date
    Jul 2007
    Location
    Peoria, IL
    Posts
    11
    Rep Power
    8

    Default

    OK, I have made a little bit of progress...well I think anyway:

    PHP Code:
    <?PHP
            $client 
    = new SoapClient(NULL,
                    array
                    (
                            
    "location" => "https://mail.myzimbraserver.com:7071/service/soap/",
                            
    "uri"      => "urn:zimbra"
                    
    )
            );

            print(
                    
    $client->__call("AuthRequest",
                            array
                            (
                                    new 
    SoapParam("admin""name"),
                                    new 
    SoapParam("mypass""password")
                            ),
                            array
                            (
                                    
    "uri"           => "urn:zimbraAdmin",
                                    
    "soapaction"    => "urn:zimbraAdmin#AuthRequest"
                            
    )
                    )
            . 
    "\n");

    ?>

    Which now gives me the same messy output but start off with:
    Code:
    Fatal error: Uncaught SoapFault exception: [soap:Receiver] system failure: Request not allowed on port 7071
    Anyone know what I'm still doing wrong here?
    Thanks!

  3. #3
    Join Date
    May 2007
    Posts
    22
    Rep Power
    8

  4. #4
    Join Date
    Jul 2007
    Location
    Peoria, IL
    Posts
    11
    Rep Power
    8

    Default

    Thanks! That got me to the point to where I could get an account to be added using the code below but I am having a hard time passing attributes i.e. COS. I know what the SOAP packet should look like but I can't get the PHP SOAP functions to put the attribute in correctly. Using CURL would be 100x easier because I could just get the traces from zmprov and then just toss in the values I needed to substitue where appropriate.

    I want to send (I got my object ID from "zmproc gc basicemail"):
    <a n="zimbraCOSid">f070eede-c0c5-4867-a158-1f35f1c39e15</a>

    But what my code is sending is:
    <a n="zimbraCOSid">f070eede-c0c5-4867-a158-1f35f1c39e15</a n="zimbraCOSid">

    I get back a:
    <soap:Reason><soap:Text>parse error: Error on line 2 of document : The end-tag for element type "a" must end with a '>' delimiter. Nested exception: The end-tag for element type "a" must end with a '>' delimiter.</soap:Text></soap:Reason>

    I can't seem to get the closing </a> to not include the n="zimbraCOSid". I am also wondering if the SOAP PHP functions are doing anything special (other than frustrating me) or if I can just make a string of the XML/SOAP that I want to send and just use CURL to send it over. Frankly, all of my problems have come from trying to guess how the PHP SOAP lib works, not how Zimbra's SOAP interface works... Any insight on how to fix my closing tag problem and/or if CURL can do it on its own would be greatly appreciated. Thanks!

    Code:
    function ZimbraAdminCreateAccount($Trace, $ServerAddress, $AdminUserName, $AdminPassword, $NewUserName, $NewPassword)
    {
            $client = new SoapClient(NULL,
                    array
                    (
                            "location"      => "https://$ServerAddress:7071/service/admin/soap",
                            "uri"           => "urn:zimbra",
                            "trace"         => $Trace,
                            "exceptions"    => "1",
                            "soap_version"  => SOAP_1_1,
                            "style"         => SOAP_RPC,
                            "use"           => SOAP_LITERAL
                    )
            );
    
            try
            {
                    $ZimbraSession = $client->__soapCall("AuthRequest",
                            array
                            (
                                    new SoapParam("$AdminUserName", "name"),
                                    new SoapParam("$AdminPassword", "password")
                            ),
                            array
                            (
                                    "uri"           => "urn:zimbraAdmin",
                                    "soapaction"    => "urn:zimbraAdmin#AuthRequest"
                            ),
                            new SoapHeader("urn:zimbra", "context")
                    );
            }
            catch (SoapFault $exception)
            {
                    echo "Login exception caught<br><br>";
                    echo htmlentities($client->__getLastRequest()) . "<br><br>";
                    echo htmlentities($client->__getLastResponse()) . "<br><br>";
                    echo $exception . "<br><br>";
            }
    
    
            // echo "----- Logged in<BR><BR>";
    
                    try
            {
                    $ZimbraReturn = $client->__soapCall("CreateAccountRequest",
                            array
                            (
                                    new SoapParam("$NewUserName", "name"),
                                    new SoapParam("$NewPassword", "password"),
                                    new SoapParam("f070eede-c0c5-4867-a158-1f35f1c39e15", "a n=\"zimbraCOSid\"")
                            ),
                            array
                            (
                                    "uri"           => "urn:zimbraAdmin",
                                    "soapaction"    => "urn:zimbraAdmin#CreateAccountRequest"
                            ),
                            array
                            (
                                    new SoapHeader("urn:zimbra", "context", new SoapVar("<ns2:context><authToken>" . $ZimbraSession[authToken] . "</authToken></ns2:context>", XSD_ANYXML))
                            )
                    );
            }
            catch (SoapFault $exception)
            {
                    echo "CreateAccountRequest exception caught<br><br>";
                    echo "Sent: " . htmlentities($client->__getLastRequest()) . "<br><br>";
                    echo "Received: " . htmlentities($client->__getLastResponse()) . "<br><br>";
            }
    
    
            // echo "Sent: " . htmlentities($client->__getLastRequest()) . "<br><br>";
            // echo "Received: " . htmlentities($client->__getLastResponse()) . "<br><br>";
            return($ZimbraReturn);
    }

  5. #5
    Join Date
    May 2007
    Posts
    22
    Rep Power
    8

    Default

    I haven't tried this to set attribute values in PHP's SOAP, but you might be able to use it:

    PHP: SOAP Functions - Manual

    Please let us know how that works!

  6. #6
    Join Date
    Jul 2007
    Location
    Peoria, IL
    Posts
    11
    Rep Power
    8

    Default Got it working!

    Well for those wondering the PHP SOAP functions really are not doing anything but making is really hard to do a simple curl HTTP POST to Zimbra's SOAP URL. Doing it the following way makes it so you can do "zmprov --debug whatever" and be able to use that trace to get done exactly the same thing in PHP. In the example below you could technically break it up into 2 functions and have the login happen in an isolated function so that it doesn't create a ton of admin sessions sitting out there every time you add an account since one authToken & sessionId can be used for an infinite amount of SOAP requests. But for my purposes my PHP script is very short lived and literally just adds the account and exits so it is not needed.

    Code:
    <?PHP
            $ServerAddress          = "192.168.1.1";
            $AdminUserName          = "admin";
            $AdminPassword          = "adminpassword";
    
            $NewUserName            = "mynewaccount@mydomain.com";
            $NewUserPassword        = "mynewpassoword";
            $COSId                  = "f070eede-c0c5-4867-a158-1f35f1c39e15";
    
            // To get your COSId for COS defualt or any other COS (I left mine in there as an example):
            // zmprov getCos default | grep "zimbraId:" from the command line
    
            if(($ZimbraSOAPResponse = ZimbraAdminCreateAccount(1, $ServerAddress, $AdminUserName, $AdminPassword, $NewUserName, $NewUserPassword, $COSId)) == FALSE)
            {
                    printf("ZimbraAdminCreateAccount Failed!<BR>\n");
                    return(FALSE);
            }
    
            print("Zimbra create account response:<BR>" . htmlentities($ZimbraSOAPResponse) . "<BR><BR>\n");
    ?>
    
    <?PHP
    
    // -------------------------------------------------------------------
    
    function ZimbraAdminCreateAccount($Trace, $ServerAddress, $AdminUserName, $AdminPassword, $NewUserName, $NewPassword, $COSId)
    {
            $CurlHandle = curl_init();
            curl_setopt($CurlHandle, CURLOPT_URL,           "https://$ServerAddress:7071/service/admin/soap");
            curl_setopt($CurlHandle, CURLOPT_POST,           TRUE);
            curl_setopt($CurlHandle, CURLOPT_RETURNTRANSFER, TRUE);
            curl_setopt($CurlHandle, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($CurlHandle, CURLOPT_SSL_VERIFYHOST, FALSE);
    
            // ------ Send the zimbraAdmin AuthRequest -----
    
            $SOAPMessage  = '<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
                                    <soap:Header>
                                            <context xmlns="urn:zimbra"/>
                                    </soap:Header>
                                    <soap:Body>
                                            <AuthRequest xmlns="urn:zimbraAdmin">
                                                    <name>' . $AdminUserName . '</name>
                                                    <password>' . $AdminPassword . '</password>
                                            </AuthRequest>
                                    </soap:Body>
                            </soap:Envelope>';
    
            curl_setopt($CurlHandle, CURLOPT_POSTFIELDS, $SOAPMessage);
    
            if(!($ZimbraSOAPResponse = curl_exec($CurlHandle)))
            {
                    print("ERROR: curl_exec - (" . curl_errno($CurlHandle) . ") " . curl_error($CurlHandle));
                    return(FALSE);
            }
    
            // print("Raw Zimbra SOAP Response:<BR>" . htmlentities($ZimbraSOAPResponse) . "<BR><BR>\n");
    
            // Parse for the sessionId
            // <sessionId type="admin" id="123">123</sessionId>
            $sessionId = strstr($ZimbraSOAPResponse, "<sessionId");
            $sessionId = strstr($sessionId, ">");
            $sessionId = substr($sessionId, 1, strpos($sessionId, "<") - 1);
            // print("sessionId = $sessionId<BR>\n");
    
            // Parse for the authToken
            // <authToken>123</authToken>
            $authToken = strstr($ZimbraSOAPResponse, "<authToken");
            $authToken = strstr($authToken, ">");
            $authToken = substr($authToken, 1, strpos($authToken, "<") - 1);
            // print("authToken = $authToken<BR>\n");
    
    
            // ------ Send the zimbraCreateAccount request -----
            $SOAPMessage = '<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
                                    <soap:Header>
                                            <context xmlns="urn:zimbra">
                                                    <authToken>' . $authToken . '</authToken>
                                                    <sessionId id="' . $sessionId . '">' . $sessionId . '</sessionId>
                                            </context>
                                    </soap:Header>
                                    <soap:Body>
                                            <CreateAccountRequest xmlns="urn:zimbraAdmin">
                                                    <name>' . $NewUserName . '</name>
                                                    <password>' . $NewUserPassword . '</password>
                                                    <a n="zimbraCOSId">' . $COSId . '</a>
                                            </CreateAccountRequest>
                                    </soap:Body>
                            </soap:Envelope>';
    
            curl_setopt($CurlHandle, CURLOPT_POSTFIELDS, $SOAPMessage);
    
            if(!($ZimbraSOAPResponse = curl_exec($CurlHandle)))
            {
                    print("ERROR: curl_exec - (" . curl_errno($CurlHandle) . ") " . curl_error($CurlHandle));
                    return(FALSE);
            }
    
            // print("Raw Zimbra SOAP Response:<BR>" . htmlentities($ZimbraSOAPResponse) . "<BR><BR>\n");
    
            return($ZimbraSOAPResponse);
    }
    ?>

  7. #7
    Join Date
    Oct 2010
    Posts
    3
    Rep Power
    5

    Default

    grat work
    but, does exists function to send mail instead of managing account ?
    thanks
    Gabriele

Similar Threads

  1. PHP SOAP vs Zimbra
    By Corey Scott in forum Developers
    Replies: 14
    Last Post: 02-05-2011, 03:41 AM
  2. PHP SOAP create appointment example
    By AddGun in forum Developers
    Replies: 13
    Last Post: 09-27-2010, 04:41 PM
  3. Soap search admin mode
    By lfasci in forum Developers
    Replies: 0
    Last Post: 07-09-2007, 09:04 AM
  4. php CreateAccountRequest via SOAP
    By bookatechie in forum Developers
    Replies: 2
    Last Post: 05-02-2007, 11:28 AM
  5. Replies: 1
    Last Post: 09-19-2006, 10:56 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •