HTML tag
//'uri_bbcode' => $t_area, // URI inside [url] or [link] BBCode
);
if ($rule) {
$bool = array(
// Rules
//'asap' => TRUE, // Quit or return As Soon As Possible
'uniqhost' => TRUE, // Show uniq host (at block notification mail)
'badhost' => TRUE, // Check badhost
);
} else {
$bool = array();
}
// Remove non-$positive values
foreach (array_keys($positive) as $key) {
if ($positive[$key] < 0) unset($positive[$key]);
}
return $positive + $bool;
}
// Simple/fast spam check
function check_uri_spam($target = '', $method = array())
{
if (! is_array($method) || empty($method)) {
$method = check_uri_spam_method();
}
$progress = array(
'sum' => array(
'quantity' => 0,
'uniqhost' => 0,
'non_uniqhost'=> 0,
'non_uniquri' => 0,
'badhost' => 0,
'area_anchor' => 0,
'area_bbcode' => 0,
'uri_anchor' => 0,
'uri_bbcode' => 0,
),
'is_spam' => array(),
'method' => & $method,
'remains' => array(),
'error' => array(),
);
$sum = & $progress['sum'];
$is_spam = & $progress['is_spam'];
$remains = & $progress['remains'];
$error = & $progress['error'];
$asap = isset($method['asap']);
// Recurse
if (is_array($target)) {
foreach($target as $str) {
// Recurse
$_progress = check_uri_spam($str, $method);
$_sum = & $_progress['sum'];
$_is_spam = & $_progress['is_spam'];
$_remains = & $_progress['remains'];
$_error = & $_progress['error'];
foreach (array_keys($_sum) as $key) {
$sum[$key] += $_sum[$key];
}
foreach (array_keys($_is_spam) as $key) {
if (is_array($_is_spam[$key])) {
// Marge keys (badhost)
foreach(array_keys($_is_spam[$key]) as $_key) {
if (! isset($is_spam[$key][$_key])) {
$is_spam[$key][$_key] = $_is_spam[$key][$_key];
} else {
$is_spam[$key][$_key] += $_is_spam[$key][$_key];
}
}
} else {
$is_spam[$key] = TRUE;
}
}
foreach ($_remains as $key=>$value) {
foreach ($value as $_key=>$_value) {
if (is_int($_key)) {
$remains[$key][] = $_value;
} else {
$remains[$key][$_key] = $_value;
}
}
}
if (! empty($_error)) $error += $_error;
if ($asap && $is_spam) break;
}
return $progress;
}
// Area: There's HTML anchor tag
if ((! $asap || ! $is_spam) && isset($method['area_anchor'])) {
$key = 'area_anchor';
$_asap = isset($method['asap']) ? array('asap' => TRUE) : array();
$result = area_pickup($target, array($key => TRUE) + $_asap);
if ($result) {
$sum[$key] = $result[$key];
if (isset($method[$key]) && $sum[$key] > $method[$key]) {
$is_spam[$key] = TRUE;
}
}
}
// Area: There's 'BBCode' linking tag
if ((! $asap || ! $is_spam) && isset($method['area_bbcode'])) {
$key = 'area_bbcode';
$_asap = isset($method['asap']) ? array('asap' => TRUE) : array();
$result = area_pickup($target, array($key => TRUE) + $_asap);
if ($result) {
$sum[$key] = $result[$key];
if (isset($method[$key]) && $sum[$key] > $method[$key]) {
$is_spam[$key] = TRUE;
}
}
}
// Return if ...
if ($asap && $is_spam) return $progress;
// URI: Pickup
$pickups = uri_pickup_normalize(spam_uri_pickup($target, $method));
//$remains['uri_pickup'] = & $pickups;
// Return if ...
if (empty($pickups)) return $progress;
// URI: Check quantity
$sum['quantity'] += count($pickups);
// URI quantity
if ((! $asap || ! $is_spam) && isset($method['quantity']) &&
$sum['quantity'] > $method['quantity']) {
$is_spam['quantity'] = TRUE;
}
// URI: used inside HTML anchor tag pair
if ((! $asap || ! $is_spam) && isset($method['uri_anchor'])) {
$key = 'uri_anchor';
foreach($pickups as $pickup) {
if (isset($pickup['area'][$key])) {
$sum[$key] += $pickup['area'][$key];
if(isset($method[$key]) &&
$sum[$key] > $method[$key]) {
$is_spam[$key] = TRUE;
if ($asap && $is_spam) break;
}
if ($asap && $is_spam) break;
}
}
}
// URI: used inside 'BBCode' pair
if ((! $asap || ! $is_spam) && isset($method['uri_bbcode'])) {
$key = 'uri_bbcode';
foreach($pickups as $pickup) {
if (isset($pickup['area'][$key])) {
$sum[$key] += $pickup['area'][$key];
if(isset($method[$key]) &&
$sum[$key] > $method[$key]) {
$is_spam[$key] = TRUE;
if ($asap && $is_spam) break;
}
if ($asap && $is_spam) break;
}
}
}
// URI: Uniqueness (and removing non-uniques)
if ((! $asap || ! $is_spam) && isset($method['non_uniquri'])) {
$uris = array();
foreach (array_keys($pickups) as $key) {
$uris[$key] = uri_pickup_implode($pickups[$key]);
}
$count = count($uris);
$uris = array_unique($uris);
$sum['non_uniquri'] += $count - count($uris);
if ($sum['non_uniquri'] > $method['non_uniquri']) {
$is_spam['non_uniquri'] = TRUE;
}
if (! $asap || ! $is_spam) {
foreach (array_diff(array_keys($pickups),
array_keys($uris)) as $remove) {
unset($pickups[$remove]);
}
}
unset($uris);
}
// Return if ...
if ($asap && $is_spam) return $progress;
// Host: Uniqueness (uniq / non-uniq)
$hosts = array();
foreach ($pickups as $pickup) $hosts[] = & $pickup['host'];
$hosts = array_unique($hosts);
//$remains['uniqhost'] = & $hosts;
$sum['uniqhost'] += count($hosts);
if ((! $asap || ! $is_spam) && isset($method['non_uniqhost'])) {
$sum['non_uniqhost'] = $sum['quantity'] - $sum['uniqhost'];
if ($sum['non_uniqhost'] > $method['non_uniqhost']) {
$is_spam['non_uniqhost'] = TRUE;
}
}
// Return if ...
if ($asap && $is_spam) return $progress;
// URI: Bad host
if ((! $asap || ! $is_spam) && isset($method['badhost'])) {
$__remains = array();
$badhost = is_badhost($hosts, $asap, $__remains);
if (! $asap) {
if ($__remains) {
$remains['badhost'] = array();
foreach ($__remains as $value) {
$remains['badhost'][$value] = TRUE;
}
}
}
unset($__remains);
if (! empty($badhost)) {
//var_dump($badhost); // BADHOST detail
$sum['badhost'] += array_count_leaves($badhost);
foreach(array_keys($badhost) as $keys) {
$is_spam['badhost'][$keys] =
array_count_leaves($badhost[$keys]);
}
unset($badhost);
}
}
return $progress;
}
// Count leaves
function array_count_leaves($array = array(), $count_empty_array = FALSE)
{
if (! is_array($array) || (empty($array) && $count_empty_array))
return 1;
// Recurse
$result = 0;
foreach ($array as $part) {
$result += array_count_leaves($part, $count_empty_array);
}
return $result;
}
// ---------------------
// Reporting
// TODO: Don't show unused $method!
// Summarize $progress (blocked only)
function summarize_spam_progress($progress = array(), $blockedonly = FALSE)
{
if ($blockedonly) {
$tmp = array_keys($progress['is_spam']);
} else {
$tmp = array();
$method = & $progress['method'];
if (isset($progress['sum'])) {
foreach ($progress['sum'] as $key => $value) {
if (isset($method[$key])) {
$tmp[] = $key . '(' . $value . ')';
}
}
}
}
return implode(', ', $tmp);
}
// ---------------------
// Exit
// Common bahavior for blocking
// NOTE: Call this function from various blocking feature, to disgueise the reason 'why blocked'
function spam_exit($mode = '', $data = array())
{
switch ($mode) {
case '': echo("\n"); break;
case 'dump':
echo('' . "\n");
echo htmlspecialchars(var_export($data, TRUE));
echo('
' . "\n");
break;
};
// Force exit
exit;
}
// ---------------------
// Simple filtering
// TODO: Record them
// Simple/fast spam filter ($target: 'a string' or an array())
function pkwk_spamfilter($action, $page, $target = array('title' => ''), $method = array(), $exitmode = '')
{
$progress = check_uri_spam($target, $method);
if (! empty($progress['is_spam'])) {
// Mail to administrator(s)
pkwk_spamnotify($action, $page, $target, $progress, $method);
// Exit
spam_exit($exitmode, $progress);
}
}
// ---------------------
// PukiWiki original
// Mail to administrator(s)
function pkwk_spamnotify($action, $page, $target = array('title' => ''), $progress = array(), $method = array())
{
global $notify, $notify_subject;
if (! $notify) return;
$asap = isset($method['asap']);
$summary['ACTION'] = 'Blocked by: ' . summarize_spam_progress($progress, TRUE);
if (! $asap) {
$summary['METRICS'] = summarize_spam_progress($progress);
}
if (isset($progress['is_spam']['badhost'])) {
$badhost = array();
foreach($progress['is_spam']['badhost'] as $glob=>$number) {
$badhost[] = $glob . '(' . $number . ')';
}
$summary['DETAIL_BADHOST'] = implode(', ', $badhost);
}
if (! $asap && $progress['remains']['badhost']) {
$count = count($progress['remains']['badhost']);
$summary['DETAIL_NEUTRAL_HOST'] = $count .
' (' .
preg_replace(
'/[^, a-z0-9.-]/i', '',
implode(', ', array_keys($progress['remains']['badhost']))
) .
')';
}
$summary['COMMENT'] = $action;
$summary['PAGE'] = '[blocked] ' . (is_pagename($page) ? $page : '');
$summary['URI'] = get_script_uri() . '?' . rawurlencode($page);
$summary['USER_AGENT'] = TRUE;
$summary['REMOTE_ADDR'] = TRUE;
pkwk_mail_notify($notify_subject, var_export($target, TRUE), $summary, TRUE);
}
?>