diff --git a/CHANGELOG-0.x.md b/CHANGELOG-0.x.md index 54c270d..29d8405 100644 --- a/CHANGELOG-0.x.md +++ b/CHANGELOG-0.x.md @@ -2,6 +2,10 @@ This changelog references the relevant changes done in 0.x versions. +## v0.2.1 +* pull #9: Respect boolean operator preceding subquery. + + ## v0.2.0 __BREAKING CHANGES__ diff --git a/src/Node/Subquery.php b/src/Node/Subquery.php index 99552f5..c73012e 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 { @@ -16,14 +17,19 @@ final class Subquery extends Node * Subquery constructor. * * @param Node[] $nodes + * @param BoolOperator $boolOperator * @param bool $useBoost * @param float|mixed $boost * * @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) { @@ -49,7 +55,13 @@ public static function fromArray(array $data = []) } } - return new self($nodes, $useBoost, $boost); + try { + $boolOperator = isset($data['bool_operator']) ? BoolOperator::create($data['bool_operator']) : null; + } catch (\Exception $e) { + $boolOperator = null; + } + + return new self($nodes, $boolOperator, $useBoost, $boost); } /** 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), ] ],