diff --git a/src/Node/Subquery.php b/src/Node/Subquery.php index 99552f5..b1585a4 100755 --- a/src/Node/Subquery.php +++ b/src/Node/Subquery.php @@ -3,6 +3,7 @@ namespace Gdbots\QueryParser\Node; use Gdbots\QueryParser\Builder\QueryBuilder; +use Gdbots\QueryParser\Enum\BoolOperator; final class Subquery extends Node { @@ -21,9 +22,13 @@ final class Subquery extends Node * * @throws \LogicException */ - public function __construct(array $nodes, $useBoost = false, $boost = self::DEFAULT_BOOST) - { - parent::__construct(null, null, $useBoost, $boost); + public function __construct( + array $nodes, + BoolOperator $boolOperator = null, + $useBoost = false, + $boost = self::DEFAULT_BOOST + ) { + parent::__construct(null, $boolOperator, $useBoost, $boost); $this->nodes = $nodes; foreach ($this->nodes as $node) { diff --git a/src/QueryParser.php b/src/QueryParser.php index e685a4c..a261a86 100755 --- a/src/QueryParser.php +++ b/src/QueryParser.php @@ -264,7 +264,7 @@ protected function handleFieldWithRange($fieldName, BoolOperator $boolOperator) return new Field($fieldName, $nodes[0], $boolOperator, $m['use_boost'], $m['boost']); } - $subquery = new Subquery($nodes, $m['use_boost'], $m['boost']); + $subquery = new Subquery($nodes, null, $m['use_boost'], $m['boost']); return new Field($fieldName, $subquery, $boolOperator, $m['use_boost'], $m['boost']); } @@ -374,7 +374,7 @@ protected function handleSubquery(BoolOperator $queryBoolOperator) return $nodes[0]::fromArray($data); } - return new Subquery($nodes, $m['use_boost'], $m['boost']); + return new Subquery($nodes, $queryBoolOperator, $m['use_boost'], $m['boost']); } /** diff --git a/tests/Fixtures/test-queries.php b/tests/Fixtures/test-queries.php index f49de13..59bc975 100644 --- a/tests/Fixtures/test-queries.php +++ b/tests/Fixtures/test-queries.php @@ -1426,6 +1426,42 @@ new Subquery([new Word('word:a'), new Word('hashtag:b')]), ] ], + + [ + 'name' => 'booleans before and in subqueries', + 'input' => '"ipad pro" AND (gold OR silver)', + 'expected_tokens' => [ + [T::T_PHRASE, 'ipad pro'], + T::T_AND, + T::T_SUBQUERY_START, + [T::T_WORD, 'gold'], + T::T_OR, + [T::T_WORD, 'silver'], + T::T_SUBQUERY_END, + ], + 'expected_nodes' => [ + new Phrase('ipad pro', BoolOperator::REQUIRED()), + new Subquery([new Word('gold'), new Word('silver')], BoolOperator::REQUIRED()), + ] + ], + + [ + 'name' => 'booleans before and in subqueries 2', + 'input' => '"iphone 7" -(16gb OR 32gb)', + 'expected_tokens' => [ + [T::T_PHRASE, 'iphone 7'], + T::T_PROHIBITED, + T::T_SUBQUERY_START, + [T::T_WORD, '16gb'], + T::T_OR, + [T::T_WORD, '32gb'], + T::T_SUBQUERY_END, + ], + 'expected_nodes' => [ + new Phrase('iphone 7'), + new Subquery([new Word('16gb'), new Word('32gb')], BoolOperator::PROHIBITED()), + ] + ], /* * END: SUBQUERIES */ @@ -1569,7 +1605,7 @@ ], 'expected_nodes' => [ new Phrase('john smith', null, true, 2.0), - new Subquery([new Word('foo'), new Word('bar')], true, 4.0), + new Subquery([new Word('foo'), new Word('bar')], null, true, 4.0), ] ],