/administrator/components/com_zoo/libraries/mollom/mollom.php
PHP | 817 lines | 289 code | 156 blank | 372 comment | 81 complexity | 4f316f0b20f3ea087909e63992376d1a MD5 | raw file
Possible License(s): LGPL-3.0, GPL-2.0, MIT, BSD-3-Clause, LGPL-2.1
- <?php
- /**
- * Mollom class
- *
- * This source file can be used to communicate with mollom (http://mollom.com)
- *
- * The class is documented in the file itself, but you can find more documentation and examples on the docs-page (http://mollom.crsolutions.be/docs).
- * If you find any bugs help me out and report them. Reporting can be done by sending an email to php-mollom-bugs[at]verkoyen[dot]eu. If you report a bug, make sure you give me enough information (include your code).
- * If you have questions, try the Mollom-forum, don't send them by mail, I won't read them.
- *
- * Changelog since 1.0.1
- * - Fixed a nasty bug. Possible infinite loop in doCall().
- * - Fixed getServerList. I misinterpreted the documentation, so now the defaultserver is xmlrpc.mollom.com instead of the first fallback-server.
- * - Fixed the timeout-issue. With fsockopen the timeout on connect wasn't respected. Rewrote the doCall function to use CURL over sockets.
- *
- * Changelog since 1.1.0
- * - Fixed a problem with the IP-addresses. see http://blog.verkoyen.eu/2008/07/12/important-php-mollom-update/
- *
- * Changelog since 1.1.1
- * - PHPMollom was using HTTP 1.1, now HTTP 1.0.
- * - Fallbackserver are hardcoded, when no servers could be retrieved the fallbacks are used
- *
- * Changelog since 1.1.2
- * - Typo
- * - New Licence: BSD Modified
- *
- * License
- * Copyright (c) 2008, Tijs Verkoyen. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
- *
- * This software is provided by the author ``as is'' and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall the author be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage.
- *
- * @author Tijs Verkoyen <mollom@verkoyen.eu>
- * @version 1.1.3
- *
- * @copyright Copyright (c) 2008, Tijs Verkoyen. All rights reserved.
- * @license http://mollom.local/license BSD License
- */
- class Mollom
- {
- /**
- * The allowed reverse proxy addresses
- *
- * @var array
- */
- private static $allowedReverseProxyAddresses = array();
-
-
- /**
- * Your private key
- *
- * Set it by calling Mollom::setPrivateKey('<your-key>');
- *
- * @var string
- */
- private static $privateKey;
-
-
- /**
- * Your public key
- *
- * Set it by calling Mollom::setPublicKey('<your-key>');
- *
- * @var string
- */
- private static $publicKey;
-
-
- /**
- * Reverse proxy allowed?
- *
- * @var bool
- */
- private static $reverseProxy = false;
-
-
- /**
- * The default server
- *
- * No need to change
- *
- * @var string
- */
- private static $serverHost = 'xmlrpc.mollom.com';
-
-
- /**
- * The cache for the serverlist
- *
- * No need to change
- *
- * @var array
- */
- private static $serverList = array();
-
-
- /**
- * Default timeout
- *
- * @var int
- */
- private static $timeout = 10;
-
-
- /**
- * The default user-agent
- *
- * Change it by calling Mollom::setUserAgent('<your-user-agent>');
- *
- * @var string
- */
- private static $userAgent = 'MollomPHP/1.1.3';
-
-
- /**
- * The current Mollom-version
- *
- * No need to change
- *
- * @var string
- */
- private static $version = '1.0';
-
-
- /**
- * Build the value so we can use it in XML-RPC requests
- *
- * @return string
- * @param mixed $value
- */
- private function buildValue($value)
- {
- // get type
- $type = gettype($value);
-
- // build value
- switch ($type)
- {
- case 'string':
- // escape it, cause Mollom can't handle CDATA (no pun intended)
- $value = htmlspecialchars($value, ENT_QUOTES, 'ISO-8859-15');
- return '<value><string>'. $value .'</string></value>'."\n";
-
- case 'array':
- // init struct
- $struct = '<value>'."\n";
- $struct .= ' <struct>'."\n";
-
- // loop array
- foreach ($value as $key => $value) $struct .= str_replace("\n", '', '<member>'. "\n" .'<name>'. $key .'</name>'. self::buildValue($value) .'</member>') . "\n";
-
- $struct .= ' </struct>'."\n";
- $struct .= '</value>'."\n";
-
- // return
- return $struct;
-
- default:
- return '<value>'. $value .'</value>'."\n";
- }
- }
-
-
- /**
- * Validates the answer for a CAPTCHA
- *
- * When the answer is false, you should request a new image- or audio-CAPTCHA, make sure your provide the current Mollom-sessionid.
- * The sessionid will be used to track spambots that try to solve CAPTHCA's by brute force.
- *
- * @return bool
- * @param string $sessionId
- * @param string $solution
- */
- public static function checkCaptcha($sessionId, $solution)
- {
- // redefine
- $sessionId = (string) $sessionId;
- $solution = (string) $solution;
-
- // set autor ip
- $authorIp = self::getIpAddress();
-
- // set parameters
- $parameters['session_id'] = $sessionId;
- $parameters['solution'] = $solution;
- if($authorIp != null) $parameters['author_ip'] = (string) $authorIp;
-
- // do the call
- $responseString = self::doCall('checkCaptcha', $parameters);
- // validate
- if(!isset($responseString->params->param->value->boolean)) throw new Exception('Invalid response in checkCapthca.');
-
- // return
- if((string) $responseString->params->param->value->boolean == '1') return true;
-
- // fallback
- return false;
- }
-
-
- /**
- * Check if the data is spam or not, and gets an assessment of the datas quality
- *
- * This function will be used most. The more data you submit the more accurate the claasification will be.
- * If the spamstatus is 'unsure', you could send the user an extra check (eg. a captcha).
- *
- * REMARK: the Mollom-sessionid is NOT related to HTTP-session, so don't send 'session_id'.
- *
- * The function will return an array with 3 elements:
- * - spam the spam-status (unknown/ham/spam/unsure)
- * - quality an assessment of the content's quality (between 0 and 1)
- * - session_id Molloms session_id
- *
- * @return array
- * @param string[optional] $sessionId
- * @param string[optional] $postTitle
- * @param string[optional] $postBody
- * @param string[optional] $authorName
- * @param string[optional] $authorUrl
- * @param string[optional] $authorEmail
- * @param string[optional] $authorOpenId
- * @param string[optional] $authorId
- */
- public static function checkContent($sessionId = null, $postTitle = null, $postBody = null, $authorName = null, $authorUrl = null, $authorEmail = null, $authorOpenId = null, $authorId = null)
- {
- // validate
- if($sessionId === null && $postTitle === null && $postBody === null && $authorName === null && $authorUrl === null && $authorEmail === null && $authorOpenId === null && $authorId === null) throw new Exception('Specify at least on argument');
-
- // init var
- $parameters = array();
- $aReturn = array();
-
- // add parameters
- if($sessionId !== null) $parameters['session_id'] = (string) $sessionId;
- if($postTitle !== null) $parameters['post_title'] = (string) $postTitle;
- if($postBody !== null) $parameters['post_body'] = (string) $postBody;
- if($authorName !== null) $parameters['author_name'] = (string) $authorName;
- if($authorUrl !== null) $parameters['author_url'] = (string) $authorUrl;
- if($authorEmail !== null) $parameters['author_mail'] = (string) $authorEmail;
- if($authorOpenId != null) $parameters['author_openid'] = (string) $authorOpenId;
- if($authorId != null) $parameters['author_id'] = (string) $authorId;
-
- // set autor ip
- $authorIp = self::getIpAddress();
- if($authorIp != null) $parameters['author_ip'] = (string) $authorIp;
-
- // do the call
- $responseString = self::doCall('checkContent', $parameters);
-
- // validate
- if(!isset($responseString->params->param->value->struct->member)) throw new Exception('Invalid response in checkContent.');
-
- // loop parts
- foreach ($responseString->params->param->value->struct->member as $part)
- {
- // get key
- $key = $part->name;
-
- // get value
- switch ($part->name)
- {
- case 'spam':
- $value = (string) $part->value->int;
-
- switch($value)
- {
- case '0':
- $aReturn['spam'] = 'unknown';
- break;
-
- case '1':
- $aReturn['spam'] = 'ham';
- break;
-
- case '2':
- $aReturn['spam'] = 'spam';
- break;
-
- case '3':
- $aReturn['spam'] = 'unsure';
- break;
- }
- break;
-
- case 'quality':
- $aReturn['quality'] = (float) $part->value->double;
- break;
-
- case 'session_id':
- $aReturn['session_id'] = (string) $part->value->string;
- break;
- }
- }
-
- // return
- return $aReturn;
- }
-
-
- /**
- * Make the call
- *
- * @return SimpleXMLElement
- * @param string $method
- * @param array[optional] $parameters
- */
- private static function doCall($method, $parameters = array(), $server = null, $counter = 0)
- {
- // count available servers
- $countServerList = count(self::$serverList);
-
- if($server === null && $countServerList == 0) throw new Exception('No servers found, populate the serverlist. See setServerList().');
-
- // redefine var
- $method = (string) $method;
- $parameters = (array) $parameters;
-
- // possible methods
- $aPossibleMethods = array('checkCaptcha', 'checkContent', 'getAudioCaptcha', 'getImageCaptcha', 'getServerList', 'getStatistics', 'sendFeedback', 'verifyKey');
-
- // check if method is valid
- if(!in_array($method, $aPossibleMethods)) throw new Exception('Invalid method. Only '. implode(', ', $aPossibleMethods) .' are possible methods.');
-
- // check if public key is set
- if(self::$publicKey === null) throw new Exception('Public key wasn\'t set.');
-
- // check if private key is set
- if(self::$privateKey === null) throw new Exception('Private key wasn\'t set.');
-
- // still null
- if($server === null) $server = self::$serverList[$counter];
-
- // cleanup server string
- $server = str_replace(array('http://', 'https://'), '', $server);
-
- // create timestamp
- $time = gmdate("Y-m-d\TH:i:s.\\0\\0\\0O", time());
-
- // create nonce
- $nonce = md5(time());
-
- // create has
- $hash = base64_encode(
- pack("H*", sha1((str_pad(self::$privateKey, 64, chr(0x00)) ^ (str_repeat(chr(0x5c), 64))) .
- pack("H*", sha1((str_pad(self::$privateKey, 64, chr(0x00)) ^ (str_repeat(chr(0x36), 64))) .
- $time . ':'. $nonce .':'. self::$privateKey))))
- );
-
- // add parameters
- $parameters['public_key'] = self::$publicKey;
- $parameters['time'] = $time;
- $parameters['hash'] = $hash;
- $parameters['nonce'] = $nonce;
-
- // build request
- $requestBody = '<?xml version="1.0"?>' ."\n";
- $requestBody .= '<methodCall>' ."\n";
- $requestBody .= ' <methodName>mollom.'. $method .'</methodName>' ."\n";
- $requestBody .= ' <params>' ."\n";
- $requestBody .= ' <param>'."\n";
- $requestBody .= ' '. self::buildValue($parameters) ."\n";
- $requestBody .= ' </param>'."\n";
- $requestBody .= ' </params>' ."\n";
- $requestBody .= '</methodCall>' ."\n";
-
- // create curl
- $curl = @curl_init();
-
- // set useragent
- @curl_setopt($curl, CURLOPT_USERAGENT, self::$userAgent);
-
- // set options
- @curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- @curl_setopt($curl, CURLOPT_POST, true);
- @curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
- @curl_setopt($curl, CURLOPT_HEADER, true);
- @curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
- @curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, self::$timeout);
- @curl_setopt($curl, CURLOPT_TIMEOUT, self::$timeout);
-
- // set url
- @curl_setopt($curl, CURLOPT_URL, $server .'/'. self::$version);
-
- // set body
- @curl_setopt($curl, CURLOPT_POSTFIELDS, $requestBody);
-
- // get response
- $response = @curl_exec($curl);
-
- // get errors
- $errorNumber = (int) @curl_errno($curl);
- $errorString = @curl_error($curl);
-
- // close
- @curl_close($curl);
-
- // validate response
- if($response === false || $errorNumber != 0)
- {
- // increment counter
- $counter++;
-
- // no servers left
- if($errorNumber == 28 && !isset(self::$serverList[$counter]) && $countServerList != 0) throw new Exception('No more servers available, try to increase the timeout.');
-
- // timeout
- elseif($errorNumber == 28 && isset(self::$serverList[$counter])) return self::doCall($method, $parameters, self::$serverList[$counter], $counter);
-
- // other error
- else throw new Exception('Something went wrong. Maybe the following message can be handy.<br />'. $errorString, $errorNumber);
- }
-
- // process response
- $parts = explode("\r\n\r\n", $response);
-
- // validate
- if(!isset($parts[0]) || !isset($parts[1])) throw new Exception('Invalid response in doCall.');
-
- // get headers
- $headers = $parts[0];
-
- // rebuild body
- array_shift($parts);
- $body = implode('', $parts);
-
- // validate header
- $aValidHeaders = array('HTTP/1.0 200', 'HTTP/1.1 200');
- if(!in_array(substr($headers, 0, 12), $aValidHeaders)) throw new Exception('Invalid headers.');
-
- // do some validation
- $responseXML = @simplexml_load_string($body);
- if($responseXML === false) throw new Exception('Invalid body.');
-
- if(isset($responseXML->fault))
- {
- $code = (isset($responseXML->fault->value->struct->member[0]->value->int)) ? (int) $responseXML->fault->value->struct->member[0]->value->int : 'unknown';
- $message = (isset($responseXML->fault->value->struct->member[1]->value->string)) ? (string) $responseXML->fault->value->struct->member[1]->value->string : 'unknown';
-
- // handle errors
- switch ($code)
- {
- // code 1000 (Parse error or internal problem)
- case 1000:
- throw new Exception('[error '.$code .'] '. $message, $code);
-
- // code 1100 (Serverlist outdated)
- case 1100:
- throw new Exception('[error '.$code .'] '. $message, $code);
-
- // code 1200 (Server too busy)
- case 1200:
- if(self::$serverList === null) self::getServerList();
-
- // do call again
- return self::doCall($method, $parameters, self::$serverList[$counter], $counter++);
- break;
-
- default:
- throw new Exception('[error '.$code .'] '. $message, $code);
- }
- }
-
- // return
- return $responseXML;
- }
-
-
- /**
- * Get a CAPTCHA-mp3 generated by Mollom
- *
- * If your already called getAudioCaptcha make sure you provide at least the $sessionId. It will be used
- * to identify visitors that are trying to break a CAPTCHA with brute force.
- *
- * REMARK: the Mollom-sessionid is NOT related to HTTP-session, so don't send 'session_id'.
- *
- * The function will return an array with 3 elements:
- * - session_id the session_id from Mollom
- * - url the url to the mp3-file
- * - html html that can be used on your website to display the CAPTCHA
- *
- * @return array
- * @param string[optional] $sessionId
- */
- public static function getAudioCaptcha($sessionId = null)
- {
- // init vars
- $aReturn = array();
- $parameters = array();
-
- // set autor ip
- $authorIp = self::getIpAddress();
-
- // set parameters
- if($sessionId != null) $parameters['session_id'] = (string) $sessionId;
- if($authorIp != null) $parameters['author_ip'] = (string) $authorIp;
-
- // do the call
- $responseString = self::doCall('getAudioCaptcha', $parameters);
-
- // validate
- if(!isset($responseString->params->param->value->struct->member)) throw new Exception('Invalid response in getAudioCaptcha.');
-
- // loop elements
- foreach ($responseString->params->param->value->struct->member as $part) $aReturn[(string) $part->name] = (string) $part->value->string;
-
- // add image html
- $aReturn['html'] = '<object type="audio/mpeg" data="'. $aReturn['url'] .'" width="50" height="16">'."\n"
- ."\t".'<param name="autoplay" value="false" />'."\n"
- ."\t".'<param name="controller" value="true" />'."\n"
- .'</object>';
-
- // return
- return $aReturn;
- }
-
-
- /**
- * Get a CAPTCHA-image generated by Mollom
- *
- * If your already called getImageCaptcha make sure you provide at least the $sessionId. It will be used
- * to identify visitors that are trying to break a CAPTCHA with brute force.
- *
- * REMARK: the Mollom-sessionid is NOT related to HTTP-session, so don't send 'session_id'.
- *
- * The function will return an array with 3 elements:
- * - session_id the session_id from Mollom
- * - url the url to the image
- * - html html that can be used on your website to display the CAPTCHA
- *
- * @return array
- * @param string[optional] $sessionId
- */
- public static function getImageCaptcha($sessionId = null)
- {
- // init vars
- $aReturn = array();
- $parameters = array();
-
- // set autor ip
- $authorIp = self::getIpAddress();
-
- // set parameters
- if($sessionId !== null) $parameters['session_id'] = (string) $sessionId;
- if($authorIp !== null) $parameters['author_ip'] = (string) $authorIp;
-
- // do the call
- $responseString = self::doCall('getImageCaptcha', $parameters);
-
- // validate
- if(!isset($responseString->params->param->value->struct->member)) throw new Exception('Invalid response in getImageCaptcha.');
-
- // loop elements
- foreach ($responseString->params->param->value->struct->member as $part) $aReturn[(string) $part->name] = (string) $part->value->string;
-
- // add image html
- $aReturn['html'] = '<img src="'. $aReturn['url'] .'" alt="Mollom CAPTCHA" />';
-
- // return
- return $aReturn;
- }
-
-
- /**
- * Get the real IP-address
- *
- * @return string
- */
- public static function getIpAddress()
- {
- // pre check
- if(!isset($_SERVER['REMOTE_ADDR'])) return null;
-
- // get ip
- $ipAddress = $_SERVER['REMOTE_ADDR'];
-
- if(self::$reverseProxy)
- {
- if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
- {
- if(!empty(self::$allowedReverseProxyAddresses) && in_array($ipAddress, self::$allowedProxyAddresses, true))
- {
- return array_pop(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']));
- }
- }
-
- // running in a cluster environment
- if(isset($_SERVER['HTTP_X_CLUSTER_CLIENT_IP'])) return $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
- }
-
- // fallback
- return $ipAddress;
- }
-
-
- /**
- * Obtains a list of valid servers
- *
- * @return array
- */
- public static function getServerList($counter = 0)
- {
- // do the call
- $responseString = self::doCall('getServerList', array(), self::$serverHost, $counter);
-
- // validate
- if(!isset($responseString->params->param->value->array->data->value)) throw new Exception('Invalid response in getServerList.');
-
- // loop servers and add them
- foreach ($responseString->params->param->value->array->data->value as $server) self::$serverList[] = (string) $server->string;
-
- if(count(self::$serverList) == 0) self::$serverList = array('http://xmlrpc3.mollom.com', 'http://xmlrpc2.mollom.com', 'http://xmlrpc1.mollom.com');
-
- // return
- return self::$serverList;
- }
-
-
- /**
- * Retrieve statistics from Mollom
- *
- * Allowed types are listed below:
- * - total_days Number of days Mollom has been used
- * - total_accepted Total of blocked spam
- * - total_rejected Total accepted posts (not working?)
- * - yesterday_accepted Amount of spam blocked yesterday
- * - yesterday_rejected Number of posts accepted yesterday (not working?)
- * - today_accepted Amount of spam blocked today
- * - today_rejected Number of posts accepted today (not working?)
- *
- * @return int
- * @param string $type
- */
- public static function getStatistics($type)
- {
- // possible types
- $aPossibleTypes = array('total_days', 'total_accepted', 'total_rejected', 'yesterday_accepted', 'yesterday_rejected', 'today_accepted', 'today_rejected');
-
- // redefine
- $type = (string) $type;
-
- // validate
- if(!in_array($type, $aPossibleTypes)) throw new Exception('Invalid type. Only '. implode(', ', $aPossibleTypes) .' are possible types.');
-
- // do the call
- $responseString = self::doCall('getStatistics', array('type' => $type));
-
- // validate
- if(!isset($responseString->params->param->value->int)) throw new Exception('Invalid response in getStatistics.');
-
- // return
- return (int) $responseString->params->param->value->int;
- }
-
-
- /**
- * Send feedback to Mollom.
- *
- * With this method you can help train Mollom. Implement this method if possible. The more feedback is provided the more accurate
- * Mollom will be.
- *
- * Allowed feedback-strings are listed below:
- * - spam Spam or unsolicited advertising
- * - profanity Obscene, violent or profane content
- * - low-quality Low-quality content or writing
- * - unwanted Unwanted, taunting or off-topic content
- *
- * @return bool
- * @param string $sessionId
- * @param string $feedback
- */
- public static function sendFeedback($sessionId, $feedback)
- {
- // possible feedback
- $aPossibleFeedback = array('spam', 'profanity', 'low-quality', 'unwanted');
-
- // redefine
- $sessionId = (string) $sessionId;
- $feedback = (string) $feedback;
-
- // validate
- if(!in_array($feedback, $aPossibleFeedback)) throw new Exception('Invalid feedback. Only '. implode(', ', $aPossibleFeedback) .' are possible feedback-strings.');
-
- // build parameters
- $parameters['session_id'] = $sessionId;
- $parameters['feedback'] = $feedback;
-
- // do the call
- $responseString = self::doCall('sendFeedback', $parameters);
-
- // validate
- if(!isset($responseString->params->param->value->boolean)) throw new Exception('Invalid response in sendFeedback.');
-
- // return
- if((string) $responseString->params->param->value->boolean == 1) return true;
-
- // fallback
- return false;
- }
-
-
- /**
- * Set the allowed reverse proxy Addresses
- *
- * @return void
- * @param array $addresses
- */
- public static function setAllowedReverseProxyAddresses($addresses)
- {
- // store allowed ip-addresses
- self::$allowedReverseProxyAddresses = (array) $addresses;
-
- // set reverse proxy
- self::$reverseProxy = (!empty($addresses)) ? true : false;
- }
-
-
- /**
- * Set the private key
- *
- * @return void
- * @param string $key
- */
- public static function setPrivateKey($key)
- {
- self::$privateKey = (string) $key;
- }
-
-
- /**
- * Set the public key
- *
- * @return void
- * @param string $key
- */
- public static function setPublicKey($key)
- {
- self::$publicKey = (string) $key;
- }
-
-
- /**
- * Set the server list
- *
- * @return void
- * @param array $servers
- */
- public static function setServerList($servers)
- {
- // redefine
- $server = (array) $servers;
-
- // loop servers
- foreach ($servers as $server) self::$serverList[] = $server;
- }
-
-
- /**
- * Set timeout
- *
- * @return void
- * @param int $timeout
- */
- public static function setTimeOut($timeout)
- {
- // redefine
- $timeout = (int) $timeout;
-
- // validate
- if($timeout == 0) throw new Exception('Invalid timeout. Timeout shouldn\'t be 0.');
-
- // set property
- self::$timeout = $timeout;
- }
-
-
- /**
- * Set the user agent
- *
- * @return void
- * @param string $newUserAgent
- */
- public static function setUserAgent($newUserAgent)
- {
- self::$userAgent .= ' '. (string) $newUserAgent;
- }
-
-
- /**
- * Verifies your key
- *
- * Returns information about the status of your key. Mollom will respond with a boolean value (true/false).
- * False means that your keys is disabled or doesn't exists. True means the key is enabled and working properly.
- *
- * @return bool
- */
- public static function verifyKey()
- {
- // do the call
- $responseString = self::doCall('verifyKey');
-
- // validate
- if(!isset($responseString->params->param->value->boolean)) throw new Exception('Invalid response in verifyKey.');
-
- // return
- if((string) $responseString->params->param->value->boolean == '1') return true;
-
- // fallback
- return false;
- }
-
- }
-