| 
<?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;
 }
 
 }
 
 ?>
 |