MWX/SpamFerret/Special: Difference between revisions
(v0.1) |
m (Woozle moved page SpamFerret/Special to MWX/SpamFerret/Special without leaving a redirect: most mediawiki extensions belong under MWX now) |
||
(3 intermediate revisions by the same user not shown) | |||
Line 9: | Line 9: | ||
2009-08-04 0.0 (Wzl) Started writing | 2009-08-04 0.0 (Wzl) Started writing | ||
2009-10-01 0.1 (Wzl) incremental improvements; clsMenu now a separate file | 2009-10-01 0.1 (Wzl) incremental improvements; clsMenu now a separate file | ||
2009-10-06 0.2 (Wzl) text-check now shows if matching filters are deactivated | |||
2010-02-23 0.3 (Wzl) finally gave regular users some brief summary text to look at | |||
2010-08-17 0.31 (Wzl) a bit of debugging display in the regex checker | |||
*/ | */ | ||
$wgSpecialPages['SpamFerret'] = 'SpecialSpamFerret'; # Let MediaWiki know about your new special page. | $wgSpecialPages['SpamFerret'] = 'SpecialSpamFerret'; # Let MediaWiki know about your new special page. | ||
Line 16: | Line 19: | ||
'description' => 'special page for SpamFerret administration', | 'description' => 'special page for SpamFerret administration', | ||
'author' => 'Woozle (Nick) Staddon', | 'author' => 'Woozle (Nick) Staddon', | ||
'version' => '0. | 'version' => '0.31 2010-08-17 alpha' | ||
); | ); | ||
define('KS_CHAR_URL_ASSIGN',':'); // character used for encoding values in wiki-internal URLs | define('KS_CHAR_URL_ASSIGN',':'); // character used for encoding values in wiki-internal URLs | ||
Line 28: | Line 31: | ||
require_once( $wgScriptPath.'includes/SpecialPage.php' ); | require_once( $wgScriptPath.'includes/SpecialPage.php' ); | ||
if (!defined('LIBMGR')) { | |||
require('libmgr.php'); | |||
} | } | ||
clsLibMgr::Add('menus', KFP_MW_PLUGINS.'/menu.php',__FILE__,__LINE__); | |||
clsLibMgr::Load('menus' ,__FILE__,__LINE__); | |||
class SpecialSpamFerret extends SpecialPage { | class SpecialSpamFerret extends SpecialPage { | ||
//======= | //======= | ||
Line 234: | Line 147: | ||
PURPOSE: do only stuff that regular users are allowed to do | PURPOSE: do only stuff that regular users are allowed to do | ||
*/ | */ | ||
$wgOut->AddWikiText('Hello regular user! I haven\'t written anything for you yet, but eventually.'); | //$wgOut->AddWikiText('Hello regular user! I haven\'t written anything for you yet, but eventually.'); | ||
$sql = 'SELECT MIN(`When`) AS WhenEarly, COUNT(ID) AS Count, didAllow FROM attempt GROUP BY didAllow'; | |||
$objRows = self::DB()->DataSet($sql); | |||
if ($objRows->HasRows()) { | |||
$utOldest = NULL; | |||
while ($objRows->NextRow()) { | |||
$intCount = $objRows->Row['Count']; | |||
$utWhen = strtotime($objRows->Row['WhenEarly']); | |||
if (is_null($utOldest) || ($utWhen < $utOldest)) { | |||
$utOldest = $utWhen; | |||
} | |||
if ($objRows->didAllow) { | |||
$outAllowed = $intCount.' edit'.Pluralize($intCount).' allowed'; | |||
} else { | |||
$outRejected = $intCount.' attempted spam'.Pluralize($intCount).' rejected'; | |||
} | |||
} | |||
$out = $outRejected.' and '.$outAllowed.' since '.date('F j, Y',$utOldest).'.'; | |||
} else { | |||
$out = 'No edit attempts recorded by SpamFerret yet!'; | |||
} | |||
$wgOut->AddHTML($out); | |||
// URL needs to be broken up in order not to get filtered as spam >.< | |||
$wgOut->AddHTML('<br>See <a href="http'.'://htyp.org/SpamFerret">HTYP</a> for all available documentation.'); | |||
} | |||
// individual admin functions | // individual admin functions | ||
public function doInspectEdits() { | public function doInspectEdits() { | ||
global $wgOut,$wgRequest; | global $wgOut,$wgRequest; | ||
$ | $arOpts['filt'] = $wgRequest->getVal('sqlFilt',''); | ||
$ | $arOpts['sort'] = $wgRequest->getVal('sqlSort','ID DESC'); | ||
$ | $arOpts['rows'] = $wgRequest->getVal('sqlRows',50); | ||
// LATER: display form for changing these defaults | |||
//$objTbl = | |||
//$objRows-> | |||
} | } | ||
public function doEditFilter($iID) { | public function doEditFilter($iID) { | ||
Line 303: | Line 225: | ||
$id = $objRows->ID; | $id = $objRows->ID; | ||
$wtID = | $wtID = SpIDSelfLink('filter','id',$id,$id); | ||
$strPatt = '<nowiki>'.$objRows->Pattern.'</nowiki>'; | $strPatt = '<nowiki>'.$objRows->Pattern.'</nowiki>'; | ||
$isActive = $objRows->isActive; | $isActive = $objRows->isActive; | ||
Line 330: | Line 252: | ||
$inText = $wgRequest->getVal('sample'); | $inText = $wgRequest->getVal('sample'); | ||
$wgOut->AddHTML('<form method=post action=" | $wgOut->AddHTML('<form method=post action="">'); | ||
$wgOut->AddHTML('Expression: <input name=expr size=80 value="'.$inExpr.'">'); | $wgOut->AddHTML('Expression: <input name=expr size=80 value="'.htmlspecialchars($inExpr).'">'); | ||
$wgOut->AddHTML('<br>Text to check:<br><textarea name=sample cols=50 rows=10>'.$inText.'</textarea>'); | $wgOut->AddHTML('<br>Text to check:<br><textarea name=sample cols=50 rows=10>'.htmlspecialchars($inText).'</textarea>'); | ||
$wgOut->AddHTML('<input name=go type=submit value="Evaluate">'); | $wgOut->AddHTML('<input name=go type=submit value="Evaluate">'); | ||
$wgOut->AddHTML('</form>'); | $wgOut->AddHTML('</form>'); | ||
$wgOut->AddWikiText('==Results=='); | $wgOut->AddWikiText('==Results=='); | ||
$wgOut->AddWikiText("'''checked''': ".htmlspecialchars($inExpr),TRUE); | $wgOut->AddWikiText("'''checked''': <nowiki>".htmlspecialchars($inExpr),TRUE).'</nowiki>'; | ||
/* | |||
// prefix any '/' characters with an escape ('\') because we are using the format which requires '/' at either end | |||
$chDelim = '/'; | $chDelim = '/'; | ||
$strPattCk = str_replace($chDelim,'\\'.$chDelim,$inExpr); | $strPattCk = str_replace($chDelim,'\\'.$chDelim,$inExpr); | ||
$isMatch = @preg_match('/'.$strPattCk.'/',$inText,$matches); | $isMatch = @preg_match('/'.$strPattCk.'/',$inText,$matches); | ||
*/ | |||
// first 2 lines are a kluge until CheckRegex() is static, returning results in array | |||
$objSF = new SpamFerret(); | |||
global $gRegexMatches,$strDbg; | |||
$isMatch = $objSF->CheckRegex($inExpr,$inText); | |||
$wgOut->AddWikiText($strDbg,TRUE); | |||
$matches = $gRegexMatches; | |||
if (isset($php_errormsg)) { | if (isset($php_errormsg)) { | ||
$outErr .= "===Error===\n$php_errormsg"; | $outErr .= "===Error===\n$php_errormsg"; | ||
Line 345: | Line 278: | ||
} else { | } else { | ||
$wgOut->AddWikiText("===Matches==="); | $wgOut->AddWikiText("===Matches==="); | ||
$wgOut->AddHTML('<pre>'.var_export($matches,TRUE).'</pre>'); | $wgOut->AddHTML('<pre>'.htmlspecialchars(var_export($matches,TRUE)).'</pre>'); | ||
} | } | ||
} | } | ||
Line 354: | Line 287: | ||
$inText = $wgRequest->getVal('sample'); | $inText = $wgRequest->getVal('sample'); | ||
$doEcho = $wgRequest->getVal('doShowText'); | |||
$htDoEcho = $doEcho?' checked':''; | |||
$wgOut->AddHTML('Check sample text against all defined filters.'); | $wgOut->AddHTML('Check sample text against all defined filters.'); | ||
Line 359: | Line 294: | ||
$wgOut->AddHTML('<br>Text to check:<br><textarea name=sample cols=50 rows=10>'.$inText.'</textarea>'); | $wgOut->AddHTML('<br>Text to check:<br><textarea name=sample cols=50 rows=10>'.$inText.'</textarea>'); | ||
$wgOut->AddHTML('<input name=go type=submit value="Evaluate">'); | $wgOut->AddHTML('<input name=go type=submit value="Evaluate">'); | ||
$wgOut->AddHTML('<input name=doShowText type=checkbox'.$htDoEcho.'>Echo input text'); | |||
$wgOut->AddHTML('</form>'); | $wgOut->AddHTML('</form>'); | ||
if ($inText != '') { | if ($inText != '') { | ||
$wgOut->AddWikiText('==Results=='); | $wgOut->AddWikiText('==Results=='); | ||
$objSF = new SpamFerret(); | $objSF = new SpamFerret(); | ||
$objSF->OpenDatabase(); | $objSF->OpenDatabase(); | ||
$objSF->txtEditRaw = $inText; | $objSF->txtEditRaw = $inText; | ||
$ | $arArgs['doAll'] = TRUE; | ||
$ | // LATER: allow user to enter title of existing page for generating diff | ||
$arArgs['diff'] = '!!NEW: '.$inText; | |||
if ($doEcho) { | |||
$out = "* '''checked''':"; | |||
$out .= "\n** '''plain''': ".htmlspecialchars($inText); | |||
$out .= "\n** '''diff''': ".htmlspecialchars($arArgs['diff']); | |||
$wgOut->AddWikiText($out,TRUE); | |||
} | |||
$objSF->CheckFilters($arArgs); | |||
$out = | |||
"\n* ".$gFilterRows.' filter'.Pluralize($gFilterRows).' defined'. | |||
"\n* ".$gFilterCount.' filter'.Pluralize($gFilterCount).' checked'; | |||
$wgOut->AddWikiText($out); | |||
if (is_array($gFilterMatches)) { | if (is_array($gFilterMatches)) { | ||
$out = "{|\n|-\n! ID || length || filter"; | $out = "{|\n|-\n! ID || length || filter"; | ||
$isOdd = FALSE; | |||
foreach ($gFilterMatches as $id=>$text) { | foreach ($gFilterMatches as $id=>$text) { | ||
$objFilt = $objSF-> | |||
$out .= "\n|-\n| $id || ".strlen($text)." || <nowiki>{$objFilt->Pattern}</nowiki>"; | $wtStyle = $isOdd?'background:#ffffff;':'background:#eeeeee;'; | ||
$isOdd = !$isOdd; | |||
$objFilt = $objSF->FiltTbl()->GetItem($id); | |||
$isActive = $objFilt->isActive; | |||
if (!$isActive) { | |||
$wtStyle .= ' color: #888888;'; | |||
$wtStyle .= ' text-decoration: line-through;'; | |||
} | |||
$out .= "\n|- style=\"$wtStyle\"\n| $id || ".strlen($text)." || <nowiki>{$objFilt->Pattern}</nowiki>"; | |||
} | } | ||
$out .= "\n|}"; | $out .= "\n|}"; | ||
Line 384: | Line 342: | ||
} | } | ||
} | } | ||
/* | |||
LATER: for debugging why a particular string doesn't seem to be triggering the filter it should trigger | |||
public function CheckFiltersLocal($iCheckAll) { | |||
global $gRegexMatches,$gFilterMatches,$gFilterRows,$gFilterCount; | |||
global $debug; | |||
$this->PatternTbl = new clsTable($this->dbSpam); | |||
$this->PatternTbl->Name('patterns'); | |||
$this->PatternTbl->KeyName('ID'); | |||
$this->PatternRows = $this->PatternTbl->GetData(); | |||
$objRow = $this->PatternRows; | |||
$strTextEdit = strtolower($this->txtEditRaw); | |||
$this->txtEditChk = $strTextEdit; // text after being massaged for checking | |||
$this->isMatch = FALSE; | |||
$gFilterCount = 0; | |||
$gFilterRows = $this->PatternRows->RowCount(); | |||
//$objDataPatterns->StartRows(); | |||
while($objRow->NextRow() && (!$this->isMatch || $iCheckAll)) { | |||
$isMatch = FALSE; | |||
if ($objRow->isDiff) { | |||
if (isset($this->txtDiff)) { | |||
$strTextCk = $this->txtDiff; | |||
} else { | |||
$strTextCk = NULL; | |||
} | |||
} else { | |||
$strTextCk = $strTextEdit; | |||
} | |||
if (!is_null($strTextCk)) { | |||
$gFilterCount++; | |||
$strPattern = $objRow->Pattern; | |||
$isRegex = $objRow->isRegex; | |||
$this->idPattern = $objRow->ID; | |||
if ($isRegex) { | |||
$isMatch = $this->CheckRegex($strPattern,$strTextCk); | |||
if (isset($php_errormsg)) { | |||
$this->AddErrorLine('Filter #'.$this->idPattern.' generated error "'.$php_errormsg); | |||
} | |||
if ($isMatch) { | |||
$this->strMatch = $gRegexMatches[0]; | |||
} | |||
} else { | |||
if (empty($strPattern)) { | |||
$isMatch = FALSE; | |||
} else { | |||
$this->strMatch = stristr($strTextCk,$strPattern); | |||
$isMatch = ($this->strMatch != ''); | |||
} | |||
} | |||
if ($isMatch) { | |||
$this->isMatch = TRUE; | |||
if ($iCheckAll) { | |||
$gFilterMatches[$this->idPattern] = $this->strMatch; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
*/ | |||
} | } | ||
function | class clsAttempts extends clsTable { | ||
public function __construct($iDB) { | |||
parent::__construct($iDB); | |||
$this->Name('attempt'); | |||
$this->KeyName('ID'); | |||
$this->ClassSng('clsAttempt'); | |||
} | } | ||
public function GetRecent(array $iarOpts) { | |||
if (empty($iarOpts['filt'])) { | |||
$sqlFilt = ''; | |||
} else { | |||
$sqlFilt = ' WHERE '.$iarOpts['filt']; | |||
} | |||
if (empty($iarOpts['sort'])) { | |||
$sqlSort = ''; | |||
} else { | |||
$sqlSort = ' ORDER BY '.$iarOpts['sort']; | |||
} | |||
if (empty($iarOpts['rows'])) { | |||
$sqlRows = ''; | |||
} else { | |||
$sqlRows = ' LIMIT '.$iarOpts['rows']; | |||
} | |||
$sql = 'SELECT * FROM attempts'.$sqlFilt.$sqlSort.$sqlRows; | |||
$objRows = $this->DataSet($sql); | |||
return $objRows; | |||
} | |||
} | |||
class clsAttempt extends clsDataSet { | |||
} | |||
// UTILITY FUNCTIONS // | |||
function SpIDSelfLink($iDo,$iKey,$iVal,$iText) { | |||
// return '[[{{FULLPAGENAME}}/do'.KS_CHAR_URL_ASSIGN.$iDo.'/'.$iKey.KS_CHAR_URL_ASSIGN.$iVal.'|'.$iText.']]'; | |||
return '[[Special:AudioFerret/do'.KS_CHAR_URL_ASSIGN.$iDo.'/'.$iKey.KS_CHAR_URL_ASSIGN.$iVal.'|'.$iText.']]'; | |||
} | |||
/* | |||
function SelfLink($iPage,$iKey,$iVal,$iText) { | function SelfLink($iPage,$iKey,$iVal,$iText) { | ||
return '[[{{FULLPAGENAME}}/page'.KS_CHAR_URL_ASSIGN.$iPage.'/'.$iKey.KS_CHAR_URL_ASSIGN.$iVal.'|'.$iText.']]'; | return '[[{{FULLPAGENAME}}/page'.KS_CHAR_URL_ASSIGN.$iPage.'/'.$iKey.KS_CHAR_URL_ASSIGN.$iVal.'|'.$iText.']]'; | ||
} | } | ||
*/ | |||
function ShowFlag($iName,$iVal,$iText) { | function ShowFlag($iName,$iVal,$iText) { | ||
$out = '<input type=checkbox name="'.$iName.'" value='.$iVal.'>'.$iText; | $out = '<input type=checkbox name="'.$iName.'" value='.$iVal.'>'.$iText; | ||
return $out; | return $out; | ||
} | } | ||
if (!function_exists('TimeStamp_HideTime')) { | |||
//-- | |||
function TimeStamp_HideTime($iStamp) { | function TimeStamp_HideTime($iStamp) { | ||
Line 412: | Line 471: | ||
} | } | ||
} | } | ||
</php> | //-- | ||
}</php> |
Latest revision as of 20:14, 1 May 2022
Code
<php><?php /*
NAME: SpecialSpamFerret PURPOSE: Special page for administering the SpamFerret database REQUIRES: SpamFerret (for now...) AUTHOR: Woozle (Nick) Staddon VERSION:
2009-08-04 0.0 (Wzl) Started writing 2009-10-01 0.1 (Wzl) incremental improvements; clsMenu now a separate file 2009-10-06 0.2 (Wzl) text-check now shows if matching filters are deactivated 2010-02-23 0.3 (Wzl) finally gave regular users some brief summary text to look at 2010-08-17 0.31 (Wzl) a bit of debugging display in the regex checker
- /
$wgSpecialPages['SpamFerret'] = 'SpecialSpamFerret'; # Let MediaWiki know about your new special page. $wgExtensionCredits['other'][] = array(
'name' => 'Special:SpamFerret',
'url' => 'http://htyp.org/SpamFerret',
'description' => 'special page for SpamFerret administration', 'author' => 'Woozle (Nick) Staddon',
'version' => '0.31 2010-08-17 alpha' ); define('KS_CHAR_URL_ASSIGN',':'); // character used for encoding values in wiki-internal URLs
function wfSpecialSpamFerret() { // This registers the page's class. I think. global $wgRequest;
$app = new SpecialSpamFerret($wgRequest); }
require_once( $wgScriptPath.'includes/SpecialPage.php' ); if (!defined('LIBMGR')) {
require('libmgr.php');
} clsLibMgr::Add('menus', KFP_MW_PLUGINS.'/menu.php',__FILE__,__LINE__); clsLibMgr::Load('menus' ,__FILE__,__LINE__);
class SpecialSpamFerret extends SpecialPage { //======= // STATIC
static private $objDB;
static public function Setting($iName) {
global $wgSpamFerretSettings;
return $wgSpamFerretSettings[$iName];
} static public function DB() {
if (!isset(self::$objDB)) { self::$objDB = new clsDatabase(self::Setting('dbspec')); self::$objDB->Open(); } return self::$objDB;
}
//======= // DYNAMIC
protected $args;
public function __construct() {
global $wgMessageCache;
parent::__construct( 'SpamFerret' ); $this->includable( false );
$wgMessageCache->addMessage('spamferret', 'SpamFerret administration'); } function execute( $par ) {
global $wgUser;
$this->setHeaders(); $this->GetArgs($par);
if ($wgUser->isAllowed('editinterface')) { $this->doAdmin(); } else { $this->doUser(); }
} private function GetArgs($par) {
/*
PURPOSE: Parses variable arguments from the URL The URL is formatted as a series of arguments /arg=val/arg=val/..., so that we can always refer directly to any particular item as a wiki page title while also not worrying about hierarchy/order.
- /
$args_raw = split('/',$par); foreach($args_raw as $arg_raw) {
if (strpos($arg_raw,KS_CHAR_URL_ASSIGN) !== FALSE) { list($key,$val) = split(KS_CHAR_URL_ASSIGN,$arg_raw); $this->args[$key] = $val; }
} } public function doAdmin() {
global $wgOut; /* PURPOSE: do stuff that only admins are allowed to do
- /
if (isset($this->args['page'])) { $page = $this->args['page']; } else { $page = NULL; } // display menu $wtSelf = 'Special:'.$this->name();
$objMenu = new clsMenu($wtSelf); $objMenu->Add($objRow = new clsMenuRow('Utilities','menu.util')); $objRow->Add(new clsMenuItem('check expression','ckexpr')); $objRow->Add(new clsMenuItem('check text','cktext')); $objMenu->Add($objRow = new clsMenuRow('Inspect','menu.insp')); $objRow->Add(new clsMenuItem('recent edits','edits')); $objRow->Add(new clsMenuItem('filters','filters'));
$out = $objMenu->WikiText($page); $out .= $objMenu->Execute();
$wgOut->addHTML('
');
$wgOut->addWikiText($out,TRUE); $out = ; $wgOut->addHTML(' |
');
if (!is_null($page)) { $id = isset($this->args['id'])?$this->args['id']:NULL; switch ($page) { case 'ckexpr': $this->doRegexChecker(); break; case 'cktext': $this->doTextChecker(); break; case 'edits': $this->doInspectEdits(); break; case 'filters': $this->doInspectFilters(); break; case 'filter': $this->doEditFilter($id); } }
} public function doUser() {
global $wgOut; /* PURPOSE: do only stuff that regular users are allowed to do
- /
//$wgOut->AddWikiText('Hello regular user! I haven\'t written anything for you yet, but eventually.');
$sql = 'SELECT MIN(`When`) AS WhenEarly, COUNT(ID) AS Count, didAllow FROM attempt GROUP BY didAllow';
$objRows = self::DB()->DataSet($sql);
if ($objRows->HasRows()) {
$utOldest = NULL;
while ($objRows->NextRow()) {
$intCount = $objRows->Row['Count'];
$utWhen = strtotime($objRows->Row['WhenEarly']);
if (is_null($utOldest) || ($utWhen < $utOldest)) {
$utOldest = $utWhen;
}
if ($objRows->didAllow) {
$outAllowed = $intCount.' edit'.Pluralize($intCount).' allowed';
} else {
$outRejected = $intCount.' attempted spam'.Pluralize($intCount).' rejected';
}
}
$out = $outRejected.' and '.$outAllowed.' since '.date('F j, Y',$utOldest).'.';
} else {
$out = 'No edit attempts recorded by SpamFerret yet!';
}
$wgOut->AddHTML($out);
// URL needs to be broken up in order not to get filtered as spam >.<
$wgOut->AddHTML('
See <a href="http'.'://htyp.org/SpamFerret">HTYP</a> for all available documentation.');
}
// individual admin functions
public function doInspectEdits() {
global $wgOut,$wgRequest;
$arOpts['filt'] = $wgRequest->getVal('sqlFilt',); $arOpts['sort'] = $wgRequest->getVal('sqlSort','ID DESC'); $arOpts['rows'] = $wgRequest->getVal('sqlRows',50); // LATER: display form for changing these defaults
//$objTbl = //$objRows->
} public function doEditFilter($iID) {
global $wgOut;
$dbSP = self::DB(); $tblFilt = new clsTable($dbSP); $tblFilt->Name('patterns'); $tblFilt->KeyName('ID'); $objRows = $tblFilt->GetItem($iID); if ($objRows->hasRows()) { $htPattern = htmlspecialchars($objRows->Pattern);
$out = '
'; $out .= "\n"; $out .= "\n"; $out .= "\n"; $out .= "\n"; $out .= "\nID: | {$objRows->ID} |
Pattern: | {$htPattern} |
Added: | {$objRows->WhenAdded} |
Tried: | {$objRows->WhenTried} |
flags: | ";
$out .= ShowFlag('active',$objRows->isActive,'Active'); $out .= ShowFlag('regex',$objRows->isRegex,'Regex'); $out .= ShowFlag('diff',$objRows->isDiff,'Diff'); $out .= ShowFlag('isurl',$objRows->isURL,'URL'); $out .= ' |
';
$wgOut->AddHTML($out); $out = ; }
} public function doInspectFilters() {
global $wgOut;
$dbSP = self::DB(); $tblFilt = new clsTable($dbSP); $tblFilt->Name('patterns'); $tblFilt->KeyName('ID'); $objRows = $tblFilt->GetData(); if ($objRows->hasRows()) { $out = "{| class=sortable\n|-\n! ID || Pattern || A? || U? || R? || D? || Added || Tried || Count"; $isOdd = TRUE; while ($objRows->NextRow()) { $wtStyle = $isOdd?'background:#ffffff;':'background:#eeeeee;'; $isOdd = !$isOdd;
$id = $objRows->ID; $wtID = SpIDSelfLink('filter','id',$id,$id); $strPatt = ''.$objRows->Pattern.''; $isActive = $objRows->isActive; $isURL = $objRows->isURL; $isRegex = $objRows->isRegex; $isDiff = $objRows->isDiff; $wtAdded = TimeStamp_HideTime($objRows->WhenAdded); $wtTried = TimeStamp_HideTime($objRows->WhenTried); $intCount = $objRows->Count;
$out .= "\n|- style=\"$wtStyle\"\n|$wtID||$strPatt||$isActive||$isURL||$isRegex||$isDiff||$wtAdded||$wtTried||align=right|$intCount";
}
$out .= "\n|}\n";
$wgOut->AddWikiText($out);
} else {
$wgOut->AddHTML('No filters have been defined.');
if (!$dbSP->isOk()) {
$wgOut->AddHTML('
Database Error: '.$dbSP->getError());
}
}
} public function doRegexChecker() {
global $wgOut,$wgRequest;
$inExpr = $wgRequest->getVal('expr'); $inText = $wgRequest->getVal('sample');
$wgOut->AddHTML('<form method=post action="">');
$wgOut->AddHTML('Expression: <input name=expr size=80 value="'.htmlspecialchars($inExpr).'">');
$wgOut->AddHTML('
Text to check:
<textarea name=sample cols=50 rows=10>'.htmlspecialchars($inText).'</textarea>');
$wgOut->AddHTML('<input name=go type=submit value="Evaluate">');
$wgOut->AddHTML('</form>');
$wgOut->AddWikiText('==Results==');
$wgOut->AddWikiText("checked: ".htmlspecialchars($inExpr),TRUE).'';
/*
// prefix any '/' characters with an escape ('\') because we are using the format which requires '/' at either end
$chDelim = '/';
$strPattCk = str_replace($chDelim,'\\'.$chDelim,$inExpr);
$isMatch = @preg_match('/'.$strPattCk.'/',$inText,$matches);
- /
// first 2 lines are a kluge until CheckRegex() is static, returning results in array $objSF = new SpamFerret();
global $gRegexMatches,$strDbg; $isMatch = $objSF->CheckRegex($inExpr,$inText); $wgOut->AddWikiText($strDbg,TRUE); $matches = $gRegexMatches;
if (isset($php_errormsg)) { $outErr .= "===Error===\n$php_errormsg"; $wgOut->AddWikiText($outErr); } else { $wgOut->AddWikiText("===Matches===");
$wgOut->AddHTML('
'.htmlspecialchars(var_export($matches,TRUE)).'
');
}
} public function doTextChecker() {
global $wgOut,$wgRequest; global $gFilterMatches,$gFilterCount,$gFilterRows; global $debug;
$inText = $wgRequest->getVal('sample'); $doEcho = $wgRequest->getVal('doShowText'); $htDoEcho = $doEcho?' checked':;
$wgOut->AddHTML('Check sample text against all defined filters.');
$wgOut->AddHTML('<form method=post action="">');
$wgOut->AddHTML('
Text to check:
<textarea name=sample cols=50 rows=10>'.$inText.'</textarea>');
$wgOut->AddHTML('<input name=go type=submit value="Evaluate">');
$wgOut->AddHTML('<input name=doShowText type=checkbox'.$htDoEcho.'>Echo input text');
$wgOut->AddHTML('</form>');
if ($inText != ) {
$wgOut->AddWikiText('==Results==');
$objSF = new SpamFerret(); $objSF->OpenDatabase(); $objSF->txtEditRaw = $inText; $arArgs['doAll'] = TRUE; // LATER: allow user to enter title of existing page for generating diff $arArgs['diff'] = '!!NEW: '.$inText; if ($doEcho) { $out = "* checked:"; $out .= "\n** plain: ".htmlspecialchars($inText); $out .= "\n** diff: ".htmlspecialchars($arArgs['diff']); $wgOut->AddWikiText($out,TRUE); } $objSF->CheckFilters($arArgs); $out = "\n* ".$gFilterRows.' filter'.Pluralize($gFilterRows).' defined'. "\n* ".$gFilterCount.' filter'.Pluralize($gFilterCount).' checked'; $wgOut->AddWikiText($out); if (is_array($gFilterMatches)) { $out = "{|\n|-\n! ID || length || filter"; $isOdd = FALSE; foreach ($gFilterMatches as $id=>$text) {
$wtStyle = $isOdd?'background:#ffffff;':'background:#eeeeee;'; $isOdd = !$isOdd;
$objFilt = $objSF->FiltTbl()->GetItem($id);
$isActive = $objFilt->isActive; if (!$isActive) { $wtStyle .= ' color: #888888;'; $wtStyle .= ' text-decoration: line-through;'; }
$out .= "\n|- style=\"$wtStyle\"\n| $id || ".strlen($text)." || {$objFilt->Pattern}"; } $out .= "\n|}"; } else { $out = "* No filter matches"; } $wgOut->AddWikiText($out); //$wgOut->AddWikiText('* DEBUG: '.$debug); }
}
/*
LATER: for debugging why a particular string doesn't seem to be triggering the filter it should trigger public function CheckFiltersLocal($iCheckAll) {
global $gRegexMatches,$gFilterMatches,$gFilterRows,$gFilterCount; global $debug;
$this->PatternTbl = new clsTable($this->dbSpam); $this->PatternTbl->Name('patterns'); $this->PatternTbl->KeyName('ID');
$this->PatternRows = $this->PatternTbl->GetData(); $objRow = $this->PatternRows;
$strTextEdit = strtolower($this->txtEditRaw); $this->txtEditChk = $strTextEdit; // text after being massaged for checking $this->isMatch = FALSE; $gFilterCount = 0; $gFilterRows = $this->PatternRows->RowCount(); //$objDataPatterns->StartRows(); while($objRow->NextRow() && (!$this->isMatch || $iCheckAll)) { $isMatch = FALSE; if ($objRow->isDiff) { if (isset($this->txtDiff)) { $strTextCk = $this->txtDiff; } else { $strTextCk = NULL; } } else { $strTextCk = $strTextEdit; } if (!is_null($strTextCk)) { $gFilterCount++; $strPattern = $objRow->Pattern; $isRegex = $objRow->isRegex; $this->idPattern = $objRow->ID; if ($isRegex) { $isMatch = $this->CheckRegex($strPattern,$strTextCk);
if (isset($php_errormsg)) { $this->AddErrorLine('Filter #'.$this->idPattern.' generated error "'.$php_errormsg); }
if ($isMatch) { $this->strMatch = $gRegexMatches[0]; } } else { if (empty($strPattern)) { $isMatch = FALSE; } else { $this->strMatch = stristr($strTextCk,$strPattern); $isMatch = ($this->strMatch != ); } } if ($isMatch) { $this->isMatch = TRUE; if ($iCheckAll) { $gFilterMatches[$this->idPattern] = $this->strMatch; } } } }
}
- /
} class clsAttempts extends clsTable {
public function __construct($iDB) {
parent::__construct($iDB); $this->Name('attempt'); $this->KeyName('ID'); $this->ClassSng('clsAttempt');
} public function GetRecent(array $iarOpts) {
if (empty($iarOpts['filt'])) { $sqlFilt = ; } else { $sqlFilt = ' WHERE '.$iarOpts['filt']; }
if (empty($iarOpts['sort'])) { $sqlSort = ; } else { $sqlSort = ' ORDER BY '.$iarOpts['sort']; }
if (empty($iarOpts['rows'])) { $sqlRows = ; } else { $sqlRows = ' LIMIT '.$iarOpts['rows']; } $sql = 'SELECT * FROM attempts'.$sqlFilt.$sqlSort.$sqlRows; $objRows = $this->DataSet($sql); return $objRows;
}
} class clsAttempt extends clsDataSet { }
// UTILITY FUNCTIONS // function SpIDSelfLink($iDo,$iKey,$iVal,$iText) { // return ''.$iText.'';
return ''.$iText.'';
} /* function SelfLink($iPage,$iKey,$iVal,$iText) {
return ''.$iText.'';
}
- /
function ShowFlag($iName,$iVal,$iText) {
$out = '<input type=checkbox name="'.$iName.'" value='.$iVal.'>'.$iText; return $out;
}
if (!function_exists('TimeStamp_HideTime')) { //-- function TimeStamp_HideTime($iStamp) {
if (is_string($iStamp)) {
$intStamp = strtotime($iStamp);
} else if (is_int($iStamp)) {
$intStamp = $iStamp;
} else {
$intStamp = NULL;
} if (!is_null($intStamp)) {
return date('Y-m-d',$intStamp);
} else {
return NULL;
}
} //-- }</php>