<?php
declare(strict_types=1);
/*
* sync*gw SpamBot Bundle
*
* @copyright https://syncgw.com, 2013 - 2022
* @author Florian Daeumling, https://syncgw.com
* @license http://opensource.org/licenses/lgpl-3.0.html
*/
namespace syncgw\SpamBotBundle\Module;
use Contao\Validator;
use Contao\Widget;
class SpamBotMod extends SpamBot {
/*
* @array
*/
protected $Fields = ['spambot_page' => 0, 'spambot_msg' => 0, 'spambot_mod' => 0,
'spambot_internal_logspam' => 0, 'spambot_internal_logham' => 0, ];
/**
* Wipe everything from template except our error message - called during FE template processing
*
* @param content
* @param template name
*
* @return string content
*/
public function clearTemplate(string $strContent, string $strTemplate): string {
$str = [];
if ($GLOBALS['SpamBot']['Catch'] & (SpamBot::SPAM | SpamBot::BLACKL) && 'mod_article' === $strTemplate) {
preg_match('/(?<=<!-- SpamBot::start -->).*(?=<!-- SpamBot::end -->)/s', $strContent, $str);
// clear flag
unset($GLOBALS['SpamBot']['Catch']);
return $str[0];
}
return $strContent;
}
/**
* Replace insert tags - called during processing of insert tags
*
* @param insert tag
* @param $strTag
*
* @return string replacement
*/
public function replaceInsertTag(string $strTag) {
$parm = explode('::', $strTag);
// are we responsible?
if ('spambot' !== strtolower($parm[0]))
return FALSE;
// get information
if (!is_array($arr = deserialize(base64_decode($this->Input->cookie('SpamBot'), TRUE))))
$arr = [];
return isset($arr[$parm[1]]) ? $arr[$parm[1]] : '';
}
/**
* Check special regular expression - called during processing of textfields in any forms
*
* @param rgxp name
* @param e-mail
* @param $obj
*
* @return bool
*/
public function checkMail(string $strRegexp, string $email, Widget $obj): bool {
global $objPage;
// are we responsible?
if ('rgxSpamBots' !== $strRegexp)
return FALSE;
// standard e-mail validation
if (!Validator::isEmail($email))
$obj->addError($GLOBALS['TL_LANG']['ERR']['email']);
// check for active module included in this page
$rc = $this->Db->prepare(
'SELECT c.id FROM tl_article a LEFT JOIN tl_content b ON (b.pid=a.id) '.
'LEFT JOIN tl_module c ON (c.id=b.module) WHERE '.
'a.pid=? AND b.invisible<>1 AND c.type=?')
->execute($objPage->id, 'SpamBot-Mail');
// if not on page check layout
if (!$rc->numRows) {
// get list of SpamBot-Mail modules
$mods = $this->Db->prepare('SELECT id FROM tl_module WHERE type=?')->execute('SpamBot-Mail');
$mods = is_array($mods->id) ? $mods->id : [$mods->id];
// clear module ID
$this->modID = 0;
// check for modules included in page layout
$rc = $this->Db->prepare('SELECT modules FROM tl_layout WHERE id=?')->execute($objPage->layout);
if ($rc->modules) {
foreach (deserialize($rc->modules) as $v) {
foreach ($mods as $mid) {
if ($mid === $v['mod']) {
$this->modID = $mid;
break;
}
}
if ($this->modID)
break;
}
}
// not in page and not in layout :-(
if (!$this->modID)
return TRUE;
} else
$this->modID = $rc->id;
list($ptyp, , ) = self::_doCheck(SpamBot::TYP_MAIL, self::getIP(), $email);
// display user error message
if ($ptyp & (SpamBot::SPAM | SpamBot::BLACKL))
$obj->addError($GLOBALS['TL_LANG']['SpamBot']['SpamBot']['email']);
return TRUE;
}
/**
* Check IP address - called by ModuleSpamBotIP
*
* @param client IP
*
* @return array (SpamBot::Status, status message, execution time)
*/
public function checkIP(string $ip): array {
return self::_doCheck(SpamBot::TYP_IP, $ip, '');
}
/**
* Get IP address
*
* @return string
*/
public function getIP(): string {
$ip = [];
foreach (['HTTP_CF_CONNECTING_IP', 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED',
'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR', ] as $key) {
if (TRUE === array_key_exists($key, $_SERVER)) {
foreach (explode(',', $_SERVER[$key]) as $vip)
$ip[] = str_replace(' ', '', $vip);
}
}
// if for some strange reason we don't get an IP we return imemdiately with 0.0.0.0
if (empty($ip))
$ip = '0.0.0.0';
else {
$ip = array_values(array_unique($ip));
foreach ($ip as $v) {
if (filter_var($v, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
$ip = $v;
break;
}
}
}
return is_array($ip) ? $ip[0] : $ip;
}
/**
* Perform check
*
* @param function to call
* @param IP address
* @param email address
*
* @return array (SpamBot::Status, status message, execution time)
*/
private function _doCheck(int $func, string $ip, string $mail): array {
// return value is undefined
$rc = NULL;
// check all engines
$en = deserialize(parent::callMods($func, $ip, $mail, intval($this->spambot_mod)));
// check for WHITE and BLACK list?
if (SpamBot::MOD_FIRST !== $this->spambot_mod) {
foreach ($en as $v) {
if (SpamBot::NOTFOUND === $v[0])
continue;
// check type
if ($v[0] & (SpamBot::BLACKL | SpamBot::WHITEL)) {
$rc = $v;
break;
}
}
}
// check all other returned values
if (!$rc) {
foreach ($en as $v) {
if (SpamBot::NOTFOUND === $v[0])
continue;
// check modus
switch ($this->spambot_mod) {
case SpamBot::MOD_FIRST:
if (!($v[0] & SpamBot::NOTFOUND))
$rc = $v;
break;
case SpamBot::MOD_SPAM:
if ($v[0] & SpamBot::SPAM)
$rc = $v;
break;
case SpamBot::MOD_HAM:
default:
if ($v[0] & SpamBot::HAM)
$rc = $v;
break;
}
// anything found
if ($rc)
break;
}
}
// default to "Ham" (if not found)
if (!$rc || $rc[0] & SpamBot::NOTFOUND) {
$rc[0] = SpamBot::HAM;
$rc[1] = 'Default: Ham';
}
// convert LOADED
if ($rc[0] & SpamBot::LOADED)
$rc[0] = SpamBot::SPAM;
// special Intern check
if (($rc[0] & (SpamBot::WHITEL | SpamBot::BLACKL)) ||
(($rc[0] & SpamBot::HAM) && !$this->spambot_internal_logham) ||
(($rc[0] & SpamBot::SPAM) && !$this->spambot_internal_logspam))
return $rc;
// clean status message
$rc[1] = strip_tags($rc[1]);
// update internal data base
$upd = time();
if (SpamBot::TYP_IP === $func) {
$rec = $this->Db->prepare('SELECT id FROM tl_spambot WHERE module=? AND ip=? AND typ<>?')
->execute($this->modID, $ip, SpamBot::LOADED);
if ($rec->numRows)
$this->Db->prepare('UPDATE tl_spambot SET module=?, tstamp=?, browser=?, typ=?, status=? WHERE id=?')
->execute($this->modID, $upd, \Environment::get('httpUserAgent'), $rc[0], $rc[1], $rec->id);
else
$this->Db->prepare('INSERT tl_spambot SET module=?, ip=?, created=?, tstamp=?, browser=?, typ=?, status=?')
->execute($this->modID, $ip, $upd, $upd, \Environment::get('httpUserAgent'), $rc[0], $rc[1]);
} else {
$rec = $this->Db->prepare('SELECT id FROM tl_spambot WHERE module=? AND mail=? AND typ<>?')
->execute($this->modID, $mail, SpamBot::LOADED);
if ($rec->numRows)
$this->Db->prepare('UPDATE tl_spambot SET module=?, tstamp=?, ip=?, browser=?, typ=?, status=? WHERE id=?')
->execute($this->modID, $upd, self::getIP(), \Environment::get('httpUserAgent'), $rc[0], $rc[1], $rec->id);
else
$this->Db->prepare('INSERT tl_spambot SET module=?, ip=?, mail=?, created=?, tstamp=?, browser=?, typ=?, status=?')
->execute($this->modID, self::getIP(), $mail, $upd, $upd, \Environment::get('httpUserAgent'), $rc[0], $rc[1]);
}
return $rc;
}
}
?>
|