Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
mollom.inc
1 <?php
17 define('SQ_MOLLOM_SPAM', 0);
18 define('SQ_MOLLOM_UNSURE', 1);
19 define('SQ_MOLLOM_HAM', 2);
20 define('SQ_MOLLOM_UNKNOWN', 3);
21 define('SQ_MOLLOM_INCORRECT_CAPTCHA', 4);
22 
23 require_once SQ_DATA_PATH.'/private/conf/tools.inc';
24 
25 
79 class Mollom
80 {
86  private static $allowedReverseProxyAddresses = array();
87 
88 
96  private static $privateKey;
97 
98 
106  private static $publicKey;
107 
108 
114  private static $reverseProxy = false;
115 
116 
124  private static $serverHost = 'xmlrpc.mollom.com';
125 
126 
134  private static $serverList = array();
135 
136 
142  private static $timeout = 10;
143 
144 
152  private static $userAgent = 'MollomPHP/1.1.3';
153 
154 
162  private static $version = '1.0';
163 
164 
173  private static $session_expire_time = 30;
174 
180  public static $default_server_list = array('http://xmlrpc3.mollom.com', 'http://xmlrpc2.mollom.com', 'http://xmlrpc1.mollom.com');
181 
188  private function buildValue($value)
189  {
190  // get type
191  $type = gettype($value);
192 
193  // build value
194  switch ($type)
195  {
196  case 'string':
197  // escape it, cause Mollom can't handle CDATA (no pun intended)
198  $value = htmlspecialchars($value, ENT_QUOTES, 'ISO-8859-15');
199  return '<value><string>'. $value .'</string></value>'."\n";
200 
201  case 'array':
202  // init struct
203  $struct = '<value>'."\n";
204  $struct .= ' <struct>'."\n";
205 
206  // loop array
207  foreach ($value as $key => $value) $struct .= str_replace("\n", '', '<member>'. "\n" .'<name>'. $key .'</name>'. self::buildValue($value) .'</member>') . "\n";
208 
209  $struct .= ' </struct>'."\n";
210  $struct .= '</value>'."\n";
211 
212  // return
213  return $struct;
214 
215  default:
216  return '<value>'. $value .'</value>'."\n";
217  }
218  }
219 
220 
231  public static function checkCaptcha($sessionId, $solution)
232  {
233  // redefine
234  $sessionId = (string) $sessionId;
235  $solution = (string) $solution;
236 
237  // set autor ip
238  $authorIp = self::getIpAddress();
239 
240  // set parameters
241  $parameters['session_id'] = $sessionId;
242  $parameters['solution'] = $solution;
243  if($authorIp != null) $parameters['author_ip'] = (string) $authorIp;
244 
245  // do the call
246  $responseString = self::doCall('checkCaptcha', $parameters);
247  // validate
248  if(!isset($responseString->params->param->value->boolean)) throw new Exception('Invalid response in checkCapthca.');
249 
250  // return
251  if((string) $responseString->params->param->value->boolean == '1') return true;
252 
253  // fallback
254  return false;
255  }
256 
257 
281  public static function checkContent($sessionId = null, $postTitle = null, $postBody = null, $authorName = null, $authorUrl = null, $authorEmail = null, $authorOpenId = null, $authorId = null)
282  {
283  // validate
284  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');
285 
286  // init var
287  $parameters = array();
288  $aReturn = array();
289 
290  // add parameters
291  if($sessionId !== null) $parameters['session_id'] = (string) $sessionId;
292  if($postTitle !== null) $parameters['post_title'] = (string) $postTitle;
293  if($postBody !== null) $parameters['post_body'] = (string) $postBody;
294  if($authorName !== null) $parameters['author_name'] = (string) $authorName;
295  if($authorUrl !== null) $parameters['author_url'] = (string) $authorUrl;
296  if($authorEmail !== null) $parameters['author_mail'] = (string) $authorEmail;
297  if($authorOpenId != null) $parameters['author_openid'] = (string) $authorOpenId;
298  if($authorId != null) $parameters['author_id'] = (string) $authorId;
299 
300  // set autor ip
301  $authorIp = self::getIpAddress();
302  if($authorIp != null) $parameters['author_ip'] = (string) $authorIp;
303 
304  if (SQ_TOOL_MOLLOM_TEST_MODE) {
305  $parameters['testing'] = TRUE;
306  }
307 
308  // do the call
309  $responseString = self::doCall('checkContent', $parameters);
310 
311  // validate
312  if(!isset($responseString->params->param->value->struct->member)) throw new Exception('Invalid response in checkContent.');
313 
314  // loop parts
315  foreach ($responseString->params->param->value->struct->member as $part)
316  {
317  // get key
318  $key = $part->name;
319 
320  // get value
321  switch ($part->name)
322  {
323  case 'spam':
324  $value = (string) $part->value->int;
325 
326  switch($value)
327  {
328  case '0':
329  $aReturn['spam'] = 'unknown';
330  break;
331 
332  case '1':
333  $aReturn['spam'] = 'ham';
334  break;
335 
336  case '2':
337  $aReturn['spam'] = 'spam';
338  break;
339 
340  case '3':
341  $aReturn['spam'] = 'unsure';
342  break;
343  }
344  break;
345 
346  case 'quality':
347  $aReturn['quality'] = (float) $part->value->double;
348  break;
349 
350  case 'session_id':
351  $aReturn['session_id'] = (string) $part->value->string;
352  break;
353  }
354  }
355 
356  // return
357  return $aReturn;
358  }
359 
360 
368  private static function doCall($method, $parameters = array(), $server = null, $counter = 0, $test_mode = true)
369  {
370  // count available servers
371  $countServerList = count(self::$serverList);
372 
373  if($server === null && $countServerList == 0) throw new Exception('No servers found, populate the serverlist. See setServerList().');
374 
375  // redefine var
376  $method = (string) $method;
377  $parameters = (array) $parameters;
378 
379  // possible methods
380  $aPossibleMethods = array('checkCaptcha', 'checkContent', 'getAudioCaptcha', 'getImageCaptcha', 'getServerList', 'getStatistics', 'sendFeedback', 'verifyKey');
381 
382  // check if method is valid
383  if(!in_array($method, $aPossibleMethods)) throw new Exception('Invalid method. Only '. implode(', ', $aPossibleMethods) .' are possible methods.');
384 
385  // check if public key is set
386  if(self::$publicKey === null) throw new Exception('Public key wasn\'t set.');
387 
388  // check if private key is set
389  if(self::$privateKey === null) throw new Exception('Private key wasn\'t set.');
390 
391  // still null
392  if($server === null) $server = self::$serverList[$counter];
393 
394  // cleanup server string
395  $server = str_replace(array('http://', 'https://'), '', $server);
396 
397  // create timestamp
398  $time = gmdate("Y-m-d\TH:i:s.\\0\\0\\0O", time());
399 
400  // create nonce
401  $nonce = md5(time());
402 
403  // create has
404  $hash = base64_encode(
405  pack("H*", sha1((str_pad(self::$privateKey, 64, chr(0x00)) ^ (str_repeat(chr(0x5c), 64))) .
406  pack("H*", sha1((str_pad(self::$privateKey, 64, chr(0x00)) ^ (str_repeat(chr(0x36), 64))) .
407  $time . ':'. $nonce .':'. self::$privateKey))))
408  );
409 
410  // add parameters
411  $parameters['public_key'] = self::$publicKey;
412  $parameters['time'] = $time;
413  $parameters['hash'] = $hash;
414  $parameters['nonce'] = $nonce;
415 
416 
417  // build request
418  $requestBody = '<?xml version="1.0"?>' ."\n";
419  $requestBody .= '<methodCall>' ."\n";
420  $requestBody .= ' <methodName>mollom.'. $method .'</methodName>' ."\n";
421  $requestBody .= ' <params>' ."\n";
422  $requestBody .= ' <param>'."\n";
423  $requestBody .= ' '. self::buildValue($parameters) ."\n";
424  $requestBody .= ' </param>'."\n";
425  $requestBody .= ' </params>' ."\n";
426  $requestBody .= '</methodCall>' ."\n";
427 
428  $options = array(
429  'USERAGENT' => self::$userAgent,
430  'HTTP_VERSION' => CURL_HTTP_VERSION_1_0,
431  'POST' => true,
432  'FOLLOWLOCATION' => true,
433  'HEADER' => true,
434  'RETURNTRANSFER' => true,
435  'CONNECTTIMEOUT' => self::$timeout,
436  'TIMEOUT' => self::$timeout,
437  'POSTFIELDS' => $requestBody,
438  );
439 
440  $details = fetch_url($server.'/'.self::$version, $options);
441  $response = $details['response'];
442  $errorNumber = $details['errornumber'];
443  $errorString = $details['errorstring'];
444 
445  // validate response
446  if($response === false || $errorNumber != 0)
447  {
448  // increment counter
449  $counter++;
450 
451  // no servers left
452  if($errorNumber == 28 && !isset(self::$serverList[$counter]) && $countServerList != 0) throw new Exception('No more servers available, try to increase the timeout.');
453 
454  // timeout
455  elseif($errorNumber == 28 && isset(self::$serverList[$counter])) return self::doCall($method, $parameters, self::$serverList[$counter], $counter);
456 
457  // other error
458  else throw new Exception('Something went wrong. Maybe the following message can be handy.<br />'. $errorString, $errorNumber);
459  }
460 
461  // process response
462  $parts = explode("\r\n\r\n", $response);
463 
464  // validate
465  if(!isset($parts[0]) || !isset($parts[1])) throw new Exception('Invalid response in doCall.');
466 
467  // get headers
468  $headers = $parts[0];
469 
470  // rebuild body
471  array_shift($parts);
472  $body = implode('', $parts);
473 
474  // validate header
475  $aValidHeaders = array('HTTP/1.0 200', 'HTTP/1.1 200');
476  if(!in_array(substr($headers, 0, 12), $aValidHeaders)) throw new Exception('Invalid headers.');
477 
478  // do some validation
479  $responseXML = @simplexml_load_string($body);
480  if($responseXML === false) throw new Exception('Invalid body.');
481 
482  if(isset($responseXML->fault))
483  {
484  $code = (isset($responseXML->fault->value->struct->member[0]->value->int)) ? (int) $responseXML->fault->value->struct->member[0]->value->int : 'unknown';
485  $message = (isset($responseXML->fault->value->struct->member[1]->value->string)) ? (string) $responseXML->fault->value->struct->member[1]->value->string : 'unknown';
486 
487  // handle errors
488  switch ($code)
489  {
490  // code 1200 (Server too busy)
491  case 1200:
492  if(self::$serverList === null) self::getServerList();
493 
494  // do call again
495  return self::doCall($method, $parameters, self::$serverList[$counter], $counter++);
496  break;
497 
498  // code 1000 (Parse error or internal problem)
499  case 1000:
500 
501  // code 1100 (Serverlist outdated)
502  case 1100:
503 
504  default:
505  log_dump('Mollom Error '.$code .': '. $message);
506  return FALSE;
507  }//end switch
508  }
509 
510  // return
511  return $responseXML;
512  }
513 
514 
531  public static function getAudioCaptcha($sessionId = null)
532  {
533  // init vars
534  $aReturn = array();
535  $parameters = array();
536 
537  // set autor ip
538  $authorIp = self::getIpAddress();
539 
540  // set parameters
541  if($sessionId != null) $parameters['session_id'] = (string) $sessionId;
542  if($authorIp != null) $parameters['author_ip'] = (string) $authorIp;
543 
544  // do the call
545  $responseString = self::doCall('getAudioCaptcha', $parameters);
546 
547  // validate
548  if(!isset($responseString->params->param->value->struct->member)) throw new Exception('Invalid response in getAudioCaptcha.');
549 
550  // loop elements
551  foreach ($responseString->params->param->value->struct->member as $part) $aReturn[(string) $part->name] = (string) $part->value->string;
552 
553  // add image html
554  $aReturn['html'] = '<object type="audio/mpeg" data="'. $aReturn['url'] .'" width="50" height="16">'."\n"
555  ."\t".'<param name="autoplay" value="false" />'."\n"
556  ."\t".'<param name="controller" value="true" />'."\n"
557  .'</object>';
558 
559  // return
560  return $aReturn;
561  }
562 
563 
580  public static function getImageCaptcha($sessionId = null)
581  {
582  // init vars
583  $aReturn = array();
584  $parameters = array();
585 
586  // set autor ip
587  $authorIp = self::getIpAddress();
588 
589  // set parameters
590  if($sessionId !== null) $parameters['session_id'] = (string) $sessionId;
591  if($authorIp !== null) $parameters['author_ip'] = (string) $authorIp;
592 
593  // do the call
594  $responseString = self::doCall('getImageCaptcha', $parameters);
595 
596  // validate
597  if(!isset($responseString->params->param->value->struct->member)) throw new Exception('Invalid response in getImageCaptcha.');
598 
599  // loop elements
600  foreach ($responseString->params->param->value->struct->member as $part) $aReturn[(string) $part->name] = (string) $part->value->string;
601 
602  // add image html
603  $aReturn['html'] = '<img src="'. $aReturn['url'] .'" alt="Mollom CAPTCHA" />';
604 
605  // return
606  return $aReturn;
607  }
608 
609 
615  public static function getIpAddress()
616  {
617  // pre check
618  if(!isset($_SERVER['REMOTE_ADDR'])) return null;
619 
620  // get ip
621  $ipAddress = $_SERVER['REMOTE_ADDR'];
622 
623  if(self::$reverseProxy)
624  {
625  if(isset($_SERVER['HTTP_X_FORWARDED_FOR']))
626  {
627  if(!empty(self::$allowedReverseProxyAddresses) && in_array($ipAddress, self::$allowedProxyAddresses, true))
628  {
629  return array_pop(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']));
630  }
631  }
632 
633  // running in a cluster environment
634  if(isset($_SERVER['HTTP_X_CLUSTER_CLIENT_IP'])) return $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
635  }
636 
637  // fallback
638  return $ipAddress;
639  }
640 
641 
647  public static function getServerList($counter = 0)
648  {
649  // Use default list of servers to get the server list from Mollom
650  self::$serverList = self::$default_server_list;
651 
652  // do the call
653  $responseString = self::doCall('getServerList', array(), self::$serverHost, $counter);
654 
655  // validate
656  if(!isset($responseString->params->param->value->array->data->value)) throw new Exception('Invalid response in getServerList.');
657 
658  // Refresh the list
659  self::$serverList = array();
660 
661  // loop servers and add them
662  foreach ($responseString->params->param->value->array->data->value as $server) self::$serverList[] = (string) $server->string;
663 
664  if(count(self::$serverList) == 0) self::$serverList = self::$default_server_list;
665 
666  // return
667  return self::$serverList;
668  }
669 
670 
686  public static function getStatistics($type)
687  {
688  // possible types
689  $aPossibleTypes = array('total_days', 'total_accepted', 'total_rejected', 'yesterday_accepted', 'yesterday_rejected', 'today_accepted', 'today_rejected');
690 
691  // redefine
692  $type = (string) $type;
693 
694  // validate
695  if(!in_array($type, $aPossibleTypes)) throw new Exception('Invalid type. Only '. implode(', ', $aPossibleTypes) .' are possible types.');
696 
697  // do the call
698  $responseString = self::doCall('getStatistics', array('type' => $type));
699 
700  // validate
701  if(!isset($responseString->params->param->value->int)) throw new Exception('Invalid response in getStatistics.');
702 
703  // return
704  return (int) $responseString->params->param->value->int;
705  }
706 
707 
724  public static function sendFeedback($sessionId, $feedback)
725  {
726  // possible feedback
727  $aPossibleFeedback = array('spam', 'profanity', 'low-quality', 'unwanted');
728 
729  // redefine
730  $sessionId = (string) $sessionId;
731  $feedback = (string) $feedback;
732 
733  // validate
734  if(!in_array($feedback, $aPossibleFeedback)) throw new Exception('Invalid feedback. Only '. implode(', ', $aPossibleFeedback) .' are possible feedback-strings.');
735 
736  // build parameters
737  $parameters['session_id'] = $sessionId;
738  $parameters['feedback'] = $feedback;
739 
740  // do the call
741  $responseString = self::doCall('sendFeedback', $parameters);
742 
743  // validate
744  if(!isset($responseString->params->param->value->boolean)) throw new Exception('Invalid response in sendFeedback.');
745 
746  // return
747  if((string) $responseString->params->param->value->boolean == 1) return true;
748 
749  // fallback
750  return false;
751  }
752 
753 
760  public static function setAllowedReverseProxyAddresses($addresses)
761  {
762  // store allowed ip-addresses
763  self::$allowedReverseProxyAddresses = (array) $addresses;
764 
765  // set reverse proxy
766  self::$reverseProxy = (!empty($addresses)) ? true : false;
767  }
768 
769 
776  public static function setPrivateKey($key)
777  {
778  self::$privateKey = (string) $key;
779  }
780 
781 
788  public static function setPublicKey($key)
789  {
790  self::$publicKey = (string) $key;
791  }
792 
793 
800  public static function setServerList($servers)
801  {
802  // redefine
803  $server = (array) $servers;
804 
805  // loop servers
806  foreach ($servers as $server) self::$serverList[] = $server;
807  }
808 
809 
816  public static function setTimeOut($timeout)
817  {
818  // redefine
819  $timeout = (int) $timeout;
820 
821  // validate
822  if($timeout == 0) throw new Exception('Invalid timeout. Timeout shouldn\'t be 0.');
823 
824  // set property
825  self::$timeout = $timeout;
826  }
827 
828 
835  public static function setUserAgent($newUserAgent)
836  {
837  self::$userAgent .= ' '. (string) $newUserAgent;
838  }
839 
840 
849  public static function verifyKey()
850  {
851  // do the call
852  $responseString = self::doCall('verifyKey');
853 
854  // validate
855  if(!isset($responseString->params->param->value->boolean)) return false;
856 
857  // return
858  if((string) $responseString->params->param->value->boolean == '1') return true;
859 
860  // fallback
861  return false;
862  }
863 
864 
865  //-- MATRIX MOLLOM FUNCTIONS --//
866 
867 
873  public static function getContentTypes()
874  {
875  return Array(
876  0 => "Post Title",
877  1 => "Post Body",
878  2 => "Author Name",
879  3 => "Author URL",
880  4 => "Author Mail",
881  5 => "Author OpenId",
882  6 => "Author Id",
883  );
884  }
885 
886 
887  /* Set and loads all the required Mollom parameters
888  *
889  * @return boolean
890  * @access private
891  */
892  public static function loadMollom()
893  {
894  if (!SQ_TOOL_MOLLOM_PUBLIC_KEY || !SQ_TOOL_MOLLOM_PRIVATE_KEY) {
895  return FALSE;
896  }
897 
898  self::setPublicKey(SQ_TOOL_MOLLOM_PUBLIC_KEY);
899  self::setPrivateKey(SQ_TOOL_MOLLOM_PRIVATE_KEY);
900 
901  $server_list = Array();
902  if (!empty($_SESSION['SQ_MOLLOM_SERVER_LIST'])) {
903  $server_list = unserialize($_SESSION['SQ_MOLLOM_SERVER_LIST']);
904  self::setServerList($server_list);
905  } else {
906  $server_list = self::getServerList();
907  $_SESSION['SQ_MOLLOM_SERVER_LIST'] = serialize($server_list);
908  }
909 
910  return !empty($server_list);
911  }
912 
913 
923  public static function verifySubmission($assetid, $parameters)
924  {
925  // Whether to accept the submission if Mollom fails to respond expectedly
926  $unknown_submission = SQ_TOOL_MOLLOM_ACCEPT_BYPASSED_SUBMISSION ? SQ_MOLLOM_HAM : SQ_MOLLOM_SPAM;
927 
928  try {
929  self::refreshMollomSession($assetid);
930 
931  if (!self::loadMollom()) {
932  // Cannot load Mollom client, hence cannot check the response for spam.
933  return $unknown_submission;
934  }
935 
936  if (self::checkCaptchaResponse($assetid)) {
937  // Captcha check correct
938  unset($_SESSION['SQ_MOLLOM_CAPTCHA_'.$assetid]);
939  return SQ_MOLLOM_HAM;
940 
941  } else if (isset($_SESSION['SQ_MOLLOM_CAPTCHA_'.$assetid])) {
942  return SQ_MOLLOM_INCORRECT_CAPTCHA;
943  }
944 
945  $response = self::checkContent(
946  null,
947  isset($parameters[0]) ? $parameters[0] : null,
948  isset($parameters[1]) ? $parameters[1] : null,
949  isset($parameters[2]) ? $parameters[2] : null,
950  isset($parameters[3]) ? $parameters[3] : null,
951  isset($parameters[4]) ? $parameters[4] : null,
952  isset($parameters[5]) ? $parameters[5] : null,
953  isset($parameters[6]) ? $parameters[6] : null
954  );
955 
956  if (empty($response)) {
957  // No response from server, cannot check spam. Accept it anyway
958  // Better accept a spam rather than reject a legit answer
959  return $unknown_submission;
960  }
961 
962  $spam_status = array_get_index($response, 'spam', 'unknown');
963  $quality = array_get_index($response, 'quality', 0);
964  $session_id = array_get_index($response, 'session_id', '');
965 
966  switch ($spam_status) {
967 
968  case 'unsure':
969  $mollom_captcha = Array();
970  $image_captcha = self::getImageCaptcha($session_id);
971  $mollom_captcha['session_id'] = $session_id;
972  $mollom_captcha['image_url'] = array_get_index($image_captcha, 'url', '');
973  $mollom_captcha['session_time'] = time();
974 
975  $_SESSION['SQ_MOLLOM_CAPTCHA_'.$assetid] = $mollom_captcha;
976  return SQ_MOLLOM_UNSURE;
977 
978  case 'spam':
979  // Reject the answer
980  return SQ_MOLLOM_SPAM;
981 
982  case 'ham':
983  // Its not a spam
984  return SQ_MOLLOM_HAM;
985  }
986  } catch (Exception $e) {
987  $add_msg = SQ_TOOL_MOLLOM_ACCEPT_BYPASSED_SUBMISSION ? 'Submission accepted anyway.' : 'Submission not accepted.';
988  trigger_error("Error occured when trying to verify the submission with the Mollom: ".$e->getMessage()."\n".$add_msg, E_USER_WARNING);
989  }
990 
991  return $unknown_submission;
992 
993  }//end verifySubmission()
994 
995 
996  //-- MOLLOM MATRIX KEYWORD REPLACEMENT FUNCTIONS --//
997 
998 
1007  public static function getMollomCaptchaKeywordReplacement($assetid)
1008  {
1009  self::refreshMollomSession($assetid);
1010 
1011  if (empty($_SESSION['SQ_MOLLOM_CAPTCHA_'.$assetid]['session_id'])) {
1012  return null;
1013  }
1014 
1015  $captcha = self::getMollomCaptchaImageKeywordReplacement($assetid).
1016  self::getMollomCaptchaRegenLinkKeywordReplacement($assetid).
1017  "<br />".self::getMollomCaptchaFieldKeywordReplacement($assetid);
1018 
1019  return $captcha;
1020  }
1021 
1022 
1031  public static function getMollomCaptchaFieldKeywordReplacement($assetid)
1032  {
1033  self::refreshMollomSession($assetid);
1034 
1035  if (empty($_SESSION['SQ_MOLLOM_CAPTCHA_'.$assetid]['session_id']) || (empty($_SESSION['SQ_MOLLOM_CAPTCHA_'.$assetid]['image_url']))) {
1036  return '';
1037  }
1038 
1039  $name = 'sq_mollom_captcha_'.$assetid.'_input';
1040  $width = 7;
1041  $max = 20;
1042 
1043  ob_start();
1044  text_box($name, '', $width, $max, FALSE, '');
1045  hidden_field($name.'_session', $_SESSION['SQ_MOLLOM_CAPTCHA_'.$assetid]['session_id']);
1046  $input_box = ob_get_contents();
1047  ob_end_clean();
1048 
1049  return $input_box;
1050  }
1051 
1052 
1062  public static function getMollomCaptchaRegenLinkKeywordReplacement($assetid, $regen_text='Regenerate security key')
1063  {
1064  self::refreshMollomSession($assetid);
1065 
1066  if (!empty($_SESSION['SQ_MOLLOM_CAPTCHA_'.$assetid]['session_id'])) {
1067  $image_id = 'sq_mollom_captcha_'.$assetid.'_image';
1068  $image_url = $_SESSION['SQ_MOLLOM_CAPTCHA_'.$assetid]['image_url'];
1069 
1070  return '<a href="#" onClick="var img=document.getElementById(\''.$image_id.'\'); img.src=\''.$image_url.'?SQ_MOLLOM_REGEN_PARAM=\'+Math.random(); return false;">'.$regen_text.'</a>';
1071  }
1072 
1073  return '';
1074  }
1075 
1076 
1085  public static function getMollomCaptchaAudioKeywordReplacement($assetid)
1086  {
1087  self::refreshMollomSession($assetid);
1088 
1089  if (!empty($_SESSION['SQ_MOLLOM_CAPTCHA_'.$assetid]['session_id'])) {
1090  if (empty($_SESSION['SQ_MOLLOM_CAPTCHA_'.$assetid]['audio_url'])) {
1091  if (!self::loadMollom()) {
1092  return '';
1093  }
1094  $audio_captcha = self::getAudioCaptcha($_SESSION['SQ_MOLLOM_CAPTCHA_'.$assetid]['session_id']);
1095  $_SESSION['SQ_MOLLOM_CAPTCHA_'.$assetid]['audio_url'] = $audio_captcha['url'];
1096  }
1097 
1098  return '<object type="audio/mpeg" data="'.$_SESSION['SQ_MOLLOM_CAPTCHA_'.$assetid]['audio_url'].'" width="50" height="16">'."\n"
1099  ."\t".'<param name="autoplay" value="false" />'."\n"
1100  ."\t".'<param name="controller" value="true" />'."\n"
1101  .'</object>';
1102  }
1103 
1104  return '';
1105  }
1106 
1107 
1116  public static function getMollomCaptchaImageKeywordReplacement($assetid)
1117  {
1118  self::refreshMollomSession($assetid);
1119 
1120  if (!empty($_SESSION['SQ_MOLLOM_CAPTCHA_'.$assetid]['image_url'])) {
1121  $image_id = 'sq_mollom_captcha_'.$assetid.'_image';
1122  return '<img id="'.$image_id.'" src="'.$_SESSION['SQ_MOLLOM_CAPTCHA_'.$assetid]['image_url'].'" alt="CAPTCHA Image" />';
1123  }
1124 
1125  return '';
1126  }
1127 
1128 
1137  public static function checkCaptchaResponse($assetid)
1138  {
1139  if (!self::loadMollom()) {
1140  return FALSE;
1141  }
1142 
1143  $name = 'sq_mollom_captcha_'.$assetid.'_input';
1144  $captcha_solution = array_get_index($_POST, $name, '');
1145  $captcha_session_id = array_get_index($_POST, $name.'_session', '');
1146 
1147  if (empty($captcha_session_id) || empty($captcha_solution)) {
1148  return FALSE;
1149  }
1150 
1151  return self::checkCaptcha($captcha_session_id, $captcha_solution);
1152  }
1153 
1154 
1164  public static function refreshMollomSession($assetid)
1165  {
1166  if (isset($_SESSION['SQ_MOLLOM_CAPTCHA_'.$assetid]['session_id'])) {
1167 
1168  $session_time = array_get_index($_SESSION['SQ_MOLLOM_CAPTCHA_'.$assetid], 'session_time', 0);
1169  $current_time = time();
1170  if (($current_time - $session_time) > (60 * self::$session_expire_time)) {
1171  unset($_SESSION['SQ_MOLLOM_CAPTCHA_'.$assetid]);
1172  }
1173  }
1174  }
1175 
1176 
1177 }//end class Mollom
1178 
1179 ?>