PageRenderTime 60ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/administrator/components/com_zoo/libraries/mollom/mollom.php

https://bitbucket.org/organicdevelopment/joomla-2.5
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
  1. <?php
  2. /**
  3. * Mollom class
  4. *
  5. * This source file can be used to communicate with mollom (http://mollom.com)
  6. *
  7. * 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).
  8. * 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).
  9. * If you have questions, try the Mollom-forum, don't send them by mail, I won't read them.
  10. *
  11. * Changelog since 1.0.1
  12. * - Fixed a nasty bug. Possible infinite loop in doCall().
  13. * - Fixed getServerList. I misinterpreted the documentation, so now the defaultserver is xmlrpc.mollom.com instead of the first fallback-server.
  14. * - Fixed the timeout-issue. With fsockopen the timeout on connect wasn't respected. Rewrote the doCall function to use CURL over sockets.
  15. *
  16. * Changelog since 1.1.0
  17. * - Fixed a problem with the IP-addresses. see http://blog.verkoyen.eu/2008/07/12/important-php-mollom-update/
  18. *
  19. * Changelog since 1.1.1
  20. * - PHPMollom was using HTTP 1.1, now HTTP 1.0.
  21. * - Fallbackserver are hardcoded, when no servers could be retrieved the fallbacks are used
  22. *
  23. * Changelog since 1.1.2
  24. * - Typo
  25. * - New Licence: BSD Modified
  26. *
  27. * License
  28. * Copyright (c) 2008, Tijs Verkoyen. All rights reserved.
  29. *
  30. * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  31. *
  32. * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  33. * 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.
  34. * 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
  35. *
  36. * 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.
  37. *
  38. * @author Tijs Verkoyen <mollom@verkoyen.eu>
  39. * @version 1.1.3
  40. *
  41. * @copyright Copyright (c) 2008, Tijs Verkoyen. All rights reserved.
  42. * @license http://mollom.local/license BSD License
  43. */
  44. class Mollom
  45. {
  46. /**
  47. * The allowed reverse proxy addresses
  48. *
  49. * @var array
  50. */
  51. private static $allowedReverseProxyAddresses = array();
  52. /**
  53. * Your private key
  54. *
  55. * Set it by calling Mollom::setPrivateKey('<your-key>');
  56. *
  57. * @var string
  58. */
  59. private static $privateKey;
  60. /**
  61. * Your public key
  62. *
  63. * Set it by calling Mollom::setPublicKey('<your-key>');
  64. *
  65. * @var string
  66. */
  67. private static $publicKey;
  68. /**
  69. * Reverse proxy allowed?
  70. *
  71. * @var bool
  72. */
  73. private static $reverseProxy = false;
  74. /**
  75. * The default server
  76. *
  77. * No need to change
  78. *
  79. * @var string
  80. */
  81. private static $serverHost = 'xmlrpc.mollom.com';
  82. /**
  83. * The cache for the serverlist
  84. *
  85. * No need to change
  86. *
  87. * @var array
  88. */
  89. private static $serverList = array();
  90. /**
  91. * Default timeout
  92. *
  93. * @var int
  94. */
  95. private static $timeout = 10;
  96. /**
  97. * The default user-agent
  98. *
  99. * Change it by calling Mollom::setUserAgent('<your-user-agent>');
  100. *
  101. * @var string
  102. */
  103. private static $userAgent = 'MollomPHP/1.1.3';
  104. /**
  105. * The current Mollom-version
  106. *
  107. * No need to change
  108. *
  109. * @var string
  110. */
  111. private static $version = '1.0';
  112. /**
  113. * Build the value so we can use it in XML-RPC requests
  114. *
  115. * @return string
  116. * @param mixed $value
  117. */
  118. private function buildValue($value)
  119. {
  120. // get type
  121. $type = gettype($value);
  122. // build value
  123. switch ($type)
  124. {
  125. case 'string':
  126. // escape it, cause Mollom can't handle CDATA (no pun intended)
  127. $value = htmlspecialchars($value, ENT_QUOTES, 'ISO-8859-15');
  128. return '<value><string>'. $value .'</string></value>'."\n";
  129. case 'array':
  130. // init struct
  131. $struct = '<value>'."\n";
  132. $struct .= ' <struct>'."\n";
  133. // loop array
  134. foreach ($value as $key => $value) $struct .= str_replace("\n", '', '<member>'. "\n" .'<name>'. $key .'</name>'. self::buildValue($value) .'</member>') . "\n";
  135. $struct .= ' </struct>'."\n";
  136. $struct .= '</value>'."\n";
  137. // return
  138. return $struct;
  139. default:
  140. return '<value>'. $value .'</value>'."\n";
  141. }
  142. }
  143. /**
  144. * Validates the answer for a CAPTCHA
  145. *
  146. * When the answer is false, you should request a new image- or audio-CAPTCHA, make sure your provide the current Mollom-sessionid.
  147. * The sessionid will be used to track spambots that try to solve CAPTHCA's by brute force.
  148. *
  149. * @return bool
  150. * @param string $sessionId
  151. * @param string $solution
  152. */
  153. public static function checkCaptcha($sessionId, $solution)
  154. {
  155. // redefine
  156. $sessionId = (string) $sessionId;
  157. $solution = (string) $solution;
  158. // set autor ip
  159. $authorIp = self::getIpAddress();
  160. // set parameters
  161. $parameters['session_id'] = $sessionId;
  162. $parameters['solution'] = $solution;
  163. if($authorIp != null) $parameters['author_ip'] = (string) $authorIp;
  164. // do the call
  165. $responseString = self::doCall('checkCaptcha', $parameters);
  166. // validate
  167. if(!isset($responseString->params->param->value->boolean)) throw new Exception('Invalid response in checkCapthca.');
  168. // return
  169. if((string) $responseString->params->param->value->boolean == '1') return true;
  170. // fallback
  171. return false;
  172. }
  173. /**
  174. * Check if the data is spam or not, and gets an assessment of the datas quality
  175. *
  176. * This function will be used most. The more data you submit the more accurate the claasification will be.
  177. * If the spamstatus is 'unsure', you could send the user an extra check (eg. a captcha).
  178. *
  179. * REMARK: the Mollom-sessionid is NOT related to HTTP-session, so don't send 'session_id'.
  180. *
  181. * The function will return an array with 3 elements:
  182. * - spam the spam-status (unknown/ham/spam/unsure)
  183. * - quality an assessment of the content's quality (between 0 and 1)
  184. * - session_id Molloms session_id
  185. *
  186. * @return array
  187. * @param string[optional] $sessionId
  188. * @param string[optional] $postTitle
  189. * @param string[optional] $postBody
  190. * @param string[optional] $authorName
  191. * @param string[optional] $authorUrl
  192. * @param string[optional] $authorEmail
  193. * @param string[optional] $authorOpenId
  194. * @param string[optional] $authorId
  195. */
  196. public static function checkContent($sessionId = null, $postTitle = null, $postBody = null, $authorName = null, $authorUrl = null, $authorEmail = null, $authorOpenId = null, $authorId = null)
  197. {
  198. // validate
  199. 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');
  200. // init var
  201. $parameters = array();
  202. $aReturn = array();
  203. // add parameters
  204. if($sessionId !== null) $parameters['session_id'] = (string) $sessionId;
  205. if($postTitle !== null) $parameters['post_title'] = (string) $postTitle;
  206. if($postBody !== null) $parameters['post_body'] = (string) $postBody;
  207. if($authorName !== null) $parameters['author_name'] = (string) $authorName;
  208. if($authorUrl !== null) $parameters['author_url'] = (string) $authorUrl;
  209. if($authorEmail !== null) $parameters['author_mail'] = (string) $authorEmail;
  210. if($authorOpenId != null) $parameters['author_openid'] = (string) $authorOpenId;
  211. if($authorId != null) $parameters['author_id'] = (string) $authorId;
  212. // set autor ip
  213. $authorIp = self::getIpAddress();
  214. if($authorIp != null) $parameters['author_ip'] = (string) $authorIp;
  215. // do the call
  216. $responseString = self::doCall('checkContent', $parameters);
  217. // validate
  218. if(!isset($responseString->params->param->value->struct->member)) throw new Exception('Invalid response in checkContent.');
  219. // loop parts
  220. foreach ($responseString->params->param->value->struct->member as $part)
  221. {
  222. // get key
  223. $key = $part->name;
  224. // get value
  225. switch ($part->name)
  226. {
  227. case 'spam':
  228. $value = (string) $part->value->int;
  229. switch($value)
  230. {
  231. case '0':
  232. $aReturn['spam'] = 'unknown';
  233. break;
  234. case '1':
  235. $aReturn['spam'] = 'ham';
  236. break;
  237. case '2':
  238. $aReturn['spam'] = 'spam';
  239. break;
  240. case '3':
  241. $aReturn['spam'] = 'unsure';
  242. break;
  243. }
  244. break;
  245. case 'quality':
  246. $aReturn['quality'] = (float) $part->value->double;
  247. break;
  248. case 'session_id':
  249. $aReturn['session_id'] = (string) $part->value->string;
  250. break;
  251. }
  252. }
  253. // return
  254. return $aReturn;
  255. }
  256. /**
  257. * Make the call
  258. *
  259. * @return SimpleXMLElement
  260. * @param string $method
  261. * @param array[optional] $parameters
  262. */
  263. private static function doCall($method, $parameters = array(), $server = null, $counter = 0)
  264. {
  265. // count available servers
  266. $countServerList = count(self::$serverList);
  267. if($server === null && $countServerList == 0) throw new Exception('No servers found, populate the serverlist. See setServerList().');
  268. // redefine var
  269. $method = (string) $method;
  270. $parameters = (array) $parameters;
  271. // possible methods
  272. $aPossibleMethods = array('checkCaptcha', 'checkContent', 'getAudioCaptcha', 'getImageCaptcha', 'getServerList', 'getStatistics', 'sendFeedback', 'verifyKey');
  273. // check if method is valid
  274. if(!in_array($method, $aPossibleMethods)) throw new Exception('Invalid method. Only '. implode(', ', $aPossibleMethods) .' are possible methods.');
  275. // check if public key is set
  276. if(self::$publicKey === null) throw new Exception('Public key wasn\'t set.');
  277. // check if private key is set
  278. if(self::$privateKey === null) throw new Exception('Private key wasn\'t set.');
  279. // still null
  280. if($server === null) $server = self::$serverList[$counter];
  281. // cleanup server string
  282. $server = str_replace(array('http://', 'https://'), '', $server);
  283. // create timestamp
  284. $time = gmdate("Y-m-d\TH:i:s.\\0\\0\\0O", time());
  285. // create nonce
  286. $nonce = md5(time());
  287. // create has
  288. $hash = base64_encode(
  289. pack("H*", sha1((str_pad(self::$privateKey, 64, chr(0x00)) ^ (str_repeat(chr(0x5c), 64))) .
  290. pack("H*", sha1((str_pad(self::$privateKey, 64, chr(0x00)) ^ (str_repeat(chr(0x36), 64))) .
  291. $time . ':'. $nonce .':'. self::$privateKey))))
  292. );
  293. // add parameters
  294. $parameters['public_key'] = self::$publicKey;
  295. $parameters['time'] = $time;
  296. $parameters['hash'] = $hash;
  297. $parameters['nonce'] = $nonce;
  298. // build request
  299. $requestBody = '<?xml version="1.0"?>' ."\n";
  300. $requestBody .= '<methodCall>' ."\n";
  301. $requestBody .= ' <methodName>mollom.'. $method .'</methodName>' ."\n";
  302. $requestBody .= ' <params>' ."\n";
  303. $requestBody .= ' <param>'."\n";
  304. $requestBody .= ' '. self::buildValue($parameters) ."\n";
  305. $requestBody .= ' </param>'."\n";
  306. $requestBody .= ' </params>' ."\n";
  307. $requestBody .= '</methodCall>' ."\n";
  308. // create curl
  309. $curl = @curl_init();
  310. // set useragent
  311. @curl_setopt($curl, CURLOPT_USERAGENT, self::$userAgent);
  312. // set options
  313. @curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
  314. @curl_setopt($curl, CURLOPT_POST, true);
  315. @curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
  316. @curl_setopt($curl, CURLOPT_HEADER, true);
  317. @curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  318. @curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, self::$timeout);
  319. @curl_setopt($curl, CURLOPT_TIMEOUT, self::$timeout);
  320. // set url
  321. @curl_setopt($curl, CURLOPT_URL, $server .'/'. self::$version);
  322. // set body
  323. @curl_setopt($curl, CURLOPT_POSTFIELDS, $requestBody);
  324. // get response
  325. $response = @curl_exec($curl);
  326. // get errors
  327. $errorNumber = (int) @curl_errno($curl);
  328. $errorString = @curl_error($curl);
  329. // close
  330. @curl_close($curl);
  331. // validate response
  332. if($response === false || $errorNumber != 0)
  333. {
  334. // increment counter
  335. $counter++;
  336. // no servers left
  337. if($errorNumber == 28 && !isset(self::$serverList[$counter]) && $countServerList != 0) throw new Exception('No more servers available, try to increase the timeout.');
  338. // timeout
  339. elseif($errorNumber == 28 && isset(self::$serverList[$counter])) return self::doCall($method, $parameters, self::$serverList[$counter], $counter);
  340. // other error
  341. else throw new Exception('Something went wrong. Maybe the following message can be handy.<br />'. $errorString, $errorNumber);
  342. }
  343. // process response
  344. $parts = explode("\r\n\r\n", $response);
  345. // validate
  346. if(!isset($parts[0]) || !isset($parts[1])) throw new Exception('Invalid response in doCall.');
  347. // get headers
  348. $headers = $parts[0];
  349. // rebuild body
  350. array_shift($parts);
  351. $body = implode('', $parts);
  352. // validate header
  353. $aValidHeaders = array('HTTP/1.0 200', 'HTTP/1.1 200');
  354. if(!in_array(substr($headers, 0, 12), $aValidHeaders)) throw new Exception('Invalid headers.');
  355. // do some validation
  356. $responseXML = @simplexml_load_string($body);
  357. if($responseXML === false) throw new Exception('Invalid body.');
  358. if(isset($responseXML->fault))
  359. {
  360. $code = (isset($responseXML->fault->value->struct->member[0]->value->int)) ? (int) $responseXML->fault->value->struct->member[0]->value->int : 'unknown';
  361. $message = (isset($responseXML->fault->value->struct->member[1]->value->string)) ? (string) $responseXML->fault->value->struct->member[1]->value->string : 'unknown';
  362. // handle errors
  363. switch ($code)
  364. {
  365. // code 1000 (Parse error or internal problem)
  366. case 1000:
  367. throw new Exception('[error '.$code .'] '. $message, $code);
  368. // code 1100 (Serverlist outdated)
  369. case 1100:
  370. throw new Exception('[error '.$code .'] '. $message, $code);
  371. // code 1200 (Server too busy)
  372. case 1200:
  373. if(self::$serverList === null) self::getServerList();
  374. // do call again
  375. return self::doCall($method, $parameters, self::$serverList[$counter], $counter++);
  376. break;
  377. default:
  378. throw new Exception('[error '.$code .'] '. $message, $code);
  379. }
  380. }
  381. // return
  382. return $responseXML;
  383. }
  384. /**
  385. * Get a CAPTCHA-mp3 generated by Mollom
  386. *
  387. * If your already called getAudioCaptcha make sure you provide at least the $sessionId. It will be used
  388. * to identify visitors that are trying to break a CAPTCHA with brute force.
  389. *
  390. * REMARK: the Mollom-sessionid is NOT related to HTTP-session, so don't send 'session_id'.
  391. *
  392. * The function will return an array with 3 elements:
  393. * - session_id the session_id from Mollom
  394. * - url the url to the mp3-file
  395. * - html html that can be used on your website to display the CAPTCHA
  396. *
  397. * @return array
  398. * @param string[optional] $sessionId
  399. */
  400. public static function getAudioCaptcha($sessionId = null)
  401. {
  402. // init vars
  403. $aReturn = array();
  404. $parameters = array();
  405. // set autor ip
  406. $authorIp = self::getIpAddress();
  407. // set parameters
  408. if($sessionId != null) $parameters['session_id'] = (string) $sessionId;
  409. if($authorIp != null) $parameters['author_ip'] = (string) $authorIp;
  410. // do the call
  411. $responseString = self::doCall('getAudioCaptcha', $parameters);
  412. // validate
  413. if(!isset($responseString->params->param->value->struct->member)) throw new Exception('Invalid response in getAudioCaptcha.');
  414. // loop elements
  415. foreach ($responseString->params->param->value->struct->member as $part) $aReturn[(string) $part->name] = (string) $part->value->string;
  416. // add image html
  417. $aReturn['html'] = '<object type="audio/mpeg" data="'. $aReturn['url'] .'" width="50" height="16">'."\n"
  418. ."\t".'<param name="autoplay" value="false" />'."\n"
  419. ."\t".'<param name="controller" value="true" />'."\n"
  420. .'</object>';
  421. // return
  422. return $aReturn;
  423. }
  424. /**
  425. * Get a CAPTCHA-image generated by Mollom
  426. *
  427. * If your already called getImageCaptcha make sure you provide at least the $sessionId. It will be used
  428. * to identify visitors that are trying to break a CAPTCHA with brute force.
  429. *
  430. * REMARK: the Mollom-sessionid is NOT related to HTTP-session, so don't send 'session_id'.
  431. *
  432. * The function will return an array with 3 elements:
  433. * - session_id the session_id from Mollom
  434. * - url the url to the image
  435. * - html html that can be used on your website to display the CAPTCHA
  436. *
  437. * @return array
  438. * @param string[optional] $sessionId
  439. */
  440. public static function getImageCaptcha($sessionId = null)
  441. {
  442. // init vars
  443. $aReturn = array();
  444. $parameters = array();
  445. // set autor ip
  446. $authorIp = self::getIpAddress();
  447. // set parameters
  448. if($sessionId !== null) $parameters['session_id'] = (string) $sessionId;
  449. if($authorIp !== null) $parameters['author_ip'] = (string) $authorIp;
  450. // do the call
  451. $responseString = self::doCall('getImageCaptcha', $parameters);
  452. // validate
  453. if(!isset($responseString->params->param->value->struct->member)) throw new Exception('Invalid response in getImageCaptcha.');
  454. // loop elements
  455. foreach ($responseString->params->param->value->struct->member as $part) $aReturn[(string) $part->name] = (string) $part->value->string;
  456. // add image html
  457. $aReturn['html'] = '<img src="'. $aReturn['url'] .'" alt="Mollom CAPTCHA" />';
  458. // return
  459. return $aReturn;
  460. }
  461. /**
  462. * Get the real IP-address
  463. *
  464. * @return string
  465. */
  466. public static function getIpAddress()
  467. {
  468. // pre check
  469. if(!isset($_SERVER['REMOTE_ADDR'])) return null;
  470. // get ip
  471. $ipAddress = $_SERVER['REMOTE_ADDR'];
  472. if(self::$reverseProxy)
  473. {
  474. if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
  475. {
  476. if(!empty(self::$allowedReverseProxyAddresses) && in_array($ipAddress, self::$allowedProxyAddresses, true))
  477. {
  478. return array_pop(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']));
  479. }
  480. }
  481. // running in a cluster environment
  482. if(isset($_SERVER['HTTP_X_CLUSTER_CLIENT_IP'])) return $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
  483. }
  484. // fallback
  485. return $ipAddress;
  486. }
  487. /**
  488. * Obtains a list of valid servers
  489. *
  490. * @return array
  491. */
  492. public static function getServerList($counter = 0)
  493. {
  494. // do the call
  495. $responseString = self::doCall('getServerList', array(), self::$serverHost, $counter);
  496. // validate
  497. if(!isset($responseString->params->param->value->array->data->value)) throw new Exception('Invalid response in getServerList.');
  498. // loop servers and add them
  499. foreach ($responseString->params->param->value->array->data->value as $server) self::$serverList[] = (string) $server->string;
  500. if(count(self::$serverList) == 0) self::$serverList = array('http://xmlrpc3.mollom.com', 'http://xmlrpc2.mollom.com', 'http://xmlrpc1.mollom.com');
  501. // return
  502. return self::$serverList;
  503. }
  504. /**
  505. * Retrieve statistics from Mollom
  506. *
  507. * Allowed types are listed below:
  508. * - total_days Number of days Mollom has been used
  509. * - total_accepted Total of blocked spam
  510. * - total_rejected Total accepted posts (not working?)
  511. * - yesterday_accepted Amount of spam blocked yesterday
  512. * - yesterday_rejected Number of posts accepted yesterday (not working?)
  513. * - today_accepted Amount of spam blocked today
  514. * - today_rejected Number of posts accepted today (not working?)
  515. *
  516. * @return int
  517. * @param string $type
  518. */
  519. public static function getStatistics($type)
  520. {
  521. // possible types
  522. $aPossibleTypes = array('total_days', 'total_accepted', 'total_rejected', 'yesterday_accepted', 'yesterday_rejected', 'today_accepted', 'today_rejected');
  523. // redefine
  524. $type = (string) $type;
  525. // validate
  526. if(!in_array($type, $aPossibleTypes)) throw new Exception('Invalid type. Only '. implode(', ', $aPossibleTypes) .' are possible types.');
  527. // do the call
  528. $responseString = self::doCall('getStatistics', array('type' => $type));
  529. // validate
  530. if(!isset($responseString->params->param->value->int)) throw new Exception('Invalid response in getStatistics.');
  531. // return
  532. return (int) $responseString->params->param->value->int;
  533. }
  534. /**
  535. * Send feedback to Mollom.
  536. *
  537. * With this method you can help train Mollom. Implement this method if possible. The more feedback is provided the more accurate
  538. * Mollom will be.
  539. *
  540. * Allowed feedback-strings are listed below:
  541. * - spam Spam or unsolicited advertising
  542. * - profanity Obscene, violent or profane content
  543. * - low-quality Low-quality content or writing
  544. * - unwanted Unwanted, taunting or off-topic content
  545. *
  546. * @return bool
  547. * @param string $sessionId
  548. * @param string $feedback
  549. */
  550. public static function sendFeedback($sessionId, $feedback)
  551. {
  552. // possible feedback
  553. $aPossibleFeedback = array('spam', 'profanity', 'low-quality', 'unwanted');
  554. // redefine
  555. $sessionId = (string) $sessionId;
  556. $feedback = (string) $feedback;
  557. // validate
  558. if(!in_array($feedback, $aPossibleFeedback)) throw new Exception('Invalid feedback. Only '. implode(', ', $aPossibleFeedback) .' are possible feedback-strings.');
  559. // build parameters
  560. $parameters['session_id'] = $sessionId;
  561. $parameters['feedback'] = $feedback;
  562. // do the call
  563. $responseString = self::doCall('sendFeedback', $parameters);
  564. // validate
  565. if(!isset($responseString->params->param->value->boolean)) throw new Exception('Invalid response in sendFeedback.');
  566. // return
  567. if((string) $responseString->params->param->value->boolean == 1) return true;
  568. // fallback
  569. return false;
  570. }
  571. /**
  572. * Set the allowed reverse proxy Addresses
  573. *
  574. * @return void
  575. * @param array $addresses
  576. */
  577. public static function setAllowedReverseProxyAddresses($addresses)
  578. {
  579. // store allowed ip-addresses
  580. self::$allowedReverseProxyAddresses = (array) $addresses;
  581. // set reverse proxy
  582. self::$reverseProxy = (!empty($addresses)) ? true : false;
  583. }
  584. /**
  585. * Set the private key
  586. *
  587. * @return void
  588. * @param string $key
  589. */
  590. public static function setPrivateKey($key)
  591. {
  592. self::$privateKey = (string) $key;
  593. }
  594. /**
  595. * Set the public key
  596. *
  597. * @return void
  598. * @param string $key
  599. */
  600. public static function setPublicKey($key)
  601. {
  602. self::$publicKey = (string) $key;
  603. }
  604. /**
  605. * Set the server list
  606. *
  607. * @return void
  608. * @param array $servers
  609. */
  610. public static function setServerList($servers)
  611. {
  612. // redefine
  613. $server = (array) $servers;
  614. // loop servers
  615. foreach ($servers as $server) self::$serverList[] = $server;
  616. }
  617. /**
  618. * Set timeout
  619. *
  620. * @return void
  621. * @param int $timeout
  622. */
  623. public static function setTimeOut($timeout)
  624. {
  625. // redefine
  626. $timeout = (int) $timeout;
  627. // validate
  628. if($timeout == 0) throw new Exception('Invalid timeout. Timeout shouldn\'t be 0.');
  629. // set property
  630. self::$timeout = $timeout;
  631. }
  632. /**
  633. * Set the user agent
  634. *
  635. * @return void
  636. * @param string $newUserAgent
  637. */
  638. public static function setUserAgent($newUserAgent)
  639. {
  640. self::$userAgent .= ' '. (string) $newUserAgent;
  641. }
  642. /**
  643. * Verifies your key
  644. *
  645. * Returns information about the status of your key. Mollom will respond with a boolean value (true/false).
  646. * False means that your keys is disabled or doesn't exists. True means the key is enabled and working properly.
  647. *
  648. * @return bool
  649. */
  650. public static function verifyKey()
  651. {
  652. // do the call
  653. $responseString = self::doCall('verifyKey');
  654. // validate
  655. if(!isset($responseString->params->param->value->boolean)) throw new Exception('Invalid response in verifyKey.');
  656. // return
  657. if((string) $responseString->params->param->value->boolean == '1') return true;
  658. // fallback
  659. return false;
  660. }
  661. }