* Digest Authentication for Trusted Numbers Manipulation and CLI Mapping
See introduction to XMLAPI for details on Authentication:
https://support.sippysoft.com/a/solutions/articles/106909
#!/usr/bin/env php
<?php
class HTTPSDigestAuthTransport
{
private $username;
private $password;
private $host;
public function __construct($url)
{
$parsedUrl = parse_url($url);
$this->username = $parsedUrl['user'];
$this->password = $parsedUrl['pass'];
$this->host = $parsedUrl['host'];
}
public function request($method, $params)
{
$handler = '/xmlapi/xmlapi';
$url = "https://" . $this->host . $handler;
$requestBody = $this->encode_request($method, $params);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
curl_setopt($ch, CURLOPT_USERPWD, "$this->username:$this->password");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: text/xml',
'User-Agent: PHP-Client/1.0'
));
$response = curl_exec($ch);
if (curl_errno($ch)) {
throw new Exception('Request Error: ' . curl_error($ch));
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($httpCode != 200) {
throw new Exception("Protocol Error: $httpCode " . curl_error($ch) . "\nResponse: " . $response);
}
curl_close($ch);
return $this->decode_response($response);
}
private function encode_request($method, $params)
{
$xml = new SimpleXMLElement('<?xml version="1.0"?><methodCall></methodCall>');
$xml->addChild('methodName', $method);
$paramsNode = $xml->addChild('params');
$paramNode = $paramsNode->addChild('param');
$valueNode = $paramNode->addChild('value');
$this->add_xml_value($valueNode, $params);
return $xml->asXML();
}
private function add_xml_value($xml, $value)
{
if (is_array($value)) {
if ($this->is_assoc($value)) {
$structNode = $xml->addChild('struct');
foreach ($value as $key => $item) {
$memberNode = $structNode->addChild('member');
$memberNode->addChild('name', $key);
$this->add_xml_value($memberNode->addChild('value'), $item);
}
} else {
$arrayNode = $xml->addChild('array')->addChild('data');
foreach ($value as $item) {
$this->add_xml_value($arrayNode->addChild('value'), $item);
}
}
} elseif (is_int($value)) {
$xml->addChild('int', $value);
} elseif (is_string($value)) {
$xml->addChild('string', $value);
} else {
$xml->addChild('string', $value);
}
}
private function is_assoc($array)
{
return array_keys($array) !== range(0, count($array) - 1);
}
private function decode_response($response)
{
$xml = simplexml_load_string($response);
if ($xml === false) {
throw new Exception('Failed to parse XML response');
}
return json_decode(json_encode($xml), true);
}
}
class Client
{
private $transport;
public function __construct($url)
{
$this->transport = new HTTPSDigestAuthTransport($url);
}
public function addCLIMapping($params)
{
return $this->transport->request('addCLIMapping', $params);
}
public function listCLIMappings($params)
{
return $this->transport->request('listCLIMappings', $params);
}
}
// Configurable variables
$username = 'username';
$password = 'password';
$server = '1.2.3.4';
$i_account = 34;
$cli = '123456';
$lang = 'en';
$url = "https://$username:$password@$server/xmlapi/xmlapi";
$client = new Client($url);
try {
// Add a mapping
$res = $client->addCLIMapping(['i_account' => $i_account, 'cli' => $cli, 'lang' => $lang]);
print_r($res);
// Retrieve list of trusted numbers
$res = $client->listCLIMappings(['i_account' => $i_account]);
if ($res['result'] == 'OK') {
foreach ($res['list'] as $cli) {
echo $cli['value'] . "\n";
}
}
} catch (Exception $e) {
echo 'Error: ' . $e->getMessage() . "\n";
}
?>