PHP Soap Client

PHP is a terrific language for processing the AXL Soap API. The built-in Soap handling is very easy to use. Plus, you can install PHP separately from your web server and run PHP scripts from the command line like you would any other scripting language. This tutorial uses PHP 5.5.15 and CUCM 10.5 along with the AXL toolkit that comes with CUCM 10.5.

Set up the Soap client

Set up the Soap client

<?php
    $host="hostname";
    $username="username";
    $password="password";

    $client = new SoapClient("AXLAPI.wsdl",
        array('trace'=>true,
       'exceptions'=>true,
       'location'=>"https://".$host.":8443/axl",
       'login'=>$username,
       'password'=>$password,
    ));
?>

The first thing you want to do is instantiate a Soap client. You need to specify the AXLAPI.wsdl WSDL file as the first parameter. In this case, the WSDL file is in the same directory as the PHP code. You should also have the AXLSoap.xsd and AXLEnums.xsd files in the same directory. You can get these files from your CUCM installation via the web user interface by going to Application->Plugins, click Find and then download the Cisco AXL Toolkit.

getPhone API in PHP

How to execute a Soap call

getPhone

<?php
    $response = $client->getPhone(array("name"=>"SEP010101010101"));
?>

Now that you have instantiated a client object, you’re ready to implement any of the APIs specified in the WSDL. You call getPhone with $client->getPhone. In this first example, we simply specify the name of the phone (you have a choice between specifying the name or the uuid of the phone). That’s all there is to it.

The XML for the getPhone Soap call

getPhone XML

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.cisco.com/AXL/API/10.5">
   <soapenv:Header/>
   <soapenv:Body>
      <ns:getPhone sequence="?">
         <name>SEP010101010101</name>
<!-- OR  <uuid>uuid-goes-here</uuid>  -->
         <returnedTags ctiid="?" uuid="?">
            <name/>
            <description/>
            <product/>
            <model/>
            <class/>
            <protocol/>
         </returnedTags>
      </ns:getPhone>
   </soapenv:Body>
</soapenv:Envelope>

There are times when you only want to retrieve certain bits of information about a phone. You can specify what you want to see by defining returnedTags, as shown in this XML sample. In this next example, we narrow the returned data down to name, description, product, model, class, and protocol, as shown in the XML.

Specifying name and returnedTags

Specifying name and returnedTags

<?php
    $payload = array(
        "name"=>"SEP010101010101",
        "returnedTags"=>array("name"=>"",
                        "description"=>"",
                        "product"=>"",
                        "class"=>"",
                        "protocol"=>""
                        )
                    );

    $response = $client->getPhone($payload);
?>

Note that we created a single array of two elements, name and returnedTags. However, the latter element, returnedTags points to another array of the names of the elements we want returned. Each of these key=>value pairs points to an empty string. This is equivalent to creating a closed XML tag like <name/> or <description/>.

Getting the response

A trick to peek at the complete $response

<?php
    echo "<pre>";
    var_dump(get_object_vars($response));
    echo "</pre>";
?>

This time, let’s take a look at the $response, which is an array of objects you can traverse to get the returned information. If you’re not sure how to interpret the $response object that comes back, you can employ this little trick to examine the information.

This code will echo to your browser the entire structure of the $response object.

Sample excerpt of the $response array/object

Sample excerpt of the $response array/object

<?php
array(1) {
  ["return"]=>
  object(stdClass)#3 (1) {
    ["phone"]=>
    object(stdClass)#4 (7) {
      ["name"]=>
      string(15) "SEP010101010101"
      ["description"]=>
      string(13) "npetrele CIPC"
      ["product"]=>
      string(21) "Cisco IP Communicator"
      ["class"]=>
      string(5) "Phone"
      ["protocol"]=>
      string(3) "SIP"
      ["ctiid"]=>
      int(21)
      ["uuid"]=>
      string(38) "{BCD3D84F-AE8C-7A97-D555-DCB326D0DEEB}"
    }
  }
}?>

This is a sample of the information as a result of the var_dump. The main key in this array is return, which points to the object phone, which, in turn, points to various properties of that object, strings of data. So if you want to see the name of the phone, you would access the name with $response->return->phone->name.

Accessing the elements of the $response

Now you know how to access the details you want from $response

<?php
    echo("Name: ".$response->return->phone->name)."<br>";
    echo("Description: ".$response->return->phone->description)."<br>";
    echo("Product: ".$response->return->phone->product)."<br>";
    echo("Class: ".$response->return->phone->class)."<br>";
    echo("Protocol: ".$response->return->phone->protocol)."<br>";
?>

Now that we know the structure of the $response, we can access the data we need with a handful of simple lines of code.

This completes our getPhone example.

listUser – A more complex AXL request

Specify searchCriteria and returnedTags

XML for listUser defining returned tags

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.cisco.com/AXL/API/10.5">
   <soapenv:Header/>
   <soapenv:Body>
      <ns:listUser sequence="?">
         <searchCriteria>
            <userid>%</userid>
         </searchCriteria>
         <returnedTags uuid="?">
            <firstName/>
            <lastName/>
            <userid/>
         </returnedTags>
      </ns:listUser>
   </soapenv:Body>
</soapenv:Envelope>

Now let’s look at an AXL request that includes both searchCriteria and returnedTags.

Examine the XML for this request. If you check the WSDL file, you’ll see that you can search by firstName, lastName, userid, and department. This example searches only by userid, and we use the wild card % so that we’ll end up listing every user.

This example also specifies firstName, lastName and userid as the returned tags.

A complete example of a listUser request

Here’s how you translate that XML into PHP Soap code, and then list the results

<?php
    $host="hostname";
    $username="username";
    $password="password";

    $client = new SoapClient("AXLAPI.wsdl",
        array('trace'=>true,
       'exceptions'=>true,
       'location'=>"https://".$host.":8443/axl",
       'login'=>$username,
       'password'=>$password,
    ));

    // Just set every tag you want returned to an empty string ("") in this array
    $returnedTags = array("firstName"=>"","lastName"=>"","userid"=>"");

    // "%" is a wild card to find every user
    $searchCriteria = array("userid"=>"%");

    try {
        $response = $client->listUser(array("returnedTags"=>
            $returnedTags,"searchCriteria"=>$searchCriteria));
    }
    catch (SoapFault $sf) {
        echo "SoapFault: " . $sf . "<BR>";
    }
    catch (Exception $e) {
        echo "Exception: ". $e ."<br>";
    }


    // Iterate through array of returned values (as specified by $returnedTags)
    foreach($response->return->user as $user) {
        echo("First Name: ".$user->firstName."<br>");
        echo("Last Name: ".$user->lastName."<br>");
        echo("User ID: ".$user->userid."<br>");
        echo("<hr>");
    }

?>

Here is a working example of listUser, including code to iterate through the returned values and echo them to the screen or browser. We pass both the search criteria and specified returned tags as arrays to the Soap client. As we did in the getPhone example, we specify key=>value pairs pointing to empty strings for the returned tags.

addUser - How to handle duplicate tags

The associatedGroups tag has multiple userGroup tags

The associatedGroups tag has multiple userGroup tags

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://www.cisco.com/AXL/API/10.5">
    <soapenv:Header/>
    <soapenv:Body>
        <ns:addUser sequence="?">
            <user>
                <firstName>Joey</firstName>
                <lastName>Bishop</lastName>
                <userid>joey</userid>
                <password>bishop</password>
                <enableCti>true</enableCti>
                <enableMobility>true</enableMobility>
                <imAndPresenceEnable>true</imAndPresenceEnable>
                <associatedGroups>
                    <userGroup>
                        <name>Application Client Users</name>
                    </userGroup>
                    <userGroup>
                        <name>Standard CTI Enabled</name>
                    </userGroup>
                    <userGroup>
                        <name>Standard CTI Secure Connection</name>
                    </userGroup>
                    <userGroup>
                        <name>Third Party Application Users</name>
                    </userGroup>
                </associatedGroups>
            </user>
        </ns:addUser>
    </soapenv:Body>
</soapenv:Envelope>

Up until now, we’ve been passing arrays to the AXL functions. That is precisely what makes AXL and PHP so easy.

However, arrays can present a problem when the XML must include duplicate tags. For example, suppose you want to add a user and define a number of the user’s associated groups. Note that this would require duplicate userGroup keys.

This will not work

This will not work

<?php
array(
    "userGroup"=>array("name"=>"Application Client Users"),
    "userGroup"=>array("name"=>"Standard CTI Enabled"),
    "userGroup"=>array("name"=>"Standard CTI Secure Connection"),
    "userGroup"=>array("name"=>"Third Party Application Users")
    );
?>

You can’t load a PHP array with multiple key=>value pairs where the key is always userGroup. Actually, PHP won’t complain if you define an array that way, but you won’t get the correct results, because PHP expects array keys to be unique.

Create a userGroup class

Instead, create a userGroup class

<?php
    class userGroup
    {
        public $name;
    }
?>

Because you can’t use an array of userGroup tags, use instead an array of objects with properties. First, create the class userGroup with the property name.

Create objects based on the userGroup class

Create objects instead of an array of key=>value pairs

<?php
    $userGroup1 = new userGroup();
    $userGroup2 = new userGroup();
    $userGroup3 = new userGroup();
    $userGroup4 = new userGroup();
    $userGroup1->name = 'Application Client Users';
    $userGroup2->name = 'Standard CTI Enabled';
    $userGroup3->name = 'Standard CTI Secure Connection';
    $userGroup4->name = 'Third Party Application Users';
?>

Now you can create multiple userGroup objects and define the name property as you would have if it was an array value.

Load the objects into an array

Array of objects

<?php
    $something = array(
            $userGroup1,
            $userGroup2,
            $userGroup3,
            $userGroup4);
?>

Then you can load these userGroup objects into an array. An array of objects does not violate the unique key requirement for PHP arrays of keys in key=>value pairs.

Complete addUser code sample

Complete code sample integrating the array of objects

<?php
    $host="hostname";
    $username="username";
    $password="password";

    $client = new SoapClient("AXLAPI.wsdl",
        array('trace'=>true,
       'exceptions'=>true,
       'location'=>"https://".$host.":8443/axl",
       'login'=>$username,
       'password'=>$password,
    ));


    class userGroup
    {
        public $name;
    }

    echo "<p>Add User Test</p>";

    $userGroup1 = new userGroup();
    $userGroup2 = new userGroup();
    $userGroup3 = new userGroup();
    $userGroup4 = new userGroup();
    $userGroup1->name = 'Application Client Users';
    $userGroup2->name = 'Standard CTI Enabled';
    $userGroup3->name = 'Standard CTI Secure Connection';
    $userGroup4->name = 'Third Party Application Users';

    $user=array("user"=>
        array("firstName"=>"Joey",
            "lastName"=>"Bishop",
            "userid"=>"joey",
            "password"=>"bishop",
            "enableCti"=>"true",
            "enableMobility"=>"true",
            "imAndPresenceEnable"=>"true",
            "presenceGroupName"=>"Standard Presence group",
            "associatedGroups"=>array(
                        $userGroup1,
                        $userGroup2,
                        $userGroup3,
                        $userGroup4)
        )
    );

    try {
        $response = $client->addUser($user);
    }
    catch (SoapFault $sf) {
        echo "SoapFault: " . $sf . "<BR>";
    }
    catch (Exception $e) {
        echo "Exception: ". $e ."<br>";
    }

?>

Now let’s put that all together as a sample application that adds the user Joey Bishop.

PHP