Manage CMC and FAC with PHP and AXL
This is a tutorial on how to use PHP and AXL to manage your Client Matter Codes and Forced Authorization Codes. We’ll start by reviewing how to create a PHP Soap Client for AXL, and then address the various ways to manage these codes. This tutorial uses PHP 5.5.15 and CUCM 10.5 along with the AXL toolkit that comes with CUCM 10.5.
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.
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 object. You need to specify the AXLAPI.wsdl
WSDL file as the first parameter. In this case, we placed the WSDL file 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.
Client Matter Code (CMC) handling
CMC
Client Matter Codes (CMC) assist with call accounting and billing for billable clients. A CMC forces the user to enter a code to specify that the call relates to a specific client matter. You can assign client matter codes to customers, students, or other populations for call accounting and billing purposes.
List CMC Info
List CMC Info
<?php function listCmcInfo($client) { // Just set every tag you want returned to "" in this array $returnedTags = array("code"=>"","description"=>""); // "%" is a wild card to find every CMC $searchCriteria = array("code"=>"%"); try { $response = $client->listCmcInfo(array("returnedTags"=>$returnedTags, "searchCriteria"=>$searchCriteria)); } catch (SoapFault $sf) { echo "SoapFault: " . $sf . "<BR>"; } catch (Exception $e) { echo "Exception: " . $e . "<br>"; } ?>
Start by writing a function to list the CMC information you already have stored. You can define the tags you want returned from the list command as an array of the desired elements pointing to empty strings.
Then define the search criteria. This example returns all CMC entries because the code
in the search criteria is set to the wild card %
.
Now that you’ve defined the searchCriteria
and the returnedTags
, proceed with the listCmcInfo Soap request function.
Handling the returned data
Handle the returned data
<?php // Iterate through array of returned values (as specified by $returnedTags) // Make sure it's an array before iterating through it if ( is_array($response->return->cmcInfo) ) { foreach($response->return->cmcInfo as $cmcInfo) { echo("Uuid: ".$cmcInfo->uuid."<br>"); echo("Code: ".$cmcInfo->code."<br>"); echo("Description: ".$cmcInfo->description."<br>"); echo("<hr>"); } // if it's not an array, then just get the values } else { echo("Uuid: ".$response->return->cmcInfo->uuid."<br>"); echo("Code: ".$response->return->cmcInfo->code."<br>"); echo("Description: ".$response->return->cmcInfo->description."<br>"); echo("<hr>"); } } // end function ?>
If there is only one CMC entry, $response->return->cmcInfo
will be an object. If there are multiple CMC entries, $response->return->cmcInfo
will be an array of cmcInfo
objects. We can handle both possibilities by checking to see if $response->return->cmcInfo
is an array with is_array
.
This function will print the CMC uuid, code and description for one or more entries, depending on how many you have created. On our test system, there are three entries:
Uuid: {78E07494-EDAE-980E-383B-18EC7948AE1F}
Code: 777
Description: Heavenly Calls
Uuid: {3420C42A-DDD9-B7D2-CDEE-74B5F427F09F}
Code: 666
Description: Helly Calls
Uuid: {825703AF-FA47-42DC-AC9F-87EDA26119CF}
Code: 555
Description: Earthly Calls
Get CMC Info
Get CMC Info
<?php function getCmcInfo($client,$code) { // Just set every tag you want returned to "" in this array $returnedTags = array("code"=>"","description"=>""); try { $response = $client->getCmcInfo(array("code"=>$code),array("returnedTags"=>$returnedTags)); } catch (SoapFault $sf) { echo "SoapFault: " . $sf . "<BR>"; } catch (Exception $e) { echo "Exception: " . $e . "<br>"; } echo("Uuid: ".$response->return->cmcInfo->uuid."<br>"); echo("Code: ".$response->return->cmcInfo->code."<br>"); echo("Description: ".$response->return->cmcInfo->description."<br>"); echo("<hr>"); } ?>
If you want to retrieve information about a single CMC info entry, use the getCmcInfo
API call. You can retrieve it by code
or by uuid
. This example retrieves it by the code
tag.
As with most PHP AXL requests, this contains the XML information stored as arrays and arrays within arrays (nested arrays), mirroring the nesting in the XML.
Here’s how the arrays mirror the XML:
<code>somecode</code>
<- array(“code”=>“somecode”);
<returnedTags>
<- array(“returnedTags”=>array(
<code/>
<- “code”=>“”,
<description/>
<- “description”=>“”)
</returnedTags>
<- );
Removing a CMC entry
Remove a CMC entry
<?php function removeCmcInfo($client,$code) { try { $response = $client->removeCmcInfo(array("code"=>$code)); } catch (SoapFault $sf) { echo "SoapFault: " . $sf . "<BR>"; } catch (Exception $e) { echo "Exception: " . $e . "<br>"; } } ?>
Identify the entry you want deleted by code
or by uuid
. Then, invoke the removeCmcInfo
API to delete that entry. Our example removes an entry by code
.
Adding a CMC entry
Add a CMC entry
<?php function addCmcInfo($client,$code,$description) { $cmcInfo = array("code"=>$code,"description"=>$description); try { $response = $client->addCmcInfo(array("cmcInfo"=>$cmcInfo)); } catch (SoapFault $sf) { echo "SoapFault: " . $sf . "<BR>"; } catch (Exception $e) { echo "Exception: " . $e . "<br>"; } } ?>
A Client Matter Code consists of only a dial code and a description. Simply define the code
and description
in an array, and invoke the addCmcInfo
API to add a new CMC.
Updating a CMC entry
Update a CMC entry
<?php function updateCmcInfo($client,$code,$description) { // update the CMC information try { $response = $client->updateCmcInfo(array("code"=>$code,"description"=>$description)); } catch (SoapFault $sf) { echo "SoapFault: " . $sf . "<BR>"; } catch (Exception $e) { echo "Exception: " . $e . "<br>"; } } ?>
You can update a CMC entry by identifying the entry by code
or by uuid
. In this example, we only want to update the description. If you don’t want to change the code
when you perform the update, then you only need to specify the code
as your search term and then change the value for description
.
If you want to change the code
with the update in addition to the description, then set "code"=>$old_code
and "newCode"=>$new_code
in the array you pass to the API (with the desired values in the variables $old_code
and $new_code
). If you want to leave the description alone, just omit it from the array. For example, $client->updateCmcInfo(array("code"=>$old_code,"newCode"=>$new_code)
.
Putting it all together
A complete sample application
<?php echo "<h1>CMC Info Test</h1>"; $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, )); function listCmcInfo($client) { // Just set every tag you want returned to "" in this array $returnedTags = array("code"=>"","description"=>""); // "%" is a wild card to find every CMC $searchCriteria = array("code"=>"%"); try { $response = $client->listCmcInfo(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) // Make sure it's an array before iterating through it if ( is_array($response->return->cmcInfo) ) { foreach($response->return->cmcInfo as $cmcInfo) { echo("Uuid: ".$cmcInfo->uuid."<br>"); echo("Code: ".$cmcInfo->code."<br>"); echo("Description: ".$cmcInfo->description."<br>"); echo("<hr>"); } // if it's not an array, then just get the values } else { echo("Uuid: ".$response->return->cmcInfo->uuid."<br>"); echo("Code: ".$response->return->cmcInfo->code."<br>"); echo("Description: ".$response->return->cmcInfo->description."<br>"); echo("<hr>"); } } function getCmcInfo($client,$code) { // Just set every tag you want returned to "" in this array $returnedTags = array("code"=>"","description"=>""); try { $response = $client->getCmcInfo(array("code"=>$code),array("returnedTags"=>$returnedTags)); } catch (SoapFault $sf) { echo "SoapFault: " . $sf . "<BR>"; } catch (Exception $e) { echo "Exception: " . $e . "<br>"; } echo("Uuid: ".$response->return->cmcInfo->uuid."<br>"); echo("Code: ".$response->return->cmcInfo->code."<br>"); echo("Description: ".$response->return->cmcInfo->description."<br>"); echo("<hr>"); } function removeCmcInfo($client,$code) { try { $response = $client->removeCmcInfo(array("code"=>$code)); } catch (SoapFault $sf) { echo "SoapFault: " . $sf . "<BR>"; } catch (Exception $e) { echo "Exception: " . $e . "<br>"; } } function addCmcInfo($client,$code,$description) { $cmcInfo = array("code"=>$code,"description"=>$description); try { $response = $client->addCmcInfo(array("cmcInfo"=>$cmcInfo)); } catch (SoapFault $sf) { echo "SoapFault: " . $sf . "<BR>"; } catch (Exception $e) { echo "Exception: " . $e . "<br>"; } } function updateCmcInfo($client,$code,$description) { // update the CMC information try { $response = $client->updateCmcInfo(array("code"=>$code,"description"=>$description)); } catch (SoapFault $sf) { echo "SoapFault: " . $sf . "<BR>"; } catch (Exception $e) { echo "Exception: " . $e . "<br>"; } } echo "<h2>List CMC Info</h2>"; listCmcInfo($client); echo "<h2>Get CMC Info</h2>"; getCmcInfo($client,"777"); echo "<h2>Remove CMC Info</h2>"; removeCmcInfo($client,"555"); listCmcInfo($client); echo "<h2>Add CMC Info</h2>"; addCmcInfo($client,"555","Earthly Calls"); listCmcInfo($client); echo "<h2>Update CMC Info</h2>"; updateCmcInfo($client,"777","Up There"); updateCmcInfo($client,"666","Down There"); updateCmcInfo($client,"555","Neither"); listCmcInfo($client); echo "<h2>Update CMC Info</h2>"; updateCmcInfo($client,"777","Heavenly Calls"); updateCmcInfo($client,"666","Helly Calls"); updateCmcInfo($client,"555","Earthly Calls"); listCmcInfo($client); ?>
This sample application demonstrates the APIs that list, get, remove, add, and update CMC information. Each change to the CMC information is followed by a listCmcInfo
so you can see the results of that operation. As noted above, the test starts with these three entries:
Uuid: {78E07494-EDAE-980E-383B-18EC7948AE1F}
Code: 777
Description: Heavenly Calls
Uuid: {3420C42A-DDD9-B7D2-CDEE-74B5F427F09F}
Code: 666
Description: Helly Calls
Uuid: {825703AF-FA47-42DC-AC9F-87EDA26119CF}
Code: 555
Description: Earthly Calls
Forced Authorization Code (FAC) handling
Forced Authorization Codes (FAC) allow you to regulate the types of calls that certain users can place. A FAC forces the user to enter a valid authorization code on the phone before the call completes. The values for the authorizationLevel
parameter are largely arbitrary. You’ll want to define them to restrict such things as international calls.
This tutorial starts with three FAC Info entries in the system. Keep in mind that the authorization level must be a number between 0 and 255, so this example arbitrarily uses 100, 150, and 200. The records are as follows:
Uuid: {4FA8F305-1C65-1944-FDE6-CF8A279100DD}
Name: Regular Caller FAC
Code: 4321
Auth Level: 150
Uuid: {A334FF0C-1A9D-2F78-AB52-BC64F5EEA24D}
Name: Lowly Grunt FAC
Code: 1111
Auth Level: 100
Uuid: {62724065-ED78-EF16-E12D-BFB9A302F818}
Name: The Big Cheese FAC
Code: 1234
Auth Level: 200
List FAC Info
List FAC Info
<?php function listFacInfo($client) { // Just set every tag you want returned to "" in this array $returnedTags = array("name"=>"","code"=>"","authorizationLevel"=>""); // "%" is a wild card to find every FAC $searchCriteria = array("name"=>"%"); try { $response = $client->listFacInfo(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) // Make sure it's an array before iterating through it if ( is_array($response->return->facInfo) ) { foreach($response->return->facInfo as $facInfo) { echo("Uuid: ".$facInfo->uuid."<br>"); echo("Name: ".$facInfo->name."<br>"); echo("Code: ".$facInfo->code."<br>"); echo("Auth Level: ".$facInfo->authorizationLevel."<br>"); echo("<hr>"); } // if it's not an array, then just get the values } else { echo("Uuid: ".$response->return->facInfo->uuid."<br>"); echo("Name: ".$response->return->facInfo->name."<br>"); echo("Code: ".$response->return->facInfo->code."<br>"); echo("Auth Level: ".$response->return->facInfo->authorizationLevel."<br>"); echo("<hr>"); } } ?>
Create a listFacInfo
function so you can see the values and check them again after changes. This is almost the same as the listCmcInfo
function in the previous section on CMC Info. Like the CMC function, the response value can contain a single object if there is only one FAC Info entry, or an array of objects if there are more. This function checks the response to see if it’s an array. If so, it iterates through the array. If not, it simply echoes the values of the object.
Get FAC Info
Get FAC Info
<?php function getFacInfo($client, $name) { $returnedTags = array("name"=>"","code"=>"","authorizationLevel"=>""); try { $response = $client->getFacInfo(array("name"=>$name),array("returnedTags"=>$returnedTags)); } catch (SoapFault $sf) { echo "SoapFault: " . $sf . "<BR>"; } catch (Exception $e) { echo "Exception: " . $e . "<BR>"; } echo("Uuid: ".$response->return->facInfo->uuid."<br>"); echo("Name: ".$response->return->facInfo->name."<br>"); echo("Code: ".$response->return->facInfo->code."<br>"); echo("Auth Level: ".$response->return->facInfo->authorizationLevel."<br>"); echo("<hr>"); } ?>
If you have a specific FAC Info entry in mind, you can retrieve it with the getFacInfo
request. You can specify which FAC Info you want to retrieve by name
or by uuid
. This example searches by name
.
The getFacInfo
request also requires a set of returnedTags
in an array. Simply create an array of the tags you want returned, each pointing to an empty string. And then include that array as the value of another array with the element returnedTags
.
Add FAC info
Add FAC Info
<?php function addFacInfo($client) { $facInfo = array("name"=>"New FAC","code"=>"5555","authorizationLevel"=>"250"); try { $response = $client->addFacInfo(array("facInfo"=>$facInfo)); } catch (SoapFault $sf) { echo "SoapFault: " . $sf . "<BR>"; } catch (Exception $e) { echo "Exception: " . $e . "<BR>"; } } ?>
The addFacInfo
API is probably the second easiest of the FAC commands. All it takes is an array with the element facInfo
pointing to an array of the tags defining a FAC, that is, name
, code
, and authorizationLevel
. In this case, we’re calling the FAC New FAC
, giving it a code
of 5555
and an authorizationLevel
of 250
.
Remove FAC Info
Remove FAC Info
<?php function removeFacInfo($client) { try { $response = $client->removeFacInfo(array("name"=>"New FAC")); } catch (SoapFault $sf) { echo "SoapFault: " . $sf . "<BR>"; } catch (Exception $e) { echo "Exception: " . $e . "<BR>"; } } ?>
The removeFacInfo
API is arguably the easiest. Simply identify the FAC you want removed by name
or uuid
. In this case, we use name
and remove the FAC we just added.
Update FAC Info
Update FAC Info
<?php function updateFacInfo($client, $name, $authLevel) { try { $newresponse = $client->updateFacInfo(array("name"=>$name, "authorizationLevel"=>$authLevel)); } catch (SoapFault $sf) { echo "SoapFault: " . $sf . "<BR>"; } catch (Exception $e) { echo "Exception: " . $e . "<BR>"; } } ?>
Finally, the updateFacInfo
API lets you change information in a FAC entry. This example changes the authorizationLevel
, but you could also change the name (use the newName
tag for that), and/or the code
. In this case, we identify the FAC entry we want changed by name
, but you could use the uuid
instead.
Putting it all together
A complete sample application
<?php echo "<h1>Fac Info Test</h1>"; $host="host"; $username="username"; $password="password"; $client = new SoapClient("AXLAPI.wsdl", array('trace'=>true, 'exceptions'=>true, 'location'=>"https://".$host.":8443/axl", 'login'=>$username, 'password'=>$password )); function listFacInfo($client) { // Just set every tag you want returned to "" in this array $returnedTags = array("name"=>"","code"=>"","authorizationLevel"=>""); // "%" is a wild card to find every FAC $searchCriteria = array("name"=>"%"); try { $response = $client->listFacInfo(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) // Make sure it's an array before iterating through it if ( is_array($response->return->facInfo) ) { foreach($response->return->facInfo as $facInfo) { echo("Uuid: ".$facInfo->uuid."<br>"); echo("Name: ".$facInfo->name."<br>"); echo("Code: ".$facInfo->code."<br>"); echo("Auth Level: ".$facInfo->authorizationLevel."<br>"); echo("<hr>"); } // if it's not an array, then just get the values } else { echo("Uuid: ".$response->return->facInfo->uuid."<br>"); echo("Name: ".$response->return->facInfo->name."<br>"); echo("Code: ".$response->return->facInfo->code."<br>"); echo("Auth Level: ".$response->return->facInfo->authorizationLevel."<br>"); echo("<hr>"); } } function getFacInfo($client, $name) { $returnedTags = array("name"=>"","code"=>"","authorizationLevel"=>""); try { $response = $client->getFacInfo(array("name"=>$name),array("returnedTags"=>$returnedTags)); } catch (SoapFault $sf) { echo "SoapFault: " . $sf . "<BR>"; } catch (Exception $e) { echo "Exception: " . $e . "<BR>"; } echo("Uuid: ".$response->return->facInfo->uuid."<br>"); echo("Name: ".$response->return->facInfo->name."<br>"); echo("Code: ".$response->return->facInfo->code."<br>"); echo("Auth Level: ".$response->return->facInfo->authorizationLevel."<br>"); echo("<hr>"); } function addFacInfo($client) { $facInfo = array("name"=>"New FAC","code"=>"5555","authorizationLevel"=>"250"); try { $response = $client->addFacInfo(array("facInfo"=>$facInfo)); } catch (SoapFault $sf) { echo "SoapFault: " . $sf . "<BR>"; } catch (Exception $e) { echo "Exception: " . $e . "<BR>"; } } function removeFacInfo($client) { try { $response = $client->removeFacInfo(array("name"=>"New FAC")); } catch (SoapFault $sf) { echo "SoapFault: " . $sf . "<BR>"; } catch (Exception $e) { echo "Exception: " . $e . "<BR>"; } } function updateFacInfo($client, $name, $authLevel) { try { $newresponse = $client->updateFacInfo(array("name"=>$name, "authorizationLevel"=>$authLevel)); } catch (SoapFault $sf) { echo "SoapFault: " . $sf . "<BR>"; } catch (Exception $e) { echo "Exception: " . $e . "<BR>"; } } echo "<h2>List Fac Info</h2>"; listFacInfo($client); echo "<h2>Get Fac Info</h2>"; getFacInfo($client, "The Big Cheese FAC"); echo "<h2>Add Fac Info</h2>"; addFacInfo($client); listFacInfo($client); echo "<h2>Remove Fac Info</h2>"; removeFacInfo($client); listFacInfo($client); echo "<h2>Update Fac Info 170</h2>"; // Change auth code of "Regular Caller FAC" to 170 updateFacInfo($client, "Regular Caller FAC", "170"); listFacInfo($client); echo "<h2>Update Fac Info back to 150</h2>"; // Change it back for the next test updateFacInfo($client, "Regular Caller FAC", "150"); listFacInfo($client); ?>
This sample application demonstrates the APIs that list, get, remove, add, and update FAC information. Each change to the FAC information is followed by a listCmcInfo
so you can see the results of that operation. As noted above, the test starts with these three entries:
Uuid: {4FA8F305-1C65-1944-FDE6-CF8A279100DD}
Name: Regular Caller FAC
Code: 4321
Auth Level: 150
Uuid: {A334FF0C-1A9D-2F78-AB52-BC64F5EEA24D}
Name: Lowly Grunt FAC
Code: 1111
Auth Level: 100
Uuid: {62724065-ED78-EF16-E12D-BFB9A302F818}
Name: The Big Cheese FAC
Code: 1234
Auth Level: 200