title = PLUGIN_EVENT_RECAPTCHA_TITLE; $propbag->add('name', PLUGIN_EVENT_RECAPTCHA_TITLE); $propbag->add('description', PLUGIN_EVENT_RECAPTCHA_DESC); $propbag->add('stackable', false); $propbag->add('author', 'Christian Brabandt (based on work of Garvin Hicking, Sebastian Nohn)'); $propbag->add('requirements', array( 'serendipity' => '1.0', 'smarty' => '2.6.7', 'php' => '4.1.0' )); $propbag->add('version', '0.11'); $propbag->add('event_hooks', array( 'frontend_configure' => true, 'frontend_saveComment' => true, 'frontend_comment' => true )); $propbag->add('configuration', array( 'info', 'sep', 'hide_for_authors', 'recaptcha', 'recaptcha_style', 'recaptcha_pub', 'recaptcha_priv', 'captchas_ttl', 'logtype', 'logfile')); $propbag->add('groups', array('ANTISPAM')); } function introspect_config_item($name, &$propbag) { global $serendipity; switch($name) { case 'recaptcha': $propbag->add('type', 'radio'); $propbag->add('name', PLUGIN_EVENT_RECAPTCHA_RECAPTCHA); $propbag->add('description', PLUGIN_EVENT_RECAPTCHA_RECAPTCHA_DESC); $propbag->add('default', 'no'); $propbag->add('radio', array( 'value' => array('yes', 'no'), 'desc' => array(YES, NO) )); break; case 'recaptcha_pub': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_EVENT_RECAPTCHA_RECAPTCHA_PUB); $propbag->add('description', PLUGIN_EVENT_RECAPTCHA_RECAPTCHA_PUB_DESC); $propbag->add('default', ''); break; case 'recaptcha_priv': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_EVENT_RECAPTCHA_RECAPTCHA_PRIV); $propbag->add('description', PLUGIN_EVENT_RECAPTCHA_RECAPTCHA_PRIV_DESC); $propbag->add('default', ''); break; case 'recaptcha_style': $propbag->add('type', 'radio'); $propbag->add('name', PLUGIN_EVENT_RECAPTCHA_RECAPTCHA_STYLE); $propbag->add('description', PLUGIN_EVENT_RECAPTCHA_RECAPTCHA_STYLE_DESC); $propbag->add('default', 'red'); $propbag->add('radio', array( 'value' => array('red', 'white', 'blackglass'), 'desc' => array('Red', 'White', 'Blackglass') )); break; case 'hide_for_authors': $_groups =& serendipity_getAllGroups(); $groups = array( 'all' => ALL_AUTHORS, 'none' => NONE ); foreach($_groups AS $group) { $groups[$group['confkey']] = $group['confvalue']; } $propbag->add('type', 'multiselect'); $propbag->add('name', PLUGIN_EVENT_RECAPTCHA_HIDE); $propbag->add('description', PLUGIN_EVENT_RECAPTCHA_HIDE_DESC); $propbag->add('select_values', $groups); $propbag->add('select_size', 5); $propbag->add('default', 'all'); break; case 'logfile': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_EVENT_RECAPTCHA_LOGFILE); $propbag->add('description', PLUGIN_EVENT_RECAPTCHA_LOGFILE_DESC); $propbag->add('default', $serendipity['serendipityPath'] . 'spamblock.log'); break; case 'logtype': $propbag->add('type', 'radio'); $propbag->add('name', PLUGIN_EVENT_RECAPTCHA_LOGTYPE); $propbag->add('description', PLUGIN_EVENT_RECAPTCHA_LOGTYPE_DESC); $propbag->add('default', 'db'); $propbag->add('radio', array( 'value' => array('file', 'db', 'none'), 'desc' => array(PLUGIN_EVENT_RECAPTCHA_LOGTYPE_FILE, PLUGIN_EVENT_RECAPTCHA_LOGTYPE_DB, PLUGIN_EVENT_RECAPTCHA_LOGTYPE_NONE) )); $propbag->add('radio_per_row', '1'); break; case 'captchas_ttl': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_EVENT_RECAPTCHA_CAPTCHAS_TTL); $propbag->add('description', PLUGIN_EVENT_RECAPTCHA_CAPTCHAS_TTL_DESC); $propbag->add('default', '7'); break; case 'info': $suche='!http(?:s)?:\/\/(?:(?:[^.]*)\.)?([^.\/]*)!'; $result=preg_match($suche,$serendipity['baseURL'],$domain); $propbag->add('type', 'content'); $propbag->add('default', PLUGIN_EVENT_RECAPTCHA_INFO1.$domain[1]. PLUGIN_EVENT_RECAPTCHA_INFO2); break; case 'sep': $propbag->add('type', 'seperator'); break; default: return false; } return true; } function generate_content(&$title) { $title = $this->title; } // Checks whether the current author is contained in one of the groups that // need no spam checking function inGroup() { global $serendipity; $checkgroups = explode('^', $this->get_config('hide_for_authors')); if (!isset($serendipity['authorid']) || !is_array($checkgroups)) { return false; } $mygroups =& serendipity_getGroups($serendipity['authorid'], true); if (!is_array($mygroups)) { return false; } foreach($checkgroups AS $key => $groupid) { if ($groupid == 'all') { return true; } elseif (in_array($groupid, $mygroups)) { return true; } } return false; } function event_hook($event, &$bag, &$eventData, $addData = null) { global $serendipity; $hooks = &$bag->get('event_hooks'); if (isset($hooks[$event])) { $captchas_ttl = $this->get_config('captchas_ttl', 7); $_recaptcha = $this->get_config('recaptcha', 'no'); $recaptcha = ($_recaptcha ==='yes' || $_recaptcha !== 'no' || serendipity_db_bool($_recaptcha)); // Check if the entry is older than the allowed amount of time. // Enforce captchas if that is true of if captchas are activated // for every entry $show_captcha = (($recaptcha) && isset($eventData['timestamp']) && ($captchas_ttl < 1 || ($eventData['timestamp'] < (time() - ($captchas_ttl*60*60*24)))) ? true : false); switch($event) { case 'frontend_configure': // set a variable, so that the spamblock plugin can disable the captcha when recaptcha is found. if ($_recaptcha) { $serendipity['plugins']['disable_internal_captcha'] = true; } return true; break; case 'frontend_saveComment': if (!is_array($eventData) || serendipity_db_bool($eventData['allow_comments'])) { //$serendipity['csuccess'] = 'true'; $logfile = $this->logfile = $this->get_config('logfile', $serendipity['serendipityPath'] . 'spamblock.log'); // Check whether to allow comments from registered authors if (serendipity_userLoggedIn() && $this->inGroup()) { return true; } // Captcha checking if ($show_captcha && $addData['type'] == 'NORMAL') { $privatekey = $this->get_config('recaptcha_priv'); if ($_POST["recaptcha_response_field"] != 1) { $resp = recaptcha_check_answer($privatekey, $_SERVER["REMOTE_ADDR"], $_POST["recaptcha_challenge_field"], $_POST["recaptcha_response_field"]); if (!$resp->is_valid) { # set the error code so that we can display it $this->error = $resp->error; $this->log($logfile, $eventData['id'], 'REJECTED', $this->error, $addData); $eventData = array('allow_comments' => false); $serendipity['messagestack']['comments'][] = PLUGIN_EVENT_RECAPTCHA_ERROR_CAPTCHAS; return false; } } else { return false; } } } return true; break; case 'frontend_comment': // Check whether to allow comments from registered authors if (serendipity_userLoggedIn() && $this->inGroup()) { return true; } if ($show_captcha) { $pubkey = $this->get_config('recaptcha_pub'); $privkey = $this->get_config('recaptcha_priv'); if ( $recaptcha && (($pubkey == null || $pubkey == '') || ($privkey == null || $pubkey == '')) ) { $recaptcha = false; //$captchas = true; printf('
%s
',PLUGIN_EVENT_RECAPTCHA_ERROR_RECAPTCHA); } // The response from recaptcha.net $resp = null; $theme = $this->get_config('recaptcha_style', 'red'); echo "\n"; echo recaptcha_get_html($pubkey, $this->error); } return true; break; default: return false; break; } } else { return false; } } function log($logfile, $id, $switch, $reason, $comment) { global $serendipity; $method = $this->get_config('logtype'); switch($method) { case 'file': if (empty($logfile)) { return; } $fp = @fopen($logfile, 'a+'); if (!is_resource($fp)) { return; } fwrite($fp, sprintf( '[%s] - [%s: %s] - [#%s, Name "%s", E-Mail "%s", URL "%s", User-Agent "%s", IP %s] - [%s]' . "\n", date('Y-m-d H:i:s', serendipity_serverOffsetHour()), $switch, $reason, $id, str_replace("\n", ' ', $comment['name']), str_replace("\n", ' ', $comment['email']), str_replace("\n", ' ', $comment['url']), str_replace("\n", ' ', $_SERVER['HTTP_USER_AGENT']), $_SERVER['REMOTE_ADDR'], str_replace("\n", ' ', $comment['comment']) )); fclose($fp); break; case 'none': return; break; case 'db': default: $q = sprintf("INSERT INTO {$serendipity['dbPrefix']}spamblocklog (timestamp, type, reason, entry_id, author, email, url, useragent, ip, referer, body) VALUES (%d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')", serendipity_serverOffsetHour(), serendipity_db_escape_string($switch), serendipity_db_escape_string($reason), serendipity_db_escape_string($id), serendipity_db_escape_string($comment['name']), serendipity_db_escape_string($comment['email']), serendipity_db_escape_string($comment['url']), serendipity_db_escape_string($_SERVER['HTTP_USER_AGENT']), serendipity_db_escape_string($_SERVER['REMOTE_ADDR']), serendipity_db_escape_string(isset($_SESSION['HTTP_REFERER']) ? $_SESSION['HTTP_REFERER'] : $_SERVER['HTTP_REFERER']), serendipity_db_escape_string($comment['comment']) ); serendipity_db_query($q); break; } } } /* vim: set sts=4 ts=4 expandtab : */