2021-01-03 21:41:15 +00:00
|
|
|
<?php
|
|
|
|
/** @license MIT
|
|
|
|
* Copyright 2017 J. King, Dustin Wilson et al.
|
|
|
|
* See LICENSE and AUTHORS files for details */
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace JKingWeb\Arsse\Rule;
|
|
|
|
|
|
|
|
abstract class Rule {
|
|
|
|
public static function prep(string $pattern): string {
|
2021-01-08 19:17:46 +00:00
|
|
|
if (!strlen($pattern)) {
|
|
|
|
return "";
|
|
|
|
}
|
2021-01-03 21:41:15 +00:00
|
|
|
if (preg_match_all("<`>", $pattern, $m, \PREG_OFFSET_CAPTURE)) {
|
|
|
|
// where necessary escape our chosen delimiter (backtick) in reverse order
|
|
|
|
foreach (array_reverse($m[0]) as [,$pos]) {
|
|
|
|
// count the number of backslashes preceding the delimiter character
|
|
|
|
$count = 0;
|
|
|
|
$p = $pos;
|
|
|
|
while ($p-- && $pattern[$p] === "\\" && ++$count);
|
|
|
|
// if the number is even (including zero), add a backslash
|
|
|
|
if ($count % 2 === 0) {
|
|
|
|
$pattern = substr($pattern, 0, $pos)."\\".substr($pattern, $pos);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// add the delimiters and test the pattern
|
|
|
|
$pattern = "`$pattern`u";
|
|
|
|
if (@preg_match($pattern, "") === false) {
|
|
|
|
throw new Exception("invalidPattern");
|
|
|
|
}
|
|
|
|
return $pattern;
|
|
|
|
}
|
2021-01-04 03:15:39 +00:00
|
|
|
|
|
|
|
public static function validate(string $pattern): bool {
|
|
|
|
try {
|
|
|
|
static::prep($pattern);
|
|
|
|
} catch (Exception $e) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** applies keep and block rules against the title and categories of an article
|
2021-01-08 20:47:19 +00:00
|
|
|
*
|
2021-01-04 03:15:39 +00:00
|
|
|
* Returns true if the article is to be kept, and false if it is to be suppressed
|
|
|
|
*/
|
2021-01-08 19:17:46 +00:00
|
|
|
public static function apply(string $keepPattern, string $blockPattern, string $title, array $categories = []): bool {
|
|
|
|
// ensure input is valid
|
|
|
|
assert(!strlen($keepPattern) || @preg_match($keepPattern, "") !== false, new \Exception("Keep pattern is invalid"));
|
|
|
|
assert(!strlen($blockPattern) || @preg_match($blockPattern, "") !== false, new \Exception("Block pattern is invalid"));
|
|
|
|
assert(sizeof(array_filter($categories, function($v) {
|
|
|
|
return !is_string($v);
|
|
|
|
})) === 0, new \Exception("All categories must be strings"));
|
2021-01-04 03:15:39 +00:00
|
|
|
// if neither rule is processed we should keep
|
|
|
|
$keep = true;
|
2021-01-07 20:08:50 +00:00
|
|
|
// merge and clean the data to match
|
|
|
|
$data = array_map(function($str) {
|
|
|
|
return preg_replace('/\s+/', " ", $str);
|
|
|
|
}, array_merge([$title], $categories));
|
2021-01-04 03:15:39 +00:00
|
|
|
// process the keep rule if it exists
|
2021-01-08 19:17:46 +00:00
|
|
|
if (strlen($keepPattern)) {
|
2021-01-04 03:15:39 +00:00
|
|
|
// if a keep rule is specified the default state is now not to keep
|
|
|
|
$keep = false;
|
2021-01-07 20:08:50 +00:00
|
|
|
foreach ($data as $str) {
|
2021-01-08 19:17:46 +00:00
|
|
|
if (preg_match($keepPattern, $str)) {
|
|
|
|
// keep if the keep-rule matches one of the strings
|
|
|
|
$keep = true;
|
|
|
|
break;
|
2021-01-04 03:15:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// process the block rule if the keep rule was matched
|
2021-01-08 19:17:46 +00:00
|
|
|
if ($keep && strlen($blockPattern)) {
|
2021-01-07 20:08:50 +00:00
|
|
|
foreach ($data as $str) {
|
2021-01-08 19:17:46 +00:00
|
|
|
if (preg_match($blockPattern, $str)) {
|
|
|
|
// do not keep if the block-rule matches one of the strings
|
|
|
|
$keep = false;
|
|
|
|
break;
|
2021-01-04 03:15:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $keep;
|
|
|
|
}
|
|
|
|
}
|