mirror of
https://framagit.org/hubzilla/core.git
synced 2026-06-21 00:52:33 -04:00
extend MessageFilter::test_condition() to deal with && and || conditions and add tests
This commit is contained in:
@@ -124,9 +124,7 @@ class MessageFilter {
|
||||
|
||||
|
||||
/**
|
||||
* @brief Test for Conditional Execution conditions. Shamelessly ripped off from Code/Render/Comanche
|
||||
*
|
||||
* This is extensible. The first version of variable testing supports tests of the forms:
|
||||
* Evaluate a conditional expression with support for AND (&&) and OR (||) operators.
|
||||
*
|
||||
* - ?foo ~= baz which will check if item.foo contains the string 'baz';
|
||||
* - ?foo == baz which will check if item.foo is the string 'baz';
|
||||
@@ -143,103 +141,109 @@ class MessageFilter {
|
||||
*
|
||||
* The values 0, '', an empty array, and an unset value will all evaluate to false.
|
||||
*
|
||||
* @param string $s
|
||||
* @param array $item
|
||||
* @return bool
|
||||
* @param string $s The condition string to evaluate.
|
||||
* @param array $item The associative array providing variable values.
|
||||
* @return bool True if the condition is met, false otherwise.
|
||||
*/
|
||||
|
||||
public static function test_condition($s,$item) {
|
||||
public static function test_condition($s, $item) {
|
||||
$s = trim($s);
|
||||
|
||||
// Handle OR (||)
|
||||
// Split on '||' not inside quotes
|
||||
$or_parts = preg_split('/\s*\|\|\s*/', $s);
|
||||
if (count($or_parts) > 1) {
|
||||
foreach ($or_parts as $part) {
|
||||
if (self::test_condition($part, $item)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Handle AND (&&)
|
||||
// Split on '&&' not inside quotes
|
||||
$and_parts = preg_split('/\s*\&\&\s*/', $s);
|
||||
if (count($and_parts) > 1) {
|
||||
foreach ($and_parts as $part) {
|
||||
if (!self::test_condition($part, $item)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Basic checks
|
||||
|
||||
// Contains substring (case-insensitive)
|
||||
if (preg_match('/(.*?)\s\~\=\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if (stripos($x, trim($matches[2])) !== false) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
$x = ((array_key_exists(trim($matches[1]), $item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
return (stripos($x, trim($matches[2])) !== false);
|
||||
}
|
||||
|
||||
// Equality
|
||||
if (preg_match('/(.*?)\s\=\=\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if ($x == trim($matches[2])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
$x = ((array_key_exists(trim($matches[1]), $item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
return ($x == trim($matches[2]));
|
||||
}
|
||||
|
||||
// Inequality
|
||||
if (preg_match('/(.*?)\s\!\=\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if ($x != trim($matches[2])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
$x = ((array_key_exists(trim($matches[1]), $item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
return ($x != trim($matches[2]));
|
||||
}
|
||||
|
||||
// Greater than or equal
|
||||
if (preg_match('/(.*?)\s\>\=\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if ($x >= trim($matches[2])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
$x = ((array_key_exists(trim($matches[1]), $item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
return ($x >= trim($matches[2]));
|
||||
}
|
||||
|
||||
// Less than or equal
|
||||
if (preg_match('/(.*?)\s\<\=\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if ($x <= trim($matches[2])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
$x = ((array_key_exists(trim($matches[1]), $item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
return ($x <= trim($matches[2]));
|
||||
}
|
||||
|
||||
// Greater than
|
||||
if (preg_match('/(.*?)\s\>\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if ($x > trim($matches[2])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
$x = ((array_key_exists(trim($matches[1]), $item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
return ($x > trim($matches[2]));
|
||||
}
|
||||
|
||||
if (preg_match('/(.*?)\s\>\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if ($x < trim($matches[2])) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
// Less than
|
||||
if (preg_match('/(.*?)\s\<\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]), $item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
return ($x < trim($matches[2]));
|
||||
}
|
||||
|
||||
if (preg_match('/[\$](.*?)\s\{\}\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if (is_array($x) && in_array(trim($matches[2]), $x)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
// Array contains value
|
||||
if (preg_match('/(.*?)\s\{\}\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]), $item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
return (is_array($x) && in_array(trim($matches[2]), $x));
|
||||
}
|
||||
|
||||
// Array contains key
|
||||
if (preg_match('/(.*?)\s\{\*\}\s(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if (is_array($x) && array_key_exists(trim($matches[2]), $x)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
$x = ((array_key_exists(trim($matches[1]), $item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
return (is_array($x) && array_key_exists(trim($matches[2]), $x));
|
||||
}
|
||||
|
||||
// Ordering of this check (for falsiness) with relation to the following one (check for truthiness) is important.
|
||||
// Falsy check
|
||||
if (preg_match('/\!(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if (!$x) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
$x = ((array_key_exists(trim($matches[1]), $item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
return !$x;
|
||||
}
|
||||
|
||||
// Truthy check (default)
|
||||
if (preg_match('/(.*?)$/', $s, $matches)) {
|
||||
$x = ((array_key_exists(trim($matches[1]),$item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
if ($x) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
$x = ((array_key_exists(trim($matches[1]), $item)) ? $item[trim($matches[1])] : EMPTY_STR);
|
||||
return (bool)$x;
|
||||
}
|
||||
|
||||
// If no conditions matched, return false
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ class ActivityTest extends UnitTestCase {
|
||||
*
|
||||
* @dataProvider get_mid_and_uuid_provider
|
||||
*/
|
||||
public function test_get_mid_and_uuid(string $payload, $mid, $uuid): void {
|
||||
public function test_get_mid_and_uuid(string $payload, string $mid, string $uuid): void {
|
||||
|
||||
|
||||
//
|
||||
|
||||
129
tests/unit/Lib/MessageFilterTest.php
Normal file
129
tests/unit/Lib/MessageFilterTest.php
Normal file
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
namespace Zotlabs\Tests\Unit\Lib;
|
||||
|
||||
use Zotlabs\Tests\Unit\UnitTestCase;
|
||||
use Zotlabs\Lib\MessageFilter;
|
||||
|
||||
class MessageFilterTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* Test the `evaluate` function.
|
||||
*
|
||||
* @dataProvider evaluate_provider
|
||||
*/
|
||||
public function test_evaluate(string $incl, string $excl, bool $result) : void {
|
||||
$item = [
|
||||
'title' => '',
|
||||
'body' => "A grasshopper spent the summer hopping about in the sun and singing to his heart's content. One day, an ant went hurrying by, looking very hot and weary.\r\n#story #grasshopper #ant",
|
||||
'term' => [
|
||||
['ttype' => TERM_HASHTAG, 'term' => 'story'],
|
||||
['ttype' => TERM_HASHTAG, 'term' => 'grasshopper'],
|
||||
['ttype' => TERM_HASHTAG, 'term' => 'ant']
|
||||
],
|
||||
'verb' => 'Create',
|
||||
'obj_type' => 'Note',
|
||||
'obj' => [
|
||||
|
||||
],
|
||||
'item_private' => 1,
|
||||
'item_thread_top' => 1
|
||||
];
|
||||
|
||||
$this->assertEquals($result, MessageFilter::evaluate($item, $incl, $excl));
|
||||
}
|
||||
|
||||
public static function evaluate_provider() : array {
|
||||
return [
|
||||
'body contains incl' => [
|
||||
'summer',
|
||||
'',
|
||||
true
|
||||
],
|
||||
'body contains excl' => [
|
||||
'',
|
||||
'summer',
|
||||
false
|
||||
],
|
||||
'lang=en in incl' => [
|
||||
'lang=en',
|
||||
'',
|
||||
true
|
||||
],
|
||||
'lang=en in excl' => [
|
||||
'',
|
||||
'lang=en',
|
||||
false
|
||||
],
|
||||
'lang=de in incl' => [
|
||||
'lang=de',
|
||||
'',
|
||||
false
|
||||
],
|
||||
'lang=de in excl' => [
|
||||
'',
|
||||
'lang=de',
|
||||
true
|
||||
],
|
||||
'hashtag in incl' => [
|
||||
'#grasshopper',
|
||||
'',
|
||||
true
|
||||
],
|
||||
'hashtag in excl' => [
|
||||
'',
|
||||
'#grasshopper',
|
||||
false
|
||||
],
|
||||
'any hashtag in excl' => [
|
||||
'',
|
||||
'#*',
|
||||
false
|
||||
],
|
||||
'item.verb == Announce in excl' => [
|
||||
'',
|
||||
'?verb == Announce',
|
||||
true
|
||||
],
|
||||
'item.verb != Announce in incl' => [
|
||||
'?verb != Announce',
|
||||
'',
|
||||
true
|
||||
],
|
||||
'combined body contains word and item.verb == Announce in excl' => [
|
||||
'',
|
||||
"summer\r\n?verb == Announce",
|
||||
false
|
||||
],
|
||||
'item.item_thread_top == 1 in excl' => [
|
||||
'',
|
||||
"?item_thread_top == 1",
|
||||
false
|
||||
],
|
||||
'combined item_private == 0 and item.item_thread_top == 1 in excl' => [
|
||||
'',
|
||||
"?item_private == 0\r\n?item_thread_top == 1",
|
||||
false
|
||||
],
|
||||
'item.item_private < 1 in excl' => [
|
||||
'',
|
||||
"?item_private < 1",
|
||||
true
|
||||
],
|
||||
'item.item_thread_top == 1 and item.item_private < 1 in excl' => [
|
||||
'',
|
||||
"?item_thread_top == 1 && ?item_private > 0 ",
|
||||
true
|
||||
],
|
||||
'item.item_thread_top == 1 and item.item_private < 1 in excl' => [
|
||||
'',
|
||||
"?item_thread_top == 1 && ?item_private < 1 ",
|
||||
false
|
||||
],
|
||||
'item.item_thread_top == 1 or item.item_private < 1 in excl' => [
|
||||
'',
|
||||
"?item_thread_top == 1 || ?item_private = 0",
|
||||
false
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
4
vendor/composer/installed.php
vendored
4
vendor/composer/installed.php
vendored
@@ -3,7 +3,7 @@
|
||||
'name' => 'zotlabs/hubzilla',
|
||||
'pretty_version' => 'dev-10.2RC',
|
||||
'version' => 'dev-10.2RC',
|
||||
'reference' => '0d51ff1906df6e02f2aa028b753f25ae988d5d64',
|
||||
'reference' => '17777981ac07c39fcef35e34a53e9160a213c1a4',
|
||||
'type' => 'application',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@@ -430,7 +430,7 @@
|
||||
'zotlabs/hubzilla' => array(
|
||||
'pretty_version' => 'dev-10.2RC',
|
||||
'version' => 'dev-10.2RC',
|
||||
'reference' => '0d51ff1906df6e02f2aa028b753f25ae988d5d64',
|
||||
'reference' => '17777981ac07c39fcef35e34a53e9160a213c1a4',
|
||||
'type' => 'application',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
|
||||
Reference in New Issue
Block a user