diff --git a/serendipity_event_spamblock_bee/ChangeLog b/serendipity_event_spamblock_bee/ChangeLog index 9e47979c..168208a3 100644 --- a/serendipity_event_spamblock_bee/ChangeLog +++ b/serendipity_event_spamblock_bee/ChangeLog @@ -1,3 +1,9 @@ +Version 1.2.9 +* add a linebreak + +Version 1.2.8 +* Size honepot form field in case it is actually shown + Version 1.2.7 * Made it work more nice with the contactform plugin diff --git a/serendipity_event_spamblock_bee/serendipity_event_spamblock_bee.js b/serendipity_event_spamblock_bee/serendipity_event_spamblock_bee.js index 80fda51b..ac755abe 100644 --- a/serendipity_event_spamblock_bee/serendipity_event_spamblock_bee.js +++ b/serendipity_event_spamblock_bee/serendipity_event_spamblock_bee.js @@ -7,22 +7,22 @@ var url = typeof loadData.url != 'undefined' ? loadData.url : null; var answer = typeof loadData.answer != 'undefined' ? loadData.answer : null; var scrambleKey = typeof loadData.scrambleKey != 'undefined' ? loadData.scrambleKey : null; - + this.attachToLoadEvent = function() { var handlerCalled = false; var eventHandler = function() { // Since we use multiple handlers, only run this function once if (handlerCalled) return; handlerCalled = true; - + that.initCaptcha(); - + // We don't need any additional load events anymore if (document.addEventListener) { document.removeEventListener('load', eventHandler, true); } } - + if (document.addEventListener) { // Use DOMContentLoaded for modern browsers, load for older ones document.addEventListener('DOMContentLoaded', eventHandler, true); @@ -39,35 +39,35 @@ } } } - + this.initCaptcha = function() { if (null === inputCaptcha) { return; } - + if ('default' == method && null !== answer) { fillCaptcha(answer, scrambleKey) } else if ('json' == method && null !== url) { fetchJsonData(); } } - + this.hideBeeElement = function() { var elementClass = divCaptcha.className; if (null === elementClass.match(/\bspambeehidden\b/)) { divCaptcha.className = elementClass + ' spambeehidden'; } } - + function fillCaptcha(answer, scrambleKey) { if (typeof scrambleKey != 'undefined' && null !== scrambleKey) { answer = xorDescramble(decodeUtf8(unescape(answer)), scrambleKey); } - + inputCaptcha.value = answer; that.hideBeeElement(); } - + function fetchJsonData() { if (window.XMLHttpRequest) { // Mozilla, Safari, Opera, IE7 var httpRequest = new XMLHttpRequest(); @@ -81,35 +81,35 @@ httpRequest.setRequestHeader('content-Type', 'application/x-www-form-urlencoded; charset=utf-8'); httpRequest.send(); } - + function fetchJsonDataReady(httpRequest) { if (null !== httpRequest && 4 == httpRequest.readyState && 200 == httpRequest.status) { - + var response = httpRequest.responseText; var jsonResponse = typeof JSON != 'undefined' ? JSON.parse(response) : eval('(' + response + ')'); var answer = jsonResponse.answer; var scrambleKey = typeof jsonResponse.scrambleKey != 'undefined' ? jsonResponse.scrambleKey : null; - + if (typeof answer != 'string' || 'ERROR' != answer.toUpperCase()) { fillCaptcha(answer, scrambleKey); } } } - + function decodeUtf8(string) { return decodeURIComponent(escape(string)); } - + function xorDescramble(string, key) { var decoded = ''; for (i = 0; i < string.length; ++i) { decoded += String.fromCharCode(string.charCodeAt(i) ^ key); } - + return decoded; } } - + var spamBeeObj = new SpamBeeCaptcha(spamBeeData); spamBeeObj.attachToLoadEvent(); })(); \ No newline at end of file diff --git a/serendipity_event_spamblock_bee/serendipity_event_spamblock_bee.php b/serendipity_event_spamblock_bee/serendipity_event_spamblock_bee.php index 15b24c6c..a0d44792 100644 --- a/serendipity_event_spamblock_bee/serendipity_event_spamblock_bee.php +++ b/serendipity_event_spamblock_bee/serendipity_event_spamblock_bee.php @@ -1,6 +1,5 @@ null); - + /** * Type of question asked in the Captcha. This is either 'math' or 'custom' * @var string */ var $captchaQuestionType = null; - + /** * Whether to use RegExp matching for the hidden Captcha * @var boolean */ var $useRegularExpressions = false; - + /** * Constructor. Initialize class variables from configuration * @return void */ function serendipity_event_spamblock_bee($instance) { $this->instance = $instance; - + $this->answerRetrievalMethod = $this->get_config('answer_retrieval_method', 'default'); $this->captchaQuestionType = $this->get_config('question_type', 'math'); $this->useHoneyPot = $this->get_config('do_honeypot', true); $this->hiddenCaptchaHandle = $this->get_config('do_hiddencaptcha', PLUGIN_EVENT_SPAMBLOCK_SWTCH_MODERATE); $this->useRegularExpressions = $this->get_config('use_regexp', false); } - + /** * Declare Serendipity backend properties. - * + * * @param serendipity_property_bag $propbag */ function introspect(&$propbag) @@ -106,28 +105,29 @@ class serendipity_event_spamblock_bee extends serendipity_event 'smarty' => '2.6.7', 'php' => '4.1.0' )); - + $propbag->add('version', PLUGIN_SPAMBLOCK_BEE_VERSION); // setup via version.inc.php - + $propbag->add('event_hooks', array( - 'frontend_comment' => true, + 'frontend_comment' => true, 'frontend_saveComment' => true, - 'frontend_footer' => true, - 'css' => true, - 'external_plugin' => true, + 'frontend_footer' => true, + 'css' => true, + 'external_plugin' => true )); $propbag->add('groups', array('ANTISPAM')); - + $configuration = array('header_desc','do_honeypot', 'do_hiddencaptcha' ); - if (!class_exists('serendipity_event_spamblock')) { // Only do that, if spamblock is not installed. - $configuration =array_merge($configuration, array('entrytitle', 'samebody', 'required_fields')); + // Only do that, if spamblock is not installed + if (!class_exists('serendipity_event_spamblock')) { + $configuration = array_merge($configuration, array('entrytitle', 'samebody', 'required_fields')); } - $configuration =array_merge($configuration, array('spamlogtype', 'spamlogfile', 'plugin_path')); - $configuration =array_merge($configuration, array( + $configuration = array_merge($configuration, array('spamlogtype', 'spamlogfile', 'plugin_path')); + $configuration = array_merge($configuration, array( 'advanced_cc_desc', 'answer_retrieval_method', 'question_type', 'questions', 'answers', 'use_regexp' )); - + $propbag->add('configuration', $configuration ); $propbag->add('config_groups', array( PLUGIN_EVENT_SPAMBLOCK_BEE_CONFIG_SECTION_LOGGING => array( @@ -140,19 +140,19 @@ class serendipity_event_spamblock_bee extends serendipity_event ) ); } - + /** * Set plug-in title. - * + * * @param string $title */ function generate_content(&$title) { $title = PLUGIN_EVENT_SPAMBLOCK_BEE_TITLE; } - + /** * Generate backend configuration fields - * + * * @param string $name field name * @param serendipity_property_bag $propbag properties * @return bool @@ -160,27 +160,27 @@ class serendipity_event_spamblock_bee extends serendipity_event function introspect_config_item($name, &$propbag) { global $serendipity; - + $rejectType = array( - PLUGIN_EVENT_SPAMBLOCK_SWTCH_OFF => PLUGIN_EVENT_SPAMBLOCK_BEE_RESULT_OFF, + PLUGIN_EVENT_SPAMBLOCK_SWTCH_OFF => PLUGIN_EVENT_SPAMBLOCK_BEE_RESULT_OFF, PLUGIN_EVENT_SPAMBLOCK_SWTCH_MODERATE => PLUGIN_EVENT_SPAMBLOCK_BEE_RESULT_MODERATE, - PLUGIN_EVENT_SPAMBLOCK_SWTCH_REJECT => PLUGIN_EVENT_SPAMBLOCK_BEE_RESULT_REJECT, + PLUGIN_EVENT_SPAMBLOCK_SWTCH_REJECT => PLUGIN_EVENT_SPAMBLOCK_BEE_RESULT_REJECT, ); - + $retrievalMethod = array( 'default' => PLUGIN_EVENT_SPAMBLOCK_BEE_CONFIG_ADV_RM_DEFAULT, 'json' => PLUGIN_EVENT_SPAMBLOCK_BEE_CONFIG_ADV_RM_JSON, 'smarty' => PLUGIN_EVENT_SPAMBLOCK_BEE_CONFIG_ADV_RM_SMARTY, 'smarty_enc' => PLUGIN_EVENT_SPAMBLOCK_BEE_CONFIG_ADV_RM_SMARTY_ENC ); - + $questionType = array( 'math' => PLUGIN_EVENT_SPAMBLOCK_BEE_CONFIG_ADV_QT_MATH, 'custom' => PLUGIN_EVENT_SPAMBLOCK_BEE_CONFIG_ADV_QT_CUSTOM ); - + switch($name) { - case 'header_desc': + case 'header_desc': $propbag->add('type', 'content'); $propbag->add('default', PLUGIN_EVENT_SPAMBLOCK_BEE_EXTRA_DESC . '' ); @@ -192,7 +192,7 @@ class serendipity_event_spamblock_bee extends serendipity_event $propbag->add('description', PLUGIN_EVENT_SPAMBLOCK_BEE_CONFIG_SPAM_HONEYPOT_DESC); $propbag->add('default', true); break; - + case 'do_hiddencaptcha': $propbag->add('type', 'select'); $propbag->add('name', PLUGIN_EVENT_SPAMBLOCK_BEE_CONFIG_SPAM_HCAPTCHA); @@ -207,7 +207,7 @@ class serendipity_event_spamblock_bee extends serendipity_event $propbag->add('description', PLUGIN_EVENT_SPAMBLOCK_BEE_REQUIRED_FIELDS_DESC); $propbag->add('default', ''); break; - + case 'entrytitle': $propbag->add('type', 'select'); $propbag->add('name', PLUGIN_EVENT_SPAMBLOCK_BEE_FILTER_TITLE); @@ -215,7 +215,7 @@ class serendipity_event_spamblock_bee extends serendipity_event $propbag->add('select_values', $rejectType); $propbag->add('default', PLUGIN_EVENT_SPAMBLOCK_SWTCH_REJECT); break; - + case 'samebody': $propbag->add('type', 'select'); $propbag->add('name', PLUGIN_EVENT_SPAMBLOCK_BEE_FILTER_SAMEBODY); @@ -223,7 +223,7 @@ class serendipity_event_spamblock_bee extends serendipity_event $propbag->add('select_values', $rejectType); $propbag->add('default', PLUGIN_EVENT_SPAMBLOCK_SWTCH_REJECT); break; - + case 'spamlogtype': $logtypevalues = array ( 'none' => PLUGIN_EVENT_SPAMBLOCK_BEE_CONFIG_SPAM_LOGTYPE_NONE, @@ -236,7 +236,7 @@ class serendipity_event_spamblock_bee extends serendipity_event $propbag->add('select_values', $logtypevalues); $propbag->add('default', 'none'); break; - + case 'spamlogfile': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_EVENT_SPAMBLOCK_BEE_CONFIG_SPAM_LOGFILE); @@ -250,12 +250,12 @@ class serendipity_event_spamblock_bee extends serendipity_event $propbag->add('description', PLUGIN_EVENT_SPAMBLOCK_BEE_PATH_DESC); $propbag->add('default', $serendipity['serendipityHTTPPath'] . 'plugins/serendipity_event_spamblock_bee/'); break; - + case 'advanced_cc_desc': $propbag->add('type', 'content'); $propbag->add('default', PLUGIN_EVENT_SPAMBLOCK_BEE_CONFIG_ADV_DESC); break; - + case 'answer_retrieval_method': $propbag->add('type', 'select'); $propbag->add('name', PLUGIN_EVENT_SPAMBLOCK_BEE_CONFIG_ADV_ANSWER_RETRIEVAL); @@ -263,7 +263,7 @@ class serendipity_event_spamblock_bee extends serendipity_event $propbag->add('select_values', $retrievalMethod); $propbag->add('default', 'default'); break; - + case 'question_type': $propbag->add('type', 'select'); $propbag->add('name', PLUGIN_EVENT_SPAMBLOCK_BEE_CONFIG_ADV_QUESTION_TYPE); @@ -271,7 +271,7 @@ class serendipity_event_spamblock_bee extends serendipity_event $propbag->add('select_values', $questionType); $propbag->add('default', 'math'); break; - + case 'questions': $propbag->add('type', 'text'); $propbag->add('rows', 8); @@ -279,7 +279,7 @@ class serendipity_event_spamblock_bee extends serendipity_event $propbag->add('description', PLUGIN_EVENT_SPAMBLOCK_BEE_CONFIG_ADV_QUESTIONS_DESC); $propbag->add('default', PLUGIN_EVENT_SPAMBLOCK_BEE_CONFIG_ADV_DEFAULT_QUESTIONS); break; - + case 'answers': $propbag->add('type', 'text'); $propbag->add('rows', 8); @@ -287,23 +287,23 @@ class serendipity_event_spamblock_bee extends serendipity_event $propbag->add('description', PLUGIN_EVENT_SPAMBLOCK_BEE_CONFIG_ADV_ANSWERS_DESC); $propbag->add('default', PLUGIN_EVENT_SPAMBLOCK_BEE_CONFIG_ADV_DEFAULT_ANSWERS); break; - + case 'use_regexp': $propbag->add('type', 'boolean'); $propbag->add('name', PLUGIN_EVENT_SPAMBLOCK_BEE_CONFIG_ADV_USE_REGEXP); $propbag->add('description', PLUGIN_EVENT_SPAMBLOCK_BEE_CONFIG_ADV_USE_REGEXP_DESC); $propbag->add('default', false); break; - + default: return false; } return true; } - + /** * Hook for Serendipity events, initialize plug-in features - * + * * @param string $event * @param serendipity_property_bag $bag * @param array $eventData @@ -312,7 +312,7 @@ class serendipity_event_spamblock_bee extends serendipity_event */ function event_hook($event, &$bag, &$eventData, $addData = null) { global $serendipity; - + $hooks = &$bag->get('event_hooks'); if (isset($hooks[$event])) { switch($event) { @@ -327,7 +327,7 @@ class serendipity_event_spamblock_bee extends serendipity_event break; } break; - + case 'frontend_saveComment': // Check only, if no one else denied it before if (!is_array ( $eventData ) || serendipity_db_bool ( $eventData ['allow_comments'] )) { @@ -335,9 +335,11 @@ class serendipity_event_spamblock_bee extends serendipity_event } return true; break; + case 'frontend_comment': $this->printCommentEditExtras($eventData, $addData); break; + case 'frontend_footer': // Comment header code only if in single article mode or contactform // If contact form is installed, display on any page not being the article list @@ -349,9 +351,11 @@ class serendipity_event_spamblock_bee extends serendipity_event $this->printJsExtras(); } break; - case 'css': + + case 'css': $this->printCss($eventData, $addData); break; + default: return false; break; @@ -361,20 +365,20 @@ class serendipity_event_spamblock_bee extends serendipity_event return false; } } - + /** * Check if Honey Pot or Captcha have been filled correctly (or if any * other indications for spam can be found). - * + * * @param array $eventData * @param array $addData * @return bool */ function checkComment(&$eventData, &$addData) { global $serendipity; - + if ("NORMAL" == $addData['type']) { // only supported for normal comments - + // Check for Honey Pot: $phone = $serendipity['POST']['phone']; if ($this->useHoneyPot && (!empty($phone) || $phone == '0') ) { @@ -385,28 +389,28 @@ class serendipity_event_spamblock_bee extends serendipity_event $eventData = array('allow_comments' => false); return false; } - + // Check hidden Captcha if (PLUGIN_EVENT_SPAMBLOCK_SWTCH_OFF != $this->hiddenCaptchaHandle) { $answer = trim(strtolower($serendipity['POST']['beecaptcha'])); $correctAnswer = $this->getCaptchaAnswer(); $correctAnswer['answer'] = strtolower($correctAnswer['answer']); $isCorrect = false; - + // If provided answer is longer than 1000 characters and RegExp matching is on, // reject comment for security reasons (minimize risk of ReDoS) if ($this->useRegularExpressions && mb_strlen($answer) > 1000) { $this->processComment($this->hiddenCaptchaHandle, $eventData, $addData, PLUGIN_EVENT_SPAMBLOCK_BEE_ERROR_HCAPTCHA, "BEE HiddenCaptcha [ Captcha input too long ]"); return false; } - + if ($this->captchaQuestionType == 'custom' && $this->useRegularExpressions) { // Sanitize regular expression and remove answer part $pattern = preg_replace('/^\s*\/(.*)\/\s*[imsxeADSUXJu]*\s*$/s', '$1', $correctAnswer['pattern']); - + // Try to match pattern with given answer $match = @preg_match('/' . $pattern . '/si', $answer); - + // If pattern contains errors, fall back to basic string comparison if ($match === false) { $this->useRegularExpressions = false; @@ -414,17 +418,17 @@ class serendipity_event_spamblock_bee extends serendipity_event $isCorrect = ($match === 1); } } - + if ($this->captchaQuestionType != 'custom' || !$this->useRegularExpressions) { $isCorrect = ($answer == $correctAnswer['answer']); } - + // Also allow numbers as words if (!$isCorrect && $this->captchaQuestionType == 'math') { $number = $this->generateNumberString($correctAnswer['answer']); $isCorrect = ($answer == $number && $number != 'ERROR'); } - + if (!$isCorrect) { if (mb_strlen($answer) > 40) { $answer = mb_substr($answer, 0, 40) . '..'; @@ -435,7 +439,7 @@ class serendipity_event_spamblock_bee extends serendipity_event } // AntiSpam check, the general spamblock supports, too: Only if spamblock is not installed. if (!class_exists('serendipity_event_spamblock')) { - + // Check for required fields. Don't log but tell the user about the fields. $required_fields = $this->get_config('required_fields', ''); if (!empty($required_fields)) { @@ -450,7 +454,7 @@ class serendipity_event_spamblock_bee extends serendipity_event } } } - + // AntiSpam check, the general spamblock supports, too: Only if spamblock is not installed. if (!class_exists('serendipity_event_spamblock')) { @@ -461,7 +465,7 @@ class serendipity_event_spamblock_bee extends serendipity_event $comment = str_replace($serendipity['blogTitle'], '', $addData['comment']); $comment = str_replace($eventData['title'], '', $comment); // Now blog- and entry title was stripped from comment. - // Remove special letters, that might have been between them: + // Remove special letters, that might have been between them: $comment = trim(preg_replace('@[\s\-_:\(\)\|/]*@', '', $comment)); // Now that we stripped blog and entry title: Do we have an empty comment? @@ -470,33 +474,33 @@ class serendipity_event_spamblock_bee extends serendipity_event return false; } } - + // This check loads from DB, so do it last! // Check if we already have a comment with the same body. (it's a reload normaly) $spamHandle = $this->get_config('samebody', PLUGIN_EVENT_SPAMBLOCK_SWTCH_REJECT); if (PLUGIN_EVENT_SPAMBLOCK_SWTCH_OFF!=$spamHandle) { $query = "SELECT count(id) AS counter FROM {$serendipity['dbPrefix']}comments WHERE type = '" . $addData['type'] . "' AND body = '" . serendipity_db_escape_string($addData['comment']) . "'"; - // This is a little different to the normal Spam Plugin: + // This is a little different to the normal Spam Plugin: // We allow the same comment, if it is a trackback, but never on the same article // (One article sending trackbacks to more than one local article) if ($addData['type'] == 'PINGBACK' || $addData['type'] == 'TRACKBACK') { - $query .= ' AND entry_id=' . $eventData['id']; + $query .= ' AND entry_id=' . $eventData['id']; } $row = serendipity_db_query($query, true); if (is_array($row) && $row['counter'] > 0) { $this->processComment($spamHandle, $eventData, $addData, PLUGIN_EVENT_SPAMBLOCK_BEE_ERROR_BODY, "BEE Body already saved"); return false; } - + } } - + return true; } /** * Reject or moderate a comment. Convenience function. - * + * * @param string $spamHandle * @param array $eventData * @param array $addData @@ -512,10 +516,10 @@ class serendipity_event_spamblock_bee extends serendipity_event $this->reject($eventData, $addData, $remoteResponse, $logResponse); } } - + /** * Reject a comment with optional log entry. - * + * * @param array $eventData * @param array $addData * @param string $remoteResponse @@ -523,17 +527,17 @@ class serendipity_event_spamblock_bee extends serendipity_event */ function reject(&$eventData, &$addData, $remoteResponse, $logResponse = NULL) { global $serendipity; - + if (!empty($logResponse)) { $this->spamlog($eventData['id'], 'REJECTED', $logResponse, $addData); } $eventData = array('allow_comments' => false); - $serendipity['csuccess'] = 'false'; + $serendipity['csuccess'] = 'false'; $serendipity['messagestack']['comments'][] = $remoteResponse; - + $this->log(print_r($serendipity['messagestack'], true)); } - + /** * Moderate a comment with optional log entry * @param array $eventData @@ -544,7 +548,7 @@ class serendipity_event_spamblock_bee extends serendipity_event */ function moderate(&$eventData, &$addData, $remoteResponse, $logResponse = NULL) { global $serendipity; - + if (!empty($logResponse)) { $this->spamlog($eventData['id'], 'MODERATE', $logResponse, $addData); } @@ -555,38 +559,38 @@ class serendipity_event_spamblock_bee extends serendipity_event $this->log(print_r($serendipity['messagestack'], true)); } - + /** * Produce JSON string with the correct for fetching via Ajax. - * + * * @return string The generated JSON string */ function produceCaptchaAnswerJson() { $answer = $this->getCaptchaAnswer(); $scrambleKey = rand(); - + if (!isset($answer['answer'])) { $answer = array('answer' => 'ERROR'); } else { $answer['answer'] = rawurlencode($this->xorScramble($answer['answer'], $scrambleKey)); $answer['scrambleKey'] = $scrambleKey; } - + return json_encode($answer); } - + /** * Write the Honey Pot and Captcha field to the output buffer. - * + * * @param array $eventData * @param array $addData */ function printCommentEditExtras(&$eventData, &$addData) { global $serendipity; - + // Don't put extras on admin menu. They are not working there: ...or other backend forms like guestbook if ((isset($eventData['GET']['action']) && $eventData['GET']['action']=='admin') || (int)$serendipity['serendipityUserlevel'] >= (int)USERLEVEL_ADMIN) return; - + // Honeypot if (serendipity_db_bool($this->useHoneyPot)) { echo '
'; } else { $statsString .= '' . sprintf(PLUGIN_SPAMBLOCK_BEE_LAST_X_DAYS, $day) . '
'; } - + foreach ($searches as $search) { $singleSearch = explode(':', $search, 2); $singleSearch[0] = trim($singleSearch[0]); $singleSearch[1] = trim($singleSearch[1]); - + if (empty($statsCached)) { $sql = "SELECT COUNT(*) as total FROM {$serendipity['dbPrefix']}spamblocklog WHERE reason like '%s' and timestamp>%d;"; $singleSql = sprintf($sql, serendipity_db_escape_string($singleSearch[1]), $timestamp); @@ -129,21 +129,21 @@ Bayes:%Bayes%' $stats[$day][$singleSearch[1]] = 0; } } - + $searchResult = isset($stats[$day][$singleSearch[1]]) ? $stats[$day][$singleSearch[1]] : 0; if ($searchResult) { $statsString .= "{$singleSearch[0]}: {$searchResult}
"; } } } - + if (empty($statsCached)) { $this->cacheStats($stats); } - + echo $statsString; } - + function loadCachedStats() { $cacheFile = $this->getCacheFilename(); $cachesecs = $this->get_config('cachemin', '10') * 60; @@ -159,6 +159,7 @@ Bayes:%Bayes%' } return array(); } + function cacheStats($stats) { $stats = serialize($stats); $cacheFile = $this->getCacheFilename(); @@ -166,7 +167,7 @@ Bayes:%Bayes%' fputs($fh, $stats, strlen($stats)); fclose($fh); } - + /** * Returns the cache file name */ @@ -177,12 +178,12 @@ Bayes:%Bayes%' } return $this->cache_file; } - + function cleanup() { $cacheFile = $this->getCacheFilename(); if (file_exists($cacheFile)) { unlink($cacheFile); } } - -} \ No newline at end of file + +} diff --git a/serendipity_event_spamblock_bee/version.inc.php b/serendipity_event_spamblock_bee/version.inc.php index 7f0cc5dc..cb68cbe6 100644 --- a/serendipity_event_spamblock_bee/version.inc.php +++ b/serendipity_event_spamblock_bee/version.inc.php @@ -1,2 +1,2 @@