Allow flipping of subqueries

This commit is contained in:
Sobuno
2025-01-03 00:07:57 +01:00
parent a62916a63d
commit 0c955efa8b
3 changed files with 34 additions and 17 deletions

View File

@@ -23,10 +23,10 @@ declare(strict_types=1);
namespace FireflyIII\Providers;
use FireflyIII\Support\Search\GdbotsQueryParser;
use FireflyIII\Support\Search\QueryParser\GdbotsQueryParser;
use FireflyIII\Support\Search\OperatorQuerySearch;
use FireflyIII\Support\Search\QueryParser;
use FireflyIII\Support\Search\QueryParserInterface;
use FireflyIII\Support\Search\QueryParser\QueryParser;
use FireflyIII\Support\Search\QueryParser\QueryParserInterface;
use FireflyIII\Support\Search\SearchInterface;
use Illuminate\Foundation\Application;
use Illuminate\Support\ServiceProvider;

View File

@@ -150,7 +150,7 @@ class OperatorQuerySearch implements SearchInterface
}
app('log')->debug(sprintf('Found %d node(s) at top-level', count($parsedQuery->getNodes())));
$this->handleSearchNode($parsedQuery);
$this->handleSearchNode($parsedQuery, $parsedQuery->isProhibited(false));
// add missing information
$this->collector->withBillInformation();
@@ -164,21 +164,21 @@ class OperatorQuerySearch implements SearchInterface
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
private function handleSearchNode(Node $node): void
private function handleSearchNode(Node $node, $flipProhibitedFlag): void
{
app('log')->debug(sprintf('Now in handleSearchNode(%s)', get_class($node)));
switch (true) {
case $node instanceof StringNode:
$this->handleStringNode($node);
$this->handleStringNode($node, $flipProhibitedFlag);
break;
case $node instanceof FieldNode:
$this->handleFieldNode($node);
$this->handleFieldNode($node, $flipProhibitedFlag);
break;
case $node instanceof NodeGroup:
$this->handleNodeGroup($node);
$this->handleNodeGroup($node, $flipProhibitedFlag);
break;
default:
@@ -187,20 +187,24 @@ class OperatorQuerySearch implements SearchInterface
}
}
private function handleNodeGroup(NodeGroup $node): void
private function handleNodeGroup(NodeGroup $node, $flipProhibitedFlag): void
{
//TODO: Handle Subquery prohibition, i.e. flip all prohibition flags inside the subquery
$prohibited = $node->isProhibited($flipProhibitedFlag);
foreach ($node->getNodes() as $subNode) {
$this->handleSearchNode($subNode);
$this->handleSearchNode($subNode, $prohibited);
}
}
private function handleStringNode(StringNode $node): void
private function handleStringNode(StringNode $node, $flipProhibitedFlag): void
{
$string = (string) $node->getValue();
if($node->isProhibited()) {
$prohibited = $node->isProhibited($flipProhibitedFlag);
if($prohibited) {
app('log')->debug(sprintf('Exclude string "%s" from search string', $string));
$this->prohibitedWords[] = $string;
} else {
@@ -212,11 +216,11 @@ class OperatorQuerySearch implements SearchInterface
/**
* @throws FireflyException
*/
private function handleFieldNode(FieldNode $node): void
private function handleFieldNode(FieldNode $node, $flipProhibitedFlag): void
{
$operator = strtolower($node->getOperator());
$value = $node->getValue();
$prohibited = $node->isProhibited();
$prohibited = $node->isProhibited($flipProhibitedFlag);
$context = config(sprintf('search.operators.%s.needs_context', $operator));

View File

@@ -11,8 +11,21 @@ abstract class Node
{
protected bool $prohibited;
public function isProhibited(): bool
/**
* Returns the prohibited status of the node, optionally inverted based on flipFlag
*
* Flipping is used when a node is inside a NodeGroup that has a prohibited status itself, causing inversion of the query parts inside
*
* @param bool $flipFlag When true, inverts the prohibited status
* @return bool The (potentially inverted) prohibited status
*/
public function isProhibited(bool $flipFlag): bool
{
if ($flipFlag === true) {
return !$this->prohibited;
} else {
return $this->prohibited;
}
}
}