diff --git a/.travis.yml b/.travis.yml index d2d90a5..b9b08fb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,8 @@ language: php php: - - 5.4 - - 5.5 - - 5.6 -# - hhvm # currently failing with: Message was: "DateTimeZone::__construct(): Unknown or bad timezone (+00:00)" + - 7.1 + - 7.2 before_script: - composer self-update diff --git a/CHANGELOG-0.x.md b/CHANGELOG-0.x.md index 29d8405..ca7a976 100644 --- a/CHANGELOG-0.x.md +++ b/CHANGELOG-0.x.md @@ -2,6 +2,14 @@ This changelog references the relevant changes done in 0.x versions. +## v0.3.0 +__BREAKING CHANGES__ + +* Update `ElasticaQueryBuilder` to use `"ruflin/elastica": "~5.3"`. +* Require php `>=7.1` in `composer.json`. +* Add php7 type hinting and use `declare(strict_types=1);`. + + ## v0.2.1 * pull #9: Respect boolean operator preceding subquery. @@ -9,7 +17,7 @@ This changelog references the relevant changes done in 0.x versions. ## v0.2.0 __BREAKING CHANGES__ -* issue #7: Update ElasticaQueryBuilder to use 2.x queries/filters. Requires `"ruflin/elastica": "~3.2"`. +* issue #7: Update `ElasticaQueryBuilder` to use 2.x queries/filters. Requires `"ruflin/elastica": "~3.2"`. * issue #6: Make TimeZone configurable on any builders that use date nodes. * The `Number` class was renamed to `Numbr` to prevent issue with scalar type hints in php7. diff --git a/composer.json b/composer.json index 383794e..8e9edc9 100755 --- a/composer.json +++ b/composer.json @@ -5,12 +5,12 @@ "type": "library", "license": "Apache-2.0", "require": { - "php": ">=5.4", + "php": ">=7.1", "gdbots/common": "~0.1|~1.0" }, "require-dev": { - "phpunit/phpunit": "~4.3", - "ruflin/elastica": "~3.2" + "phpunit/phpunit": "~6.4", + "ruflin/elastica": "~5.3" }, "autoload": { "psr-4": { @@ -22,9 +22,12 @@ "Gdbots\\Tests\\QueryParser\\": "tests" } }, + "scripts": { + "test": "vendor/bin/phpunit" + }, "extra": { "branch-alias": { - "dev-master": "0.2.x-dev" + "dev-master": "0.3.x-dev" } } } diff --git a/examples/elastica.php b/examples/elastica.php index dfc9511..0c94283 100644 --- a/examples/elastica.php +++ b/examples/elastica.php @@ -16,12 +16,17 @@ class EchoLogger implements \Psr\Log\LoggerInterface * @param mixed $level * @param string $message * @param array $context - * - * @return null */ public function log($level, $message, array $context = array()) { echo $message.PHP_EOL; + + // nuke hits from context since we print those + // after response data anyways + if (isset($context['response']) && isset($context['response']['hits']) && isset($context['response']['hits']['hits'])) { + unset($context['response']['hits']['hits']); + } + echo json_encode($context, JSON_PRETTY_PRINT).PHP_EOL.PHP_EOL; echo str_repeat(PHP_EOL, 2).str_repeat('*', 70).str_repeat(PHP_EOL, 2); } @@ -34,11 +39,16 @@ public function log($level, $message, array $context = array()) $client->setLogger(new EchoLogger()); $parser = new QueryParser(); +/** @var ElasticaQueryBuilder $builder */ $builder = (new ElasticaQueryBuilder()) + ->addNestedField('dynamic_fields') ->setDefaultFieldName('_all') ->setEmoticonFieldName('emoticons') ->setHashtagFieldName('hashtags') ->setMentionFieldName('mentions') + ->addFullTextSearchField('subject') + ->addFullTextSearchField('dynamic_fields.string_val') + ->addFullTextSearchField('dynamic_fields.text_val') ->setLocalTimeZone(new DateTimeZone('America/Los_Angeles')) ; @@ -58,13 +68,13 @@ public function log($level, $message, array $context = array()) ->setQuery($query) ->setBoostMode(FunctionScore::BOOST_MODE_SUM) ->addFunction('field_value_factor', [ - 'field' => '__popularity', + 'field' => 'priority', 'modifier' => 'none', ], null, 0.4); */ $query = \Elastica\Query::create($query); //$query->setExplain(true); -//$query->setSort(['published_at' => 'desc']); +$query->setSort(['date_sent' => 'desc']); $results = $client->getIndex($index)->search($query, $options); echo 'Total Time (ms) / Records Found:' . PHP_EOL; diff --git a/src/Builder/AbstractQueryBuilder.php b/src/Builder/AbstractQueryBuilder.php index bc3889b..6767f3e 100755 --- a/src/Builder/AbstractQueryBuilder.php +++ b/src/Builder/AbstractQueryBuilder.php @@ -1,4 +1,5 @@ true, - 'title' => true, - 'tiny_title' => true, - 'short_title' => true, - 'excerpt' => true, - 'description' => true, - 'overview' => true, - 'summary' => true, - 'story' => true, - 'html' => true, - 'text' => true, - 'markdown' => true, - 'content' => true, - 'contents' => true, + '_all' => true, + 'title' => true, + 'tiny_title' => true, + 'short_title' => true, + 'excerpt' => true, + 'description' => true, + 'overview' => true, + 'summary' => true, + 'story' => true, + 'html' => true, + 'text' => true, + 'markdown' => true, + 'content' => true, + 'contents' => true, 'contents-continued' => true, - 'contents-md' => true, - 'contents-mobile' => true, - 'mobile-contents' => true, - 'txt-contents' => true, - 'text-contents' => true, - 'abstract' => true, - 'search_text' => true, - 'cover' => true, - 'bio' => true, - 'mini_bio' => true, - 'meta_title' => true, - 'meta_description' => true, - 'meta_keywords' => true, - 'og_title' => true, - 'og_description' => true, - 'og_keywords' => true, - 'seo_title' => true, - 'seo_description' => true, - 'seo_keywords' => true, - 'img_credit' => true, - 'img_caption' => true, - 'credit' => true, - 'caption' => true, - 'img_credits' => true, - 'img_captions' => true, - 'image_credits' => true, - 'image_captions' => true, - 'credits' => true, - 'captions' => true, - 'full_name' => true, - 'first_name' => true, - 'last_name' => true, - 'street1' => true, - 'street2' => true, - 'city' => true, - 'address.street1' => true, - 'address.street2' => true, - 'address.city' => true, + 'contents-md' => true, + 'contents-mobile' => true, + 'mobile-contents' => true, + 'txt-contents' => true, + 'text-contents' => true, + 'abstract' => true, + 'search_text' => true, + 'cover' => true, + 'bio' => true, + 'mini_bio' => true, + 'meta_title' => true, + 'meta_description' => true, + 'meta_keywords' => true, + 'og_title' => true, + 'og_description' => true, + 'og_keywords' => true, + 'seo_title' => true, + 'seo_description' => true, + 'seo_keywords' => true, + 'img_credit' => true, + 'img_caption' => true, + 'credit' => true, + 'caption' => true, + 'img_credits' => true, + 'img_captions' => true, + 'image_credits' => true, + 'image_captions' => true, + 'credits' => true, + 'captions' => true, + 'full_name' => true, + 'first_name' => true, + 'last_name' => true, + 'street1' => true, + 'street2' => true, + 'city' => true, + 'address.street1' => true, + 'address.street2' => true, + 'address.city' => true, 'ctx_ip_geo.street1' => true, 'ctx_ip_geo.street2' => true, - 'ctx_ip_geo.city' => true, + 'ctx_ip_geo.city' => true, ]; /** @var string */ @@ -119,125 +120,114 @@ abstract class AbstractQueryBuilder implements QueryBuilder protected $localTimeZone; /** - * @return static + * {@inheritdoc} */ - public function clear() + public function clear(): QueryBuilder { return $this; } /** - * @param array $fields - * @return static + * {@inheritdoc} */ - final public function setFullTextSearchFields(array $fields) + final public function setFullTextSearchFields(array $fields): QueryBuilder { $this->fullTextSearchFields = array_flip($fields); return $this; } /** - * @param string $fieldName - * @return static + * {@inheritdoc} */ - final public function addFullTextSearchField($fieldName) + final public function addFullTextSearchField(string $fieldName): QueryBuilder { $this->fullTextSearchFields[$fieldName] = true; return $this; } /** - * @param string $fieldName - * @return static + * {@inheritdoc} */ - final public function removeFullTextSearchField($fieldName) + final public function removeFullTextSearchField(string $fieldName): QueryBuilder { unset($this->fullTextSearchFields[$fieldName]); return $this; } /** - * @return array + * {@inheritdoc} */ - final public function getFullTextSearchFields() + final public function getFullTextSearchFields(): array { return array_keys($this->fullTextSearchFields); } /** - * @param string $fieldName - * @return bool + * {@inheritdoc} */ - final public function supportsFullTextSearch($fieldName) + final public function supportsFullTextSearch(string $fieldName): bool { return isset($this->fullTextSearchFields[trim(strtolower($fieldName))]); } /** - * @param string $fieldName - * @return static + * {@inheritdoc} */ - final public function setDefaultFieldName($fieldName) + final public function setDefaultFieldName(string $fieldName): QueryBuilder { $this->defaultFieldName = $fieldName; return $this; } /** - * @param string $fieldName - * @return static + * {@inheritdoc} */ - final public function setEmojiFieldName($fieldName) + final public function setEmojiFieldName(string $fieldName): QueryBuilder { $this->emojiFieldName = $fieldName; return $this; } /** - * @param string $fieldName - * @return static + * {@inheritdoc} */ - final public function setEmoticonFieldName($fieldName) + final public function setEmoticonFieldName(string $fieldName): QueryBuilder { $this->emoticonFieldName = $fieldName; return $this; } /** - * @param string $fieldName - * @return static + * {@inheritdoc} */ - final public function setHashtagFieldName($fieldName) + final public function setHashtagFieldName(string $fieldName): QueryBuilder { $this->hashtagFieldName = $fieldName; return $this; } /** - * @param string $fieldName - * @return static + * {@inheritdoc} */ - final public function setMentionFieldName($fieldName) + final public function setMentionFieldName(string $fieldName): QueryBuilder { $this->mentionFieldName = $fieldName; return $this; } /** - * @param \DateTimeZone $timeZone - * @return static + * {@inheritdoc} */ - final public function setLocalTimeZone(\DateTimeZone $timeZone) + final public function setLocalTimeZone(\DateTimeZone $timeZone): QueryBuilder { $this->localTimeZone = $timeZone; return $this; } /** - * @param ParsedQuery $parsedQuery - * @return static + * {@inheritdoc} */ - final public function addParsedQuery(ParsedQuery $parsedQuery) + final public function addParsedQuery(ParsedQuery $parsedQuery): QueryBuilder { foreach ($parsedQuery->getNodes() as $node) { $node->acceptBuilder($this); @@ -247,20 +237,18 @@ final public function addParsedQuery(ParsedQuery $parsedQuery) } /** - * @param Date $date - * @return static + * {@inheritdoc} */ - final public function addDate(Date $date) + final public function addDate(Date $date): QueryBuilder { $this->handleTerm($date); return $this; } /** - * @param Emoji $emoji - * @return static + * {@inheritdoc} */ - final public function addEmoji(Emoji $emoji) + final public function addEmoji(Emoji $emoji): QueryBuilder { if ($this->inField || null === $this->emojiFieldName) { $this->handleTerm($emoji); @@ -279,10 +267,9 @@ final public function addEmoji(Emoji $emoji) } /** - * @param Emoticon $emoticon - * @return static + * {@inheritdoc} */ - final public function addEmoticon(Emoticon $emoticon) + final public function addEmoticon(Emoticon $emoticon): QueryBuilder { if ($this->inField || null === $this->emoticonFieldName) { $this->handleTerm($emoticon); @@ -301,12 +288,9 @@ final public function addEmoticon(Emoticon $emoticon) } /** - * @param Field $field - * @return static - * - * @throws \LogicException + * {@inheritdoc} */ - final public function addField(Field $field) + final public function addField(Field $field): QueryBuilder { if ($this->inField || $this->inRange) { throw new \LogicException('A Field cannot be nested in another Field or Range.'); @@ -325,10 +309,9 @@ final public function addField(Field $field) } /** - * @param Hashtag $hashtag - * @return static + * {@inheritdoc} */ - final public function addHashtag(Hashtag $hashtag) + final public function addHashtag(Hashtag $hashtag): QueryBuilder { if ($this->inField || null === $this->hashtagFieldName) { $this->handleTerm($hashtag); @@ -347,10 +330,9 @@ final public function addHashtag(Hashtag $hashtag) } /** - * @param Mention $mention - * @return static + * {@inheritdoc} */ - final public function addMention(Mention $mention) + final public function addMention(Mention $mention): QueryBuilder { if ($this->inField || null === $this->mentionFieldName) { $this->handleTerm($mention); @@ -369,32 +351,27 @@ final public function addMention(Mention $mention) } /** - * @param Numbr $number - * @return static + * {@inheritdoc} */ - final public function addNumber(Numbr $number) + final public function addNumber(Numbr $number): QueryBuilder { $this->handleTerm($number); return $this; } /** - * @param Phrase $phrase - * @return static + * {@inheritdoc} */ - final public function addPhrase(Phrase $phrase) + final public function addPhrase(Phrase $phrase): QueryBuilder { $this->handleText($phrase); return $this; } /** - * @param Range $range - * @return static - * - * @throws \LogicException + * {@inheritdoc} */ - final public function addRange(Range $range) + final public function addRange(Range $range): QueryBuilder { if (!$this->inField || $this->inRange || $this->inSubquery) { throw new \LogicException('A Range can only be used within a field. e.g. rating:[1..5]'); @@ -407,10 +384,9 @@ final public function addRange(Range $range) } /** - * @param Subquery $subquery - * @return static + * {@inheritdoc} */ - final public function addSubquery(Subquery $subquery) + final public function addSubquery(Subquery $subquery): QueryBuilder { if ($this->inRange || $this->inSubquery) { throw new \LogicException('A Subquery cannot be nested or within a Range.'); @@ -430,20 +406,18 @@ final public function addSubquery(Subquery $subquery) } /** - * @param Url $url - * @return static + * {@inheritdoc} */ - final public function addUrl(Url $url) + final public function addUrl(Url $url): QueryBuilder { $this->handleTerm($url); return $this; } /** - * @param Word $word - * @return static + * {@inheritdoc} */ - final public function addWord(Word $word) + final public function addWord(Word $word): QueryBuilder { $this->handleText($word); return $this; @@ -452,7 +426,7 @@ final public function addWord(Word $word) /** * @return bool */ - final protected function inField() + final protected function inField(): bool { return $this->inField; } @@ -460,7 +434,7 @@ final protected function inField() /** * @return bool */ - final protected function inRange() + final protected function inRange(): bool { return $this->inRange; } @@ -468,7 +442,7 @@ final protected function inRange() /** * @return bool */ - final protected function inSubquery() + final protected function inSubquery(): bool { return $this->inSubquery; } @@ -476,20 +450,33 @@ final protected function inSubquery() /** * @param Node $node */ - private function handleText(Node $node) + private function handleText(Node $node): void { if ($this->inField && !$this->supportsFullTextSearch($this->currentField->getName())) { $this->handleTerm($node); return; } + /* + * When in a simple field, the bool operator is based on + * the field, not the node in the field. + * +field:value vs. field:+value + */ + if ($this->inField && !$this->currentField->hasCompoundNode()) { + $isOptional = $this->currentField->isOptional(); + $isRequired = $this->currentField->isRequired(); + } else { + $isOptional = $node->isOptional(); + $isRequired = $node->isRequired(); + } + if ($node instanceof Word && $node->isStopWord()) { $this->shouldMatch($node, $this->currentField); return; - } elseif ($node->isOptional()) { + } elseif ($isOptional) { $this->shouldMatch($node, $this->currentField); return; - } elseif ($node->isRequired()) { + } elseif ($isRequired) { $this->mustMatch($node, $this->currentField); return; } @@ -500,7 +487,7 @@ private function handleText(Node $node) /** * @param Node $node */ - private function handleTerm(Node $node) + private function handleTerm(Node $node): void { /* * When in a simple field, the bool operator is based on @@ -508,22 +495,17 @@ private function handleTerm(Node $node) * +field:value vs. field:+value */ if ($this->inField && !$this->currentField->hasCompoundNode()) { - if ($this->currentField->isOptional()) { - $this->shouldMatchTerm($node, $this->currentField); - return; - } elseif ($this->currentField->isRequired()) { - $this->mustMatchTerm($node, $this->currentField, $this->queryOnFieldIsCacheable); - return; - } - - $this->mustNotMatchTerm($node, $this->currentField, $this->queryOnFieldIsCacheable); - return; + $isOptional = $this->currentField->isOptional(); + $isRequired = $this->currentField->isRequired(); + } else { + $isOptional = $node->isOptional(); + $isRequired = $node->isRequired(); } - if ($node->isOptional()) { + if ($isOptional) { $this->shouldMatchTerm($node, $this->currentField); return; - } elseif ($node->isRequired()) { + } elseif ($isRequired) { $this->mustMatchTerm($node, $this->currentField, $this->queryOnFieldIsCacheable); return; } @@ -543,9 +525,10 @@ private function handleTerm(Node $node) * to even search for cats in a video when status is not active. * * @param Field $field + * * @return bool */ - protected function queryOnFieldIsCacheable(Field $field) + protected function queryOnFieldIsCacheable(Field $field): bool { if ($field->isOptional() || $field->useBoost()) { return false; @@ -567,70 +550,78 @@ protected function queryOnFieldIsCacheable(Field $field) /** * @param Field $field - * @param bool $cacheable + * @param bool $cacheable */ - protected function startField(Field $field, $cacheable = false) {} + protected function startField(Field $field, bool $cacheable = false): void + { + } /** * @param Field $field - * @param bool $cacheable + * @param bool $cacheable */ - protected function endField(Field $field, $cacheable = false) {} + protected function endField(Field $field, bool $cacheable = false): void + { + } /** * @param Subquery $subquery - * @param Field|null $field + * @param Field $field */ - protected function startSubquery(Subquery $subquery, Field $field = null) {} + protected function startSubquery(Subquery $subquery, ?Field $field = null): void + { + } /** * @param Subquery $subquery - * @param Field|null $field + * @param Field $field */ - protected function endSubquery(Subquery $subquery, Field $field = null) {} + protected function endSubquery(Subquery $subquery, ?Field $field = null): void + { + } /** * @param Range $range * @param Field $field - * @param bool $cacheable + * @param bool $cacheable */ - abstract protected function handleRange(Range $range, Field $field, $cacheable = false); + abstract protected function handleRange(Range $range, Field $field, bool $cacheable = false): void; /** - * @param Node $node - * @param Field|null $field + * @param Node $node + * @param Field $field */ - abstract protected function mustMatch(Node $node, Field $field = null); + abstract protected function mustMatch(Node $node, ?Field $field = null): void; /** - * @param Node $node - * @param Field|null $field + * @param Node $node + * @param Field $field */ - abstract protected function shouldMatch(Node $node, Field $field = null); + abstract protected function shouldMatch(Node $node, ?Field $field = null): void; /** - * @param Node $node - * @param Field|null $field + * @param Node $node + * @param Field $field */ - abstract protected function mustNotMatch(Node $node, Field $field = null); + abstract protected function mustNotMatch(Node $node, ?Field $field = null): void; /** - * @param Node $node - * @param Field|null $field - * @param bool $cacheable + * @param Node $node + * @param Field $field + * @param bool $cacheable */ - abstract protected function mustMatchTerm(Node $node, Field $field = null, $cacheable = false); + abstract protected function mustMatchTerm(Node $node, ?Field $field = null, bool $cacheable = false): void; /** - * @param Node $node - * @param Field|null $field + * @param Node $node + * @param Field $field */ - abstract protected function shouldMatchTerm(Node $node, Field $field = null); + abstract protected function shouldMatchTerm(Node $node, ?Field $field = null): void; /** - * @param Node $node - * @param Field|null $field - * @param bool $cacheable + * @param Node $node + * @param Field $field + * @param bool $cacheable */ - abstract protected function mustNotMatchTerm(Node $node, Field $field = null, $cacheable = false); + abstract protected function mustNotMatchTerm(Node $node, ?Field $field = null, bool $cacheable = false): void; } diff --git a/src/Builder/ElasticaQueryBuilder.php b/src/Builder/ElasticaQueryBuilder.php index 91ae0d1..85b2e3c 100755 --- a/src/Builder/ElasticaQueryBuilder.php +++ b/src/Builder/ElasticaQueryBuilder.php @@ -1,10 +1,14 @@ qb = new QueryBuilder(); + $this->qb = new RuflinQueryBuilder(); $this->clear(); } /** - * @return static + * {@inheritdoc} */ - public function clear() + public function clear(): QueryBuilder { $this->boolQuery = $this->qb->query()->bool(); $this->outerBoolQuery = $this->boolQuery; @@ -91,49 +95,54 @@ public function clear() /** * @param bool $ignoreEmojis + * * @return static */ - public function ignoreEmojis($ignoreEmojis = true) + public function ignoreEmojis(bool $ignoreEmojis = true): self { - $this->ignoreEmojis = (bool)$ignoreEmojis; + $this->ignoreEmojis = $ignoreEmojis; return $this; } /** * @param bool $ignoreEmoticons + * * @return static */ - public function ignoreEmoticons($ignoreEmoticons = true) + public function ignoreEmoticons(bool $ignoreEmoticons = true): self { - $this->ignoreEmoticons = (bool)$ignoreEmoticons; + $this->ignoreEmoticons = $ignoreEmoticons; return $this; } /** * @param bool $ignoreStopWords + * * @return static */ - public function ignoreStopWords($ignoreStopWords = true) + public function ignoreStopWords(bool $ignoreStopWords = true): self { - $this->ignoreStopWords = (bool)$ignoreStopWords; + $this->ignoreStopWords = $ignoreStopWords; return $this; } /** * @param bool $lowerCaseTerms + * * @return static */ - public function lowerCaseTerms($lowerCaseTerms = true) + public function lowerCaseTerms(bool $lowerCaseTerms = true): self { - $this->lowerCaseTerms = (bool)$lowerCaseTerms; + $this->lowerCaseTerms = $lowerCaseTerms; return $this; } /** - * @param array $fields + * @param string[] $fields + * * @return static */ - public function setNestedFields(array $fields) + public function setNestedFields(array $fields): self { $this->nestedFields = array_flip($fields); return $this; @@ -141,9 +150,10 @@ public function setNestedFields(array $fields) /** * @param string $fieldName + * * @return static */ - public function addNestedField($fieldName) + public function addNestedField(string $fieldName): self { $this->nestedFields[$fieldName] = true; return $this; @@ -151,9 +161,10 @@ public function addNestedField($fieldName) /** * @param string $fieldName + * * @return static */ - public function removeNestedField($fieldName) + public function removeNestedField(string $fieldName): self { unset($this->nestedFields[$fieldName]); return $this; @@ -162,34 +173,32 @@ public function removeNestedField($fieldName) /** * @return array */ - public function getNestedFields() + public function getNestedFields(): array { return array_keys($this->nestedFields); } /** - * @return Query\Bool + * @return BoolQuery */ - public function getBoolQuery() + public function getBoolQuery(): BoolQuery { if ($this->boolQuery->hasParam('must')) { // if a "must" is used we assume they wanted everything else optional return $this->boolQuery; } - return $this->boolQuery->setMinimumNumberShouldMatch('2<80%'); + return $this->boolQuery->setMinimumShouldMatch('2<80%'); } /** - * @param Range $range - * @param Field $field - * @param bool $cacheable + * {@inheritdoc} */ - protected function handleRange(Range $range, Field $field, $cacheable = false) + protected function handleRange(Range $range, Field $field, bool $cacheable = false): void { $useBoost = $field->useBoost(); - $boost = $field->getBoost(); - $boolOp = $field->getBoolOperator(); + $boost = $field->getBoost(); + $boolOp = $field->getBoolOperator(); if ($boolOp->equals(BoolOperator::REQUIRED())) { $method = 'addMust'; @@ -211,10 +220,15 @@ protected function handleRange(Range $range, Field $field, $cacheable = false) if ($range instanceof DateRange) { if ($range->hasLowerNode()) { - $data[$lowerOperator] = $range->getLowerNode()->toDateTime($this->localTimeZone)->format('U'); + $data[$lowerOperator] = $range->getLowerNode() + ->toDateTime($this->localTimeZone) + ->format('Y-m-d'); } if ($range->hasUpperNode()) { - $data[$upperOperator] = $range->getUpperNode()->toDateTime($this->localTimeZone)->modify('+1 day')->format('U'); + $data[$upperOperator] = $range->getUpperNode() + ->toDateTime($this->localTimeZone) + ->modify('+1 day') + ->format('Y-m-d'); } } else { if ($range->hasLowerNode()) { @@ -243,33 +257,31 @@ protected function handleRange(Range $range, Field $field, $cacheable = false) } /** - * @param Subquery $subquery - * @param Field|null $field + * {@inheritdoc} */ - protected function startSubquery(Subquery $subquery, Field $field = null) + protected function startSubquery(Subquery $subquery, ?Field $field = null): void { $this->outerBoolQuery = $this->boolQuery; $this->boolQuery = $this->qb->query()->bool(); } /** - * @param Subquery $subquery - * @param Field|null $field + * {@inheritdoc} */ - protected function endSubquery(Subquery $subquery, Field $field = null) + protected function endSubquery(Subquery $subquery, ?Field $field = null): void { $params = $this->boolQuery->getParams(); if (!empty($params)) { - $this->boolQuery->setMinimumNumberShouldMatch(1); + $this->boolQuery->setMinimumShouldMatch(1); if ($this->inField()) { $useBoost = $field->useBoost(); - $boost = $field->getBoost(); - $boolOp = $field->getBoolOperator(); + $boost = $field->getBoost(); + $boolOp = $field->getBoolOperator(); } else { $useBoost = $subquery->useBoost(); - $boost = $subquery->getBoost(); - $boolOp = $subquery->getBoolOperator(); + $boost = $subquery->getBoost(); + $boolOp = $subquery->getBoolOperator(); } if ($useBoost) { @@ -289,28 +301,25 @@ protected function endSubquery(Subquery $subquery, Field $field = null) } /** - * @param Node $node - * @param Field|null $field + * {@inheritdoc} */ - protected function mustMatch(Node $node, Field $field = null) + protected function mustMatch(Node $node, ?Field $field = null): void { $this->addTextToQuery('addMust', $node, $field); } /** - * @param Node $node - * @param Field|null $field + * {@inheritdoc} */ - protected function shouldMatch(Node $node, Field $field = null) + protected function shouldMatch(Node $node, ?Field $field = null): void { $this->addTextToQuery('addShould', $node, $field); } /** - * @param Node $node - * @param Field|null $field + * {@inheritdoc} */ - protected function mustNotMatch(Node $node, Field $field = null) + protected function mustNotMatch(Node $node, ?Field $field = null): void { $this->addTextToQuery('addMustNot', $node, $field); } @@ -320,10 +329,10 @@ protected function mustNotMatch(Node $node, Field $field = null) * text searching is needed/supported. * * @param string $method - * @param Node $node - * @param Field|null $field + * @param Node $node + * @param Field $field */ - protected function addTextToQuery($method, Node $node, Field $field = null) + protected function addTextToQuery(string $method, Node $node, ?Field $field = null): void { if ($node instanceof Word && $node->isStopWord() && $this->ignoreStopWords) { return; @@ -332,15 +341,15 @@ protected function addTextToQuery($method, Node $node, Field $field = null) $fieldName = $this->inField() ? $field->getName() : $this->defaultFieldName; if ($this->inField() && !$this->inSubquery()) { - $useBoost = $field->useBoost(); - $boost = $field->getBoost(); - $useFuzzy = $field->useFuzzy(); - $fuzzy = $field->getFuzzy(); + $useBoost = $field->useBoost(); + $boost = $field->getBoost(); + $useFuzzy = $field->useFuzzy(); + $fuzzy = $field->getFuzzy(); } else { - $useBoost = $node->useBoost(); - $boost = $node->getBoost(); - $useFuzzy = $node->useFuzzy(); - $fuzzy = $node->getFuzzy(); + $useBoost = $node->useBoost(); + $boost = $node->getBoost(); + $useFuzzy = $node->useFuzzy(); + $fuzzy = $node->getFuzzy(); } /* @@ -358,9 +367,9 @@ protected function addTextToQuery($method, Node $node, Field $field = null) if ($useFuzzy && $node instanceof Phrase) { $data = [ - 'query' => $node->getValue(), - 'type' => Phrase::NODE_TYPE, - 'lenient' => true, + 'query' => $node->getValue(), + 'type' => Phrase::NODE_TYPE, + 'lenient' => true, 'phrase_slop' => $fuzzy, ]; @@ -370,7 +379,6 @@ protected function addTextToQuery($method, Node $node, Field $field = null) $query = $this->qb->query()->match(); $query->setField($fieldName, $data); - } elseif ($useFuzzy) { $query = $this->qb->query()->fuzzy(); $query->setField($fieldName, $node->getValue()); @@ -379,11 +387,9 @@ protected function addTextToQuery($method, Node $node, Field $field = null) if ($useBoost) { $query->setFieldOption('boost', $boost); } - } elseif ($node instanceof Word && $node->hasTrailingWildcard()) { $query = $this->qb->query()->wildcard(); - $query->setValue($fieldName, strtolower($node->getValue()).'*', $useBoost ? $boost : Word::DEFAULT_BOOST); - + $query->setValue($fieldName, strtolower($node->getValue()) . '*', $useBoost ? $boost : Word::DEFAULT_BOOST); } else { $data = ['query' => $node->getValue(), 'operator' => 'and', 'lenient' => true]; @@ -403,30 +409,25 @@ protected function addTextToQuery($method, Node $node, Field $field = null) } /** - * @param Node $node - * @param Field|null $field - * @param bool $cacheable + * {@inheritdoc} */ - protected function mustMatchTerm(Node $node, Field $field = null, $cacheable = false) + protected function mustMatchTerm(Node $node, ?Field $field = null, bool $cacheable = false): void { $this->addTermToQuery('addMust', $node, $field, $cacheable); } /** - * @param Node $node - * @param Field|null $field + * {@inheritdoc} */ - protected function shouldMatchTerm(Node $node, Field $field = null) + protected function shouldMatchTerm(Node $node, ?Field $field = null): void { $this->addTermToQuery('addShould', $node, $field); } /** - * @param Node $node - * @param Field|null $field - * @param bool $cacheable + * {@inheritdoc} */ - protected function mustNotMatchTerm(Node $node, Field $field = null, $cacheable = false) + protected function mustNotMatchTerm(Node $node, ?Field $field = null, bool $cacheable = false): void { $this->addTermToQuery('addMustNot', $node, $field, $cacheable); } @@ -436,11 +437,11 @@ protected function mustNotMatchTerm(Node $node, Field $field = null, $cacheable * request for that item could be cached, like documents with hashtag of cats. * * @param string $method - * @param Node $node - * @param Field|null $field - * @param bool $cacheable + * @param Node $node + * @param Field $field + * @param bool $cacheable */ - protected function addTermToQuery($method, Node $node, Field $field = null, $cacheable = false) + protected function addTermToQuery(string $method, Node $node, ?Field $field = null, bool $cacheable = false): void { if ($node instanceof Emoji && $this->ignoreEmojis) { return; @@ -450,24 +451,24 @@ protected function addTermToQuery($method, Node $node, Field $field = null, $cac return; } - $value = $this->lowerCaseTerms ? strtolower($node->getValue()) : $node->getValue(); + $value = $this->lowerCaseTerms ? strtolower((string)$node->getValue()) : $node->getValue(); $fieldName = $this->inField() ? $field->getName() : $this->defaultFieldName; if ($this->inField() && !$this->inSubquery()) { $useBoost = $field->useBoost(); - $boost = $field->getBoost(); + $boost = $field->getBoost(); } else { $useBoost = $node->useBoost(); - $boost = $node->getBoost(); + $boost = $node->getBoost(); } if ('_exists_' === $fieldName) { - $term = new Query\Exists($value); + $term = new Exists($value); $method = 'addMust'; $cacheable = true; } elseif ('_missing_' === $fieldName) { - $term = new Query\Missing($value); - $method = 'addMust'; + $term = new Exists($value); + $method = 'addMustNot'; $cacheable = true; } elseif ($node instanceof Date) { $term = $this->createDateRangeForSingleNode( @@ -476,14 +477,12 @@ protected function addTermToQuery($method, Node $node, Field $field = null, $cac $cacheable, $useBoost ? $boost : Date::DEFAULT_BOOST ); - } elseif ($node instanceof Numbr && $node->useComparisonOperator()) { $data = [$node->getComparisonOperator()->getValue() => $value]; if ($useBoost) { $data['boost'] = $boost; } $term = $this->qb->query()->range($fieldName, $data); - } else { $term = $this->qb->query()->term(); $term->setTerm($fieldName, $value, $boost); @@ -509,25 +508,28 @@ protected function addTermToQuery($method, Node $node, Field $field = null, $cac * The Date node is a date with no time component. @see Date::toDateTime * * @param string $fieldName - * @param Date $node - * @param bool $cacheable - * @param float $boost + * @param Date $node + * @param bool $cacheable + * @param float $boost * - * @return Filter\Range|Query\Range + * @return RangeQuery */ protected function createDateRangeForSingleNode( - $fieldName, + string $fieldName, Date $node, - $cacheable = false, - $boost = Date::DEFAULT_BOOST - ) { + bool $cacheable = false, + float $boost = Date::DEFAULT_BOOST + ): RangeQuery { $operator = $node->getComparisonOperator()->getValue(); if ($operator === ComparisonOperator::EQ) { $date = $node->toDateTime($this->localTimeZone); - $data = ['gte' => $date->format('U'), 'lt' => $date->modify('+1 day')->format('U')]; + $data = [ + 'gte' => $date->format('Y-m-d'), + 'lt' => $date->modify('+1 day')->format('Y-m-d'), + ]; } else { - $data = [$operator => $node->toDateTime($this->localTimeZone)->format('U')]; + $data = [$operator => $node->toDateTime($this->localTimeZone)->format('Y-m-d')]; } if ($cacheable) { @@ -539,19 +541,19 @@ protected function createDateRangeForSingleNode( } /** - * @param string $method - * @param string $fieldName - * @param Query\AbstractQuery $query + * @param string $method + * @param string $fieldName + * @param AbstractQuery $query */ - protected function addToBoolQuery($method, $fieldName, Query\AbstractQuery $query) + protected function addToBoolQuery(string $method, string $fieldName, AbstractQuery $query): void { if (false === strpos($fieldName, '.')) { $this->boolQuery->$method($query); return; } + $fieldName = str_replace('.raw', '', $fieldName); $nestedPath = substr($fieldName, 0, strrpos($fieldName, '.')); - if (!isset($this->nestedFields[$nestedPath])) { $this->boolQuery->$method($query); return; @@ -559,8 +561,8 @@ protected function addToBoolQuery($method, $fieldName, Query\AbstractQuery $quer $nestedQuery = $nestedPath . '-' . $method; if (!isset($this->nestedQueries[$nestedQuery])) { - $this->nestedQueries[$nestedQuery] = (new Query\Nested()) - ->setQuery($this->qb->query()->bool()->setMinimumNumberShouldMatch('2<80%')) + $this->nestedQueries[$nestedQuery] = (new Nested()) + ->setQuery($this->qb->query()->bool()->setMinimumShouldMatch('2<80%')) ->setPath($nestedPath); $this->boolQuery->$method($this->nestedQueries[$nestedQuery]); } diff --git a/src/Builder/QueryBuilder.php b/src/Builder/QueryBuilder.php index fd87717..3896ce8 100755 --- a/src/Builder/QueryBuilder.php +++ b/src/Builder/QueryBuilder.php @@ -1,4 +1,5 @@ result = ''; $this->indent = 2; @@ -42,15 +43,15 @@ public function clear() /** * @return string */ - public function toXmlString() + public function toXmlString(): string { - return ''.PHP_EOL.''.PHP_EOL.rtrim($this->result).PHP_EOL.''; + return '' . PHP_EOL . '' . PHP_EOL . rtrim((string)$this->result) . PHP_EOL . ''; } /** * @return \SimpleXMLElement */ - public function toSimpleXmlElement() + public function toSimpleXmlElement(): \SimpleXMLElement { try { $xml = new \SimpleXMLElement($this->toXmlString()); @@ -66,10 +67,9 @@ public function toSimpleXmlElement() } /** - * @param Field $field - * @param bool $cacheable + * {@inheritdoc} */ - protected function startField(Field $field, $cacheable = false) + protected function startField(Field $field, bool $cacheable = false): void { $tag = sprintf('field name="%s"', $field->getName()); @@ -90,24 +90,21 @@ protected function startField(Field $field, $cacheable = false) } /** - * @param Field $field - * @param bool $cacheable + * {@inheritdoc} */ - protected function endField(Field $field, $cacheable = false) + protected function endField(Field $field, bool $cacheable = false): void { $this->outdent(); $this->printLine(''); } /** - * @param Range $range - * @param Field $field - * @param bool $cacheable + * {@inheritdoc} */ - protected function handleRange(Range $range, Field $field, $cacheable = false) + protected function handleRange(Range $range, Field $field, bool $cacheable = false): void { $this->printLine( - $range->isExclusive() ? '<'.$range::NODE_TYPE.' exclusive="true">' : '<'.$range::NODE_TYPE.'>' + $range->isExclusive() ? '<' . $range::NODE_TYPE . ' exclusive="true">' : '<' . $range::NODE_TYPE . '>' ); $this->indent(); $this->printLine(''); @@ -134,14 +131,13 @@ protected function handleRange(Range $range, Field $field, $cacheable = false) $this->printLine(''); $this->outdent(); - $this->printLine(''); + $this->printLine(''); } /** - * @param Subquery $subquery - * @param Field|null $field + * {@inheritdoc} */ - protected function startSubquery(Subquery $subquery, Field $field = null) + protected function startSubquery(Subquery $subquery, ?Field $field = null): void { $tag = $subquery::NODE_TYPE; $inField = $field instanceof Field; @@ -155,77 +151,68 @@ protected function startSubquery(Subquery $subquery, Field $field = null) } /** - * @param Subquery $subquery - * @param Field|null $field + * {@inheritdoc} */ - protected function endSubquery(Subquery $subquery, Field $field = null) + protected function endSubquery(Subquery $subquery, ?Field $field = null): void { $this->outdent(); $this->printLine(''); } /** - * @param Node $node - * @param Field|null $field + * {@inheritdoc} */ - protected function mustMatch(Node $node, Field $field = null) + protected function mustMatch(Node $node, ?Field $field = null): void { $this->printSimpleNode(__FUNCTION__, $node, $field); } /** - * @param Node $node - * @param Field|null $field + * {@inheritdoc} */ - protected function shouldMatch(Node $node, Field $field = null) + protected function shouldMatch(Node $node, ?Field $field = null): void { $this->printSimpleNode(__FUNCTION__, $node, $field); } /** - * @param Node $node - * @param Field|null $field + * {@inheritdoc} */ - protected function mustNotMatch(Node $node, Field $field = null) + protected function mustNotMatch(Node $node, ?Field $field = null): void { $this->printSimpleNode(__FUNCTION__, $node, $field); } /** - * @param Node $node - * @param Field|null $field - * @param bool $cacheable + * {@inheritdoc} */ - protected function mustMatchTerm(Node $node, Field $field = null, $cacheable = false) + protected function mustMatchTerm(Node $node, ?Field $field = null, bool $cacheable = false): void { $this->printSimpleNode(__FUNCTION__, $node, $field); } /** - * @param Node $node - * @param Field|null $field + * {@inheritdoc} */ - protected function shouldMatchTerm(Node $node, Field $field = null) + protected function shouldMatchTerm(Node $node, ?Field $field = null): void { $this->printSimpleNode(__FUNCTION__, $node, $field); } /** - * @param Node $node - * @param Field|null $field - * @param bool $cacheable + * {@inheritdoc} */ - protected function mustNotMatchTerm(Node $node, Field $field = null, $cacheable = false) + protected function mustNotMatchTerm(Node $node, ?Field $field = null, bool $cacheable = false): void { $this->printSimpleNode(__FUNCTION__, $node, $field); } /** * @param string $rule - * @param Node $node - * @param Field|null $field + * @param Node $node + * @param Field $field */ - protected function printSimpleNode($rule, Node $node, Field $field = null) + protected function printSimpleNode(string $rule, Node $node, ?Field $field = null): void { if ($this->inRange()) { $this->printLine(sprintf('<%s>%s', $node::NODE_TYPE, $node->getValue(), $node::NODE_TYPE)); @@ -278,7 +265,7 @@ protected function printSimpleNode($rule, Node $node, Field $field = null) } } - $value = $node->getValue(); + $value = (string)$node->getValue(); if (preg_match('/[^a-zA-Z0-9\s!@#$%\^\*\(\)_\-+"\'\\{\}:;\?\.]+/', $value)) { $value = ''; } @@ -288,9 +275,9 @@ protected function printSimpleNode($rule, Node $node, Field $field = null) /** * @param string $line - * @param bool $newLine + * @param bool $newLine */ - protected function printLine($line, $newLine = true) + protected function printLine(string $line, bool $newLine = true): void { $this->result .= str_repeat(' ', $this->indent) . $line . ($newLine ? PHP_EOL : ''); } @@ -298,7 +285,7 @@ protected function printLine($line, $newLine = true) /** * @param int $step */ - protected function indent($step = 2) + protected function indent(int $step = 2): void { $this->indent += $step; } @@ -306,7 +293,7 @@ protected function indent($step = 2) /** * @param int $step */ - protected function outdent($step = 2) + protected function outdent(int $step = 2): void { $this->indent -= $step; } diff --git a/src/Enum/BoolOperator.php b/src/Enum/BoolOperator.php index 31c9b51..bdf983a 100644 --- a/src/Enum/BoolOperator.php +++ b/src/Enum/BoolOperator.php @@ -1,4 +1,5 @@ comparisonOperator = $comparisonOperator ?: ComparisonOperator::EQ(); @@ -48,15 +49,16 @@ public function __construct( /** * @param array $data + * * @return self */ public static function fromArray(array $data = []) { - $value = isset($data['value']) ? $data['value'] : null; + $value = isset($data['value']) ? $data['value'] : ''; $useBoost = isset($data['use_boost']) ? (bool)$data['use_boost'] : false; - $boost = isset($data['boost']) ? (float)$data['boost'] : self::DEFAULT_BOOST; + $boost = isset($data['boost']) ? (float)$data['boost'] : self::DEFAULT_BOOST; $useFuzzy = isset($data['use_fuzzy']) ? (bool)$data['use_fuzzy'] : false; - $fuzzy = isset($data['fuzzy']) ? (int)$data['fuzzy'] : self::DEFAULT_FUZZY; + $fuzzy = isset($data['fuzzy']) ? (int)$data['fuzzy'] : self::DEFAULT_FUZZY; try { $boolOperator = isset($data['bool_operator']) ? BoolOperator::create($data['bool_operator']) : null; @@ -90,7 +92,7 @@ public function toArray() /** * @return bool */ - public function useComparisonOperator() + public function useComparisonOperator(): bool { return !$this->comparisonOperator->equals(ComparisonOperator::EQ()); } @@ -98,7 +100,7 @@ public function useComparisonOperator() /** * @return ComparisonOperator */ - public function getComparisonOperator() + public function getComparisonOperator(): ComparisonOperator { return $this->comparisonOperator; } @@ -108,9 +110,10 @@ public function getComparisonOperator() * that the value it holds is localized and should be converted to UTC. * * @param \DateTimeZone $timeZone + * * @return \DateTime */ - public function toDateTime(\DateTimeZone $timeZone = null) + public function toDateTime(\DateTimeZone $timeZone = null): \DateTime { if (null === self::$utc) { self::$utc = new \DateTimeZone('UTC'); @@ -131,7 +134,7 @@ public function toDateTime(\DateTimeZone $timeZone = null) /** * @param QueryBuilder $builder */ - public function acceptBuilder(QueryBuilder $builder) + public function acceptBuilder(QueryBuilder $builder): void { $builder->addDate($this); } diff --git a/src/Node/DateRange.php b/src/Node/DateRange.php index 6281c1a..6183642 100755 --- a/src/Node/DateRange.php +++ b/src/Node/DateRange.php @@ -1,4 +1,5 @@ addEmoji($this); } diff --git a/src/Node/Emoticon.php b/src/Node/Emoticon.php index a336d38..767c17c 100755 --- a/src/Node/Emoticon.php +++ b/src/Node/Emoticon.php @@ -1,4 +1,5 @@ addEmoticon($this); } diff --git a/src/Node/Field.php b/src/Node/Field.php index d6fc9d9..7b3da4d 100755 --- a/src/Node/Field.php +++ b/src/Node/Field.php @@ -1,4 +1,5 @@ getValue(); + /** @var string $name */ + $name = $this->getValue(); + return $name; } /** * @return Node */ - public function getNode() + public function getNode(): Node { return $this->node; } @@ -102,7 +106,7 @@ public function getNode() /** * @return bool */ - public function hasCompoundNode() + public function hasCompoundNode(): bool { return $this->node->isCompoundNode(); } @@ -110,7 +114,7 @@ public function hasCompoundNode() /** * @param QueryBuilder $builder */ - public function acceptBuilder(QueryBuilder $builder) + public function acceptBuilder(QueryBuilder $builder): void { $builder->addField($this); } diff --git a/src/Node/Hashtag.php b/src/Node/Hashtag.php index f79fdfc..4ebfd76 100755 --- a/src/Node/Hashtag.php +++ b/src/Node/Hashtag.php @@ -1,4 +1,5 @@ addHashtag($this); } diff --git a/src/Node/Mention.php b/src/Node/Mention.php index d36616c..8b35a58 100755 --- a/src/Node/Mention.php +++ b/src/Node/Mention.php @@ -1,4 +1,5 @@ addMention($this); } diff --git a/src/Node/Node.php b/src/Node/Node.php index 28585d1..e99c0e9 100755 --- a/src/Node/Node.php +++ b/src/Node/Node.php @@ -1,4 +1,5 @@ value = $value; $this->boolOperator = $boolOperator ?: BoolOperator::OPTIONAL(); - $this->useBoost = (bool)$useBoost && static::SUPPORTS_BOOST && $this->boolOperator === BoolOperator::OPTIONAL(); + $this->useBoost = $useBoost && static::SUPPORTS_BOOST && $this->boolOperator === BoolOperator::OPTIONAL(); if ($this->useBoost) { - $this->boost = (float)$boost; + $this->boost = $boost; if ($this->boost < static::MIN_BOOST) { $this->boost = static::MIN_BOOST; } @@ -77,7 +78,7 @@ public function __construct( } } - $this->useFuzzy = (bool)$useFuzzy && static::SUPPORTS_FUZZY && $this->boolOperator === BoolOperator::OPTIONAL(); + $this->useFuzzy = $useFuzzy && static::SUPPORTS_FUZZY && $this->boolOperator === BoolOperator::OPTIONAL(); if ($this->useFuzzy) { $this->fuzzy = NumberUtils::bound($fuzzy, static::MIN_FUZZY, static::MAX_FUZZY); } @@ -85,10 +86,11 @@ public function __construct( /** * @param array $data + * * @return static * @throws \InvalidArgumentException */ - public static function factory(array $data = []) + public static function factory(array $data = []): self { $type = $data['type']; // fix for php7 reserved name (scalar type hint) @@ -112,7 +114,7 @@ public function toArray() { $array = ['type' => static::NODE_TYPE]; - if (null !== $this->value) { + if ($this->hasValue()) { $array['value'] = $this->value; } @@ -144,13 +146,13 @@ final public function jsonSerialize() /** * @return bool */ - final public function hasValue() + final public function hasValue(): bool { - return null !== $this->value; + return null !== $this->value && '' !== $this->value; } /** - * @return mixed|null + * @return mixed */ final public function getValue() { @@ -160,7 +162,7 @@ final public function getValue() /** * @return BoolOperator */ - final public function getBoolOperator() + final public function getBoolOperator(): BoolOperator { return $this->boolOperator; } @@ -168,7 +170,7 @@ final public function getBoolOperator() /** * @return bool */ - final public function isOptional() + final public function isOptional(): bool { return $this->boolOperator->equals(BoolOperator::OPTIONAL()); } @@ -176,7 +178,7 @@ final public function isOptional() /** * @return bool */ - final public function isRequired() + final public function isRequired(): bool { return $this->boolOperator->equals(BoolOperator::REQUIRED()); } @@ -184,7 +186,7 @@ final public function isRequired() /** * @return bool */ - final public function isProhibited() + final public function isProhibited(): bool { return $this->boolOperator->equals(BoolOperator::PROHIBITED()); } @@ -192,7 +194,7 @@ final public function isProhibited() /** * @return bool */ - final public function isCompoundNode() + final public function isCompoundNode(): bool { return static::COMPOUND_NODE; } @@ -200,7 +202,7 @@ final public function isCompoundNode() /** * @return bool */ - public function useComparisonOperator() + public function useComparisonOperator(): bool { return false; } @@ -208,7 +210,7 @@ public function useComparisonOperator() /** * @return bool */ - final public function useBoost() + final public function useBoost(): bool { return $this->useBoost; } @@ -216,7 +218,7 @@ final public function useBoost() /** * @return float */ - final public function getBoost() + final public function getBoost(): float { return $this->boost; } @@ -224,7 +226,7 @@ final public function getBoost() /** * @return bool */ - final public function useFuzzy() + final public function useFuzzy(): bool { return $this->useFuzzy; } @@ -232,7 +234,7 @@ final public function useFuzzy() /** * @return int */ - final public function getFuzzy() + final public function getFuzzy(): int { return $this->fuzzy; } @@ -240,7 +242,7 @@ final public function getFuzzy() /** * @param QueryBuilder $builder */ - public function acceptBuilder(QueryBuilder $builder) + public function acceptBuilder(QueryBuilder $builder): void { // do nothing } diff --git a/src/Node/NumberRange.php b/src/Node/NumberRange.php index aaf9421..c4543c2 100755 --- a/src/Node/NumberRange.php +++ b/src/Node/NumberRange.php @@ -1,4 +1,5 @@ comparisonOperator = $comparisonOperator ?: ComparisonOperator::EQ(); @@ -29,11 +30,12 @@ public function __construct($value, ComparisonOperator $comparisonOperator = nul /** * @param array $data + * * @return self */ public static function fromArray(array $data = []) { - $value = isset($data['value']) ? (float)$data['value'] : null; + $value = isset($data['value']) ? (float)$data['value'] : 0.0; try { $comparisonOperator = isset($data['comparison_operator']) ? ComparisonOperator::create($data['comparison_operator']) : null; @@ -61,7 +63,7 @@ public function toArray() /** * @return bool */ - public function useComparisonOperator() + public function useComparisonOperator(): bool { return !$this->comparisonOperator->equals(ComparisonOperator::EQ()); } @@ -69,7 +71,7 @@ public function useComparisonOperator() /** * @return ComparisonOperator */ - public function getComparisonOperator() + public function getComparisonOperator(): ComparisonOperator { return $this->comparisonOperator; } @@ -77,7 +79,7 @@ public function getComparisonOperator() /** * @param QueryBuilder $builder */ - public function acceptBuilder(QueryBuilder $builder) + public function acceptBuilder(QueryBuilder $builder): void { $builder->addNumber($this); } diff --git a/src/Node/Phrase.php b/src/Node/Phrase.php index 90da402..d7620e7 100755 --- a/src/Node/Phrase.php +++ b/src/Node/Phrase.php @@ -1,4 +1,5 @@ addPhrase($this); } diff --git a/src/Node/Range.php b/src/Node/Range.php index 8769f9c..b9964f0 100755 --- a/src/Node/Range.php +++ b/src/Node/Range.php @@ -1,4 +1,5 @@ lowerNode = $lowerNode; $this->upperNode = $upperNode; - $this->exclusive = (bool)$exclusive; + $this->exclusive = $exclusive; if (null === $this->lowerNode && null === $this->upperNode) { throw new \LogicException('Range requires at least a lower or upper node.'); @@ -41,6 +42,7 @@ public function __construct(Node $lowerNode = null, Node $upperNode = null, $exc /** * @param array $data + * * @return self */ final public static function fromArray(array $data = []) @@ -76,7 +78,7 @@ final public function toArray() /** * @return bool */ - final public function hasLowerNode() + final public function hasLowerNode(): bool { return null !== $this->lowerNode; } @@ -84,7 +86,7 @@ final public function hasLowerNode() /** * @return Node */ - public function getLowerNode() + public function getLowerNode(): ?Node { return $this->lowerNode; } @@ -92,7 +94,7 @@ public function getLowerNode() /** * @return bool */ - final public function hasUpperNode() + final public function hasUpperNode(): bool { return null !== $this->upperNode; } @@ -100,7 +102,7 @@ final public function hasUpperNode() /** * @return Node */ - public function getUpperNode() + public function getUpperNode(): ?Node { return $this->upperNode; } @@ -108,7 +110,7 @@ public function getUpperNode() /** * @return bool */ - final public function isInclusive() + final public function isInclusive(): bool { return !$this->exclusive; } @@ -116,7 +118,7 @@ final public function isInclusive() /** * @return bool */ - final public function isExclusive() + final public function isExclusive(): bool { return $this->exclusive; } @@ -124,7 +126,7 @@ final public function isExclusive() /** * @param QueryBuilder $builder */ - final public function acceptBuilder(QueryBuilder $builder) + final public function acceptBuilder(QueryBuilder $builder): void { $builder->addRange($this); } diff --git a/src/Node/Subquery.php b/src/Node/Subquery.php index c73012e..ef48c95 100755 --- a/src/Node/Subquery.php +++ b/src/Node/Subquery.php @@ -1,4 +1,5 @@ nodes = $nodes; @@ -41,12 +42,13 @@ public function __construct( /** * @param array $data + * * @return self */ public static function fromArray(array $data = []) { $useBoost = isset($data['use_boost']) ? (bool)$data['use_boost'] : false; - $boost = isset($data['boost']) ? (float)$data['boost'] : self::DEFAULT_BOOST; + $boost = isset($data['boost']) ? (float)$data['boost'] : self::DEFAULT_BOOST; $nodes = []; if (isset($data['nodes'])) { @@ -82,7 +84,7 @@ public function toArray() /** * @return Node[] */ - public function getNodes() + public function getNodes(): array { return $this->nodes; } @@ -90,7 +92,7 @@ public function getNodes() /** * @param QueryBuilder $builder */ - public function acceptBuilder(QueryBuilder $builder) + public function acceptBuilder(QueryBuilder $builder): void { $builder->addSubquery($this); } diff --git a/src/Node/Url.php b/src/Node/Url.php index a4ca918..e31ee6f 100755 --- a/src/Node/Url.php +++ b/src/Node/Url.php @@ -1,4 +1,5 @@ addUrl($this); } diff --git a/src/Node/Word.php b/src/Node/Word.php index 35cd561..3df27c4 100755 --- a/src/Node/Word.php +++ b/src/Node/Word.php @@ -1,4 +1,5 @@ trailingWildcard = (bool)$trailingWildcard; + $this->trailingWildcard = $trailingWildcard; } /** * @param array $data + * * @return self */ public static function fromArray(array $data = []) { - $value = isset($data['value']) ? $data['value'] : null; + $value = isset($data['value']) ? $data['value'] : ''; $useBoost = isset($data['use_boost']) ? (bool)$data['use_boost'] : false; - $boost = isset($data['boost']) ? (float)$data['boost'] : self::DEFAULT_BOOST; + $boost = isset($data['boost']) ? (float)$data['boost'] : self::DEFAULT_BOOST; $useFuzzy = isset($data['use_fuzzy']) ? (bool)$data['use_fuzzy'] : false; - $fuzzy = isset($data['fuzzy']) ? (int)$data['fuzzy'] : self::DEFAULT_FUZZY; + $fuzzy = isset($data['fuzzy']) ? (int)$data['fuzzy'] : self::DEFAULT_FUZZY; $trailingWildcard = isset($data['trailing_wildcard']) ? (bool)$data['trailing_wildcard'] : false; try { @@ -83,7 +85,7 @@ public function toArray() /** * @return bool */ - public function hasTrailingWildcard() + public function hasTrailingWildcard(): bool { return $this->trailingWildcard; } @@ -91,7 +93,7 @@ public function hasTrailingWildcard() /** * @return bool */ - public function isStopWord() + public function isStopWord(): bool { return in_array(strtolower($this->getValue()), self::$stopWords); } @@ -99,7 +101,7 @@ public function isStopWord() /** * @param QueryBuilder $builder */ - public function acceptBuilder(QueryBuilder $builder) + public function acceptBuilder(QueryBuilder $builder): void { $builder->addWord($this); } diff --git a/src/Node/WordRange.php b/src/Node/WordRange.php index 4c760cb..5d25cd9 100755 --- a/src/Node/WordRange.php +++ b/src/Node/WordRange.php @@ -1,4 +1,5 @@ addNode($node); @@ -61,9 +64,10 @@ public function addNodes(array $nodes) /** * @param Node $node + * * @return static */ - public function addNode(Node $node) + public function addNode(Node $node): self { $this->nodes[] = $node; $this->nodesByType[$node::NODE_TYPE][] = $node; @@ -73,16 +77,17 @@ public function addNode(Node $node) /** * @return Node[] */ - public function getNodes() + public function getNodes(): array { return $this->nodes; } /** * @param string $type + * * @return Node[] */ - public function getNodesOfType($type) + public function getNodesOfType(string $type): array { return isset($this->nodesByType[$type]) ? $this->nodesByType[$type] : []; } @@ -94,7 +99,7 @@ public function getNodesOfType($type) * * @return bool */ - public function hasAMatchableNode() + public function hasAMatchableNode(): bool { foreach ($this->nodes as $node) { if (!$node->isProhibited()) { @@ -111,7 +116,7 @@ public function hasAMatchableNode() * * @return array */ - public function getFieldsUsed() + public function getFieldsUsed(): array { $fields = []; diff --git a/src/QueryParser.php b/src/QueryParser.php index a261a86..538fb5c 100755 --- a/src/QueryParser.php +++ b/src/QueryParser.php @@ -1,4 +1,5 @@ stream = $this->tokenizer->scan($input); $this->query = new ParsedQuery(); @@ -67,8 +68,8 @@ public function parse($input) } /** - * @param Token $token - * @param BoolOperator $boolOperator + * @param Token $token + * @param BoolOperator $boolOperator * @param ComparisonOperator $comparisonOperator * * @return Node[] @@ -76,8 +77,8 @@ public function parse($input) protected function createNodes( Token $token, BoolOperator $boolOperator, - ComparisonOperator $comparisonOperator = null - ) { + ?ComparisonOperator $comparisonOperator = null + ): array { switch ($token->getType()) { case Token::T_WORD: $nodes = $this->createWord($token->getValue(), $boolOperator); @@ -132,12 +133,12 @@ protected function createNodes( } /** - * @param string $fieldName + * @param string $fieldName * @param BoolOperator $boolOperator * * @return Field|Node[]|Node */ - protected function handleField($fieldName, BoolOperator $boolOperator) + protected function handleField(string $fieldName, BoolOperator $boolOperator) { $lookahead = $this->stream->getLookahead(); if (!$lookahead instanceof Token) { @@ -187,12 +188,12 @@ protected function handleField($fieldName, BoolOperator $boolOperator) } /** - * @param string $fieldName + * @param string $fieldName * @param BoolOperator $boolOperator * * @return Field|Node[]|Node */ - protected function handleFieldWithRange($fieldName, BoolOperator $boolOperator) + protected function handleFieldWithRange(string $fieldName, BoolOperator $boolOperator) { $exclusive = $this->stream->typeIs(Token::T_RANGE_EXCL_START); $matchTypes = true; @@ -285,12 +286,12 @@ protected function handleFieldWithRange($fieldName, BoolOperator $boolOperator) } /** - * @param string $fieldName + * @param string $fieldName * @param BoolOperator $boolOperator * * @return Field|Node */ - protected function handleFieldWithSubquery($fieldName, BoolOperator $boolOperator) + protected function handleFieldWithSubquery(string $fieldName, BoolOperator $boolOperator): Node { $this->stream->nextIf(Token::T_SUBQUERY_START); $subquery = $this->handleSubquery($boolOperator); @@ -378,14 +379,17 @@ protected function handleSubquery(BoolOperator $queryBoolOperator) } /** - * @param string $value - * @param BoolOperator $boolOperator + * @param string $value + * @param BoolOperator $boolOperator * @param ComparisonOperator $comparisonOperator * * @return Date */ - protected function createDate($value, BoolOperator $boolOperator, ComparisonOperator $comparisonOperator = null) - { + protected function createDate( + string $value, + BoolOperator $boolOperator, + ?ComparisonOperator $comparisonOperator = null + ): Date { $m = $this->getModifiers(); return new Date( $value, @@ -399,12 +403,12 @@ protected function createDate($value, BoolOperator $boolOperator, ComparisonOper } /** - * @param string $value + * @param string $value * @param BoolOperator $boolOperator * * @return Emoji */ - protected function createEmoji($value, BoolOperator $boolOperator) + protected function createEmoji(string $value, BoolOperator $boolOperator): Emoji { $boolOperator = $boolOperator->equals(BoolOperator::OPTIONAL()) ? BoolOperator::REQUIRED() : $boolOperator; $m = $this->getModifiers(); @@ -412,12 +416,12 @@ protected function createEmoji($value, BoolOperator $boolOperator) } /** - * @param string $value + * @param string $value * @param BoolOperator $boolOperator * * @return Emoticon */ - protected function createEmoticon($value, BoolOperator $boolOperator) + protected function createEmoticon(string $value, BoolOperator $boolOperator): Emoticon { $boolOperator = $boolOperator->equals(BoolOperator::OPTIONAL()) ? BoolOperator::REQUIRED() : $boolOperator; $m = $this->getModifiers(); @@ -425,12 +429,12 @@ protected function createEmoticon($value, BoolOperator $boolOperator) } /** - * @param string $value + * @param string $value * @param BoolOperator $boolOperator * * @return Hashtag */ - protected function createHashtag($value, BoolOperator $boolOperator) + protected function createHashtag(string $value, BoolOperator $boolOperator): Hashtag { $boolOperator = $boolOperator->equals(BoolOperator::OPTIONAL()) ? BoolOperator::REQUIRED() : $boolOperator; $m = $this->getModifiers(); @@ -438,12 +442,12 @@ protected function createHashtag($value, BoolOperator $boolOperator) } /** - * @param string $value + * @param string $value * @param BoolOperator $boolOperator * * @return Mention */ - protected function createMention($value, BoolOperator $boolOperator) + protected function createMention(string $value, BoolOperator $boolOperator): Mention { $boolOperator = $boolOperator->equals(BoolOperator::OPTIONAL()) ? BoolOperator::REQUIRED() : $boolOperator; $m = $this->getModifiers(); @@ -451,12 +455,12 @@ protected function createMention($value, BoolOperator $boolOperator) } /** - * @param float $value + * @param float $value * @param ComparisonOperator $comparisonOperator * * @return Numbr */ - protected function createNumber($value, ComparisonOperator $comparisonOperator = null) + protected function createNumber(float $value, ?ComparisonOperator $comparisonOperator = null): Numbr { // move the stream and ignore them if they exist $this->getModifiers(); @@ -464,36 +468,36 @@ protected function createNumber($value, ComparisonOperator $comparisonOperator = } /** - * @param string $value + * @param string $value * @param BoolOperator $boolOperator * * @return Phrase */ - protected function createPhrase($value, BoolOperator $boolOperator) + protected function createPhrase(string $value, BoolOperator $boolOperator): Phrase { $m = $this->getModifiers(); return new Phrase($value, $boolOperator, $m['use_boost'], $m['boost'], $m['use_fuzzy'], $m['fuzzy']); } /** - * @param string $value + * @param string $value * @param BoolOperator $boolOperator * * @return Url */ - protected function createUrl($value, BoolOperator $boolOperator) + protected function createUrl(string $value, BoolOperator $boolOperator): Url { $m = $this->getModifiers(); return new Url($value, $boolOperator, $m['use_boost'], $m['boost']); } /** - * @param string $value + * @param string $value * @param BoolOperator $boolOperator * * @return Word */ - protected function createWord($value, BoolOperator $boolOperator) + protected function createWord(string $value, BoolOperator $boolOperator): Word { $m = $this->getModifiers(); return new Word( @@ -512,7 +516,7 @@ protected function createWord($value, BoolOperator $boolOperator) * * @return BoolOperator */ - protected function getBoolOperator($default = BoolOperator::OPTIONAL) + protected function getBoolOperator(int $default = BoolOperator::OPTIONAL): BoolOperator { if ($this->stream->nextIf(Token::T_REQUIRED) || $this->stream->lookaheadTypeIs(Token::T_AND) @@ -529,9 +533,9 @@ protected function getBoolOperator($default = BoolOperator::OPTIONAL) } /** - * @return ComparisonOperator|null + * @return ComparisonOperator */ - protected function getComparisonOperator() + protected function getComparisonOperator(): ?ComparisonOperator { if ($this->stream->nextIf(Token::T_GREATER_THAN)) { $op = ComparisonOperator::GT; @@ -551,25 +555,25 @@ protected function getComparisonOperator() /** * @return array */ - protected function getModifiers() + protected function getModifiers(): array { $array = [ 'trailing_wildcard' => $this->stream->nextIfLookahead(Token::T_WILDCARD), - 'use_boost' => false, - 'boost' => Node::DEFAULT_BOOST, - 'use_fuzzy' => false, - 'fuzzy' => Node::DEFAULT_FUZZY, + 'use_boost' => false, + 'boost' => Node::DEFAULT_BOOST, + 'use_fuzzy' => false, + 'fuzzy' => Node::DEFAULT_FUZZY, ]; if ($this->stream->nextIfLookahead(Token::T_BOOST) && $this->stream->nextIfLookahead(Token::T_NUMBER)) { $array['use_boost'] = true; - $array['boost'] = $this->stream->getCurrent()->getValue(); + $array['boost'] = (float)$this->stream->getCurrent()->getValue(); } if ($this->stream->nextIfLookahead(Token::T_FUZZY)) { $array['use_fuzzy'] = true; if ($this->stream->nextIfLookahead(Token::T_NUMBER)) { - $array['fuzzy'] = $this->stream->getCurrent()->getValue(); + $array['fuzzy'] = (int)$this->stream->getCurrent()->getValue(); } } diff --git a/src/Token.php b/src/Token.php index a01e926..2348570 100755 --- a/src/Token.php +++ b/src/Token.php @@ -1,4 +1,5 @@ type = (int)$type; + $this->type = $type; $this->value = $value; } @@ -66,13 +67,13 @@ public function __construct($type, $value = null) * * @return string */ - public static function name($type) + public static function name(int $type): string { if (null === self::$typeNames) { static::$typeNames = array_flip((new \ReflectionClass(__CLASS__))->getConstants()); } - return isset(self::$typeNames[$type]) ? self::$typeNames[$type] : $type; + return isset(self::$typeNames[$type]) ? self::$typeNames[$type] : (string)$type; } /** @@ -86,7 +87,7 @@ public function jsonSerialize() /** * @return string */ - public function getTypeName() + public function getTypeName(): string { return self::name($this->type); } @@ -94,7 +95,7 @@ public function getTypeName() /** * @return int */ - public function getType() + public function getType(): int { return $this->type; } @@ -112,9 +113,9 @@ public function getValue() * * @return bool */ - public function typeEquals($type) + public function typeEquals(int $type): bool { - return (int)$type === $this->type; + return $type === $this->type; } /** @@ -122,7 +123,7 @@ public function typeEquals($type) * * @return bool */ - public function typeEqualsAnyOf(array $types) + public function typeEqualsAnyOf(array $types): bool { return in_array($this->type, $types, true); } @@ -130,7 +131,7 @@ public function typeEqualsAnyOf(array $types) /** * @return bool */ - public function isWhiteSpace() + public function isWhiteSpace(): bool { return self::T_WHITE_SPACE === $this->type; } @@ -138,7 +139,7 @@ public function isWhiteSpace() /** * @return bool */ - public function isIgnored() + public function isIgnored(): bool { return self::T_IGNORED === $this->type; } @@ -146,7 +147,7 @@ public function isIgnored() /** * @return bool */ - public function isEndOfInput() + public function isEndOfInput(): bool { return self::T_EOI === $this->type; } diff --git a/src/TokenStream.php b/src/TokenStream.php index 7a25da9..a7b2ac3 100755 --- a/src/TokenStream.php +++ b/src/TokenStream.php @@ -1,8 +1,9 @@ position = 0; $this->current = isset($this->tokens[$this->position]) ? $this->tokens[$this->position] : self::$eoi; @@ -47,7 +48,7 @@ public function reset() * * @return bool */ - public function next() + public function next(): bool { $this->current = isset($this->tokens[$this->position]) ? $this->tokens[$this->position++] : self::$eoi; return !$this->current->typeEquals(Token::T_EOI); @@ -58,7 +59,7 @@ public function next() * * @param int $type */ - public function skipUntil($type) + public function skipUntil(int $type): void { while (!$this->current->typeEquals($type) && !$this->current->typeEquals(Token::T_EOI)) { $this->next(); @@ -73,7 +74,7 @@ public function skipUntil($type) * * @return bool */ - public function nextIf($type) + public function nextIf(int $type): bool { if (!$this->current->typeEquals($type)) { return false; @@ -91,7 +92,7 @@ public function nextIf($type) * * @return bool */ - public function nextIfAnyOf(array $types) + public function nextIfAnyOf(array $types): bool { if (!$this->current->typeEqualsAnyOf($types)) { return false; @@ -108,7 +109,7 @@ public function nextIfAnyOf(array $types) * * @return bool */ - public function nextIfLookahead($type) + public function nextIfLookahead(int $type): bool { if (!isset($this->tokens[$this->position]) || !$this->tokens[$this->position]->typeEquals($type)) { return false; @@ -125,7 +126,7 @@ public function nextIfLookahead($type) * * @return bool */ - public function nextIfLookaheadAnyOf(array $types) + public function nextIfLookaheadAnyOf(array $types): bool { if (!isset($this->tokens[$this->position]) || !$this->tokens[$this->position]->typeEqualsAnyOf($types)) { return false; @@ -142,7 +143,7 @@ public function nextIfLookaheadAnyOf(array $types) * * @return bool */ - public function typeIs($type) + public function typeIs(int $type): bool { return $this->current->typeEquals($type); } @@ -154,7 +155,7 @@ public function typeIs($type) * * @return bool */ - public function typeIsAnyOf(array $types) + public function typeIsAnyOf(array $types): bool { return $this->current->typeEqualsAnyOf($types); } @@ -166,7 +167,7 @@ public function typeIsAnyOf(array $types) * * @return bool */ - public function lookaheadTypeIs($type) + public function lookaheadTypeIs(int $type): bool { return isset($this->tokens[$this->position]) && $this->tokens[$this->position]->typeEquals($type); } @@ -178,7 +179,7 @@ public function lookaheadTypeIs($type) * * @return bool */ - public function lookaheadTypeIsAnyOf(array $types) + public function lookaheadTypeIsAnyOf(array $types): bool { return isset($this->tokens[$this->position]) && $this->tokens[$this->position]->typeEqualsAnyOf($types); } @@ -190,7 +191,7 @@ public function lookaheadTypeIsAnyOf(array $types) * * @return bool */ - public function prevTypeIs($type) + public function prevTypeIs(int $type): bool { return isset($this->tokens[$this->position - 2]) && $this->tokens[$this->position - 2]->typeEquals($type); } @@ -202,7 +203,7 @@ public function prevTypeIs($type) * * @return bool */ - public function prevTypeIsAnyOf(array $types) + public function prevTypeIsAnyOf(array $types): bool { return isset($this->tokens[$this->position - 2]) && $this->tokens[$this->position - 2]->typeEqualsAnyOf($types); } @@ -210,7 +211,7 @@ public function prevTypeIsAnyOf(array $types) /** * @return Token */ - public function getCurrent() + public function getCurrent(): Token { return $this->current; } @@ -218,7 +219,7 @@ public function getCurrent() /** * @return Token|null */ - public function getLookahead() + public function getLookahead(): ?Token { return isset($this->tokens[$this->position]) ? $this->tokens[$this->position] : null; } @@ -228,7 +229,7 @@ public function getLookahead() * * @return Token[] */ - public function getTokens() + public function getTokens(): array { return $this->tokens; } diff --git a/src/Tokenizer.php b/src/Tokenizer.php index 01f2340..bde0c27 100755 Binary files a/src/Tokenizer.php and b/src/Tokenizer.php differ diff --git a/tests/Builder/XmlQueryBuilderTest.php b/tests/Builder/XmlQueryBuilderTest.php index f187f63..b92d232 100755 --- a/tests/Builder/XmlQueryBuilderTest.php +++ b/tests/Builder/XmlQueryBuilderTest.php @@ -1,12 +1,14 @@ builder->addParsedQuery($this->parser->parse($input)); $xml = $this->builder->toSimpleXmlElement(); @@ -38,6 +40,8 @@ public function testToSimpleXmlElement($name, $input, $ignored, array $expectedN $this->fail('Failed to generate SimpleXmlElement from: ' . $input); } + $this->assertSame($expectedNodeCount, $xml->count()); + /** @var \SimpleXmlElement $child */ $i = 0; foreach ($xml->children() as $child) { @@ -59,8 +63,8 @@ public function testToSimpleXmlElement($name, $input, $ignored, array $expectedN /** * @return array */ - public function getTestQueries() + public function getTestQueries(): array { - return require __DIR__.'/../Fixtures/test-queries.php'; + return require __DIR__ . '/../Fixtures/test-queries.php'; } } diff --git a/tests/Fixtures/test-queries.php b/tests/Fixtures/test-queries.php index 59bc975..7363cd3 100644 --- a/tests/Fixtures/test-queries.php +++ b/tests/Fixtures/test-queries.php @@ -1,4 +1,5 @@ 'url', - 'input' => 'http://test.com/1_2.html?a=b%20&c=1+2#test', + 'name' => 'url', + 'input' => 'http://test.com/1_2.html?a=b%20&c=1+2#test', 'expected_tokens' => [ [T::T_URL, 'http://test.com/1_2.html?a=b%20&c=1+2#test'], ], - 'expected_nodes' => [ - new Url('http://test.com/1_2.html?a=b%20&c=1+2#test') - ] + 'expected_nodes' => [ + new Url('http://test.com/1_2.html?a=b%20&c=1+2#test'), + ], ], [ - 'name' => 'required url', - 'input' => '+http://test.com/1_2.html?a=b%20&c=1+2#test', + 'name' => 'required url', + 'input' => '+http://test.com/1_2.html?a=b%20&c=1+2#test', 'expected_tokens' => [ T::T_REQUIRED, [T::T_URL, 'http://test.com/1_2.html?a=b%20&c=1+2#test'], ], - 'expected_nodes' => [ - new Url('http://test.com/1_2.html?a=b%20&c=1+2#test', BoolOperator::REQUIRED()) - ] + 'expected_nodes' => [ + new Url('http://test.com/1_2.html?a=b%20&c=1+2#test', BoolOperator::REQUIRED()), + ], ], [ - 'name' => 'prohibited url', - 'input' => '-http://test.com/1_2.html?a=b%20&c=1+2#test', + 'name' => 'prohibited url', + 'input' => '-http://test.com/1_2.html?a=b%20&c=1+2#test', 'expected_tokens' => [ T::T_PROHIBITED, [T::T_URL, 'http://test.com/1_2.html?a=b%20&c=1+2#test'], ], - 'expected_nodes' => [ - new Url('http://test.com/1_2.html?a=b%20&c=1+2#test', BoolOperator::PROHIBITED()) - ] + 'expected_nodes' => [ + new Url('http://test.com/1_2.html?a=b%20&c=1+2#test', BoolOperator::PROHIBITED()), + ], ], [ - 'name' => 'url with boost int', - 'input' => 'http://test.com/1_2.html?a=b%20&c=1+2#test^5', + 'name' => 'url with boost int', + 'input' => 'http://test.com/1_2.html?a=b%20&c=1+2#test^5', 'expected_tokens' => [ [T::T_URL, 'http://test.com/1_2.html?a=b%20&c=1+2#test'], T::T_BOOST, [T::T_NUMBER, 5.0], ], - 'expected_nodes' => [ - new Url('http://test.com/1_2.html?a=b%20&c=1+2#test', null, true, 5.0) - ] + 'expected_nodes' => [ + new Url('http://test.com/1_2.html?a=b%20&c=1+2#test', null, true, 5.0), + ], ], [ - 'name' => 'url with boost float', - 'input' => 'http://test.com/1_2.html?a=b%20&c=1+2#test^15.5', + 'name' => 'url with boost float', + 'input' => 'http://test.com/1_2.html?a=b%20&c=1+2#test^15.5', 'expected_tokens' => [ [T::T_URL, 'http://test.com/1_2.html?a=b%20&c=1+2#test'], T::T_BOOST, [T::T_NUMBER, 15.5], ], - 'expected_nodes' => [ - new Url('http://test.com/1_2.html?a=b%20&c=1+2#test', null, true, Url::MAX_BOOST) - ] + 'expected_nodes' => [ + new Url('http://test.com/1_2.html?a=b%20&c=1+2#test', null, true, Url::MAX_BOOST), + ], ], [ - 'name' => 'url with fuzzy int', - 'input' => 'http://test.com/1_2.html?a=b%20&c=1+2#test~5', + 'name' => 'url with fuzzy int', + 'input' => 'http://test.com/1_2.html?a=b%20&c=1+2#test~5', 'expected_tokens' => [ [T::T_URL, 'http://test.com/1_2.html?a=b%20&c=1+2#test'], T::T_FUZZY, [T::T_NUMBER, 5.0], ], - 'expected_nodes' => [ - new Url('http://test.com/1_2.html?a=b%20&c=1+2#test') - ] + 'expected_nodes' => [ + new Url('http://test.com/1_2.html?a=b%20&c=1+2#test'), + ], ], [ - 'name' => 'url with fuzzy float', - 'input' => 'http://test.com/1_2.html?a=b%20&c=1+2#test~5.5', + 'name' => 'url with fuzzy float', + 'input' => 'http://test.com/1_2.html?a=b%20&c=1+2#test~5.5', 'expected_tokens' => [ [T::T_URL, 'http://test.com/1_2.html?a=b%20&c=1+2#test'], T::T_FUZZY, [T::T_NUMBER, 5.5], ], - 'expected_nodes' => [ - new Url('http://test.com/1_2.html?a=b%20&c=1+2#test') - ] + 'expected_nodes' => [ + new Url('http://test.com/1_2.html?a=b%20&c=1+2#test'), + ], ], /* * END: URLS @@ -116,16 +117,16 @@ * todo: need more emoticon tests */ [ - 'name' => 'simple emoticons', - 'input' => ':) :(', + 'name' => 'simple emoticons', + 'input' => ':) :(', 'expected_tokens' => [ [T::T_EMOTICON, ':)'], [T::T_EMOTICON, ':('], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Emoticon(':)', BoolOperator::REQUIRED()), - new Emoticon(':(', BoolOperator::REQUIRED()) - ] + new Emoticon(':(', BoolOperator::REQUIRED()), + ], ], /* * END: EMOTICONS @@ -136,8 +137,8 @@ * START: EMOJIS */ [ - 'name' => 'simple emoji', - 'input' => 'ice 🍦 poop 💩 doh 😳', + 'name' => 'simple emoji', + 'input' => 'ice 🍦 poop 💩 doh 😳', 'expected_tokens' => [ [T::T_WORD, 'ice'], [T::T_EMOJI, '🍦'], @@ -146,14 +147,14 @@ [T::T_WORD, 'doh'], [T::T_EMOJI, '😳'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('ice'), new Emoji('🍦', BoolOperator::REQUIRED()), new Word('poop'), new Emoji('💩', BoolOperator::REQUIRED()), new Word('doh'), - new Emoji('😳', BoolOperator::REQUIRED()) - ] + new Emoji('😳', BoolOperator::REQUIRED()), + ], ], /* * END: EMOJIS @@ -164,8 +165,8 @@ * START: BOOST AND FUZZY */ [ - 'name' => 'boost and fuzzy in filter', - 'input' => 'f:b^5 f:f~5', + 'name' => 'boost and fuzzy in filter', + 'input' => 'f:b^5 f:f~5', 'expected_tokens' => [ [T::T_FIELD_START, 'f'], [T::T_WORD, 'b'], @@ -178,15 +179,15 @@ T::T_FUZZY, [T::T_NUMBER, 5.0], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Field('f', new Word('b'), null, true, 5.0), new Field('f', new Word('f'), null, false, Field::DEFAULT_BOOST), - ] + ], ], [ - 'name' => 'boost and fuzzy in range', - 'input' => 'f:[1^5..5]^5 f:[1~5..5]~5', + 'name' => 'boost and fuzzy in range', + 'input' => 'f:[1^5..5]^5 f:[1~5..5]~5', 'expected_tokens' => [ [T::T_FIELD_START, 'f'], T::T_RANGE_INCL_START, @@ -209,7 +210,7 @@ T::T_FUZZY, [T::T_NUMBER, 5.0], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Field( 'f', new NumberRange( @@ -230,7 +231,7 @@ false, Field::DEFAULT_BOOST ), - ] + ], ], /* * END: BOOST AND FUZZY @@ -241,163 +242,163 @@ * START: PHRASES */ [ - 'name' => 'simple phrase', - 'input' => 'a "simple phrase"', + 'name' => 'simple phrase', + 'input' => 'a "simple phrase"', 'expected_tokens' => [ [T::T_WORD, 'a'], [T::T_PHRASE, 'simple phrase'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('a'), new Phrase('simple phrase'), - ] + ], ], [ - 'name' => 'required phrase', - 'input' => 'a +"simple phrase"', + 'name' => 'required phrase', + 'input' => 'a +"simple phrase"', 'expected_tokens' => [ [T::T_WORD, 'a'], T::T_REQUIRED, [T::T_PHRASE, 'simple phrase'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('a'), new Phrase('simple phrase', BoolOperator::REQUIRED()), - ] + ], ], [ - 'name' => 'prohibited phrase', - 'input' => 'a -"simple phrase"', + 'name' => 'prohibited phrase', + 'input' => 'a -"simple phrase"', 'expected_tokens' => [ [T::T_WORD, 'a'], T::T_PROHIBITED, [T::T_PHRASE, 'simple phrase'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('a'), new Phrase('simple phrase', BoolOperator::PROHIBITED()), - ] + ], ], [ - 'name' => 'boosted phrase int', - 'input' => 'a "simple phrase"^1', + 'name' => 'boosted phrase int', + 'input' => 'a "simple phrase"^1', 'expected_tokens' => [ [T::T_WORD, 'a'], [T::T_PHRASE, 'simple phrase'], T::T_BOOST, [T::T_NUMBER, 1.0], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('a'), new Phrase('simple phrase', null, true, 1.0), - ] + ], ], [ - 'name' => 'boosted phrase float', - 'input' => 'a "simple phrase"^0.1', + 'name' => 'boosted phrase float', + 'input' => 'a "simple phrase"^0.1', 'expected_tokens' => [ [T::T_WORD, 'a'], [T::T_PHRASE, 'simple phrase'], T::T_BOOST, [T::T_NUMBER, 0.1], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('a'), new Phrase('simple phrase', null, true, 0.1), - ] + ], ], [ - 'name' => 'fuzzy phrase int', - 'input' => 'a "simple phrase"~1', + 'name' => 'fuzzy phrase int', + 'input' => 'a "simple phrase"~1', 'expected_tokens' => [ [T::T_WORD, 'a'], [T::T_PHRASE, 'simple phrase'], T::T_FUZZY, [T::T_NUMBER, 1.0], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('a'), new Phrase('simple phrase', null, false, Phrase::DEFAULT_BOOST, true, Phrase::MIN_FUZZY), - ] + ], ], [ - 'name' => 'fuzzy phrase float', - 'input' => 'a "simple phrase"~0.1', + 'name' => 'fuzzy phrase float', + 'input' => 'a "simple phrase"~0.1', 'expected_tokens' => [ [T::T_WORD, 'a'], [T::T_PHRASE, 'simple phrase'], T::T_FUZZY, [T::T_NUMBER, 0.1], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('a'), new Phrase('simple phrase', null, false, Phrase::DEFAULT_BOOST, true, Phrase::MIN_FUZZY), - ] + ], ], [ - 'name' => 'phrase with embedded emoticons', - 'input' => '"a smiley :)"', + 'name' => 'phrase with embedded emoticons', + 'input' => '"a smiley :)"', 'expected_tokens' => [ [T::T_PHRASE, 'a smiley :)'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Phrase('a smiley :)'), - ] + ], ], [ - 'name' => 'phrase with embedded emojis', - 'input' => '"ice cream 🍦"', + 'name' => 'phrase with embedded emojis', + 'input' => '"ice cream 🍦"', 'expected_tokens' => [ [T::T_PHRASE, 'ice cream 🍦'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Phrase('ice cream 🍦'), - ] + ], ], [ - 'name' => 'phrase with embedded punctation, boosting, etc.', - 'input' => '"boosted^51.50 .. field:test~5"', + 'name' => 'phrase with embedded punctation, boosting, etc.', + 'input' => '"boosted^51.50 .. field:test~5"', 'expected_tokens' => [ [T::T_PHRASE, 'boosted^51.50 .. field:test~5'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Phrase('boosted^51.50 .. field:test~5'), - ] + ], ], [ - 'name' => 'phrase with dates', - 'input' => '"in the year >=2000-01-01"', + 'name' => 'phrase with dates', + 'input' => '"in the year >=2000-01-01"', 'expected_tokens' => [ [T::T_PHRASE, 'in the year >=2000-01-01'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Phrase('in the year >=2000-01-01'), - ] + ], ], [ - 'name' => 'phrase on phrase', - 'input' => '"p1""p2""p3', + 'name' => 'phrase on phrase', + 'input' => '"p1""p2""p3', 'expected_tokens' => [ [T::T_PHRASE, 'p1'], [T::T_PHRASE, 'p2'], [T::T_WORD, 'p3'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Phrase('p1'), new Phrase('p2'), new Word('p3'), - ] + ], ], /* * END: PHRASES @@ -408,8 +409,8 @@ * START: HASHTAGS */ [ - 'name' => 'simple hashtags', - 'input' => 'a #Cat in a #hat', + 'name' => 'simple hashtags', + 'input' => 'a #Cat in a #hat', 'expected_tokens' => [ [T::T_WORD, 'a'], [T::T_HASHTAG, 'Cat'], @@ -417,18 +418,18 @@ [T::T_WORD, 'a'], [T::T_HASHTAG, 'hat'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('a'), new Hashtag('Cat', BoolOperator::REQUIRED()), new Word('in'), new Word('a'), - new Hashtag('hat', BoolOperator::REQUIRED()) - ] + new Hashtag('hat', BoolOperator::REQUIRED()), + ], ], [ - 'name' => 'required/prohibited hashtags with boost', - 'input' => '+#Cat -#hat^100', + 'name' => 'required/prohibited hashtags with boost', + 'input' => '+#Cat -#hat^100', 'expected_tokens' => [ T::T_REQUIRED, [T::T_HASHTAG, 'Cat'], @@ -437,15 +438,15 @@ T::T_BOOST, [T::T_NUMBER, 100.0], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Hashtag('Cat', BoolOperator::REQUIRED()), - new Hashtag('hat', BoolOperator::PROHIBITED(), true, Hashtag::MAX_BOOST) - ] + new Hashtag('hat', BoolOperator::PROHIBITED(), true, Hashtag::MAX_BOOST), + ], ], [ - 'name' => 'required/prohibited hashtags with fuzzy', - 'input' => '#hat~100 #hat~100.1', + 'name' => 'required/prohibited hashtags with fuzzy', + 'input' => '#hat~100 #hat~100.1', 'expected_tokens' => [ [T::T_HASHTAG, 'hat'], T::T_FUZZY, @@ -454,15 +455,15 @@ T::T_FUZZY, [T::T_NUMBER, 100.1], ], - 'expected_nodes' => [ + 'expected_nodes' => [ + new Hashtag('hat', BoolOperator::REQUIRED()), new Hashtag('hat', BoolOperator::REQUIRED()), - new Hashtag('hat', BoolOperator::REQUIRED()) - ] + ], ], [ - 'name' => 'required/prohibited hashtags with boost', - 'input' => '+#Cat -#hat^100 #_cat #2015cat__', + 'name' => 'required/prohibited hashtags with boost', + 'input' => '+#Cat -#hat^100 #_cat #2015cat__', 'expected_tokens' => [ T::T_REQUIRED, [T::T_HASHTAG, 'Cat'], @@ -473,28 +474,28 @@ [T::T_HASHTAG, '_cat'], [T::T_HASHTAG, '2015cat__'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Hashtag('Cat', BoolOperator::REQUIRED()), new Hashtag('hat', BoolOperator::PROHIBITED(), true, Hashtag::MAX_BOOST), new Hashtag('_cat', BoolOperator::REQUIRED()), new Hashtag('2015cat__', BoolOperator::REQUIRED()), - ] + ], ], // todo: should we refactor to catch #hashtag#hashtag or @mention#tag or #tag@mention? [ - 'name' => 'hashtag on hashtag and double hashtag', - 'input' => '#cat#cat ##cat #####cat', + 'name' => 'hashtag on hashtag and double hashtag', + 'input' => '#cat#cat ##cat #####cat', 'expected_tokens' => [ [T::T_WORD, 'cat#cat'], [T::T_HASHTAG, 'cat'], [T::T_HASHTAG, 'cat'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('cat#cat'), new Hashtag('cat', BoolOperator::REQUIRED()), new Hashtag('cat', BoolOperator::REQUIRED()), - ] + ], ], /* * END: HASHTAGS @@ -505,26 +506,26 @@ * START: MENTIONS */ [ - 'name' => 'simple mentions', - 'input' => '@user @user_name @user.name @user-name', + 'name' => 'simple mentions', + 'input' => '@user @user_name @user.name @user-name', 'expected_tokens' => [ [T::T_MENTION, 'user'], [T::T_MENTION, 'user_name'], [T::T_MENTION, 'user.name'], [T::T_MENTION, 'user-name'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Mention('user', BoolOperator::REQUIRED()), new Mention('user_name', BoolOperator::REQUIRED()), new Mention('user.name', BoolOperator::REQUIRED()), new Mention('user-name', BoolOperator::REQUIRED()), - ] + ], ], [ - 'name' => 'required mentions', - 'input' => '+@user +@user_name +@user.name +@user-name', + 'name' => 'required mentions', + 'input' => '+@user +@user_name +@user.name +@user-name', 'expected_tokens' => [ T::T_REQUIRED, [T::T_MENTION, 'user'], @@ -535,17 +536,17 @@ T::T_REQUIRED, [T::T_MENTION, 'user-name'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Mention('user', BoolOperator::REQUIRED()), new Mention('user_name', BoolOperator::REQUIRED()), new Mention('user.name', BoolOperator::REQUIRED()), new Mention('user-name', BoolOperator::REQUIRED()), - ] + ], ], [ - 'name' => 'prohibited mentions', - 'input' => '-@user -@user_name -@user.name -@user-name', + 'name' => 'prohibited mentions', + 'input' => '-@user -@user_name -@user.name -@user-name', 'expected_tokens' => [ T::T_PROHIBITED, [T::T_MENTION, 'user'], @@ -556,56 +557,56 @@ T::T_PROHIBITED, [T::T_MENTION, 'user-name'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Mention('user', BoolOperator::PROHIBITED()), new Mention('user_name', BoolOperator::PROHIBITED()), new Mention('user.name', BoolOperator::PROHIBITED()), new Mention('user-name', BoolOperator::PROHIBITED()), - ] + ], ], [ - 'name' => 'mentions with emails and hashtags', - 'input' => '@john@doe.com @john#doe', + 'name' => 'mentions with emails and hashtags', + 'input' => '@john@doe.com @john#doe', 'expected_tokens' => [ [T::T_WORD, 'john@doe.com'], [T::T_WORD, 'john#doe'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('john@doe.com'), new Word('john#doe'), - ] + ], ], [ - 'name' => 'mentions with punctuation', - 'input' => '@john. @wtf! @who?', + 'name' => 'mentions with punctuation', + 'input' => '@john. @wtf! @who?', 'expected_tokens' => [ [T::T_MENTION, 'john'], [T::T_MENTION, 'wtf'], [T::T_MENTION, 'who'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Mention('john', BoolOperator::REQUIRED()), new Mention('wtf', BoolOperator::REQUIRED()), new Mention('who', BoolOperator::REQUIRED()), - ] + ], ], [ - 'name' => 'mentions with special chars', - 'input' => '@john^doe @john!doe', + 'name' => 'mentions with special chars', + 'input' => '@john^doe @john!doe', 'expected_tokens' => [ [T::T_MENTION, 'john'], T::T_BOOST, [T::T_WORD, 'doe'], [T::T_WORD, 'john!doe'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Mention('john', BoolOperator::REQUIRED()), new Word('doe'), new Word('john!doe'), - ] + ], ], /* * END: MENTIONS @@ -616,38 +617,38 @@ * START: NUMBERS */ [ - 'name' => 'integers, decimals and exponential form', - 'input' => '100 3.1415926535898 2.2E-5', + 'name' => 'integers, decimals and exponential form', + 'input' => '100 3.1415926535898 2.2E-5', 'expected_tokens' => [ [T::T_NUMBER, 100.0], [T::T_NUMBER, 3.1415926535898], [T::T_NUMBER, 2.2E-5], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Numbr(100.0), new Numbr(3.1415926535898), new Numbr(2.2E-5), - ] + ], ], [ - 'name' => 'negative integers, decimals and exponential form', - 'input' => '-100 -3.1415926535898 -2.2E-5', + 'name' => 'negative integers, decimals and exponential form', + 'input' => '-100 -3.1415926535898 -2.2E-5', 'expected_tokens' => [ [T::T_NUMBER, -100.0], [T::T_NUMBER, -3.1415926535898], [T::T_NUMBER, -2.2E-5], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Numbr(-100.0), new Numbr(-3.1415926535898), new Numbr(-2.2E-5), - ] + ], ], [ - 'name' => 'words with boosted numbers', - 'input' => 'word^100 word^3.1415926535898 word^2.2E-5', + 'name' => 'words with boosted numbers', + 'input' => 'word^100 word^3.1415926535898 word^2.2E-5', 'expected_tokens' => [ [T::T_WORD, 'word'], T::T_BOOST, @@ -659,16 +660,16 @@ T::T_BOOST, [T::T_NUMBER, 2.2E-5], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('word', null, true, 10.0), new Word('word', null, true, 3.1415926535898), new Word('word', null, true, 2.2E-5), - ] + ], ], [ - 'name' => 'words with boosted negative numbers', - 'input' => 'word^-100 word^-3.1415926535898 word^-2.2E-5', + 'name' => 'words with boosted negative numbers', + 'input' => 'word^-100 word^-3.1415926535898 word^-2.2E-5', 'expected_tokens' => [ [T::T_WORD, 'word'], T::T_BOOST, @@ -680,16 +681,16 @@ T::T_BOOST, [T::T_NUMBER, -2.2E-5], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('word', null, true, 0.0), new Word('word', null, true, 0.0), new Word('word', null, true, 0.0), - ] + ], ], [ - 'name' => 'words with fuzzy numbers', - 'input' => 'word~100 word~3.1415926535898 word~2.2E-5', + 'name' => 'words with fuzzy numbers', + 'input' => 'word~100 word~3.1415926535898 word~2.2E-5', 'expected_tokens' => [ [T::T_WORD, 'word'], T::T_FUZZY, @@ -701,16 +702,16 @@ T::T_FUZZY, [T::T_NUMBER, 2.2E-5], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('word', null, false, Word::DEFAULT_BOOST, true, Word::MAX_FUZZY), new Word('word', null, false, Word::DEFAULT_BOOST, true, Word::MAX_FUZZY), new Word('word', null, false, Word::DEFAULT_BOOST, true, Word::MIN_FUZZY), - ] + ], ], [ - 'name' => 'words with fuzzy negative numbers', - 'input' => 'word~-100 word~-3.1415926535898 word~-2.2E-5', + 'name' => 'words with fuzzy negative numbers', + 'input' => 'word~-100 word~-3.1415926535898 word~-2.2E-5', 'expected_tokens' => [ [T::T_WORD, 'word'], T::T_FUZZY, @@ -722,11 +723,11 @@ T::T_FUZZY, [T::T_NUMBER, -2.2E-5], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('word', null, false, Word::DEFAULT_BOOST, true, Word::MIN_FUZZY), new Word('word', null, false, Word::DEFAULT_BOOST, true, Word::MIN_FUZZY), new Word('word', null, false, Word::DEFAULT_BOOST, true, Word::MIN_FUZZY), - ] + ], ], /* * END: NUMBERS @@ -737,8 +738,8 @@ * START: FIELDS */ [ - 'name' => 'fields with hypen, underscore and dot', - 'input' => '+first-name:homer -last_name:simpson job.performance:poor^5', + 'name' => 'fields with hypen, underscore and dot', + 'input' => '+first-name:homer -last_name:simpson job.performance:poor^5', 'expected_tokens' => [ T::T_REQUIRED, [T::T_FIELD_START, 'first-name'], @@ -754,41 +755,41 @@ T::T_BOOST, [T::T_NUMBER, 5.0], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Field('first-name', new Word('homer'), BoolOperator::REQUIRED(), false, Field::DEFAULT_BOOST), new Field('last_name', new Word('simpson'), BoolOperator::PROHIBITED(), false, Field::DEFAULT_BOOST), new Field('job.performance', new Word('poor'), null, true, 5.0), - ] + ], ], [ - 'name' => 'field with field in it', - 'input' => 'field:subfield:what', + 'name' => 'field with field in it', + 'input' => 'field:subfield:what', 'expected_tokens' => [ [T::T_FIELD_START, 'field'], [T::T_WORD, 'subfield:what'], T::T_FIELD_END, ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Field('field', new Word('subfield:what'), null, false, Field::DEFAULT_BOOST), - ] + ], ], [ - 'name' => 'field with no value', - 'input' => 'field:', + 'name' => 'field with no value', + 'input' => 'field:', 'expected_tokens' => [ [T::T_FIELD_START, 'field'], T::T_FIELD_END, ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('field'), - ] + ], ], [ - 'name' => 'field with phrases', - 'input' => 'field:"boosted^5 +required"^1 -field:"[1..5]"~4', + 'name' => 'field with phrases', + 'input' => 'field:"boosted^5 +required"^1 -field:"[1..5]"~4', 'expected_tokens' => [ [T::T_FIELD_START, 'field'], [T::T_PHRASE, 'boosted^5 +required'], @@ -802,15 +803,15 @@ T::T_FUZZY, [T::T_NUMBER, 4.0], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Field('field', new Phrase('boosted^5 +required'), null, true, 1.0), new Field('field', new Phrase('[1..5]'), BoolOperator::PROHIBITED(), false, Field::DEFAULT_BOOST), - ] + ], ], [ - 'name' => 'field with greater/less than', - 'input' => 'field:>100 field:>=100.1 field:<100 field:<=100.1', + 'name' => 'field with greater/less than', + 'input' => 'field:>100 field:>=100.1 field:<100 field:<=100.1', 'expected_tokens' => [ [T::T_FIELD_START, 'field'], T::T_GREATER_THAN, @@ -831,17 +832,17 @@ [T::T_NUMBER, 100.1], T::T_FIELD_END, ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Field('field', new Numbr(100, ComparisonOperator::GT()), null, false, Field::DEFAULT_BOOST), new Field('field', new Numbr(100.1, ComparisonOperator::GTE()), null, false, Field::DEFAULT_BOOST), new Field('field', new Numbr(100, ComparisonOperator::LT()), null, false, Field::DEFAULT_BOOST), new Field('field', new Numbr(100.1, ComparisonOperator::LTE()), null, false, Field::DEFAULT_BOOST), - ] + ], ], [ - 'name' => 'field with a hashtag or mention', - 'input' => 'field:#cats field:@user.name', + 'name' => 'field with a hashtag or mention', + 'input' => 'field:#cats field:@user.name', 'expected_tokens' => [ [T::T_FIELD_START, 'field'], [T::T_HASHTAG, 'cats'], @@ -850,15 +851,15 @@ [T::T_MENTION, 'user.name'], T::T_FIELD_END, ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Field('field', new Hashtag('cats', BoolOperator::REQUIRED()), null, false, Field::DEFAULT_BOOST), new Field('field', new Mention('user.name', BoolOperator::REQUIRED()), null, false, Field::DEFAULT_BOOST), - ] + ], ], [ - 'name' => 'field with inclusive range', - 'input' => 'field:[1..5] +field:[1 TO 5]', + 'name' => 'field with inclusive range', + 'input' => 'field:[1..5] +field:[1 TO 5]', 'expected_tokens' => [ [T::T_FIELD_START, 'field'], T::T_RANGE_INCL_START, @@ -876,7 +877,7 @@ T::T_RANGE_INCL_END, T::T_FIELD_END, ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Field( 'field', new NumberRange( @@ -897,12 +898,12 @@ false, Field::DEFAULT_BOOST ), - ] + ], ], [ - 'name' => 'field with exclusive range', - 'input' => 'field:{1.1..5.5} +field:{1.1 TO 5.5}', + 'name' => 'field with exclusive range', + 'input' => 'field:{1.1..5.5} +field:{1.1 TO 5.5}', 'expected_tokens' => [ [T::T_FIELD_START, 'field'], T::T_RANGE_EXCL_START, @@ -920,7 +921,7 @@ T::T_RANGE_EXCL_END, T::T_FIELD_END, ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Field( 'field', new NumberRange( @@ -943,12 +944,12 @@ false, Field::DEFAULT_BOOST ), - ] + ], ], [ - 'name' => 'field with subquery', - 'input' => 'field:(cat OR dog) test', + 'name' => 'field with subquery', + 'input' => 'field:(cat OR dog) test', 'expected_tokens' => [ [T::T_FIELD_START, 'field'], T::T_SUBQUERY_START, @@ -959,24 +960,24 @@ T::T_FIELD_END, [T::T_WORD, 'test'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Field( 'field', new Subquery([ new Word('cat'), - new Word('dog') + new Word('dog'), ]), null, false, Field::DEFAULT_BOOST ), new Word('test'), - ] + ], ], [ - 'name' => 'field with range in subquery', - 'input' => 'field:(cat OR 1..5)', + 'name' => 'field with range in subquery', + 'input' => 'field:(cat OR 1..5)', 'expected_tokens' => [ [T::T_FIELD_START, 'field'], T::T_SUBQUERY_START, @@ -987,24 +988,24 @@ T::T_SUBQUERY_END, T::T_FIELD_END, ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Field( 'field', new Subquery([ new Word('cat'), new Numbr(1.0), - new Numbr(5.0) + new Numbr(5.0), ]), null, false, Field::DEFAULT_BOOST ), - ] + ], ], [ - 'name' => 'field with dates', - 'input' => 'field:2015-12-18 field:>2015-12-18 field:<2015-12-18 field:>=2015-12-18 field:<=2015-12-18', + 'name' => 'field with dates', + 'input' => 'field:2015-12-18 field:>2015-12-18 field:<2015-12-18 field:>=2015-12-18 field:<=2015-12-18', 'expected_tokens' => [ [T::T_FIELD_START, 'field'], [T::T_DATE, '2015-12-18'], @@ -1028,7 +1029,7 @@ [T::T_DATE, '2015-12-18'], T::T_FIELD_END, ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Field( 'field', new Date('2015-12-18'), @@ -1096,12 +1097,12 @@ false, Field::DEFAULT_BOOST ), - ] + ], ], [ - 'name' => 'field leading _ and uuid', - 'input' => '_id:a9fc3e46-150a-45cd-ad39-c80f93119900^5', + 'name' => 'field leading _ and uuid', + 'input' => '_id:a9fc3e46-150a-45cd-ad39-c80f93119900^5', 'expected_tokens' => [ [T::T_FIELD_START, '_id'], [T::T_WORD, 'a9fc3e46-150a-45cd-ad39-c80f93119900'], @@ -1109,14 +1110,14 @@ T::T_BOOST, [T::T_NUMBER, 5.0], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Field('_id', new Word('a9fc3e46-150a-45cd-ad39-c80f93119900'), null, true, 5.0), - ] + ], ], [ - 'name' => 'field with mentions and emails', - 'input' => 'email:john@doe.com -user:@twitterz', + 'name' => 'field with mentions and emails', + 'input' => 'email:john@doe.com -user:@twitterz', 'expected_tokens' => [ [T::T_FIELD_START, 'email'], [T::T_WORD, 'john@doe.com'], @@ -1126,7 +1127,7 @@ [T::T_MENTION, 'twitterz'], T::T_FIELD_END, ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Field('email', new Word('john@doe.com'), null, false, Field::DEFAULT_BOOST), new Field( 'user', @@ -1135,12 +1136,12 @@ false, Field::DEFAULT_BOOST ), - ] + ], ], [ - 'name' => 'field with hashtags', - 'input' => 'tags:#cats tags:(#cats || #dogs)', + 'name' => 'field with hashtags', + 'input' => 'tags:#cats tags:(#cats || #dogs)', 'expected_tokens' => [ [T::T_FIELD_START, 'tags'], [T::T_HASHTAG, 'cats'], @@ -1153,7 +1154,7 @@ T::T_SUBQUERY_END, T::T_FIELD_END, ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Field( 'tags', new Hashtag('cats', BoolOperator::REQUIRED()), @@ -1171,7 +1172,7 @@ false, Field::DEFAULT_BOOST ), - ] + ], ], /* * END: FIELDS @@ -1182,25 +1183,25 @@ * START: WORDS */ [ - 'name' => 'word with hashtag or mention in it', - 'input' => 'omg#lol omg@user @mention#tag #tag@mention', + 'name' => 'word with hashtag or mention in it', + 'input' => 'omg#lol omg@user @mention#tag #tag@mention', 'expected_tokens' => [ [T::T_WORD, 'omg#lol'], [T::T_WORD, 'omg@user'], [T::T_WORD, 'mention#tag'], [T::T_WORD, 'tag@mention'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('omg#lol'), new Word('omg@user'), new Word('mention#tag'), new Word('tag@mention'), - ] + ], ], [ - 'name' => 'required/prohibited words', - 'input' => '+c.h.u.d. -zombieland +ac/dc^5', + 'name' => 'required/prohibited words', + 'input' => '+c.h.u.d. -zombieland +ac/dc^5', 'expected_tokens' => [ T::T_REQUIRED, [T::T_WORD, 'c.h.u.d'], @@ -1211,16 +1212,16 @@ T::T_BOOST, [T::T_NUMBER, 5.0], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('c.h.u.d', BoolOperator::REQUIRED()), new Word('zombieland', BoolOperator::PROHIBITED()), new Word('ac/dc', BoolOperator::REQUIRED(), true, 5.0), - ] + ], ], [ - 'name' => 'words that have embedded operators', - 'input' => 'cANDy AND OReos || dANDy && chORes^5', + 'name' => 'words that have embedded operators', + 'input' => 'cANDy AND OReos || dANDy && chORes^5', 'expected_tokens' => [ [T::T_WORD, 'cANDy'], T::T_AND, @@ -1232,12 +1233,12 @@ T::T_BOOST, [T::T_NUMBER, 5.0], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('cANDy', BoolOperator::REQUIRED()), new Word('OReos', BoolOperator::REQUIRED()), new Word('dANDy', BoolOperator::REQUIRED()), new Word('chORes', BoolOperator::REQUIRED(), true, 5.0), - ] + ], ], /* * END: WORDS @@ -1248,8 +1249,8 @@ * START: DATES */ [ - 'name' => 'dates in string', - 'input' => '2000-01-01 >=2000-01-01 (+2015-12-18) -2015-12-18', + 'name' => 'dates in string', + 'input' => '2000-01-01 >=2000-01-01 (+2015-12-18) -2015-12-18', 'expected_tokens' => [ [T::T_DATE, '2000-01-01'], [T::T_DATE, '2000-01-01'], @@ -1260,28 +1261,28 @@ T::T_PROHIBITED, [T::T_DATE, '2015-12-18'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Date('2000-01-01'), new Date('2000-01-01'), new Date('2015-12-18', BoolOperator::REQUIRED()), new Date('2015-12-18', BoolOperator::PROHIBITED()), - ] + ], ], [ - 'name' => 'dates on dates', - 'input' => '2000-01-012000-01-01 2000-01-01^2000-01-01', + 'name' => 'dates on dates', + 'input' => '2000-01-012000-01-01 2000-01-01^2000-01-01', 'expected_tokens' => [ [T::T_WORD, '2000-01-012000-01-01'], [T::T_DATE, '2000-01-01'], T::T_BOOST, [T::T_DATE, '2000-01-01'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('2000-01-012000-01-01'), new Date('2000-01-01'), new Date('2000-01-01'), - ] + ], ], /* * END: DATES @@ -1292,24 +1293,24 @@ * START: ACCENTED CHARS */ [ - 'name' => 'accents and hyphens', - 'input' => '+Beyoncé Giselle Knowles-Carter', + 'name' => 'accents and hyphens', + 'input' => '+Beyoncé Giselle Knowles-Carter', 'expected_tokens' => [ T::T_REQUIRED, [T::T_WORD, 'Beyoncé'], [T::T_WORD, 'Giselle'], [T::T_WORD, 'Knowles-Carter'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('Beyoncé', BoolOperator::REQUIRED()), new Word('Giselle'), new Word('Knowles-Carter'), - ] + ], ], [ - 'name' => 'accents and hyphen spice', - 'input' => 'J. Lo => Emme Maribel Muñiz $p0rty-spicé', + 'name' => 'accents and hyphen spice', + 'input' => 'J. Lo => Emme Maribel Muñiz $p0rty-spicé', 'expected_tokens' => [ [T::T_WORD, 'J'], [T::T_WORD, 'Lo'], @@ -1318,14 +1319,14 @@ [T::T_WORD, 'Muñiz'], [T::T_WORD, '$p0rty-spicé'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('J'), new Word('Lo'), new Word('Emme'), new Word('Maribel'), new Word('Muñiz'), new Word('$p0rty-spicé'), - ] + ], ], /* * END: ACCENTED CHARS @@ -1336,8 +1337,8 @@ * START: RAPPERS and POP STARS */ [ - 'name' => 'crazy a$$ names', - 'input' => 'p!nk AND K$sha in a tr33 with 50¢', + 'name' => 'crazy a$$ names', + 'input' => 'p!nk AND K$sha in a tr33 with 50¢', 'expected_tokens' => [ [T::T_WORD, 'p!nk'], T::T_AND, @@ -1348,7 +1349,7 @@ [T::T_WORD, 'with'], [T::T_WORD, '50¢'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('p!nk', BoolOperator::REQUIRED()), new Word('K$sha', BoolOperator::REQUIRED()), new Word('in'), @@ -1356,12 +1357,12 @@ new Word('tr33'), new Word('with'), new Word('50¢'), - ] + ], ], [ - 'name' => 'my name is math(ish)', - 'input' => '+florence+machine ac/dc^11 Stellastarr* T\'Pau ​¡Forward, Russia! "¡Forward, Russia!"~', + 'name' => 'my name is math(ish)', + 'input' => '+florence+machine ac/dc^11 Stellastarr* T\'Pau ​¡Forward, Russia! "¡Forward, Russia!"~', 'expected_tokens' => [ T::T_REQUIRED, [T::T_WORD, 'florence+machine'], @@ -1376,7 +1377,7 @@ [T::T_PHRASE, '¡Forward, Russia!'], T::T_FUZZY, ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('florence+machine', BoolOperator::REQUIRED()), new Word('ac/dc', null, true, Word::MAX_BOOST), new Word('Stellastarr', null, false, Word::DEFAULT_BOOST, false, Word::DEFAULT_FUZZY, true), @@ -1384,7 +1385,7 @@ new Word('​¡Forward'), new Word('Russia'), new Phrase('¡Forward, Russia!', null, false, Phrase::DEFAULT_BOOST, true, Phrase::DEFAULT_FUZZY), - ] + ], ], /* * END: RAPPERS and POP STARS @@ -1395,8 +1396,8 @@ * START: SUBQUERIES */ [ - 'name' => 'mismatched subqueries', - 'input' => ') test (123 (abc f:a)', + 'name' => 'mismatched subqueries', + 'input' => ') test (123 (abc f:a)', 'expected_tokens' => [ [T::T_WORD, 'test'], T::T_SUBQUERY_START, @@ -1405,15 +1406,15 @@ [T::T_WORD, 'f:a'], T::T_SUBQUERY_END, ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('test'), new Subquery([new Numbr(123.0), new Word('abc'), new Word('f:a')]), - ] + ], ], [ - 'name' => 'filter inside of subquery', - 'input' => 'word(word:a>(#hashtag:b)', + 'name' => 'filter inside of subquery', + 'input' => 'word(word:a>(#hashtag:b)', 'expected_tokens' => [ [T::T_WORD, 'word'], T::T_SUBQUERY_START, @@ -1421,15 +1422,15 @@ [T::T_WORD, 'hashtag:b'], T::T_SUBQUERY_END, ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('word'), new Subquery([new Word('word:a'), new Word('hashtag:b')]), - ] + ], ], [ - 'name' => 'booleans before and in subqueries', - 'input' => '"ipad pro" AND (gold OR silver)', + 'name' => 'booleans before and in subqueries', + 'input' => '"ipad pro" AND (gold OR silver)', 'expected_tokens' => [ [T::T_PHRASE, 'ipad pro'], T::T_AND, @@ -1439,15 +1440,15 @@ [T::T_WORD, 'silver'], T::T_SUBQUERY_END, ], - 'expected_nodes' => [ + '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)', + 'name' => 'booleans before and in subqueries 2', + 'input' => '"iphone 7" -(16gb OR 32gb)', 'expected_tokens' => [ [T::T_PHRASE, 'iphone 7'], T::T_PROHIBITED, @@ -1457,10 +1458,10 @@ [T::T_WORD, '32gb'], T::T_SUBQUERY_END, ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Phrase('iphone 7'), new Subquery([new Word('16gb'), new Word('32gb')], BoolOperator::PROHIBITED()), - ] + ], ], /* * END: SUBQUERIES @@ -1471,8 +1472,8 @@ * START: WEIRD QUERIES */ [ - 'name' => 'whip nae nae', - 'input' => 'Watch Me (Whip/Nae Nae)', + 'name' => 'whip nae nae', + 'input' => 'Watch Me (Whip/Nae Nae)', 'expected_tokens' => [ [T::T_WORD, 'Watch'], [T::T_WORD, 'Me'], @@ -1481,31 +1482,31 @@ [T::T_WORD, 'Nae'], T::T_SUBQUERY_END, ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('Watch'), new Word('Me'), new Subquery([new Word('Whip/Nae'), new Word('Nae')]), - ] + ], ], [ - 'name' => 'epic or fail', - 'input' => 'epic or fail', + 'name' => 'epic or fail', + 'input' => 'epic or fail', 'expected_tokens' => [ [T::T_WORD, 'epic'], [T::T_WORD, 'or'], [T::T_WORD, 'fail'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('epic'), new Word('or'), new Word('fail'), - ] + ], ], [ - 'name' => 'use of || then and required subquery', - 'input' => 'test || AND what (+test)', + 'name' => 'use of || then and required subquery', + 'input' => 'test || AND what (+test)', 'expected_tokens' => [ [T::T_WORD, 'test'], T::T_OR, @@ -1516,16 +1517,16 @@ [T::T_WORD, 'test'], T::T_SUBQUERY_END, ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('test'), new Word('what', BoolOperator::REQUIRED()), new Word('test', BoolOperator::REQUIRED()), - ] + ], ], [ - 'name' => 'mega subqueries, all non-sensical', - 'input' => 'test OR ( ( 1 ) OR ( ( 2 ) ) OR ( ( ( 3.14 ) ) ) OR a OR +b ) OR +field:>1', + 'name' => 'mega subqueries, all non-sensical', + 'input' => 'test OR ( ( 1 ) OR ( ( 2 ) ) OR ( ( ( 3.14 ) ) ) OR a OR +b ) OR +field:>1', 'expected_tokens' => [ [T::T_WORD, 'test'], T::T_OR, @@ -1552,7 +1553,7 @@ [T::T_NUMBER, 1.0], T::T_FIELD_END, ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('test'), new Numbr(1), new Numbr(2), @@ -1565,33 +1566,33 @@ BoolOperator::REQUIRED(), false, Field::DEFAULT_BOOST - ) - ] + ), + ], ], [ - 'name' => 'common dotted things', - 'input' => 'R.I.P. Motörhead', + 'name' => 'common dotted things', + 'input' => 'R.I.P. Motörhead', 'expected_tokens' => [ [T::T_WORD, 'R.I.P'], [T::T_WORD, 'Motörhead'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('R.I.P'), new Word('Motörhead'), - ] + ], ], [ - 'name' => 'ignored chars', - 'input' => '!!! ! $ _ . ; %', + 'name' => 'ignored chars', + 'input' => '!!! ! $ _ . ; %', 'expected_tokens' => [], - 'expected_nodes' => [] + 'expected_nodes' => [], ], [ - 'name' => 'elastic search example 1', - 'input' => '"john smith"^2 (foo bar)^4', + 'name' => 'elastic search example 1', + 'input' => '"john smith"^2 (foo bar)^4', 'expected_tokens' => [ [T::T_PHRASE, 'john smith'], T::T_BOOST, @@ -1603,15 +1604,15 @@ T::T_BOOST, [T::T_NUMBER, 4.0], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Phrase('john smith', null, true, 2.0), new Subquery([new Word('foo'), new Word('bar')], null, true, 4.0), - ] + ], ], [ - 'name' => 'intentionally mutant', - 'input' => '[blah "[[shortcode]]" akd_ -gj% ! @* (+=} --> ;\' ;\' 'intentionally mutanterer', + 'input' => 'a"b"#c"#d e', 'expected_tokens' => [ [T::T_WORD, 'a"b"#c"#d'], [T::T_WORD, 'e'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('a"b"#c"#d'), new Word('e'), - ] + ], ], [ - 'name' => 'xss1', - 'input' => '', + 'name' => 'xss1', + 'input' => '', 'expected_tokens' => [ [T::T_WORD, 'IMG'], [T::T_WORD, 'SRC'], @@ -1707,53 +1708,53 @@ [T::T_WORD, 'test2'], T::T_SUBQUERY_END, ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('IMG'), new Word('SRC'), new Word('jAvascript:alert'), new Word('test2'), - ] + ], ], [ - 'name' => 'should not be required', - 'input' => 'token + token', + 'name' => 'should not be required', + 'input' => 'token + token', 'expected_tokens' => [ [T::T_WORD, 'token'], [T::T_WORD, 'token'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('token'), new Word('token'), - ] + ], ], [ - 'name' => 'should not be prohibited', - 'input' => 'token - token', + 'name' => 'should not be prohibited', + 'input' => 'token - token', 'expected_tokens' => [ [T::T_WORD, 'token'], [T::T_WORD, 'token'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('token'), new Word('token'), - ] + ], ], [ - 'name' => 'should not be boosted', - 'input' => 'token ^5 token', + 'name' => 'should not be boosted', + 'input' => 'token ^5 token', 'expected_tokens' => [ [T::T_WORD, 'token'], [T::T_NUMBER, 5.0], [T::T_WORD, 'token'], ], - 'expected_nodes' => [ + 'expected_nodes' => [ new Word('token'), new Numbr(5.0), new Word('token'), - ] + ], ], /* * END: WEIRD QUERIES diff --git a/tests/QueryParserTest.php b/tests/QueryParserTest.php index b7285e9..af59767 100755 --- a/tests/QueryParserTest.php +++ b/tests/QueryParserTest.php @@ -1,10 +1,12 @@ parser->parse($input); $this->assertEquals($expectedNodes, $result->getNodes(), "Test query [{$name}] with input [{$input}] failed."); @@ -31,8 +33,8 @@ public function testParse($name, $input, $ignored, array $expectedNodes = []) /** * @return array */ - public function getTestQueries() + public function getTestQueries(): array { - return require __DIR__.'/Fixtures/test-queries.php'; + return require __DIR__ . '/Fixtures/test-queries.php'; } } diff --git a/tests/TokenizerTest.php b/tests/TokenizerTest.php index f4270d1..30a049d 100755 --- a/tests/TokenizerTest.php +++ b/tests/TokenizerTest.php @@ -1,11 +1,13 @@ tokenizer = new Tokenizer(); } - public function testOnlyWhitespace() + public function testOnlyWhitespace(): void { $this->assertEquals([], $this->tokenizer->scan(' ')->getTokens()); } @@ -25,9 +27,9 @@ public function testOnlyWhitespace() * * @param string $name * @param string $input - * @param array $expectedTokens + * @param array $expectedTokens */ - public function testScan($name, $input, array $expectedTokens) + public function testScan(string $name, string $input, array $expectedTokens): void { // convert the sample 'expected' into token objects. foreach ($expectedTokens as $k => $v) { @@ -46,8 +48,8 @@ public function testScan($name, $input, array $expectedTokens) /** * @return array */ - public function getTestQueries() + public function getTestQueries(): array { - return require __DIR__.'/Fixtures/test-queries.php'; + return require __DIR__ . '/Fixtures/test-queries.php'; } }