diff --git a/CHANGELOG.md b/CHANGELOG.md index e290b2818..dfefb8b91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added union type declarations to method signatures - Solarium\Core\Query\Helper::formatDate() throws a `TypeError` instead of returning `false` if called with an incompatibly typed parameter - Managed resources queries no longer work around SOLR-6853 by default. Set the 'useDoubleEncoding' option to `true` if this bug affects you. +- Solarium codebase is now analysed at PHPStan level 2 ### Removed - Solarium\Component\Result\Stats\FacetValue::getFacets(), always returned `null` diff --git a/composer.json b/composer.json index 385ee5cbc..71a524125 100755 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "nyholm/psr7": "^1.8", "php-http/guzzle7-adapter": "^1.0", "phpstan/extension-installer": "^1.4", - "phpstan/phpstan": "^2.1", + "phpstan/phpstan": "^2.1.41", "phpstan/phpstan-deprecation-rules": "^2.0", "phpstan/phpstan-phpunit": "^2.0", "phpunit/phpunit": "^10.5", diff --git a/phpstan.dist.neon b/phpstan.dist.neon index 31f6166b6..d251c6ff0 100644 --- a/phpstan.dist.neon +++ b/phpstan.dist.neon @@ -1,5 +1,9 @@ parameters: - level: 1 + level: 2 + reportIgnoresWithoutComments: true paths: - src - tests + universalObjectCratesClasses: + - Solarium\Core\Query\DocumentInterface + - Solarium\Core\Query\Result\QueryType diff --git a/src/Builder/Analytics/AnalyticsExpressionVisitor.php b/src/Builder/Analytics/AnalyticsExpressionVisitor.php index fe67f32e7..c43cc225c 100644 --- a/src/Builder/Analytics/AnalyticsExpressionVisitor.php +++ b/src/Builder/Analytics/AnalyticsExpressionVisitor.php @@ -42,6 +42,10 @@ public function dispatch(ExpressionInterface $expr) /** * {@inheritdoc} + * + * @param ExpressionInterface&FunctionInterface $expression + * + * @return mixed */ public function walkExpression(ExpressionInterface $expression) { diff --git a/src/Builder/Analytics/FunctionBuilder.php b/src/Builder/Analytics/FunctionBuilder.php index 517f5daf0..5e7ca5e37 100644 --- a/src/Builder/Analytics/FunctionBuilder.php +++ b/src/Builder/Analytics/FunctionBuilder.php @@ -12,6 +12,7 @@ namespace Solarium\Builder\Analytics; use Solarium\Builder\ExpressionInterface; +use Solarium\Builder\FunctionInterface; /** * FunctionBuilder. @@ -20,7 +21,7 @@ */ class FunctionBuilder { - private ExpressionInterface $function; + private ExpressionInterface&FunctionInterface $function; private static ?ExpressionBuilder $expressionBuilder = null; @@ -45,11 +46,11 @@ public static function expr(): ExpressionBuilder } /** - * @param ExpressionInterface $function + * @param ExpressionInterface&FunctionInterface $function * * @return self Provides fluent interface */ - public function where(ExpressionInterface $function): self + public function where(ExpressionInterface&FunctionInterface $function): self { $this->function = $function; @@ -57,9 +58,9 @@ public function where(ExpressionInterface $function): self } /** - * @return ExpressionInterface + * @return ExpressionInterface&FunctionInterface */ - public function getFunction(): ExpressionInterface + public function getFunction(): ExpressionInterface&FunctionInterface { return $this->function; } diff --git a/src/Component/ComponentAwareQueryInterface.php b/src/Component/ComponentAwareQueryInterface.php index f807c68fb..1172bc498 100644 --- a/src/Component/ComponentAwareQueryInterface.php +++ b/src/Component/ComponentAwareQueryInterface.php @@ -104,7 +104,7 @@ interface ComponentAwareQueryInterface /** * Get all registered component types. * - * @return array + * @return array An array of self::COMPONENT_* and/or self-registered keys */ public function getComponentTypes(): array; @@ -131,9 +131,9 @@ public function getComponents(): array; * You can optionally supply an autoload class to create a new component * instance if there is no registered component for the given key yet. * - * @param string $key Use one of the constants - * @param bool $autoload Autoload if component needs to be created - * @param array|null $config Configuration to use for autoload + * @param self::COMPONENT_*|string $key A self::COMPONENT_* or self-registered key + * @param bool $autoload Autoload if component needs to be created + * @param array|null $config Configuration to use for autoload * * @throws OutOfBoundsException * @@ -146,8 +146,8 @@ public function getComponent(string $key, ?bool $autoload = false, ?array $confi * * This overwrites any existing component registered with the same key. * - * @param string $key - * @param AbstractComponent $component + * @param self::COMPONENT_*|string $key A self::COMPONENT_* or self-registered key + * @param AbstractComponent $component * * @return self Provides fluent interface */ @@ -158,7 +158,7 @@ public function setComponent(string $key, AbstractComponent $component): self; * * You can remove a component by passing its key or the component instance. * - * @param string|AbstractComponent $component + * @param self::COMPONENT_*|string|AbstractComponent $component * * @return self Provides fluent interface */ diff --git a/src/Component/ComponentAwareQueryTrait.php b/src/Component/ComponentAwareQueryTrait.php index d4827295e..d052fb272 100644 --- a/src/Component/ComponentAwareQueryTrait.php +++ b/src/Component/ComponentAwareQueryTrait.php @@ -31,7 +31,7 @@ trait ComponentAwareQueryTrait /** * Get all registered component types. * - * @return array + * @return array An array of self::COMPONENT_* and/or self-registered keys */ public function getComponentTypes(): array { @@ -69,9 +69,9 @@ public function getComponents(): array * You can optionally supply an autoload class to create a new component * instance if there is no registered component for the given key yet. * - * @param string $key Use one of the constants - * @param bool $autoload Autoload if component needs to be created - * @param array|null $config Configuration to use for autoload + * @param self::COMPONENT_*|string $key A self::COMPONENT_* or self-registered key + * @param bool $autoload Autoload if component needs to be created + * @param array|null $config Configuration to use for autoload * * @throws OutOfBoundsException * @@ -104,8 +104,8 @@ public function getComponent(string $key, ?bool $autoload = false, ?array $confi * * This overwrites any existing component registered with the same key. * - * @param string $key - * @param AbstractComponent $component + * @param self::COMPONENT_*|string $key A self::COMPONENT_* or self-registered key + * @param AbstractComponent $component * * @return self Provides fluent interface */ @@ -122,7 +122,7 @@ public function setComponent(string $key, AbstractComponent $component): self * * You can remove a component by passing its key or the component instance. * - * @param string|AbstractComponent $component + * @param self::COMPONENT_*|string|AbstractComponent $component * * @return self Provides fluent interface */ diff --git a/src/Component/Facet/FieldValueParametersInterface.php b/src/Component/Facet/FieldValueParametersInterface.php index d91886c13..a58589c19 100644 --- a/src/Component/Facet/FieldValueParametersInterface.php +++ b/src/Component/Facet/FieldValueParametersInterface.php @@ -105,9 +105,7 @@ public function getMatches(): ?string; /** * Set the facet sort type. * - * Use one of the SORT_* constants as the value. - * - * @param string $sort + * @param self::SORT_* $sort */ public function setSort(string $sort): static; @@ -177,9 +175,7 @@ public function getMissing(): ?bool; /** * Set the facet method. * - * Use one of the METHOD_* constants as value. - * - * @param string $method + * @param self::METHOD_* $method */ public function setMethod(string $method): static; diff --git a/src/Component/Facet/FieldValueParametersTrait.php b/src/Component/Facet/FieldValueParametersTrait.php index 889a7b08b..b6bdf8cc1 100644 --- a/src/Component/Facet/FieldValueParametersTrait.php +++ b/src/Component/Facet/FieldValueParametersTrait.php @@ -105,9 +105,7 @@ public function getMatches(): ?string /** * Set the facet sort type. * - * Use one of the SORT_* constants as the value. - * - * @param string $sort + * @param self::SORT_* $sort */ public function setSort(string $sort): static { @@ -217,9 +215,7 @@ public function getMissing(): ?bool /** * Set the facet method. * - * Use one of the METHOD_* constants as value. - * - * @param string $method + * @param self::METHOD_* $method */ public function setMethod(string $method): static { diff --git a/src/Component/Facet/JsonFacetInterface.php b/src/Component/Facet/JsonFacetInterface.php index df35f5795..268258d30 100644 --- a/src/Component/Facet/JsonFacetInterface.php +++ b/src/Component/Facet/JsonFacetInterface.php @@ -14,7 +14,7 @@ * * @see https://solr.apache.org/guide/json-facet-api.html */ -interface JsonFacetInterface +interface JsonFacetInterface extends FacetInterface { /** * Serializes nested facets as option "facet" and returns that array structure. diff --git a/src/Component/Facet/JsonFacetTrait.php b/src/Component/Facet/JsonFacetTrait.php index 5bedd7d54..54c7596d4 100644 --- a/src/Component/Facet/JsonFacetTrait.php +++ b/src/Component/Facet/JsonFacetTrait.php @@ -171,6 +171,28 @@ public function addFacet(FacetInterface|array $facet): static throw new InvalidArgumentException('Only JSON facets can be nested.'); } + /** + * Get a facet. + * + * @param string $key + * + * @return JsonFacetInterface|null + */ + public function getFacet(string $key): ?JsonFacetInterface + { + return $this->facets[$key] ?? null; + } + + /** + * Get all facets. + * + * @return JsonFacetInterface[] + */ + public function getFacets(): array + { + return $this->facets; + } + /** * Remove a single facet. * diff --git a/src/Component/Facet/JsonTerms.php b/src/Component/Facet/JsonTerms.php index a04afc863..1e10a9648 100644 --- a/src/Component/Facet/JsonTerms.php +++ b/src/Component/Facet/JsonTerms.php @@ -171,7 +171,7 @@ public function getLimit(): ?int * * @see https://solr.apache.org/guide/json-facet-api.html#sorting-facets-by-nested-functions * - * @param string $sort + * @param self::SORT_*|string $sort */ public function setSort(string $sort): static { @@ -385,9 +385,7 @@ public function getPrefix(): ?string /** * Set the facet algorithm to use. * - * Use one of the METHOD_* constants as value. - * - * @param string $method + * @param self::METHOD_* $method */ public function setMethod(string $method): static { diff --git a/src/Component/Facet/Pivot.php b/src/Component/Facet/Pivot.php index 2b790650c..4207d32b7 100644 --- a/src/Component/Facet/Pivot.php +++ b/src/Component/Facet/Pivot.php @@ -120,9 +120,7 @@ public function getOffset(): ?int /** * Set the facet sort type. * - * Use one of the SORT_* constants as the value. - * - * @param string $sort + * @param self::SORT_* $sort */ public function setSort(string $sort): static { diff --git a/src/Component/FacetSet.php b/src/Component/FacetSet.php index ddf6845e1..d073f2596 100644 --- a/src/Component/FacetSet.php +++ b/src/Component/FacetSet.php @@ -9,7 +9,6 @@ namespace Solarium\Component; -use Solarium\Component\Facet\FacetInterface; use Solarium\Component\Facet\Field; use Solarium\Component\Facet\FieldValueParametersInterface; use Solarium\Component\Facet\FieldValueParametersTrait; @@ -116,9 +115,9 @@ public function getExtractFromResponse(): ?bool * @param string|array|null $options * @param bool $add * - * @return Field|FacetInterface + * @return Field */ - public function createFacetField(string|array|null $options = null, bool $add = true): FacetInterface + public function createFacetField(string|array|null $options = null, bool $add = true): Field { return $this->createFacet(FacetSetInterface::FACET_FIELD, $options, $add); } @@ -133,7 +132,7 @@ public function createFacetField(string|array|null $options = null, bool $add = * * @return Query */ - public function createFacetQuery(string|array|null $options = null, bool $add = true): FacetInterface + public function createFacetQuery(string|array|null $options = null, bool $add = true): Query { return $this->createFacet(FacetSetInterface::FACET_QUERY, $options, $add); } @@ -148,7 +147,7 @@ public function createFacetQuery(string|array|null $options = null, bool $add = * * @return MultiQuery */ - public function createFacetMultiQuery(string|array|null $options = null, bool $add = true): FacetInterface + public function createFacetMultiQuery(string|array|null $options = null, bool $add = true): MultiQuery { return $this->createFacet(FacetSetInterface::FACET_MULTIQUERY, $options, $add); } @@ -163,7 +162,7 @@ public function createFacetMultiQuery(string|array|null $options = null, bool $a * * @return Range */ - public function createFacetRange(string|array|null $options = null, bool $add = true): FacetInterface + public function createFacetRange(string|array|null $options = null, bool $add = true): Range { return $this->createFacet(FacetSetInterface::FACET_RANGE, $options, $add); } @@ -178,7 +177,7 @@ public function createFacetRange(string|array|null $options = null, bool $add = * * @return Pivot */ - public function createFacetPivot(string|array|null $options = null, bool $add = true): FacetInterface + public function createFacetPivot(string|array|null $options = null, bool $add = true): Pivot { return $this->createFacet(FacetSetInterface::FACET_PIVOT, $options, $add); } @@ -193,7 +192,7 @@ public function createFacetPivot(string|array|null $options = null, bool $add = * * @return Interval */ - public function createFacetInterval(string|array|null $options = null, bool $add = true): FacetInterface + public function createFacetInterval(string|array|null $options = null, bool $add = true): Interval { return $this->createFacet(FacetSetInterface::FACET_INTERVAL, $options, $add); } @@ -208,7 +207,7 @@ public function createFacetInterval(string|array|null $options = null, bool $add * * @return JsonAggregation */ - public function createJsonFacetAggregation(string|array|null $options = null, bool $add = true): FacetInterface + public function createJsonFacetAggregation(string|array|null $options = null, bool $add = true): JsonAggregation { return $this->createFacet(FacetSetInterface::JSON_FACET_AGGREGATION, $options, $add); } @@ -223,7 +222,7 @@ public function createJsonFacetAggregation(string|array|null $options = null, bo * * @return JsonTerms */ - public function createJsonFacetTerms(string|array|null $options = null, bool $add = true): FacetInterface + public function createJsonFacetTerms(string|array|null $options = null, bool $add = true): JsonTerms { return $this->createFacet(FacetSetInterface::JSON_FACET_TERMS, $options, $add); } @@ -238,7 +237,7 @@ public function createJsonFacetTerms(string|array|null $options = null, bool $ad * * @return JsonQuery */ - public function createJsonFacetQuery(string|array|null $options = null, bool $add = true): FacetInterface + public function createJsonFacetQuery(string|array|null $options = null, bool $add = true): JsonQuery { return $this->createFacet(FacetSetInterface::JSON_FACET_QUERY, $options, $add); } @@ -253,7 +252,7 @@ public function createJsonFacetQuery(string|array|null $options = null, bool $ad * * @return JsonRange */ - public function createJsonFacetRange(string|array|null $options = null, bool $add = true): FacetInterface + public function createJsonFacetRange(string|array|null $options = null, bool $add = true): JsonRange { return $this->createFacet(FacetSetInterface::JSON_FACET_RANGE, $options, $add); } diff --git a/src/Component/Grouping.php b/src/Component/Grouping.php index 2852ebb13..f40254a74 100644 --- a/src/Component/Grouping.php +++ b/src/Component/Grouping.php @@ -513,7 +513,7 @@ public function getFormat(): ?string /** * Set the query group result class. * - * @param string $value classname + * @param class-string $value classname * * @return self Provides fluent interface */ @@ -529,7 +529,7 @@ public function setResultQueryGroupClass(string $value): self * * The value is a classname, not an instance * - * @return string|null + * @return class-string|null */ public function getResultQueryGroupClass(): ?string { @@ -539,7 +539,7 @@ public function getResultQueryGroupClass(): ?string /** * Set the value group result class. * - * @param string $value classname + * @param class-string $value classname * * @return self Provides fluent interface */ @@ -555,7 +555,7 @@ public function setResultValueGroupClass(string $value): self * * The value is a classname, not an instance * - * @return string|null + * @return class-string|null */ public function getResultValueGroupClass(): ?string { diff --git a/src/Component/Highlighting/HighlightingInterface.php b/src/Component/Highlighting/HighlightingInterface.php index 3d4bb35f3..99a144eb1 100644 --- a/src/Component/Highlighting/HighlightingInterface.php +++ b/src/Component/Highlighting/HighlightingInterface.php @@ -155,9 +155,7 @@ public function getUseFastVectorHighlighter(): ?bool; /** * Set highlighter method. * - * Use one of the METHOD_* constants as value. - * - * @param string $method + * @param self::METHOD_* $method * * @return self Provides fluent interface */ @@ -187,7 +185,7 @@ public function setUsePhraseHighlighter(bool $use): self; public function getUsePhraseHighlighter(): ?bool; /** - * Set HighlightMultiTerm option. + * Set highlightMultiTerm option. * * @param bool $highlight * @@ -196,7 +194,7 @@ public function getUsePhraseHighlighter(): ?bool; public function setHighlightMultiTerm(bool $highlight): self; /** - * Get HighlightMultiTerm option. + * Get highlightMultiTerm option. * * @return bool|null */ @@ -281,9 +279,7 @@ public function getTagPostfix(): ?string; /** * Set encoder option. * - * Use one of the ENCODER_* constants as value. - * - * @param string $encoder + * @param self::ENCODER_* $encoder * * @return self Provides fluent interface */ @@ -317,9 +313,7 @@ public function getMaxAnalyzedChars(): ?int; /** * Set offsetSource option. * - * Use one of the OFFSETSOURCE_* constants as value. - * - * @param string $offsetSource + * @param self::OFFSETSOURCE_* $offsetSource * * @return self Provides fluent interface */ @@ -503,9 +497,7 @@ public function getBoundaryScannerVariant(): ?string; /** * Set breakIterator boundary scanner type option. * - * Use one of the BOUNDARYSCANNER_TYPE_* constants as value. - * - * @param string $type + * @param self::BOUNDARYSCANNER_TYPE_* $type * * @return self Provides fluent interface */ @@ -659,9 +651,7 @@ public function getHighlightAlternate(): ?bool; /** * Set formatter option. * - * Use one of the FORMATTER_* constants as value. - * - * @param string $formatter + * @param self::FORMATTER_* $formatter * * @return self Provides fluent interface */ @@ -717,9 +707,7 @@ public function getSimplePostfix(): ?string; /** * Set fragmenter option. * - * Use one of the FRAGMENTER_* constants as value. - * - * @param string $fragmenter + * @param self::FRAGMENTER_* $fragmenter * * @return self Provides fluent interface */ @@ -815,9 +803,7 @@ public function getPayloads(): ?bool; /** * Set fragListBuilder option. * - * Use one of the FRAGLISTBUILDER_* constants as value. - * - * @param string $builder + * @param self::FRAGLISTBUILDER_* $builder * * @return self Provides fluent interface */ @@ -833,9 +819,7 @@ public function getFragListBuilder(): ?string; /** * Set fragmentsBuilder option. * - * Use one of the FRAGMENTSBUILDER_* constants or the name of your own fragments builder as value. - * - * @param string $builder + * @param self::FRAGMENTSBUILDER_* $builder * * @return self Provides fluent interface */ @@ -851,9 +835,7 @@ public function getFragmentsBuilder(): ?string; /** * Set boundaryScanner option. * - * Use one of the BOUNDARYSCANNER_* constants as value. - * - * @param string $scanner + * @param self::BOUNDARYSCANNER_* $scanner * * @return self Provides fluent interface */ diff --git a/src/Component/Highlighting/HighlightingTrait.php b/src/Component/Highlighting/HighlightingTrait.php index 32d8692a5..cd8c03a8f 100644 --- a/src/Component/Highlighting/HighlightingTrait.php +++ b/src/Component/Highlighting/HighlightingTrait.php @@ -43,9 +43,7 @@ public function getUseFastVectorHighlighter(): ?bool /** * Set highlighter method. * - * Use one of the METHOD_* constants as value. - * - * @param string $method + * @param self::METHOD_* $method * * @return self Provides fluent interface */ @@ -225,9 +223,7 @@ public function getTagPostfix(): ?string /** * Set encoder option. * - * Use one of the ENCODER_* constants as value. - * - * @param string $encoder + * @param self::ENCODER_* $encoder * * @return self Provides fluent interface */ @@ -277,15 +273,13 @@ public function getMaxAnalyzedChars(): ?int /** * Set offsetSource option. * - * Use one of the OFFSETSOURCE_* constants as value. - * - * @param string $source + * @param self::OFFSETSOURCE_* $offsetSource * * @return self Provides fluent interface */ - public function setOffsetSource(string $source): self + public function setOffsetSource(string $offsetSource): self { - $this->setOption('offsetsource', $source); + $this->setOption('offsetsource', $offsetSource); return $this; } @@ -305,13 +299,13 @@ public function getOffsetSource(): ?string * * Influences where the first highlighted text in a passage is positioned. * - * @param float $ratio + * @param float $fragAlignRatio * * @return self Provides fluent interface */ - public function setFragAlignRatio(float $ratio): self + public function setFragAlignRatio(float $fragAlignRatio): self { - $this->setOption('fragalignratio', $ratio); + $this->setOption('fragalignratio', $fragAlignRatio); return $this; } @@ -551,9 +545,7 @@ public function getBoundaryScannerVariant(): ?string /** * Set breakIterator boundary scanner type option. * - * Use one of the BOUNDARYSCANNER_TYPE_* constants as value. - * - * @param string $type + * @param self::BOUNDARYSCANNER_TYPE_* $type * * @return self Provides fluent interface */ @@ -779,9 +771,7 @@ public function getHighlightAlternate(): ?bool /** * Set formatter option. * - * Use one of the FORMATTER_* constants as value. - * - * @param string $formatter + * @param self::FORMATTER_* $formatter * * @return self Provides fluent interface */ @@ -861,9 +851,7 @@ public function getSimplePostfix(): ?string /** * Set fragmenter option. * - * Use one of the FRAGMENTER_* constants as value. - * - * @param string $fragmenter + * @param self::FRAGMENTER_* $fragmenter * * @return self Provides fluent interface */ @@ -1007,9 +995,7 @@ public function getPayloads(): ?bool /** * Set fragListBuilder option. * - * Use one of the FRAGLISTBUILDER_* constants as value. - * - * @param string $builder + * @param self::FRAGLISTBUILDER_* $builder * * @return self Provides fluent interface */ @@ -1033,9 +1019,7 @@ public function getFragListBuilder(): ?string /** * Set fragmentsBuilder option. * - * Use one of the FRAGMENTSBUILDER_* constants or the name of your own fragments builder as value. - * - * @param string $builder + * @param self::FRAGMENTSBUILDER_* $builder * * @return self Provides fluent interface */ @@ -1059,9 +1043,7 @@ public function getFragmentsBuilder(): ?string /** * Set boundaryScanner option. * - * Use one of the BOUNDARYSCANNER_* constants as value. - * - * @param string $scanner + * @param self::BOUNDARYSCANNER_* $scanner * * @return self Provides fluent interface */ diff --git a/src/Component/ReRankQuery.php b/src/Component/ReRankQuery.php index a5a80c8ce..88ae3d285 100644 --- a/src/Component/ReRankQuery.php +++ b/src/Component/ReRankQuery.php @@ -182,9 +182,7 @@ public function getOperator(): ?string /** * Set reRankOperator value. * - * Use one of the OPERATOR_* constants as value. - * - * @param string $value + * @param self::OPERATOR_* $value * * @return self Provides fluent interface */ diff --git a/src/Component/RequestBuilder/FacetSet.php b/src/Component/RequestBuilder/FacetSet.php index 4fe9f27ab..461cc598c 100644 --- a/src/Component/RequestBuilder/FacetSet.php +++ b/src/Component/RequestBuilder/FacetSet.php @@ -9,6 +9,7 @@ namespace Solarium\Component\RequestBuilder; +use Solarium\Component\Facet\FacetInterface; use Solarium\Component\Facet\Field as FacetField; use Solarium\Component\Facet\Interval as FacetInterval; use Solarium\Component\Facet\JsonFacetInterface; @@ -51,42 +52,42 @@ public function buildComponent(ConfigurableInterface $component, Request $reques // 2) get field name // 3) count occurence $facetFields = array_count_values(array_map( - static function ($value): ?string { + static function (FacetField $value): ?string { return $value->getField(); }, - array_filter($facets, static function ($value): bool { + array_filter($facets, static function (FacetInterface $value): bool { return FacetSetInterface::FACET_FIELD === $value->getType(); }) )); foreach ($facets as $key => $facet) { switch ($facet->getType()) { case FacetSetInterface::FACET_FIELD: - /* @var FacetField $facet */ + assert($facet instanceof FacetField); $this->addFacetField($request, $facet, 1 < $facetFields[$facet->getField()]); $nonJson = true; break; case FacetSetInterface::FACET_QUERY: - /* @var FacetQuery $facet */ + assert($facet instanceof FacetQuery); $this->addFacetQuery($request, $facet); $nonJson = true; break; case FacetSetInterface::FACET_MULTIQUERY: - /* @var FacetMultiQuery $facet */ + assert($facet instanceof FacetMultiQuery); $this->addFacetMultiQuery($request, $facet); $nonJson = true; break; case FacetSetInterface::FACET_RANGE: - /* @var FacetRange $facet */ + assert($facet instanceof FacetRange); $this->addFacetRange($request, $facet); $nonJson = true; break; case FacetSetInterface::FACET_PIVOT: - /* @var FacetPivot $facet */ + assert($facet instanceof FacetPivot); $this->addFacetPivot($request, $facet); $nonJson = true; break; case FacetSetInterface::FACET_INTERVAL: - /* @var FacetInterval $facet */ + assert($facet instanceof FacetInterval); $this->addFacetInterval($request, $facet); $nonJson = true; break; @@ -94,7 +95,7 @@ static function ($value): ?string { case FacetSetInterface::JSON_FACET_QUERY: case FacetSetInterface::JSON_FACET_RANGE: case FacetSetInterface::JSON_FACET_AGGREGATION: - /* @var JsonFacetInterface $facet */ + assert($facet instanceof JsonFacetInterface); $jsonFacets[$key] = $facet->serialize(); break; default: diff --git a/src/Component/ResponseParser/Analytics.php b/src/Component/ResponseParser/Analytics.php index 1d472cbf8..7b0e5bea4 100644 --- a/src/Component/ResponseParser/Analytics.php +++ b/src/Component/ResponseParser/Analytics.php @@ -28,11 +28,17 @@ class Analytics implements ComponentParserInterface { /** - * {@inheritdoc} + * Parse result data into result objects. + * + * @param ComponentAwareQueryInterface $query + * @param AbstractComponent&AnalyticsComponent $component + * @param array $data + * + * @return Result|null */ - public function parse(?ComponentAwareQueryInterface $query, ?AbstractComponent $component, array $data): ?Result + public function parse(ComponentAwareQueryInterface $query, AbstractComponent $component, array $data): ?Result { - if (false === isset($data['analytics_response']) || null === $component) { + if (!isset($data['analytics_response'])) { return null; } @@ -40,7 +46,6 @@ public function parse(?ComponentAwareQueryInterface $query, ?AbstractComponent $ $result = new Result(); $results = []; - /** @var AnalyticsComponent $component */ foreach ($component->getExpressions() as $name => $expression) { if (false === isset($response['results'][$name])) { continue; diff --git a/src/Component/ResponseParser/ComponentParserInterface.php b/src/Component/ResponseParser/ComponentParserInterface.php index 9c01f595d..10a0dff32 100644 --- a/src/Component/ResponseParser/ComponentParserInterface.php +++ b/src/Component/ResponseParser/ComponentParserInterface.php @@ -11,6 +11,7 @@ use Solarium\Component\AbstractComponent; use Solarium\Component\ComponentAwareQueryInterface; +use Solarium\Component\Result\ComponentResultInterface; /** * ComponentParserInterface. @@ -24,7 +25,7 @@ interface ComponentParserInterface * @param AbstractComponent $component * @param array $data * - * @return object|null + * @return ComponentResultInterface|null */ - public function parse(?ComponentAwareQueryInterface $query, ?AbstractComponent $component, array $data); + public function parse(ComponentAwareQueryInterface $query, AbstractComponent $component, array $data): ?ComponentResultInterface; } diff --git a/src/Component/ResponseParser/Debug.php b/src/Component/ResponseParser/Debug.php index 24629afb6..21071a978 100644 --- a/src/Component/ResponseParser/Debug.php +++ b/src/Component/ResponseParser/Debug.php @@ -28,68 +28,68 @@ class Debug implements ComponentParserInterface * Parse result data into result objects. * * @param ComponentAwareQueryInterface $query - * @param DebugComponent|AbstractComponent $component + * @param AbstractComponent&DebugComponent $component * @param array $data * * @return Result|null */ - public function parse(?ComponentAwareQueryInterface $query, ?AbstractComponent $component, array $data): ?Result + public function parse(ComponentAwareQueryInterface $query, AbstractComponent $component, array $data): ?Result { - $result = null; - - if (isset($data['debug'])) { - $debug = $data['debug']; - - // get basic values from data - $queryString = $debug['querystring'] ?? ''; - $parsedQuery = $debug['parsedquery'] ?? ''; - $queryParser = $debug['QParser'] ?? ''; - $otherQuery = $debug['otherQuery'] ?? ''; - - // parse explain data - if (isset($debug['explain']) && \is_array($debug['explain'])) { - $explain = $this->parseDocumentSet($debug['explain']); - } else { - $explain = new DocumentSet([]); - } + if (!isset($data['debug'])) { + return null; + } - // parse explainOther data - if (isset($debug['explainOther']) && \is_array($debug['explainOther'])) { - $explainOther = $this->parseDocumentSet($debug['explainOther']); - } else { - $explainOther = new DocumentSet([]); - } + $debug = $data['debug']; + + // get basic values from data + $queryString = $debug['querystring'] ?? ''; + $parsedQuery = $debug['parsedquery'] ?? ''; + $queryParser = $debug['QParser'] ?? ''; + $otherQuery = $debug['otherQuery'] ?? ''; + + // parse explain data + if (isset($debug['explain']) && \is_array($debug['explain'])) { + $explain = $this->parseDocumentSet($debug['explain']); + } else { + $explain = new DocumentSet([]); + } - // parse timing data - $timing = null; - if (isset($debug['timing']) && \is_array($debug['timing'])) { - $time = null; - $timingPhases = []; - foreach ($debug['timing'] as $key => $timingData) { - switch ($key) { - case 'time': - $time = $timingData; - break; - case \is_array($timingData): - $timingPhases[$key] = $this->parseTimingPhase($key, $timingData); - break; - } + // parse explainOther data + if (isset($debug['explainOther']) && \is_array($debug['explainOther'])) { + $explainOther = $this->parseDocumentSet($debug['explainOther']); + } else { + $explainOther = new DocumentSet([]); + } + + // parse timing data + $timing = null; + if (isset($debug['timing']) && \is_array($debug['timing'])) { + $time = null; + $timingPhases = []; + foreach ($debug['timing'] as $key => $timingData) { + switch ($key) { + case 'time': + $time = $timingData; + break; + case \is_array($timingData): + $timingPhases[$key] = $this->parseTimingPhase($key, $timingData); + break; } - $timing = new Timing($time, $timingPhases); } - - // create result object - $result = new Result( - $queryString, - $parsedQuery, - $queryParser, - $otherQuery, - $explain, - $explainOther, - $timing - ); + $timing = new Timing($time, $timingPhases); } + // create result object + $result = new Result( + $queryString, + $parsedQuery, + $queryParser, + $otherQuery, + $explain, + $explainOther, + $timing + ); + return $result; } diff --git a/src/Component/ResponseParser/FacetSet.php b/src/Component/ResponseParser/FacetSet.php index 5500ad60e..e10b97f12 100644 --- a/src/Component/ResponseParser/FacetSet.php +++ b/src/Component/ResponseParser/FacetSet.php @@ -16,7 +16,9 @@ use Solarium\Component\Facet\Interval as QueryFacetInterval; use Solarium\Component\Facet\JsonAggregation; use Solarium\Component\Facet\JsonFacetInterface; +use Solarium\Component\Facet\JsonQuery as QueryFacetJsonQuery; use Solarium\Component\Facet\JsonRange as QueryFacetJsonRange; +use Solarium\Component\Facet\JsonTerms as QueryFacetJsonTerms; use Solarium\Component\Facet\MultiQuery as QueryFacetMultiQuery; use Solarium\Component\Facet\Pivot as QueryFacetPivot; use Solarium\Component\Facet\Query as QueryFacetQuery; @@ -38,7 +40,6 @@ use Solarium\Component\Result\Stats\Result; use Solarium\Core\Query\AbstractQuery; use Solarium\Core\Query\AbstractResponseParser as ResponseParserAbstract; -use Solarium\Exception\InvalidArgumentException; use Solarium\Exception\RuntimeException; /** @@ -51,24 +52,14 @@ class FacetSet extends ResponseParserAbstract implements ComponentParserInterfac /** * Parse result data into result objects. * - * @param ComponentAwareQueryInterface|AbstractQuery $query - * @param AbstractComponent|QueryFacetSet $facetSet + * @param ComponentAwareQueryInterface&AbstractQuery $query + * @param AbstractComponent&QueryFacetSet $facetSet * @param array $data * - * @throws RuntimeException - * @throws InvalidArgumentException - * * @return ResultFacetSet */ - public function parse(?ComponentAwareQueryInterface $query, ?AbstractComponent $facetSet, array $data): ?ResultFacetSet + public function parse(ComponentAwareQueryInterface $query, AbstractComponent $facetSet, array $data): ResultFacetSet { - if (!$query) { - throw new InvalidArgumentException('A valid query object needs to be provided.'); - } - if (!$facetSet) { - throw new InvalidArgumentException('A valid facet set component needs to be provided.'); - } - if (true === $facetSet->getExtractFromResponse()) { if (false === empty($data['facet_counts'])) { foreach ($data['facet_counts'] as $key => $facets) { @@ -85,7 +76,7 @@ public function parse(?ComponentAwareQueryInterface $query, ?AbstractComponent $ case 'facet_pivot': $method = 'createFacetPivot'; break; - case 'facet_interval': + case 'facet_intervals': $method = 'createFacetInterval'; break; default: @@ -94,7 +85,7 @@ public function parse(?ComponentAwareQueryInterface $query, ?AbstractComponent $ foreach ($facets as $k => $facet) { $facetObject = $facetSet->$method($k); if ('facet_pivot' === $key) { - /* @var QueryFacetPivot $facetObject */ + assert($facetObject instanceof QueryFacetPivot); $facetObject->setFields($k); } } @@ -168,16 +159,22 @@ protected function parseJsonFacetSet(array $facetData, array $facets): array $count = $bucket['count']; unset($bucket['val'], $bucket['count']); - $buckets[] = new Bucket($val, $count, new ResultFacetSet($this->parseJsonFacetSet( - $bucket, - (isset($facets[$key]) && $facets[$key] instanceof JsonFacetInterface) ? $facets[$key]->getFacets() : [] - ))); + $facetFacets = []; + if (isset($facets[$key]) && $facets[$key] instanceof JsonFacetInterface) { + /** @var QueryFacetJsonQuery|QueryFacetJsonRange|QueryFacetJsonTerms $facet */ + $facet = $facets[$key]; + $facetFacets = $facet->getFacets(); + } + + $buckets[] = new Bucket($val, $count, new ResultFacetSet($this->parseJsonFacetSet($bucket, $facetFacets))); } + if (isset($values['numBuckets'])) { $numBuckets = $values['numBuckets']; } else { $numBuckets = null; } + if (isset($facets[$key]) && $facets[$key] instanceof QueryFacetJsonRange) { if (isset($values['before']['count'])) { $before = $values['before']['count']; @@ -194,15 +191,20 @@ protected function parseJsonFacetSet(array $facetData, array $facets): array } else { $between = null; } + $bucketsAndAggregations[$key] = new ResultFacetJsonRange($buckets, $before, $after, $between); } elseif ($buckets || $numBuckets) { $bucketsAndAggregations[$key] = new Buckets($buckets, $numBuckets); } } else { - $bucketsAndAggregations[$key] = new ResultFacetSet($this->parseJsonFacetSet( - $values, - (isset($facets[$key]) && $facets[$key] instanceof JsonFacetInterface) ? $facets[$key]->getFacets() : [] - )); + $facetFacets = []; + if (isset($facets[$key]) && $facets[$key] instanceof JsonFacetInterface) { + /** @var QueryFacetJsonQuery|QueryFacetJsonRange|QueryFacetJsonTerms $facet */ + $facet = $facets[$key]; + $facetFacets = $facet->getFacets(); + } + + $bucketsAndAggregations[$key] = new ResultFacetSet($this->parseJsonFacetSet($values, $facetFacets)); } } else { if (isset($facets[$key]) && $facets[$key] instanceof JsonAggregation) { @@ -211,6 +213,7 @@ protected function parseJsonFacetSet(array $facetData, array $facets): array continue; } } + $bucketsAndAggregations[$key] = new Aggregation($values); } } diff --git a/src/Component/ResponseParser/Grouping.php b/src/Component/ResponseParser/Grouping.php index 6c0cb77ce..1afb374ae 100644 --- a/src/Component/ResponseParser/Grouping.php +++ b/src/Component/ResponseParser/Grouping.php @@ -15,8 +15,6 @@ use Solarium\Component\Result\Grouping\FieldGroup; use Solarium\Component\Result\Grouping\Result; use Solarium\Core\Query\AbstractQuery; -use Solarium\Exception\InvalidArgumentException; -use Solarium\QueryType\Select\Query\Query; /** * Parse select component Grouping result from the data. @@ -26,27 +24,18 @@ class Grouping implements ComponentParserInterface /** * Parse result data into result objects. * - * @param ComponentAwareQueryInterface|Query $query - * @param GroupingComponent|AbstractComponent $grouping - * @param array $data - * - * @throws InvalidArgumentException + * @param ComponentAwareQueryInterface&AbstractQuery $query + * @param AbstractComponent&GroupingComponent $grouping + * @param array $data * * @return Result */ - public function parse(?ComponentAwareQueryInterface $query, ?AbstractComponent $grouping, array $data): Result + public function parse(ComponentAwareQueryInterface $query, AbstractComponent $grouping, array $data): Result { if (!isset($data['grouped'])) { return new Result([]); } - if (!$query) { - throw new InvalidArgumentException('A valid query object needs to be provided.'); - } - if (!$grouping) { - throw new InvalidArgumentException('A valid grouping component needs to be provided.'); - } - $groups = []; // parse field groups diff --git a/src/Component/ResponseParser/Highlighting.php b/src/Component/ResponseParser/Highlighting.php index 6cb27dde5..4eadb941e 100644 --- a/src/Component/ResponseParser/Highlighting.php +++ b/src/Component/ResponseParser/Highlighting.php @@ -14,7 +14,6 @@ use Solarium\Component\Highlighting\Highlighting as HighlightingComponent; use Solarium\Component\Result\Highlighting\Highlighting as HighlightingResult; use Solarium\Component\Result\Highlighting\Result; -use Solarium\QueryType\Select\Query\Query; /** * Parse select component Highlighting result from the data. @@ -24,22 +23,25 @@ class Highlighting implements ComponentParserInterface /** * Parse result data into result objects. * - * @param Query|null $query - * @param HighlightingComponent $highlighting - * @param array $data + * @param ComponentAwareQueryInterface $query + * @param AbstractComponent&HighlightingComponent $highlighting + * @param array $data * * @return HighlightingResult */ - public function parse(?ComponentAwareQueryInterface $query, ?AbstractComponent $highlighting, array $data): HighlightingResult + public function parse(ComponentAwareQueryInterface $query, AbstractComponent $highlighting, array $data): HighlightingResult { + if (!isset($data['highlighting'])) { + return new HighlightingResult([]); + } + $results = []; - if (isset($data['highlighting'])) { - $highlightResults = $data['highlighting']; - foreach ($highlightResults as $key => $result) { - $results[$key] = new Result( - $result - ); - } + + $highlightResults = $data['highlighting']; + foreach ($highlightResults as $key => $result) { + $results[$key] = new Result( + $result + ); } return new HighlightingResult($results); diff --git a/src/Component/ResponseParser/MoreLikeThis.php b/src/Component/ResponseParser/MoreLikeThis.php index a1163970a..c9e4f093f 100644 --- a/src/Component/ResponseParser/MoreLikeThis.php +++ b/src/Component/ResponseParser/MoreLikeThis.php @@ -15,7 +15,6 @@ use Solarium\Component\Result\MoreLikeThis\MoreLikeThis as MoreLikeThisResult; use Solarium\Component\Result\MoreLikeThis\Result; use Solarium\Core\Query\AbstractResponseParser; -use Solarium\Exception\InvalidArgumentException; use Solarium\QueryType\Analysis\Query\AbstractQuery; /** @@ -26,55 +25,52 @@ class MoreLikeThis extends AbstractResponseParser implements ComponentParserInte /** * Parse result data into result objects. * - * @param AbstractQuery $query - * @param MoreLikeThisComponent $moreLikeThis - * @param array $data - * - * @throws InvalidArgumentException + * @param ComponentAwareQueryInterface&AbstractQuery $query + * @param AbstractComponent&MoreLikeThisComponent $moreLikeThis + * @param array $data * * @return MoreLikeThisResult */ - public function parse(?ComponentAwareQueryInterface $query, ?AbstractComponent $moreLikeThis, array $data): MoreLikeThisResult + public function parse(ComponentAwareQueryInterface $query, AbstractComponent $moreLikeThis, array $data): MoreLikeThisResult { + if (!isset($data['moreLikeThis'])) { + return new MoreLikeThisResult([], []); + } + $results = []; $interestingTerms = []; - if (isset($data['moreLikeThis'])) { - if (!$query) { - throw new InvalidArgumentException('A valid query object needs to be provided.'); - } - $documentClass = $query->getOption('documentclass'); - $searchResults = $data['moreLikeThis']; - - // There seems to be a bug in Solr that json.nl=flat is ignored in a distributed search on Solr - // Cloud. In that case the "map" format is returned which doesn't need to be converted. But we don't - // use it in general because it has limitations for some components. - if (isset($searchResults[0]) && $query && $query::WT_JSON === $query->getResponseWriter()) { - // We have a "flat" json result. - $searchResults = $this->convertToKeyValueArray($searchResults); - } + $documentClass = $query->getOption('documentclass'); + $searchResults = $data['moreLikeThis']; - foreach ($searchResults as $key => $result) { - // create document instances - $docs = []; - foreach ($result['docs'] as $fields) { - $docs[] = new $documentClass($fields); - } + // There seems to be a bug in Solr that json.nl=flat is ignored in a distributed search on Solr + // Cloud. In that case the "map" format is returned which doesn't need to be converted. But we don't + // use it in general because it has limitations for some components. + if (isset($searchResults[0]) && $query && $query::WT_JSON === $query->getResponseWriter()) { + // We have a "flat" json result. + $searchResults = $this->convertToKeyValueArray($searchResults); + } - $results[$key] = new Result( - $result['numFound'], - isset($result['maxScore']) ? $result['maxScore'] : null, - $docs - ); + foreach ($searchResults as $key => $result) { + // create document instances + $docs = []; + foreach ($result['docs'] as $fields) { + $docs[] = new $documentClass($fields); } - if ('none' === $moreLikeThis->getInterestingTerms()) { - $interestingTerms = null; - } elseif (isset($data['interestingTerms'])) { - // We don't need to convertToKeyValueArray. Solr's MoreLikeThisComponent uses a SimpleOrderedMap - // for representing interesting terms. A SimpleOrdereMap is always returned using the "map" format. - $interestingTerms = $data['interestingTerms']; - } + $results[$key] = new Result( + $result['numFound'], + isset($result['maxScore']) ? $result['maxScore'] : null, + $docs + ); + } + + if ('none' === $moreLikeThis->getInterestingTerms()) { + $interestingTerms = null; + } elseif (isset($data['interestingTerms'])) { + // We don't need to convertToKeyValueArray. Solr's MoreLikeThisComponent uses a SimpleOrderedMap + // for representing interesting terms. A SimpleOrdereMap is always returned using the "map" format. + $interestingTerms = $data['interestingTerms']; } return new MoreLikeThisResult($results, $interestingTerms); diff --git a/src/Component/ResponseParser/Spellcheck.php b/src/Component/ResponseParser/Spellcheck.php index 918a7d0ff..0403b96cc 100644 --- a/src/Component/ResponseParser/Spellcheck.php +++ b/src/Component/ResponseParser/Spellcheck.php @@ -14,6 +14,7 @@ use Solarium\Component\Result\Spellcheck\Collation; use Solarium\Component\Result\Spellcheck\Result; use Solarium\Component\Result\Spellcheck\Suggestion; +use Solarium\Component\Spellcheck as SpellcheckComponent; use Solarium\Core\Query\AbstractQuery; use Solarium\Core\Query\AbstractResponseParser as ResponseParserAbstract; @@ -25,72 +26,72 @@ class Spellcheck extends ResponseParserAbstract implements ComponentParserInterf /** * Parse result data into result objects. * - * @param ComponentAwareQueryInterface|null $query - * @param AbstractComponent|null $spellcheck - * @param array $data + * @param ComponentAwareQueryInterface&AbstractQuery $query + * @param AbstractComponent&SpellCheckComponent $spellcheck + * @param array $data * * @return Result|null */ - public function parse(?ComponentAwareQueryInterface $query, ?AbstractComponent $spellcheck, array $data): ?Result + public function parse(ComponentAwareQueryInterface $query, AbstractComponent $spellcheck, array $data): ?Result { - if (isset($data['spellcheck'])) { - $suggestions = []; - $collations = []; - $correctlySpelled = false; - - if (isset($data['spellcheck']['suggestions']) && - \is_array($data['spellcheck']['suggestions']) && - \count($data['spellcheck']['suggestions']) > 0 - ) { - $spellcheckResults = $data['spellcheck']['suggestions']; - if ($query && $query::WT_JSON === $query->getResponseWriter()) { - $spellcheckResults = $this->convertToKeyValueArray($spellcheckResults); - } + if (!isset($data['spellcheck'])) { + return null; + } - foreach ($spellcheckResults as $key => $value) { - switch ($key) { - case 'correctlySpelled': - $correctlySpelled = $value; - break; - case 'collation': - $collations = $this->parseCollation($query, $value); - break; - default: - if (\array_key_exists(0, $value)) { - foreach ($value as $currentValue) { - $suggestions[] = $this->parseSuggestion($currentValue, $key); - } - } else { - $suggestions[] = $this->parseSuggestion($value, $key); - } - } - } + $suggestions = []; + $collations = []; + $correctlySpelled = false; + + if (isset($data['spellcheck']['suggestions']) && + \is_array($data['spellcheck']['suggestions']) && + \count($data['spellcheck']['suggestions']) > 0 + ) { + $spellcheckResults = $data['spellcheck']['suggestions']; + if ($query && $query::WT_JSON === $query->getResponseWriter()) { + $spellcheckResults = $this->convertToKeyValueArray($spellcheckResults); } - /* - * https://issues.apache.org/jira/browse/SOLR-3029 - * Solr5 has moved collations and correctlySpelled - * directly under spellcheck. - */ - if (isset($data['spellcheck']['collations']) && - \is_array($data['spellcheck']['collations']) - ) { - $collations = [$collations]; - foreach ($this->convertToKeyValueArray($data['spellcheck']['collations']) as $collationResult) { - $collations[] = $this->parseCollation($query, $collationResult); + foreach ($spellcheckResults as $key => $value) { + switch ($key) { + case 'correctlySpelled': + $correctlySpelled = $value; + break; + case 'collation': + $collations = $this->parseCollation($query, $value); + break; + default: + if (\array_key_exists(0, $value)) { + foreach ($value as $currentValue) { + $suggestions[] = $this->parseSuggestion($currentValue, $key); + } + } else { + $suggestions[] = $this->parseSuggestion($value, $key); + } } - $collations = array_merge(...$collations); } + } - if (isset($data['spellcheck']['correctlySpelled']) - ) { - $correctlySpelled = $data['spellcheck']['correctlySpelled']; + /* + * https://issues.apache.org/jira/browse/SOLR-3029 + * Solr5 has moved collations and correctlySpelled + * directly under spellcheck. + */ + if (isset($data['spellcheck']['collations']) && + \is_array($data['spellcheck']['collations']) + ) { + $collations = [$collations]; + foreach ($this->convertToKeyValueArray($data['spellcheck']['collations']) as $collationResult) { + $collations[] = $this->parseCollation($query, $collationResult); } + $collations = array_merge(...$collations); + } - return new Result($suggestions, $collations, $correctlySpelled); + if (isset($data['spellcheck']['correctlySpelled']) + ) { + $correctlySpelled = $data['spellcheck']['correctlySpelled']; } - return null; + return new Result($suggestions, $collations, $correctlySpelled); } /** diff --git a/src/Component/ResponseParser/Stats.php b/src/Component/ResponseParser/Stats.php index ef508118f..926d3da07 100644 --- a/src/Component/ResponseParser/Stats.php +++ b/src/Component/ResponseParser/Stats.php @@ -16,7 +16,6 @@ use Solarium\Component\Result\Stats\Stats as ResultStats; use Solarium\Component\Stats\Stats as StatsComponent; use Solarium\Core\Query\AbstractResponseParser as ResponseParserAbstract; -use Solarium\Exception\InvalidArgumentException; use Solarium\QueryType\Select\Query\Query; /** @@ -29,42 +28,39 @@ class Stats extends ResponseParserAbstract implements ComponentParserInterface /** * Parse result data into result objects. * - * @param Query $query - * @param StatsComponent $statsComponent - * @param array $data - * - * @throws InvalidArgumentException + * @param ComponentAwareQueryInterface&Query $query + * @param AbstractComponent&StatsComponent $statsComponent + * @param array $data * * @return ResultStats */ - public function parse(?ComponentAwareQueryInterface $query, ?AbstractComponent $statsComponent, array $data): ResultStats + public function parse(ComponentAwareQueryInterface $query, AbstractComponent $statsComponent, array $data): ResultStats { - if (!$query) { - throw new InvalidArgumentException('A valid query object needs to be provided.'); + if (!isset($data['stats']['stats_fields'])) { + return new ResultStats([]); } $results = []; - if (isset($data['stats']['stats_fields'])) { - $statResults = $data['stats']['stats_fields']; - foreach ($statResults as $field => $stats) { - if (isset($stats['facets'])) { - foreach ($stats['facets'] as $facetField => $values) { - foreach ($values as $value => $valueStats) { - if ($query::WT_JSON === $query->getResponseWriter()) { - $valueStats = $this->normalizeParsedJsonStats($valueStats); - } - $stats['facets'][$facetField][$value] = new ResultStatsFacetValue($value, $valueStats); + $statResults = $data['stats']['stats_fields']; + foreach ($statResults as $field => $stats) { + if (isset($stats['facets'])) { + foreach ($stats['facets'] as $facetField => $values) { + foreach ($values as $value => $valueStats) { + if ($query::WT_JSON === $query->getResponseWriter()) { + $valueStats = $this->normalizeParsedJsonStats($valueStats); } - } - } - if ($query::WT_JSON === $query->getResponseWriter()) { - $stats = $this->normalizeParsedJsonStats($stats); + $stats['facets'][$facetField][$value] = new ResultStatsFacetValue($value, $valueStats); + } } + } - $results[$field] = new ResultStatsResult($field, $stats); + if ($query::WT_JSON === $query->getResponseWriter()) { + $stats = $this->normalizeParsedJsonStats($stats); } + + $results[$field] = new ResultStatsResult($field, $stats); } return new ResultStats($results); diff --git a/src/Component/ResponseParser/Suggester.php b/src/Component/ResponseParser/Suggester.php index 778a2b95f..453504618 100644 --- a/src/Component/ResponseParser/Suggester.php +++ b/src/Component/ResponseParser/Suggester.php @@ -12,6 +12,7 @@ use Solarium\Component\AbstractComponent; use Solarium\Component\ComponentAwareQueryInterface; use Solarium\Component\Result\Suggester\Result; +use Solarium\Component\Suggester as SuggesterComponent; use Solarium\Core\Query\AbstractResponseParser; use Solarium\QueryType\Suggester\Result\Dictionary; use Solarium\QueryType\Suggester\Result\Term; @@ -24,31 +25,31 @@ class Suggester extends AbstractResponseParser implements ComponentParserInterfa /** * Parse result data into result objects. * - * @param ComponentAwareQueryInterface|null $query - * @param AbstractComponent|null $suggester - * @param array $data + * @param ComponentAwareQueryInterface $query + * @param AbstractComponent&SuggesterComponent $suggester + * @param array $data * * @return Result|null */ - public function parse(?ComponentAwareQueryInterface $query, ?AbstractComponent $suggester, array $data): ?Result + public function parse(ComponentAwareQueryInterface $query, AbstractComponent $suggester, array $data): ?Result { + if (!isset($data['suggest']) || !\is_array($data['suggest'])) { + return null; + } + $dictionaries = []; $allSuggestions = []; - if (isset($data['suggest']) && \is_array($data['suggest'])) { - foreach ($data['suggest'] as $dictionary => $dictionaryResults) { - $terms = []; - foreach ($dictionaryResults as $term => $termData) { - $allSuggestions[] = $this->createTerm($termData); - $terms[$term] = $this->createTerm($termData); - } - $dictionaries[$dictionary] = $this->createDictionary($terms); + foreach ($data['suggest'] as $dictionary => $dictionaryResults) { + $terms = []; + foreach ($dictionaryResults as $term => $termData) { + $allSuggestions[] = $this->createTerm($termData); + $terms[$term] = $this->createTerm($termData); } - - return new Result($dictionaries, $allSuggestions); + $dictionaries[$dictionary] = $this->createDictionary($terms); } - return null; + return new Result($dictionaries, $allSuggestions); } /** diff --git a/src/Component/ResponseParser/TermVector.php b/src/Component/ResponseParser/TermVector.php index ec74af75f..6ada967c4 100644 --- a/src/Component/ResponseParser/TermVector.php +++ b/src/Component/ResponseParser/TermVector.php @@ -19,7 +19,6 @@ use Solarium\Component\TermVector as TermVectorComponent; use Solarium\Core\Query\AbstractQuery; use Solarium\Core\Query\AbstractResponseParser; -use Solarium\Exception\InvalidArgumentException; /** * Parse Term Vector response data. @@ -29,63 +28,59 @@ class TermVector extends AbstractResponseParser implements ComponentParserInterf /** * Parse result data into result objects. * - * @param AbstractQuery $query - * @param TermVectorComponent $component - * @param array $data + * @param ComponentAwareQueryInterface&AbstractQuery $query + * @param AbstractComponent&TermVectorComponent $component + * @param array $data * * @return Result|null */ - public function parse(?ComponentAwareQueryInterface $query, ?AbstractComponent $component, array $data): ?Result + public function parse(ComponentAwareQueryInterface $query, AbstractComponent $component, array $data): ?Result { - if (!$query) { - throw new InvalidArgumentException('A valid query object needs to be provided.'); + if (!isset($data['termVectors'])) { + return null; } $responseWriter = $query->getResponseWriter(); - if (isset($data['termVectors'])) { - $warnings = null; - $documents = []; - - // if there are warnings they're always the first item in the result data - if ($query::WT_JSON === $responseWriter) { - if ('warnings' === $data['termVectors'][0] - && null !== $warnings = $this->parseWarnings($this->convertToKeyValueArray($data['termVectors'][1])) - ) { - array_shift($data['termVectors']); - array_shift($data['termVectors']); - } - } else { - if ('warnings' === array_key_first($data['termVectors']) - && null !== $warnings = $this->parseWarnings($data['termVectors']['warnings']) - ) { - unset($data['termVectors']['warnings']); - } - } + $warnings = null; + $documents = []; - if ($query::WT_JSON === $responseWriter) { - $data['termVectors'] = $this->convertToKeyValueArray($data['termVectors']); + // if there are warnings they're always the first item in the result data + if ($query::WT_JSON === $responseWriter) { + if ('warnings' === $data['termVectors'][0] + && null !== $warnings = $this->parseWarnings($this->convertToKeyValueArray($data['termVectors'][1])) + ) { + array_shift($data['termVectors']); + array_shift($data['termVectors']); + } + } else { + if ('warnings' === array_key_first($data['termVectors']) + && null !== $warnings = $this->parseWarnings($data['termVectors']['warnings']) + ) { + unset($data['termVectors']['warnings']); } + } - foreach ($data['termVectors'] as $key => $document) { - $parsedDocument = $this->parseDocument($responseWriter, $document); + if ($query::WT_JSON === $responseWriter) { + $data['termVectors'] = $this->convertToKeyValueArray($data['termVectors']); + } - if (null !== $warnings && $query::WT_PHPS === $responseWriter) { - $uniqueKey = $parsedDocument->getUniqueKey(); + foreach ($data['termVectors'] as $key => $document) { + $parsedDocument = $this->parseDocument($responseWriter, $document); - if (null !== $uniqueKey && $key !== $uniqueKey) { - // key was mangled by Solr's ResponseWriter to avoid repeats in the output - $key = $uniqueKey; - } - } + if (null !== $warnings && $query::WT_PHPS === $responseWriter) { + $uniqueKey = $parsedDocument->getUniqueKey(); - $documents[$key] = $parsedDocument; + if (null !== $uniqueKey && $key !== $uniqueKey) { + // key was mangled by Solr's ResponseWriter to avoid repeats in the output + $key = $uniqueKey; + } } - return new Result($documents, $warnings); + $documents[$key] = $parsedDocument; } - return null; + return new Result($documents, $warnings); } /** diff --git a/src/Component/ResponseParser/Terms.php b/src/Component/ResponseParser/Terms.php index d9bf74eab..baf760b07 100644 --- a/src/Component/ResponseParser/Terms.php +++ b/src/Component/ResponseParser/Terms.php @@ -25,33 +25,33 @@ class Terms extends AbstractResponseParser implements ComponentParserInterface /** * Parse result data into result objects. * - * @param AbstractQuery $query - * @param TermsComponent $component - * @param array $data + * @param ComponentAwareQueryInterface&AbstractQuery $query + * @param AbstractComponent&TermsComponent $component + * @param array $data * * @return Result|null */ - public function parse(?ComponentAwareQueryInterface $query, ?AbstractComponent $component, array $data): ?Result + public function parse(ComponentAwareQueryInterface $query, AbstractComponent $component, array $data): ?Result { + if (!isset($data['terms']) || !\is_array($data['terms'])) { + return null; + } + $allTerms = []; + $terms = []; - if (isset($data['terms']) && \is_array($data['terms'])) { - $terms = []; - foreach ($data['terms'] as $field => $termData) { - // There seems to be a bug in Solr that json.nl=flat is ignored in a distributed search on Solr - // Cloud. In that case the "map" format is returned which doesn't need to be converted. But we don't - // use it in general because it has limitations for some components. - if (isset($termData[0]) && $query && $query::WT_JSON === $query->getResponseWriter()) { - // We have a "flat" json result. - $termData = $this->convertToKeyValueArray($termData); - } - $allTerms[$field] = $termData; - $terms[$field] = new Field($termData); + foreach ($data['terms'] as $field => $termData) { + // There seems to be a bug in Solr that json.nl=flat is ignored in a distributed search on Solr + // Cloud. In that case the "map" format is returned which doesn't need to be converted. But we don't + // use it in general because it has limitations for some components. + if (isset($termData[0]) && $query && $query::WT_JSON === $query->getResponseWriter()) { + // We have a "flat" json result. + $termData = $this->convertToKeyValueArray($termData); } - - return new Result($terms, $allTerms); + $allTerms[$field] = $termData; + $terms[$field] = new Field($termData); } - return null; + return new Result($terms, $allTerms); } } diff --git a/src/Component/Result/Analytics/Result.php b/src/Component/Result/Analytics/Result.php index 24e2625e3..0d37fcad8 100644 --- a/src/Component/Result/Analytics/Result.php +++ b/src/Component/Result/Analytics/Result.php @@ -11,12 +11,14 @@ namespace Solarium\Component\Result\Analytics; +use Solarium\Component\Result\ComponentResultInterface; + /** * Analytics result. * * @author wicliff */ -class Result implements \IteratorAggregate, \Countable +class Result implements ComponentResultInterface, \IteratorAggregate, \Countable { /** * @var Expression[] diff --git a/src/Component/Result/ComponentResultInterface.php b/src/Component/Result/ComponentResultInterface.php new file mode 100644 index 000000000..565e8bbb1 --- /dev/null +++ b/src/Component/Result/ComponentResultInterface.php @@ -0,0 +1,17 @@ +getRequestBuilder(); - if (!$requestBuilder || !($requestBuilder instanceof RequestBuilderInterface)) { - throw new UnexpectedValueException(sprintf('No requestbuilder returned by query type: %s', $query->getType())); - } - $request = $requestBuilder->build($query); $event = new PostCreateRequestEvent($query, $request); @@ -862,7 +857,7 @@ public function executeRequest(Request $request, Endpoint|string|null $endpoint * @param QueryInterface|PingQuery $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|PingResult + * @return PingResult */ public function ping(QueryInterface $query, Endpoint|string|null $endpoint = null): PingResult { @@ -886,7 +881,7 @@ public function ping(QueryInterface $query, Endpoint|string|null $endpoint = nul * @param QueryInterface|UpdateQuery $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|UpdateResult + * @return UpdateResult */ public function update(QueryInterface $query, Endpoint|string|null $endpoint = null): UpdateResult { @@ -909,7 +904,7 @@ public function update(QueryInterface $query, Endpoint|string|null $endpoint = n * @param QueryInterface|SelectQuery $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|SelectResult + * @return SelectResult */ public function select(QueryInterface $query, Endpoint|string|null $endpoint = null): SelectResult { @@ -932,7 +927,7 @@ public function select(QueryInterface $query, Endpoint|string|null $endpoint = n * @param QueryInterface|MoreLikeThisQuery $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|MoreLikeThisResult + * @return MoreLikeThisResult */ public function moreLikeThis(QueryInterface $query, Endpoint|string|null $endpoint = null): MoreLikeThisResult { @@ -948,9 +943,9 @@ public function moreLikeThis(QueryInterface $query, Endpoint|string|null $endpoi * @param QueryInterface|AnalysisQueryDocument|AnalysisQueryField $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|AnalysisResultDocument|AnalysisResultField + * @return AnalysisResultDocument|AnalysisResultField */ - public function analyze(QueryInterface $query, Endpoint|string|null $endpoint = null): ResultInterface + public function analyze(QueryInterface $query, Endpoint|string|null $endpoint = null): AnalysisResultDocument|AnalysisResultField { return $this->execute($query, $endpoint); } @@ -964,7 +959,7 @@ public function analyze(QueryInterface $query, Endpoint|string|null $endpoint = * @param QueryInterface|TermsQuery $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|TermsResult + * @return TermsResult */ public function terms(QueryInterface $query, Endpoint|string|null $endpoint = null): TermsResult { @@ -980,7 +975,7 @@ public function terms(QueryInterface $query, Endpoint|string|null $endpoint = nu * @param QueryInterface|SpellcheckQuery $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|SpellcheckResult + * @return SpellcheckResult */ public function spellcheck(QueryInterface $query, Endpoint|string|null $endpoint = null): SpellcheckResult { @@ -996,7 +991,7 @@ public function spellcheck(QueryInterface $query, Endpoint|string|null $endpoint * @param QueryInterface|SuggesterQuery $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|SuggesterResult + * @return SuggesterResult */ public function suggester(QueryInterface $query, Endpoint|string|null $endpoint = null): SuggesterResult { @@ -1012,7 +1007,7 @@ public function suggester(QueryInterface $query, Endpoint|string|null $endpoint * @param QueryInterface|ExtractQuery $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|ExtractResult + * @return ExtractResult */ public function extract(QueryInterface $query, Endpoint|string|null $endpoint = null): ExtractResult { @@ -1028,7 +1023,7 @@ public function extract(QueryInterface $query, Endpoint|string|null $endpoint = * @param QueryInterface|RealtimeGetQuery $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|RealtimeGetResult + * @return RealtimeGetResult */ public function realtimeGet(QueryInterface $query, Endpoint|string|null $endpoint = null): RealtimeGetResult { @@ -1044,7 +1039,7 @@ public function realtimeGet(QueryInterface $query, Endpoint|string|null $endpoin * @param QueryInterface|LukeQuery $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|LukeResult + * @return LukeResult */ public function luke(QueryInterface $query, Endpoint|string|null $endpoint = null): LukeResult { @@ -1060,7 +1055,7 @@ public function luke(QueryInterface $query, Endpoint|string|null $endpoint = nul * @param QueryInterface|CoreAdminQuery $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|CoreAdminResult + * @return CoreAdminResult */ public function coreAdmin(QueryInterface $query, Endpoint|string|null $endpoint = null): CoreAdminResult { @@ -1141,7 +1136,7 @@ public function createQuery(string $type, ?array $options = null): QueryInterfac * * @param array|null $options * - * @return AbstractQuery|SelectQuery + * @return SelectQuery */ public function createSelect(?array $options = null): SelectQuery { @@ -1153,7 +1148,7 @@ public function createSelect(?array $options = null): SelectQuery * * @param array|null $options * - * @return AbstractQuery|MoreLikeThisQuery + * @return MoreLikeThisQuery */ public function createMoreLikeThis(?array $options = null): MoreLikeThisQuery { @@ -1165,7 +1160,7 @@ public function createMoreLikeThis(?array $options = null): MoreLikeThisQuery * * @param array|null $options * - * @return AbstractQuery|UpdateQuery + * @return UpdateQuery */ public function createUpdate(?array $options = null): UpdateQuery { @@ -1177,7 +1172,7 @@ public function createUpdate(?array $options = null): UpdateQuery * * @param array|null $options * - * @return AbstractQuery|PingQuery + * @return PingQuery */ public function createPing(?array $options = null): PingQuery { @@ -1189,7 +1184,7 @@ public function createPing(?array $options = null): PingQuery * * @param array|null $options * - * @return AbstractQuery|AnalysisQueryField + * @return AnalysisQueryField */ public function createAnalysisField(?array $options = null): AnalysisQueryField { @@ -1201,7 +1196,7 @@ public function createAnalysisField(?array $options = null): AnalysisQueryField * * @param array|null $options * - * @return AbstractQuery|AnalysisQueryDocument + * @return AnalysisQueryDocument */ public function createAnalysisDocument(?array $options = null): AnalysisQueryDocument { @@ -1213,7 +1208,7 @@ public function createAnalysisDocument(?array $options = null): AnalysisQueryDoc * * @param array|null $options * - * @return AbstractQuery|TermsQuery + * @return TermsQuery */ public function createTerms(?array $options = null): TermsQuery { @@ -1225,7 +1220,7 @@ public function createTerms(?array $options = null): TermsQuery * * @param array|null $options * - * @return AbstractQuery|SpellcheckQuery + * @return SpellcheckQuery */ public function createSpellcheck(?array $options = null): SpellcheckQuery { @@ -1237,7 +1232,7 @@ public function createSpellcheck(?array $options = null): SpellcheckQuery * * @param array|null $options * - * @return AbstractQuery|SuggesterQuery + * @return SuggesterQuery */ public function createSuggester(?array $options = null): SuggesterQuery { @@ -1249,7 +1244,7 @@ public function createSuggester(?array $options = null): SuggesterQuery * * @param array|null $options * - * @return AbstractQuery|ExtractQuery + * @return ExtractQuery */ public function createExtract(?array $options = null): ExtractQuery { @@ -1261,7 +1256,7 @@ public function createExtract(?array $options = null): ExtractQuery * * @param array|null $options * - * @return AbstractQuery|StreamQuery + * @return StreamQuery */ public function createStream(?array $options = null): StreamQuery { @@ -1277,7 +1272,7 @@ public function createStream(?array $options = null): StreamQuery * * @param array|null $options * - * @return AbstractQuery|GraphQuery + * @return GraphQuery */ public function createGraph(?array $options = null): GraphQuery { @@ -1293,7 +1288,7 @@ public function createGraph(?array $options = null): GraphQuery * * @param array|null $options * - * @return AbstractQuery|RealtimeGetQuery + * @return RealtimeGetQuery */ public function createRealtimeGet(?array $options = null): RealtimeGetQuery { @@ -1305,7 +1300,7 @@ public function createRealtimeGet(?array $options = null): RealtimeGetQuery * * @param array|null $options * - * @return AbstractQuery|LukeQuery + * @return LukeQuery */ public function createLuke(?array $options = null): LukeQuery { @@ -1317,7 +1312,7 @@ public function createLuke(?array $options = null): LukeQuery * * @param array|null $options * - * @return AbstractQuery|CoreAdminQuery + * @return CoreAdminQuery */ public function createCoreAdmin(?array $options = null): CoreAdminQuery { @@ -1329,7 +1324,7 @@ public function createCoreAdmin(?array $options = null): CoreAdminQuery * * @param array|null $options * - * @return AbstractQuery|CollectionsQuery + * @return CollectionsQuery */ public function createCollections(?array $options = null): CollectionsQuery { @@ -1341,7 +1336,7 @@ public function createCollections(?array $options = null): CollectionsQuery * * @param array|null $options * - * @return AbstractQuery|ConfigsetsQuery + * @return ConfigsetsQuery */ public function createConfigsets(?array $options = null): ConfigsetsQuery { @@ -1353,7 +1348,7 @@ public function createConfigsets(?array $options = null): ConfigsetsQuery * * @param array|null $options * - * @return AbstractQuery|ApiQuery + * @return ApiQuery */ public function createApi(?array $options = null): ApiQuery { @@ -1365,7 +1360,7 @@ public function createApi(?array $options = null): ApiQuery * * @param array|null $options * - * @return AbstractQuery|ManagedResourcesQuery + * @return ManagedResourcesQuery */ public function createManagedResources(?array $options = null): ManagedResourcesQuery { @@ -1377,7 +1372,7 @@ public function createManagedResources(?array $options = null): ManagedResources * * @param array|null $options * - * @return AbstractQuery|ManagedStopwordsQuery + * @return ManagedStopwordsQuery */ public function createManagedStopwords(?array $options = null): ManagedStopwordsQuery { @@ -1389,7 +1384,7 @@ public function createManagedStopwords(?array $options = null): ManagedStopwords * * @param array|null $options * - * @return AbstractQuery|ManagedSynonymsQuery + * @return ManagedSynonymsQuery */ public function createManagedSynonyms(?array $options = null): ManagedSynonymsQuery { diff --git a/src/Core/Client/ClientInterface.php b/src/Core/Client/ClientInterface.php index 3c8697059..15be0d96d 100644 --- a/src/Core/Client/ClientInterface.php +++ b/src/Core/Client/ClientInterface.php @@ -350,7 +350,7 @@ public function executeRequest(Request $request, Endpoint|string|null $endpoint * @param QueryInterface|PingQuery $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|PingResult + * @return PingResult */ public function ping(QueryInterface $query, Endpoint|string|null $endpoint = null): PingResult; @@ -374,7 +374,7 @@ public function ping(QueryInterface $query, Endpoint|string|null $endpoint = nul * @param QueryInterface|UpdateQuery $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|UpdateResult + * @return UpdateResult */ public function update(QueryInterface $query, Endpoint|string|null $endpoint = null): UpdateResult; @@ -397,7 +397,7 @@ public function update(QueryInterface $query, Endpoint|string|null $endpoint = n * @param QueryInterface|SelectQuery $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|SelectResult + * @return SelectResult */ public function select(QueryInterface $query, Endpoint|string|null $endpoint = null): SelectResult; @@ -420,7 +420,7 @@ public function select(QueryInterface $query, Endpoint|string|null $endpoint = n * @param QueryInterface|MoreLikeThisQuery $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|MoreLikeThisResult + * @return MoreLikeThisResult */ public function moreLikeThis(QueryInterface $query, Endpoint|string|null $endpoint = null): MoreLikeThisResult; @@ -433,9 +433,9 @@ public function moreLikeThis(QueryInterface $query, Endpoint|string|null $endpoi * @param QueryInterface|AnalysisQueryDocument|AnalysisQueryField $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|AnalysisResultDocument|AnalysisResultField + * @return AnalysisResultDocument|AnalysisResultField */ - public function analyze(QueryInterface $query, Endpoint|string|null $endpoint = null): ResultInterface; + public function analyze(QueryInterface $query, Endpoint|string|null $endpoint = null): AnalysisResultDocument|AnalysisResultField; /** * Execute a terms query. @@ -446,7 +446,7 @@ public function analyze(QueryInterface $query, Endpoint|string|null $endpoint = * @param QueryInterface|TermsQuery $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|TermsResult + * @return TermsResult */ public function terms(QueryInterface $query, Endpoint|string|null $endpoint = null): TermsResult; @@ -459,7 +459,7 @@ public function terms(QueryInterface $query, Endpoint|string|null $endpoint = nu * @param QueryInterface|SpellcheckQuery $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|SpellcheckResult + * @return SpellcheckResult */ public function spellcheck(QueryInterface $query, Endpoint|string|null $endpoint = null): SpellcheckResult; @@ -472,7 +472,7 @@ public function spellcheck(QueryInterface $query, Endpoint|string|null $endpoint * @param QueryInterface|SuggesterQuery $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|SuggesterResult + * @return SuggesterResult */ public function suggester(QueryInterface $query, Endpoint|string|null $endpoint = null): SuggesterResult; @@ -485,7 +485,7 @@ public function suggester(QueryInterface $query, Endpoint|string|null $endpoint * @param QueryInterface|ExtractQuery $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|ExtractResult + * @return ExtractResult */ public function extract(QueryInterface $query, Endpoint|string|null $endpoint = null): ExtractResult; @@ -498,7 +498,7 @@ public function extract(QueryInterface $query, Endpoint|string|null $endpoint = * @param QueryInterface|RealtimeGetQuery $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|RealtimeGetResult + * @return RealtimeGetResult */ public function realtimeGet(QueryInterface $query, Endpoint|string|null $endpoint = null): RealtimeGetResult; @@ -511,7 +511,7 @@ public function realtimeGet(QueryInterface $query, Endpoint|string|null $endpoin * @param QueryInterface|LukeQuery $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|LukeResult + * @return LukeResult */ public function luke(QueryInterface $query, Endpoint|string|null $endpoint = null): LukeResult; @@ -524,7 +524,7 @@ public function luke(QueryInterface $query, Endpoint|string|null $endpoint = nul * @param QueryInterface|CoreAdminQuery $query * @param Endpoint|string|null $endpoint * - * @return ResultInterface|CoreAdminResult + * @return CoreAdminResult */ public function coreAdmin(QueryInterface $query, Endpoint|string|null $endpoint = null): CoreAdminResult; diff --git a/src/Core/Client/Request.php b/src/Core/Client/Request.php index 473a8c7b7..72fcd65fa 100644 --- a/src/Core/Client/Request.php +++ b/src/Core/Client/Request.php @@ -160,9 +160,7 @@ public function getHandler(): ?string /** * Set request method. * - * Use one of the METHOD_* constants as value. - * - * @param string $method + * @param self::METHOD_* $method * * @return self Provides fluent interface */ @@ -186,12 +184,10 @@ public function getMethod(): ?string /** * Set request Content-Type. * - * Use one of the CONTENT_TYPE_* constants as value. - * * Content-Type parameters can be passed in $params or set with {@see setContentTypeParams()}. * - * @param string|null $contentType - * @param array|null $params + * @param self::CONTENT_TYPE_*|null $contentType + * @param array|null $params * * @return self Provides fluent interface */ @@ -506,9 +502,7 @@ public function getIsServerRequest(): bool /** * Set Solr API version. * - * Use one of the API_* constants as value. - * - * @param string $api + * @param self::API_* $api * * @return self Provides fluent interface */ diff --git a/src/Core/Query/AbstractQuery.php b/src/Core/Query/AbstractQuery.php index 1c57a16c5..546ac1c87 100644 --- a/src/Core/Query/AbstractQuery.php +++ b/src/Core/Query/AbstractQuery.php @@ -67,7 +67,7 @@ public function getHandler(): ?string * Also you need to make sure it extends the orginal result class of the * query or has an identical API. * - * @param string $classname + * @param class-string $classname * * @return self Provides fluent interface */ @@ -81,7 +81,7 @@ public function setResultClass(string $classname): self /** * Get resultclass option. * - * @return string|null + * @return class-string|null */ public function getResultClass(): ?string { diff --git a/src/Core/Query/AbstractRequestBuilder.php b/src/Core/Query/AbstractRequestBuilder.php index cd97ded1e..c394b22d4 100644 --- a/src/Core/Query/AbstractRequestBuilder.php +++ b/src/Core/Query/AbstractRequestBuilder.php @@ -26,11 +26,11 @@ abstract class AbstractRequestBuilder implements RequestBuilderInterface /** * Build request for a generic query. * - * @param QueryInterface|AbstractQuery $query + * @param QueryInterface&AbstractQuery $query * * @return Request */ - public function build(QueryInterface|AbstractQuery $query): Request + public function build(QueryInterface $query): Request { $request = new Request(); $request->setHandler($query->getHandler()); diff --git a/src/Core/Query/Helper.php b/src/Core/Query/Helper.php index 60491eb51..1a75a0312 100644 --- a/src/Core/Query/Helper.php +++ b/src/Core/Query/Helper.php @@ -139,23 +139,26 @@ public function escapeLocalParamValue(string $value, ?string $preEscapedSeparato * The trailing "Z" designates UTC time and is mandatory. * * Besides an integer timestamp, a date string, or an instance of - * DateTime/DateTimeImmutable, boolean false is also accepted as input. + * DateTime or DateTimeImmutable, boolean false is also accepted as input. * This allows you to use the return value of strtotime() directly * without checking its return value for boolean false first. * * @see https://solr.apache.org/guide/working-with-dates.html#date-formatting * - * @param int|string|\DateTimeInterface|false $input Accepted formats: timestamp, date string, DateTime or DateTimeImmutable + * @param int|string|\DateTime|\DateTimeImmutable|false $input * * @return string|false false is returned in case of invalid input */ - public function formatDate(int|string|\DateTimeInterface|false $input): string|false + public function formatDate(int|string|\DateTime|\DateTimeImmutable|false $input): string|false { switch (true) { - case $input instanceof \DateTimeInterface: - // input of DateTime or DateTimeImmutable object + case $input instanceof \DateTime: + // don't work on the original object, DateTime::setTimezone() will modify it $input = clone $input; break; + case $input instanceof \DateTimeImmutable: + // no action needed, DateTimeImmutable::setTimezone() will return a new object + break; case \is_string($input): case is_numeric($input): // input of timestamp or date/time string @@ -164,7 +167,7 @@ public function formatDate(int|string|\DateTimeInterface|false $input): string|f $input = strtotime($input); } - // now try converting the timestamp to a datetime instance, on failure return false + // now try converting the timestamp to a DateTime instance, on failure return false try { $input = new \DateTime('@'.$input); } catch (\Exception) { diff --git a/src/Core/Query/QueryInterface.php b/src/Core/Query/QueryInterface.php index 18f66011b..487c6c38e 100644 --- a/src/Core/Query/QueryInterface.php +++ b/src/Core/Query/QueryInterface.php @@ -62,7 +62,7 @@ public function getHandler(): ?string; * * Also you need to make sure this class implements the ResultInterface. * - * @param string $classname + * @param class-string $classname * * @return self Provides fluent interface */ @@ -71,7 +71,7 @@ public function setResultClass(string $classname): self; /** * Get resultclass option. * - * @return string|null + * @return class-string|null */ public function getResultClass(): ?string; diff --git a/src/Plugin/AbstractBufferedUpdate/AbstractBufferedUpdate.php b/src/Plugin/AbstractBufferedUpdate/AbstractBufferedUpdate.php index e7c386eaa..2853c1181 100644 --- a/src/Plugin/AbstractBufferedUpdate/AbstractBufferedUpdate.php +++ b/src/Plugin/AbstractBufferedUpdate/AbstractBufferedUpdate.php @@ -65,9 +65,7 @@ public function getEndpoint(): ?Endpoint /** * Set the request format for the updates. * - * Use one of the UpdateQuery::REQUEST_FORMAT_* constants as value. - * - * @param string $requestFormat + * @param UpdateQuery::REQUEST_FORMAT_* $requestFormat * * @throws InvalidArgumentException * diff --git a/src/Plugin/BufferedDelete/BufferedDeleteLite.php b/src/Plugin/BufferedDelete/BufferedDeleteLite.php index 28c1184fb..957140ddb 100644 --- a/src/Plugin/BufferedDelete/BufferedDeleteLite.php +++ b/src/Plugin/BufferedDelete/BufferedDeleteLite.php @@ -30,7 +30,7 @@ class BufferedDeleteLite extends AbstractBufferedUpdate /** * Buffered document ids and/or queries to delete. * - * @var AbstractDelete[] + * @var DeleteInterface[] */ protected array $buffer = []; @@ -107,7 +107,7 @@ public function addDeleteQueries(array $queries): self * * Any previously flushed deletes will not be included! * - * @return AbstractDelete[] + * @return DeleteInterface[] */ public function getDeletes(): array { @@ -177,7 +177,7 @@ public function commit(?bool $softCommit = null, ?bool $waitSearcher = null, ?bo /** * Add all deletes from the buffer as commands to the update query. * - * @param AbstractDelete[] $buffer + * @param DeleteInterface[] $buffer */ protected function addBufferToQuery(array $buffer): void { @@ -189,10 +189,12 @@ protected function addBufferToQuery(array $buffer): void $delete = $it->current(); switch ($delete->getType()) { - case AbstractDelete::TYPE_ID: + case DeleteInterface::TYPE_ID: + assert($delete instanceof DeleteById); $command->addId($delete->getId()); break; - case AbstractDelete::TYPE_QUERY: + case DeleteInterface::TYPE_QUERY: + assert($delete instanceof DeleteQuery); $command->addQuery($delete->getQuery()); break; default: diff --git a/src/Plugin/BufferedDelete/Delete/Id.php b/src/Plugin/BufferedDelete/Delete/Id.php index 3f5693ca3..632c3de5a 100644 --- a/src/Plugin/BufferedDelete/Delete/Id.php +++ b/src/Plugin/BufferedDelete/Delete/Id.php @@ -9,12 +9,12 @@ namespace Solarium\Plugin\BufferedDelete\Delete; -use Solarium\Plugin\BufferedDelete\AbstractDelete; +use Solarium\Plugin\BufferedDelete\DeleteInterface; /** * Wrapper class for the id of a document to delete. */ -class Id extends AbstractDelete +class Id implements DeleteInterface { /** * Document id to delete. @@ -32,11 +32,13 @@ public function __construct(int|string $id) } /** - * {@inheritdoc} + * Get delete type. + * + * @return self::TYPE_ID */ public function getType(): string { - return AbstractDelete::TYPE_ID; + return DeleteInterface::TYPE_ID; } /** diff --git a/src/Plugin/BufferedDelete/Delete/Query.php b/src/Plugin/BufferedDelete/Delete/Query.php index d591b8fba..96089ae91 100644 --- a/src/Plugin/BufferedDelete/Delete/Query.php +++ b/src/Plugin/BufferedDelete/Delete/Query.php @@ -9,12 +9,12 @@ namespace Solarium\Plugin\BufferedDelete\Delete; -use Solarium\Plugin\BufferedDelete\AbstractDelete; +use Solarium\Plugin\BufferedDelete\DeleteInterface; /** * Wrapper class for a query to delete matching documents. */ -class Query extends AbstractDelete +class Query implements DeleteInterface { /** * Query to delete matching documents. @@ -32,11 +32,13 @@ public function __construct(string $query) } /** - * {@inheritdoc} + * Get delete type. + * + * @return self::TYPE_QUERY */ public function getType(): string { - return AbstractDelete::TYPE_QUERY; + return DeleteInterface::TYPE_QUERY; } /** diff --git a/src/Plugin/BufferedDelete/AbstractDelete.php b/src/Plugin/BufferedDelete/DeleteInterface.php similarity index 72% rename from src/Plugin/BufferedDelete/AbstractDelete.php rename to src/Plugin/BufferedDelete/DeleteInterface.php index 4b999f5be..d4594fae9 100644 --- a/src/Plugin/BufferedDelete/AbstractDelete.php +++ b/src/Plugin/BufferedDelete/DeleteInterface.php @@ -10,9 +10,9 @@ namespace Solarium\Plugin\BufferedDelete; /** - * Delete base class. + * Delete interface. */ -abstract class AbstractDelete +interface DeleteInterface { /** * Delete by id. @@ -27,9 +27,9 @@ abstract class AbstractDelete /** * Get delete type. * - * @return string + * @return self::TYPE_* */ - abstract public function getType(): string; + public function getType(): string; - abstract public function __toString(): string; + public function __toString(): string; } diff --git a/src/Plugin/BufferedDelete/Event/PreCommit.php b/src/Plugin/BufferedDelete/Event/PreCommit.php index 10995e919..d5d3f3bcb 100644 --- a/src/Plugin/BufferedDelete/Event/PreCommit.php +++ b/src/Plugin/BufferedDelete/Event/PreCommit.php @@ -12,7 +12,7 @@ namespace Solarium\Plugin\BufferedDelete\Event; use Solarium\Plugin\AbstractBufferedUpdate\Event\AbstractPreCommit; -use Solarium\Plugin\BufferedDelete\AbstractDelete; +use Solarium\Plugin\BufferedDelete\DeleteInterface; /** * PreCommit event, see {@see Events} for details. @@ -20,7 +20,7 @@ class PreCommit extends AbstractPreCommit { /** - * @var AbstractDelete[] + * @var DeleteInterface[] */ protected array $buffer; } diff --git a/src/Plugin/BufferedDelete/Event/PreFlush.php b/src/Plugin/BufferedDelete/Event/PreFlush.php index 47b948eb6..1283dd87e 100644 --- a/src/Plugin/BufferedDelete/Event/PreFlush.php +++ b/src/Plugin/BufferedDelete/Event/PreFlush.php @@ -12,7 +12,7 @@ namespace Solarium\Plugin\BufferedDelete\Event; use Solarium\Plugin\AbstractBufferedUpdate\Event\AbstractPreFlush; -use Solarium\Plugin\BufferedDelete\AbstractDelete; +use Solarium\Plugin\BufferedDelete\DeleteInterface; /** * PreFlush event, see {@see Events} for details. @@ -20,7 +20,7 @@ class PreFlush extends AbstractPreFlush { /** - * @var AbstractDelete[] + * @var DeleteInterface[] */ protected array $buffer; } diff --git a/src/Plugin/Loadbalancer/Loadbalancer.php b/src/Plugin/Loadbalancer/Loadbalancer.php index 3891b1363..8cb894a56 100755 --- a/src/Plugin/Loadbalancer/Loadbalancer.php +++ b/src/Plugin/Loadbalancer/Loadbalancer.php @@ -393,7 +393,7 @@ public function getBlockedQueryTypes(): array * * Overwrites any existing types * - * @param array $types Use an array with the constants defined in Solarium\Client as values + * @param array $types An array of Client::QUERY_* and/or self-registered types * * @return self Provides fluent interface */ @@ -408,7 +408,7 @@ public function setBlockedQueryTypes(array $types): self /** * Add a querytype to block from loadbalancing. * - * @param string $type Use one of the constants defined in Solarium\Client + * @param Client::QUERY_*|string $type A Client::QUERY_* or self-registered type * * @return self Provides fluent interface */ @@ -426,7 +426,7 @@ public function addBlockedQueryType(string $type): self * * Appended to any existing types * - * @param array $types Use an array with the constants defined in Solarium\Client as values + * @param array $types An array of Client::QUERY_* and/or self-registered types * * @return self Provides fluent interface */ @@ -442,7 +442,7 @@ public function addBlockedQueryTypes(array $types): self /** * Remove a single querytype from the block list. * - * @param string $type + * @param Client::QUERY_*|string $type A Client::QUERY_* or self-registered type * * @return self Provides fluent interface */ diff --git a/src/Plugin/MinimumScoreFilter/Document.php b/src/Plugin/MinimumScoreFilter/Document.php index 41a69d5d5..93b24b625 100644 --- a/src/Plugin/MinimumScoreFilter/Document.php +++ b/src/Plugin/MinimumScoreFilter/Document.php @@ -16,7 +16,9 @@ /** * Minimum score filter query result document. * - * Decorates the original document with a filter indicator + * Decorates the original document with a filter indicator. + * + * @mixin SelectDocument */ class Document implements DocumentInterface, \IteratorAggregate, \Countable, \ArrayAccess, \JsonSerializable { diff --git a/src/Plugin/PostBigExtractRequest.php b/src/Plugin/PostBigExtractRequest.php index 65b118df1..71ce1e0ec 100644 --- a/src/Plugin/PostBigExtractRequest.php +++ b/src/Plugin/PostBigExtractRequest.php @@ -125,7 +125,9 @@ public function postCreateRequest(PostCreateRequestEvent $event): self protected function initPluginType(): void { $dispatcher = $this->client->getEventDispatcher(); - $dispatcher->addListener(Events::POST_CREATE_REQUEST, [$this, 'postCreateRequest']); + if (is_subclass_of($dispatcher, '\Symfony\Component\EventDispatcher\EventDispatcherInterface')) { + $dispatcher->addListener(Events::POST_CREATE_REQUEST, [$this, 'postCreateRequest']); + } } /** @@ -136,6 +138,8 @@ protected function initPluginType(): void public function deinitPlugin(): void { $dispatcher = $this->client->getEventDispatcher(); - $dispatcher->removeListener(Events::POST_CREATE_REQUEST, [$this, 'postCreateRequest']); + if (is_subclass_of($dispatcher, '\Symfony\Component\EventDispatcher\EventDispatcherInterface')) { + $dispatcher->removeListener(Events::POST_CREATE_REQUEST, [$this, 'postCreateRequest']); + } } } diff --git a/src/QueryType/Analysis/RequestBuilder/Field.php b/src/QueryType/Analysis/RequestBuilder/Field.php index 61d79670b..66c5a5381 100644 --- a/src/QueryType/Analysis/RequestBuilder/Field.php +++ b/src/QueryType/Analysis/RequestBuilder/Field.php @@ -21,7 +21,7 @@ class Field extends RequestBuilder /** * Build request for an analysis field query. * - * @param QueryInterface|QueryField $query + * @param QueryInterface&QueryField $query * * @return Request */ diff --git a/src/QueryType/Analysis/RequestBuilder/RequestBuilder.php b/src/QueryType/Analysis/RequestBuilder/RequestBuilder.php index 47845a8ca..20fdc1b3d 100644 --- a/src/QueryType/Analysis/RequestBuilder/RequestBuilder.php +++ b/src/QueryType/Analysis/RequestBuilder/RequestBuilder.php @@ -22,7 +22,7 @@ class RequestBuilder extends BaseRequestBuilder /** * Build request for an analysis query. * - * @param QueryInterface|AbstractAnalysisQuery $query + * @param QueryInterface&AbstractAnalysisQuery $query * * @return Request */ diff --git a/src/QueryType/Extract/Query.php b/src/QueryType/Extract/Query.php index a0d482cdc..9eaf3f95d 100644 --- a/src/QueryType/Extract/Query.php +++ b/src/QueryType/Extract/Query.php @@ -378,7 +378,7 @@ public function setFieldMappings(array $mappings): self * * This class should implement the document interface * - * @param string $value classname + * @param class-string $value classname * * @return self Provides fluent interface */ @@ -394,7 +394,7 @@ public function setDocumentClass(string $value): self * * The value is a classname, not an instance * - * @return string|null + * @return class-string|null */ public function getDocumentClass(): ?string { @@ -430,7 +430,7 @@ public function getExtractOnly(): ?bool * * This parameter is valid only if 'extractonly' is set to true. * - * @param string $format Use one of the EXTRACT_FORMAT_* constants + * @param self::EXTRACT_FORMAT_* $format * * @return self Provides fluent interface * diff --git a/src/QueryType/Extract/RequestBuilder.php b/src/QueryType/Extract/RequestBuilder.php index ab67b847c..653e71cf9 100644 --- a/src/QueryType/Extract/RequestBuilder.php +++ b/src/QueryType/Extract/RequestBuilder.php @@ -23,7 +23,7 @@ class RequestBuilder extends BaseRequestBuilder /** * Build the request. * - * @param QueryInterface|Query $query + * @param QueryInterface&Query $query * * @throws RuntimeException * @@ -52,7 +52,7 @@ public function build(QueryInterface|Query $query): Request /** @var Document $doc */ $doc = $query->getDocument(); if (null !== $doc) { - // @phpstan-ignore-next-line we're calling a deprecated method on purpose + // @phpstan-ignore method.deprecated (we're calling a deprecated method on purpose) if (null !== $doc->getBoost()) { throw new RuntimeException('Extract does not support document-level boosts, use field boosts instead.'); } diff --git a/src/QueryType/Extract/Result.php b/src/QueryType/Extract/Result.php index 4f1078b84..344af2e0a 100644 --- a/src/QueryType/Extract/Result.php +++ b/src/QueryType/Extract/Result.php @@ -72,9 +72,12 @@ public function getData(): array parent::getData(); if (true === $this->query->getOption('extractonly')) { + /** @var Query $query */ + $query = $this->query; + // Solr versions before 8.6 used the file name as key within the response. Solr 8.6 uses the general key 'file'. // To be compatible to any version we reference the file data by both the specific and the general key. - $filename = $this->query->getResourceName(); + $filename = $query->getResourceName(); if (!isset($this->data[$filename]) && isset($this->data['file'])) { $this->data[$filename] = &$this->data['file']; diff --git a/src/QueryType/Luke/Query.php b/src/QueryType/Luke/Query.php index 942e5269a..36a76b64b 100644 --- a/src/QueryType/Luke/Query.php +++ b/src/QueryType/Luke/Query.php @@ -117,7 +117,7 @@ public function getResponseParser(): ResponseParserInterface * * This class should implement the document interface. * - * @param string $value classname + * @param class-string $value classname * * @return self Provides fluent interface */ @@ -133,7 +133,7 @@ public function setDocumentClass(string $value): self * * The value is a classname, not an instance. * - * @return string|null + * @return class-string|null */ public function getDocumentClass(): ?string { @@ -143,8 +143,6 @@ public function getDocumentClass(): ?string /** * Set the data about the index to include in the response. * - * Use one of the SHOW_* constants as value. - * * {@see SHOW_ALL} returns all fields plus the index details. This is also the * default behaviour if no 'show' and no 'id' or 'docId' is set. * @@ -157,7 +155,7 @@ public function getDocumentClass(): ?string * It works in conjunction with {@see setId()} or {@see setDocId()}. This is * also the default behaviour if 'show' isn't set and an 'id' or 'docId' is set. * - * @param string $show + * @param self::SHOW_* $show * * @return self Provides fluent interface */ diff --git a/src/QueryType/Luke/RequestBuilder.php b/src/QueryType/Luke/RequestBuilder.php index 3d088b96c..d8c4ece2d 100644 --- a/src/QueryType/Luke/RequestBuilder.php +++ b/src/QueryType/Luke/RequestBuilder.php @@ -21,7 +21,7 @@ class RequestBuilder extends AbstractRequestBuilder /** * Build request for a Luke query. * - * @param QueryInterface|Query $query + * @param QueryInterface&Query $query * * @return Request */ diff --git a/src/QueryType/Luke/ResponseParser/Doc.php b/src/QueryType/Luke/ResponseParser/Doc.php index 5a3c4abfb..cb3b40822 100644 --- a/src/QueryType/Luke/ResponseParser/Doc.php +++ b/src/QueryType/Luke/ResponseParser/Doc.php @@ -18,6 +18,7 @@ use Solarium\QueryType\Luke\Result\Doc\DocInfo; use Solarium\QueryType\Luke\Result\FlagList; use Solarium\QueryType\Luke\Result\Result; +use Solarium\QueryType\Luke\Query; /** * Parse Luke doc response data. @@ -162,7 +163,9 @@ protected function parseLuceneField(string $name, array $details): DocFieldInfo */ protected function parseSolr(array $solrData): DocumentInterface { - $documentClass = $this->result->getQuery()->getDocumentClass(); + /** @var Query $query */ + $query = $this->result->getQuery(); + $documentClass = $query->getDocumentClass(); $classes = class_implements($documentClass); if (!\in_array(DocumentInterface::class, $classes, true)) { throw new RuntimeException('The result document class must implement a document interface'); diff --git a/src/QueryType/Luke/ResponseParser/Schema.php b/src/QueryType/Luke/ResponseParser/Schema.php index 8640409bf..8f1a20079 100644 --- a/src/QueryType/Luke/ResponseParser/Schema.php +++ b/src/QueryType/Luke/ResponseParser/Schema.php @@ -19,7 +19,6 @@ use Solarium\QueryType\Luke\Result\Schema\Field\WildcardField; use Solarium\QueryType\Luke\Result\Schema\Schema as SchemaResult; use Solarium\QueryType\Luke\Result\Schema\Similarity; -use Solarium\QueryType\Luke\Result\Schema\Type\AbstractAnalyzer; use Solarium\QueryType\Luke\Result\Schema\Type\CharFilter; use Solarium\QueryType\Luke\Result\Schema\Type\Filter; use Solarium\QueryType\Luke\Result\Schema\Type\IndexAnalyzer; @@ -164,7 +163,7 @@ protected function parseTypes(array $typeData): array * * @return IndexAnalyzer|QueryAnalyzer */ - protected function parseAnalyzer(array $analyzerData, string $analyzerClass): AbstractAnalyzer + protected function parseAnalyzer(array $analyzerData, string $analyzerClass): IndexAnalyzer|QueryAnalyzer { $analyzer = new $analyzerClass($analyzerData['className']); @@ -245,11 +244,13 @@ protected function linkFields(array &$fieldsToLink, array &$fieldData, array &$f $field->addCopyDest($fields[$copyDest]); } else { if (!isset($dynamicBasedFields[$copyDest])) { - $dynamicBasedField = $dynamicFields[$this->findDynamicField($copyDest, array_keys($dynamicFields))]->createField($copyDest); - $dynamicBasedFields[$copyDest] = $dynamicBasedField; + /** @var DynamicField $dynamicField */ + $dynamicField = $dynamicFields[$this->findDynamicField($copyDest, array_keys($dynamicFields))]; + $dynamicBasedFields[$copyDest] = $dynamicField->createField($copyDest); } - $dynamicBasedFields[$copyDest]->addCopySource($fieldsToLink[$name]); - $field->addCopyDest($dynamicBasedFields[$copyDest]); + $dynamicBasedField = &$dynamicBasedFields[$copyDest]; + $dynamicBasedField->addCopySource($fieldsToLink[$name]); + $field->addCopyDest($dynamicBasedField); } } @@ -259,21 +260,23 @@ protected function linkFields(array &$fieldsToLink, array &$fieldData, array &$f $field->addCopySource($dynamicFields[$copySource]); } else { if (!isset($wildcardFields[$copySource])) { - $wildcardField = new WildcardField($copySource); - $wildcardFields[$copySource] = $wildcardField; + $wildcardFields[$copySource] = new WildcardField($copySource); } - $wildcardFields[$copySource]->addCopyDest($fieldsToLink[$name]); - $field->addCopySource($wildcardFields[$copySource]); + $wildcardField = $wildcardFields[$copySource]; + $wildcardField->addCopyDest($fieldsToLink[$name]); + $field->addCopySource($wildcardField); } } elseif (isset($fields[$copySource])) { $field->addCopySource($fields[$copySource]); } else { if (!isset($dynamicBasedFields[$copySource])) { - $dynamicBasedField = $dynamicFields[$this->findDynamicField($copySource, array_keys($dynamicFields))]->createField($copySource); - $dynamicBasedFields[$copySource] = $dynamicBasedField; + /** @var DynamicField $dynamicField */ + $dynamicField = $dynamicFields[$this->findDynamicField($copySource, array_keys($dynamicFields))]; + $dynamicBasedFields[$copySource] = $dynamicField->createField($copySource); } - $dynamicBasedFields[$copySource]->addCopyDest($fieldsToLink[$name]); - $field->addCopySource($dynamicBasedFields[$copySource]); + $dynamicBasedField = &$dynamicBasedFields[$copySource]; + $dynamicBasedField->addCopyDest($fieldsToLink[$name]); + $field->addCopySource($dynamicBasedField); } } } diff --git a/src/QueryType/ManagedResources/Query/Synonyms/InitArgs.php b/src/QueryType/ManagedResources/Query/Synonyms/InitArgs.php index e10fbccdb..f982277c6 100644 --- a/src/QueryType/ManagedResources/Query/Synonyms/InitArgs.php +++ b/src/QueryType/ManagedResources/Query/Synonyms/InitArgs.php @@ -78,9 +78,7 @@ public function getIgnoreCase(): ?bool /** * Set format. * - * Use one of the FORMAT_* constants as the value - * - * @param string $format + * @param self::FORMAT_* $format * * @throws UnexpectedValueException * diff --git a/src/QueryType/ManagedResources/RequestBuilder/Resource.php b/src/QueryType/ManagedResources/RequestBuilder/Resource.php index 36f8315dd..b3f4e13c3 100644 --- a/src/QueryType/ManagedResources/RequestBuilder/Resource.php +++ b/src/QueryType/ManagedResources/RequestBuilder/Resource.php @@ -14,6 +14,12 @@ use Solarium\Core\Query\QueryInterface; use Solarium\Exception\RuntimeException; use Solarium\QueryType\ManagedResources\Query\AbstractQuery as BaseQuery; +use Solarium\QueryType\ManagedResources\Query\Command\AbstractAdd as Add; +use Solarium\QueryType\ManagedResources\Query\Command\AbstractCreate as Create; +use Solarium\QueryType\ManagedResources\Query\Command\Config; +use Solarium\QueryType\ManagedResources\Query\Command\Delete; +use Solarium\QueryType\ManagedResources\Query\Command\Exists; +use Solarium\QueryType\ManagedResources\Query\Command\Remove; /** * Resource. @@ -23,7 +29,7 @@ class Resource extends AbstractRequestBuilder /** * Build request for a resource query. * - * @param QueryInterface|BaseQuery $query + * @param QueryInterface&BaseQuery $query * * @throws RuntimeException * @@ -64,7 +70,7 @@ public function build(QueryInterface|BaseQuery $query): Request } /** - * @param QueryInterface|BaseQuery $query + * @param QueryInterface&BaseQuery $query * @param Request $request * * @throws RuntimeException @@ -79,6 +85,8 @@ protected function buildCommand(QueryInterface|BaseQuery $query, Request $reques switch ($command->getType()) { case BaseQuery::COMMAND_ADD: + assert($command instanceof Add); + if (null === $rawData = $command->getRawData()) { throw new RuntimeException('Missing data for ADD command.'); } @@ -86,6 +94,8 @@ protected function buildCommand(QueryInterface|BaseQuery $query, Request $reques $request->setRawData($rawData); break; case BaseQuery::COMMAND_CONFIG: + assert($command instanceof Config); + if (null === $rawData = $command->getRawData()) { throw new RuntimeException('Missing initArgs for CONFIG command.'); } @@ -93,6 +103,8 @@ protected function buildCommand(QueryInterface|BaseQuery $query, Request $reques $request->setRawData($rawData); break; case BaseQuery::COMMAND_CREATE: + assert($command instanceof Create); + if (null === $rawData = $command->getRawData()) { throw new RuntimeException('Missing class for CREATE command.'); } @@ -100,6 +112,8 @@ protected function buildCommand(QueryInterface|BaseQuery $query, Request $reques $request->setRawData($rawData); break; case BaseQuery::COMMAND_DELETE: + assert($command instanceof Delete); + if (null === $term = $command->getTerm()) { throw new RuntimeException('Missing term for DELETE command.'); } @@ -112,6 +126,8 @@ protected function buildCommand(QueryInterface|BaseQuery $query, Request $reques $request->setHandler($request->getHandler().'/'.$term); break; case BaseQuery::COMMAND_EXISTS: + assert($command instanceof Exists); + if (null !== $term = $command->getTerm()) { $term = rawurlencode($term); if ($query->getUseDoubleEncoding()) { @@ -123,6 +139,8 @@ protected function buildCommand(QueryInterface|BaseQuery $query, Request $reques break; case BaseQuery::COMMAND_REMOVE: + assert($command instanceof Remove); + break; default: throw new RuntimeException(sprintf('Unsupported command type: %s', $command->getType())); diff --git a/src/QueryType/MoreLikeThis/RequestBuilder.php b/src/QueryType/MoreLikeThis/RequestBuilder.php index c6de6b660..acda83101 100644 --- a/src/QueryType/MoreLikeThis/RequestBuilder.php +++ b/src/QueryType/MoreLikeThis/RequestBuilder.php @@ -21,7 +21,7 @@ class RequestBuilder extends SelectRequestBuilder /** * Build request for a MoreLikeThis query. * - * @param QueryInterface|Query $query + * @param QueryInterface&Query $query * * @return Request */ diff --git a/src/QueryType/MoreLikeThis/Result.php b/src/QueryType/MoreLikeThis/Result.php index 3cd0794b8..7521ef190 100644 --- a/src/QueryType/MoreLikeThis/Result.php +++ b/src/QueryType/MoreLikeThis/Result.php @@ -63,6 +63,7 @@ class Result extends SelectResult */ public function getInterestingTerms(): ?array { + /** @var Query $query */ $query = $this->getQuery(); if ('none' === $query->getInterestingTerms()) { throw new UnexpectedValueException('interestingterms is none'); @@ -83,6 +84,7 @@ public function getInterestingTerms(): ?array */ public function getMatch(): ?ReadOnlyDocument { + /** @var Query $query */ $query = $this->getQuery(); if (true !== $query->getMatchInclude()) { throw new UnexpectedValueException('matchinclude was disabled in the MLT query'); diff --git a/src/QueryType/Ping/RequestBuilder.php b/src/QueryType/Ping/RequestBuilder.php index e390f6f49..db6d91ad2 100644 --- a/src/QueryType/Ping/RequestBuilder.php +++ b/src/QueryType/Ping/RequestBuilder.php @@ -21,7 +21,7 @@ class RequestBuilder extends BaseRequestBuilder /** * Build request for a ping query. * - * @param QueryInterface|Query $query + * @param QueryInterface&Query $query * * @return Request */ diff --git a/src/QueryType/RealtimeGet/Query.php b/src/QueryType/RealtimeGet/Query.php index c90a4ab38..00aceba31 100644 --- a/src/QueryType/RealtimeGet/Query.php +++ b/src/QueryType/RealtimeGet/Query.php @@ -165,7 +165,7 @@ public function setIds(array $ids): self * * This class should implement the document interface * - * @param string $value classname + * @param class-string $value classname * * @return self Provides fluent interface */ @@ -181,7 +181,7 @@ public function setDocumentClass(string $value): self * * The value is a classname, not an instance * - * @return string + * @return class-string */ public function getDocumentClass(): string { diff --git a/src/QueryType/RealtimeGet/RequestBuilder.php b/src/QueryType/RealtimeGet/RequestBuilder.php index a11b761f1..423aa8b96 100644 --- a/src/QueryType/RealtimeGet/RequestBuilder.php +++ b/src/QueryType/RealtimeGet/RequestBuilder.php @@ -21,11 +21,11 @@ class RequestBuilder extends BaseRequestBuilder /** * Build request for a ping query. * - * @param QueryInterface|Query $query + * @param QueryInterface&Query $query * * @return Request */ - public function build(QueryInterface|Query $query): Request + public function build(QueryInterface $query): Request { $request = parent::build($query); $request->setMethod(Request::METHOD_GET); diff --git a/src/QueryType/Select/Query/Query.php b/src/QueryType/Select/Query/Query.php index 3688b7ac5..ca7da00c8 100644 --- a/src/QueryType/Select/Query/Query.php +++ b/src/QueryType/Select/Query/Query.php @@ -202,7 +202,7 @@ public function getResponseParser(): ?ResponseParserInterface * * This class should implement the document interface * - * @param string $value classname + * @param class-string $value classname * * @return self Provides fluent interface */ @@ -218,7 +218,7 @@ public function setDocumentClass(string $value): self * * The value is a classname, not an instance * - * @return string|null + * @return class-string|null */ public function getDocumentClass(): ?string { @@ -228,9 +228,7 @@ public function getDocumentClass(): ?string /** * Set default query operator. * - * Use one of the constants as value - * - * @param string $operator + * @param self::QUERY_OPERATOR_* $operator * * @return self Provides fluent interface */ @@ -464,8 +462,8 @@ public function setFields(string|array $fields): self /** * Add a sort. * - * @param string $sort - * @param string $order + * @param string $sort + * @param self::SORT_* $order * * @return self Provides fluent interface */ @@ -481,7 +479,7 @@ public function addSort(string $sort, string $order): self * * The input array must contain sort items as keys and the order as values. * - * @param array $sorts + * @param array $sorts * * @return self Provides fluent interface */ @@ -525,7 +523,7 @@ public function clearSorts(): self /** * Get a list of the sorts. * - * @return array + * @return array */ public function getSorts(): array { @@ -537,7 +535,7 @@ public function getSorts(): array * * This overwrites any existing sorts * - * @param array $sorts + * @param array $sorts * * @return self Provides fluent interface */ diff --git a/src/QueryType/Select/RequestBuilder.php b/src/QueryType/Select/RequestBuilder.php index 71a6a6cc1..30bd7210b 100644 --- a/src/QueryType/Select/RequestBuilder.php +++ b/src/QueryType/Select/RequestBuilder.php @@ -22,7 +22,7 @@ class RequestBuilder extends BaseRequestBuilder /** * Build request for a select query. * - * @param QueryInterface|SelectQuery $query + * @param QueryInterface&SelectQuery $query * * @return Request */ diff --git a/src/QueryType/Server/Api/Query.php b/src/QueryType/Server/Api/Query.php index 2c4607e3a..c33ae80c0 100644 --- a/src/QueryType/Server/Api/Query.php +++ b/src/QueryType/Server/Api/Query.php @@ -114,12 +114,10 @@ public function getAccept(): ?string /** * Set request Content-Type. * - * Use one of the Request::CONTENT_TYPE_* constants as value. - * * Content-Type parameters can be passed in $params or set with {@see setContentTypeParams()}. * - * @param string|null $contentType - * @param array|null $params + * @param Request::CONTENT_TYPE_*|null $contentType + * @param array|null $params * * @return self Provides fluent interface */ diff --git a/src/QueryType/Server/Api/RequestBuilder.php b/src/QueryType/Server/Api/RequestBuilder.php index e6ebcc663..85449cee2 100644 --- a/src/QueryType/Server/Api/RequestBuilder.php +++ b/src/QueryType/Server/Api/RequestBuilder.php @@ -22,7 +22,7 @@ class RequestBuilder extends BaseRequestBuilder /** * Build request for a API query. * - * @param QueryInterface|ApiQuery $query + * @param QueryInterface&ApiQuery $query * * @return Request */ diff --git a/src/QueryType/Server/Collections/Query/Query.php b/src/QueryType/Server/Collections/Query/Query.php index e41828f4c..5369bcde6 100644 --- a/src/QueryType/Server/Collections/Query/Query.php +++ b/src/QueryType/Server/Collections/Query/Query.php @@ -17,7 +17,6 @@ use Solarium\QueryType\Server\Collections\Query\Action\Create; use Solarium\QueryType\Server\Collections\Query\Action\Delete; use Solarium\QueryType\Server\Collections\Query\Action\Reload; -use Solarium\QueryType\Server\Query\Action\ActionInterface; use Solarium\QueryType\Server\Query\RequestBuilder; use Solarium\QueryType\Server\Query\ResponseParser; @@ -298,7 +297,7 @@ public function getResponseParser(): ResponseParserInterface /** * @param array $options * - * @return ActionInterface|Create + * @return Create */ public function createCreate(array $options = []): Create { @@ -308,7 +307,7 @@ public function createCreate(array $options = []): Create /** * @param array $options * - * @return Delete|ActionInterface + * @return Delete */ public function createDelete(array $options = []): Delete { @@ -318,7 +317,7 @@ public function createDelete(array $options = []): Delete /** * @param array $options * - * @return Reload|ActionInterface + * @return Reload */ public function createReload(array $options = []): Reload { @@ -328,7 +327,7 @@ public function createReload(array $options = []): Reload /** * @param array $options * - * @return ClusterStatus|ActionInterface + * @return ClusterStatus */ public function createClusterStatus(array $options = []): ClusterStatus { diff --git a/src/QueryType/Server/Configsets/Query/Query.php b/src/QueryType/Server/Configsets/Query/Query.php index 1c8e9241c..42e08880d 100644 --- a/src/QueryType/Server/Configsets/Query/Query.php +++ b/src/QueryType/Server/Configsets/Query/Query.php @@ -18,7 +18,6 @@ use Solarium\QueryType\Server\Configsets\Query\Action\ListConfigsets; use Solarium\QueryType\Server\Configsets\Query\Action\Upload; use Solarium\QueryType\Server\Configsets\RequestBuilder; -use Solarium\QueryType\Server\Query\Action\ActionInterface; use Solarium\QueryType\Server\Query\ResponseParser; /** @@ -98,7 +97,7 @@ public function getResponseParser(): ResponseParserInterface /** * @param array $options * - * @return ListConfigsets|ActionInterface + * @return ListConfigsets */ public function createList(array $options = []): ListConfigsets { @@ -108,7 +107,7 @@ public function createList(array $options = []): ListConfigsets /** * @param array $options * - * @return Upload|ActionInterface + * @return Upload */ public function createUpload(array $options = []): Upload { @@ -118,7 +117,7 @@ public function createUpload(array $options = []): Upload /** * @param array $options * - * @return Create|ActionInterface + * @return Create */ public function createCreate(array $options = []): Create { @@ -128,7 +127,7 @@ public function createCreate(array $options = []): Create /** * @param array $options * - * @return Delete|ActionInterface + * @return Delete */ public function createDelete(array $options = []): Delete { diff --git a/src/QueryType/Server/Configsets/RequestBuilder.php b/src/QueryType/Server/Configsets/RequestBuilder.php index aef6d9ced..64d311c0d 100644 --- a/src/QueryType/Server/Configsets/RequestBuilder.php +++ b/src/QueryType/Server/Configsets/RequestBuilder.php @@ -23,7 +23,7 @@ class RequestBuilder extends ServerRequestBuilder /** * Build request for an API query. * - * @param QueryInterface|ConfigsetsQuery $query + * @param QueryInterface&ConfigsetsQuery $query * * @return Request */ diff --git a/src/QueryType/Server/CoreAdmin/Query/Query.php b/src/QueryType/Server/CoreAdmin/Query/Query.php index 6bf9a3208..b44e0bb02 100644 --- a/src/QueryType/Server/CoreAdmin/Query/Query.php +++ b/src/QueryType/Server/CoreAdmin/Query/Query.php @@ -24,7 +24,6 @@ use Solarium\QueryType\Server\CoreAdmin\Query\Action\Swap; use Solarium\QueryType\Server\CoreAdmin\Query\Action\Unload; use Solarium\QueryType\Server\CoreAdmin\ResponseParser; -use Solarium\QueryType\Server\Query\Action\ActionInterface; use Solarium\QueryType\Server\Query\RequestBuilder; /** @@ -140,7 +139,7 @@ public function getResponseParser(): ResponseParserInterface /** * @param array $options * - * @return Create|ActionInterface + * @return Create */ public function createCreate(array $options = []): Create { @@ -150,7 +149,7 @@ public function createCreate(array $options = []): Create /** * @param array $options * - * @return MergeIndexes|ActionInterface + * @return MergeIndexes */ public function createMergeIndexes(array $options = []): MergeIndexes { @@ -160,7 +159,7 @@ public function createMergeIndexes(array $options = []): MergeIndexes /** * @param array $options * - * @return Reload|ActionInterface + * @return Reload */ public function createReload(array $options = []): Reload { @@ -170,7 +169,7 @@ public function createReload(array $options = []): Reload /** * @param array $options * - * @return Rename|ActionInterface + * @return Rename */ public function createRename(array $options = []): Rename { @@ -180,7 +179,7 @@ public function createRename(array $options = []): Rename /** * @param array $options * - * @return RequestRecovery|ActionInterface + * @return RequestRecovery */ public function createRequestRecovery(array $options = []): RequestRecovery { @@ -190,7 +189,7 @@ public function createRequestRecovery(array $options = []): RequestRecovery /** * @param array $options * - * @return RequestStatus|ActionInterface + * @return RequestStatus */ public function createRequestStatus(array $options = []): RequestStatus { @@ -200,7 +199,7 @@ public function createRequestStatus(array $options = []): RequestStatus /** * @param array $options * - * @return Split|ActionInterface + * @return Split */ public function createSplit(array $options = []): Split { @@ -210,7 +209,7 @@ public function createSplit(array $options = []): Split /** * @param array $options * - * @return Status|ActionInterface + * @return Status */ public function createStatus(array $options = []): Status { @@ -220,7 +219,7 @@ public function createStatus(array $options = []): Status /** * @param array $options * - * @return Swap|ActionInterface + * @return Swap */ public function createSwap(array $options = []): Swap { @@ -230,7 +229,7 @@ public function createSwap(array $options = []): Swap /** * @param array $options * - * @return Unload|ActionInterface + * @return Unload */ public function createUnload(array $options = []): Unload { diff --git a/src/QueryType/Server/Query/RequestBuilder.php b/src/QueryType/Server/Query/RequestBuilder.php index 40b029327..68a766f80 100644 --- a/src/QueryType/Server/Query/RequestBuilder.php +++ b/src/QueryType/Server/Query/RequestBuilder.php @@ -23,7 +23,7 @@ class RequestBuilder extends BaseRequestBuilder /** * Build request for an API query. * - * @param QueryInterface|AbstractServerQuery $query + * @param QueryInterface&AbstractServerQuery $query * * @return Request */ diff --git a/src/QueryType/Server/Query/ResponseParser.php b/src/QueryType/Server/Query/ResponseParser.php index e6e1f14f8..1c72c14e2 100644 --- a/src/QueryType/Server/Query/ResponseParser.php +++ b/src/QueryType/Server/Query/ResponseParser.php @@ -9,20 +9,19 @@ namespace Solarium\QueryType\Server\Query; -use Solarium\Core\Query\AbstractResponseParser as ResponseParserAbstract; +use Solarium\Core\Query\AbstractResponseParser; use Solarium\Core\Query\ResponseParserInterface; use Solarium\Core\Query\Result\ResultInterface; -use Solarium\QueryType\Server\Collections\Result\AbstractResult; /** * Parse Collections API response data. */ -class ResponseParser extends ResponseParserAbstract implements ResponseParserInterface +class ResponseParser extends AbstractResponseParser implements ResponseParserInterface { /** * Parse response data. * - * @param AbstractResult $result + * @param ResultInterface $result * * @return array */ diff --git a/src/QueryType/Spellcheck/RequestBuilder.php b/src/QueryType/Spellcheck/RequestBuilder.php index 1b60535b5..000a742da 100644 --- a/src/QueryType/Spellcheck/RequestBuilder.php +++ b/src/QueryType/Spellcheck/RequestBuilder.php @@ -22,7 +22,7 @@ class RequestBuilder extends BaseRequestBuilder /** * Build request for a Spellcheck query. * - * @param QueryInterface|Query $query + * @param QueryInterface&Query $query * * @return Request */ diff --git a/src/QueryType/Stream/Query.php b/src/QueryType/Stream/Query.php index 7419cfd14..c78f6d66c 100644 --- a/src/QueryType/Stream/Query.php +++ b/src/QueryType/Stream/Query.php @@ -88,7 +88,7 @@ public function getExpression(): ?string * * This class should implement the document interface * - * @param string $value classname + * @param class-string $value classname * * @return self Provides fluent interface */ @@ -104,7 +104,7 @@ public function setDocumentClass(string $value): self * * The value is a classname, not an instance * - * @return string|null + * @return class-string|null */ public function getDocumentClass(): ?string { diff --git a/src/QueryType/Stream/RequestBuilder.php b/src/QueryType/Stream/RequestBuilder.php index 849898b94..0fce4e2ba 100644 --- a/src/QueryType/Stream/RequestBuilder.php +++ b/src/QueryType/Stream/RequestBuilder.php @@ -21,7 +21,7 @@ class RequestBuilder implements RequestBuilderInterface /** * Build request for a stream query. * - * @param QueryInterface|Query $query + * @param QueryInterface&Query $query * * @return Request */ diff --git a/src/QueryType/Suggester/RequestBuilder.php b/src/QueryType/Suggester/RequestBuilder.php index 4d3abd772..109fe2b11 100644 --- a/src/QueryType/Suggester/RequestBuilder.php +++ b/src/QueryType/Suggester/RequestBuilder.php @@ -22,7 +22,7 @@ class RequestBuilder extends BaseRequestBuilder /** * Build request for a Suggester query. * - * @param QueryInterface|Query $query + * @param QueryInterface&Query $query * * @return Request */ diff --git a/src/QueryType/Terms/RequestBuilder.php b/src/QueryType/Terms/RequestBuilder.php index b64f343f7..dfde983a4 100644 --- a/src/QueryType/Terms/RequestBuilder.php +++ b/src/QueryType/Terms/RequestBuilder.php @@ -22,7 +22,7 @@ class RequestBuilder extends BaseRequestBuilder /** * Build request for a Terms query. * - * @param QueryInterface|Query $query + * @param QueryInterface&Query $query * * @return Request */ diff --git a/src/QueryType/Update/Query/Query.php b/src/QueryType/Update/Query/Query.php index 5de9559cc..141a711d7 100644 --- a/src/QueryType/Update/Query/Query.php +++ b/src/QueryType/Update/Query/Query.php @@ -138,9 +138,7 @@ public function getType(): string /** * Set the request format for this query. * - * Use one of the REQUEST_FORMAT_* constants as value. - * - * @param string $requestFormat + * @param self::REQUEST_FORMAT_* $requestFormat * * @throws InvalidArgumentException * @@ -194,8 +192,8 @@ public function getResponseParser(): ResponseParserInterface /** * Create a command instance. * - * @param string $type - * @param array|null $options + * @param self::COMMAND_* $type + * @param array|null $options * * @throws InvalidArgumentException * @@ -533,7 +531,7 @@ public function addRawXmlFile(string $filename): self * * This class should implement the document interface * - * @param string $value classname + * @param class-string $value classname * * @return self Provides fluent interface */ @@ -549,7 +547,7 @@ public function setDocumentClass(string $value): self * * The value is a classname, not an instance. * - * @return string + * @return class-string */ public function getDocumentClass(): string { diff --git a/src/QueryType/Update/RequestBuilder/Cbor.php b/src/QueryType/Update/RequestBuilder/Cbor.php index bcdb6e61d..4057ae9ce 100644 --- a/src/QueryType/Update/RequestBuilder/Cbor.php +++ b/src/QueryType/Update/RequestBuilder/Cbor.php @@ -25,9 +25,11 @@ use Composer\InstalledVersions; use Solarium\Core\Client\Request; use Solarium\Core\Query\AbstractRequestBuilder; +use Solarium\Core\Query\DocumentInterface; use Solarium\Core\Query\QueryInterface; use Solarium\Exception\RuntimeException; use Solarium\QueryType\Update\Query\Command\Add; +use Solarium\QueryType\Update\Query\Document; use Solarium\QueryType\Update\Query\Query as UpdateQuery; /** @@ -40,7 +42,7 @@ class Cbor extends AbstractRequestBuilder /** * Build request for an update query. * - * @param QueryInterface|UpdateQuery $query + * @param QueryInterface&UpdateQuery $query * * @throws RuntimeException * @@ -87,7 +89,8 @@ public function getRawData(UpdateQuery $query): string foreach ($query->getCommands() as $command) { if (UpdateQuery::COMMAND_ADD === $command->getType()) { - /* @var Add $command */ + assert($command instanceof Add); + $this->addDocuments($command->getDocuments(), $cbor); if (null !== $overwrite = $command->getOverwrite()) { @@ -113,6 +116,7 @@ public function getRawData(UpdateQuery $query): string */ protected function addDocuments(array $documents, IndefiniteLengthListObject $cbor): void { + /** @var Document $doc */ foreach ($documents as $doc) { $fields = IndefiniteLengthMapObject::create(); diff --git a/src/QueryType/Update/RequestBuilder/Json.php b/src/QueryType/Update/RequestBuilder/Json.php index e26bfe4ad..e61e32f91 100644 --- a/src/QueryType/Update/RequestBuilder/Json.php +++ b/src/QueryType/Update/RequestBuilder/Json.php @@ -27,7 +27,7 @@ class Json extends AbstractRequestBuilder /** * Build request for an update query. * - * @param QueryInterface|UpdateQuery $query + * @param QueryInterface&UpdateQuery $query * * @throws RuntimeException * diff --git a/src/QueryType/Update/RequestBuilder/Xml.php b/src/QueryType/Update/RequestBuilder/Xml.php index 1ce2dc16e..a4b5c6ebe 100644 --- a/src/QueryType/Update/RequestBuilder/Xml.php +++ b/src/QueryType/Update/RequestBuilder/Xml.php @@ -29,7 +29,7 @@ class Xml extends AbstractRequestBuilder /** * Build request for an update query. * - * @param QueryInterface|UpdateQuery $query + * @param QueryInterface&UpdateQuery $query * * @return Request */ @@ -100,8 +100,10 @@ public function buildAddXml(Add $command): string $xml .= $this->attrib('commitWithin', $command->getCommitWithin()); $xml .= '>'; + /** @var Document $doc */ foreach ($command->getDocuments() as $doc) { $xml .= 'attrib('boost', $doc->getBoost()); $xml .= '>'; diff --git a/tests/Builder/Analytics/FunctionBuilderTest.php b/tests/Builder/Analytics/FunctionBuilderTest.php index c3cee116b..3c92e12fc 100644 --- a/tests/Builder/Analytics/FunctionBuilderTest.php +++ b/tests/Builder/Analytics/FunctionBuilderTest.php @@ -9,6 +9,7 @@ use Solarium\Builder\Analytics\AnalyticsExpressionVisitor; use Solarium\Builder\Analytics\FunctionBuilder; use Solarium\Builder\ExpressionInterface; +use Solarium\Component\Analytics\Analytics as AnalyticsComponent; use Solarium\Exception\RuntimeException; /** @@ -617,6 +618,40 @@ public function testConcatSeparated(): void $this->assertSame('concat_sep(foo,bar)', (string) $builder->getFunction()); } + + /** + * Test the example in docs/queries/query-helper/function-builder.md. + * + * @throws \PHPUnit\Framework\ExpectationFailedException + */ + public function testExample(): void + { + $analytics = new AnalyticsComponent(); + + $expr = FunctionBuilder::expr(); + $builder = FunctionBuilder::create() + ->where($expr->div( + $expr->sum( + 'a', + $expr->fillMissing('b', 0) + ), + $expr->add( + 10.5, + $expr->count( + $expr->mult('a', 'c') + ) + ) + )) + ; + + $analytics + ->addFunction('sale()', (string) $builder->getFunction()) + ; + + $this->assertSame([ + 'sale()' => 'div(sum(a,fill_missing(b,0)),add(10.5,count(mult(a,c))))', + ], $analytics->getFunctions()); + } } /** diff --git a/tests/Component/Facet/FacetTest.php b/tests/Component/Facet/FacetTest.php index 99a930251..dd84f7ced 100644 --- a/tests/Component/Facet/FacetTest.php +++ b/tests/Component/Facet/FacetTest.php @@ -4,11 +4,10 @@ use PHPUnit\Framework\TestCase; use Solarium\Component\Facet\AbstractFacet; -use Solarium\Component\Facet\FacetInterface; class FacetTest extends TestCase { - protected FacetInterface $facet; + protected TestFacet $facet; public function setUp(): void { diff --git a/tests/Component/Facet/JsonQueryTest.php b/tests/Component/Facet/JsonQueryTest.php index af5833547..22ca9d159 100644 --- a/tests/Component/Facet/JsonQueryTest.php +++ b/tests/Component/Facet/JsonQueryTest.php @@ -3,6 +3,7 @@ namespace Solarium\Tests\Component\Facet; use PHPUnit\Framework\TestCase; +use Solarium\Component\Facet\JsonAggregation; use Solarium\Component\Facet\JsonQuery; use Solarium\Component\FacetSet; @@ -47,4 +48,15 @@ public function testSetAndGetQueryWithBind(): void $this->facet->setQuery('id:%1%', [678]); $this->assertSame('id:678', $this->facet->getQuery()); } + + public function testAddAndRemoveFacets(): void + { + $this->facet->addFacet(new JsonAggregation(['local_key' => 'f1', 'function' => 'avg(mul(price,popularity))'])); + $this->facet->addFacet(new JsonAggregation(['local_key' => 'f2', 'function' => 'unique(popularity)'])); + $this->assertSame(['f1', 'f2'], array_keys($this->facet->getFacets())); + + $this->facet->removeFacet('f1'); + $this->assertNull($this->facet->getFacet('f1')); + $this->assertNotNull($this->facet->getFacet('f2')); + } } diff --git a/tests/Component/FacetSetTest.php b/tests/Component/FacetSetTest.php index a712aeb72..7bb80ad67 100644 --- a/tests/Component/FacetSetTest.php +++ b/tests/Component/FacetSetTest.php @@ -387,6 +387,10 @@ public function testCreateFacet(): void $facet = $this->facetSet->createFacet($type, $options); // check class mapping + $this->assertInstanceOf( + Field::class, + $facet + ); $this->assertSame( $type, $facet->getType() diff --git a/tests/Component/Highlighting/FieldTest.php b/tests/Component/Highlighting/FieldTest.php index ce2c17b99..f861b440e 100644 --- a/tests/Component/Highlighting/FieldTest.php +++ b/tests/Component/Highlighting/FieldTest.php @@ -7,7 +7,10 @@ class FieldTest extends AbstractHighlightingTestCase { - protected HighlightingInterface|Field $hlt; + /** + * @var Field + */ + protected HighlightingInterface $hlt; public function setUp(): void { diff --git a/tests/Component/Highlighting/HighlightingTest.php b/tests/Component/Highlighting/HighlightingTest.php index 01fe1e9a5..bbeb73908 100644 --- a/tests/Component/Highlighting/HighlightingTest.php +++ b/tests/Component/Highlighting/HighlightingTest.php @@ -10,7 +10,10 @@ class HighlightingTest extends AbstractHighlightingTestCase { - protected HighlightingInterface|Highlighting $hlt; + /** + * @var Highlighting + */ + protected HighlightingInterface $hlt; public function setUp(): void { diff --git a/tests/Component/ResponseParser/AnalyticsTest.php b/tests/Component/ResponseParser/AnalyticsTest.php index 260dfc254..ed8ee117a 100644 --- a/tests/Component/ResponseParser/AnalyticsTest.php +++ b/tests/Component/ResponseParser/AnalyticsTest.php @@ -8,10 +8,11 @@ use Solarium\Component\Analytics\Analytics; use Solarium\Component\Analytics\Facet\AbstractFacet; use Solarium\Component\Analytics\Grouping; -use Solarium\Component\ResponseParser\Analytics as ResponseParser; +use Solarium\Component\ResponseParser\Analytics as Parser; use Solarium\Component\Result\Analytics\Expression; use Solarium\Component\Result\Analytics\Grouping as ResultGrouping; use Solarium\Component\Result\Analytics\Result as AnalyticsResult; +use Solarium\QueryType\Select\Query\Query; /** * Analytics Test. @@ -20,6 +21,16 @@ */ class AnalyticsTest extends TestCase { + protected Parser $parser; + + protected Query $query; + + public function setUp(): void + { + $this->parser = new Parser(); + $this->query = new Query(); + } + public function testParseData(): void { $grouping = new Grouping([ @@ -99,8 +110,7 @@ public function testParseData(): void ], ]; - $parser = new ResponseParser(); - $result = $parser->parse(null, $component, $data); + $result = $this->parser->parse($this->query, $component, $data); $this->assertSameSize($result->getResults(), $result); $this->assertSameSize($result->getIterator(), $result); @@ -130,26 +140,16 @@ public function testParseData(): void $this->assertCount(1, $facets[0]->getChildren()[0]->getChildren()); } - public function testNullResponse(): void + public function testParseNoData(): void { $component = new Analytics(); $component ->addExpression('max_sale', 'max(sale())') ->addExpression('med_sale', 'median(sale())'); - $data = [ - 'analytics_response' => [ - 'results' => [ - 'max_sale' => 50.0, - 'med_sale' => 31.0, - ], - ], - ]; - - $parser = new ResponseParser(); + $result = $this->parser->parse($this->query, $component, []); - $this->assertNull($parser->parse(null, $component, [])); - $this->assertNull($parser->parse(null, null, $data)); + $this->assertNull($result); } public function testNotReturnedExpressionsAndFacets(): void @@ -219,8 +219,7 @@ public function testNotReturnedExpressionsAndFacets(): void ], ]; - $parser = new ResponseParser(); - $result = $parser->parse(null, $component, $data); + $result = $this->parser->parse($this->query, $component, $data); $this->assertNull($result->getResult('min_sale')); $this->assertNull($result->getGrouping('foo')); diff --git a/tests/Component/ResponseParser/DebugTest.php b/tests/Component/ResponseParser/DebugTest.php index 662b6e6f1..17930257f 100644 --- a/tests/Component/ResponseParser/DebugTest.php +++ b/tests/Component/ResponseParser/DebugTest.php @@ -3,16 +3,24 @@ namespace Solarium\Tests\Component\ResponseParser; use PHPUnit\Framework\TestCase; +use Solarium\Component\Debug; use Solarium\Component\ResponseParser\Debug as Parser; use Solarium\Component\Result\Debug\Detail; +use Solarium\QueryType\Select\Query\Query; class DebugTest extends TestCase { protected Parser $parser; + protected Query $query; + + protected Debug $debug; + public function setUp(): void { $this->parser = new Parser(); + $this->query = new Query(); + $this->debug = $this->query->getDebug(); } public function testParse(): void @@ -87,7 +95,8 @@ public function testParse(): void ], ]; - $result = $this->parser->parse(null, null, $data); + $result = $this->parser->parse($this->query, $this->debug, $data); + $this->assertEquals('dummy-qs', $result->getQueryString()); $this->assertEquals('dummy-pq', $result->getParsedQuery()); $this->assertEquals('dummy-qp', $result->getQueryParser()); @@ -146,7 +155,8 @@ public function testParseNoExplainData(): void ], ]; - $result = $this->parser->parse(null, null, $data); + $result = $this->parser->parse($this->query, $this->debug, $data); + $this->assertEquals('dummy-qs', $result->getQueryString()); $this->assertEquals('dummy-pq', $result->getParsedQuery()); $this->assertEquals('dummy-qp', $result->getQueryParser()); @@ -158,7 +168,8 @@ public function testParseNoExplainData(): void public function testParseNoData(): void { - $result = $this->parser->parse(null, null, []); + $result = $this->parser->parse($this->query, $this->debug, []); + $this->assertNull($result); } } diff --git a/tests/Component/ResponseParser/FacetSetTest.php b/tests/Component/ResponseParser/FacetSetTest.php index f519a5e11..8f5a0e8a3 100644 --- a/tests/Component/ResponseParser/FacetSetTest.php +++ b/tests/Component/ResponseParser/FacetSetTest.php @@ -3,13 +3,21 @@ namespace Solarium\Tests\Component\ResponseParser; use PHPUnit\Framework\TestCase; -use Solarium\Component\Facet\FacetInterface; use Solarium\Component\Facet\Field; use Solarium\Component\Facet\JsonRange; +use Solarium\Component\Facet\JsonTerms; use Solarium\Component\FacetSet; use Solarium\Component\ResponseParser\FacetSet as Parser; use Solarium\Component\Result\Stats\Result; +use Solarium\Component\Result\Facet\Aggregation as ResultFacetAggregation; +use Solarium\Component\Result\Facet\Buckets as ResultFacetBuckets; +use Solarium\Component\Result\Facet\Field as ResultFacetField; +use Solarium\Component\Result\Facet\Interval as ResultFacetInterval; use Solarium\Component\Result\Facet\JsonRange as ResultFacetJsonRange; +use Solarium\Component\Result\Facet\MultiQuery as ResultFacetMultiQuery; +use Solarium\Component\Result\Facet\Query as ResultFacetQuery; +use Solarium\Component\Result\Facet\Pivot\Pivot as ResultFacetPivot; +use Solarium\Component\Result\Facet\Range as ResultFacetRange; use Solarium\Exception\RuntimeException; use Solarium\QueryType\Select\Query\Query; @@ -17,15 +25,15 @@ class FacetSetTest extends TestCase { protected Parser $parser; - protected FacetSet $facetSet; - protected Query $query; + protected FacetSet $facetSet; + public function setUp(): void { $this->parser = new Parser(); - - $this->facetSet = new FacetSet(); + $this->query = new Query(); + $this->facetSet = $this->query->getFacetSet(); $this->facetSet->createFacet('field', ['local_key' => 'keyA', 'field' => 'fieldA']); $this->facetSet->createFacet('query', ['local_key' => 'keyB']); $this->facetSet->createFacet( @@ -42,7 +50,7 @@ public function setUp(): void $this->facetSet->createFacet('range', ['local_key' => 'keyD_A', 'pivot' => ['local_key' => 'keyF']]); $this->facetSet->createFacet('pivot', ['local_key' => 'keyE', 'fields' => 'cat,price']); $this->facetSet->createFacet('pivot', ['local_key' => 'keyF', 'fields' => 'cat']); - $this->query = new Query(); + $this->facetSet->createFacet('interval', ['local_key' => 'keyG']); } public function testParse(): void @@ -123,26 +131,36 @@ public function testParse(): void ], ], ], + 'facet_intervals' => [ + 'keyG' => [ + '1-5' => 3, + '6-10' => 4, + ], + ], ], ]; $result = $this->parser->parse($this->query, $this->facetSet, $data); $facets = $result->getFacets(); - $this->assertEquals(['keyA', 'keyB', 'keyC', 'keyD', 'keyD_A', 'keyE', 'keyF'], array_keys($facets)); + $this->assertEquals(['keyA', 'keyB', 'keyC', 'keyD', 'keyD_A', 'keyE', 'keyF', 'keyG'], array_keys($facets)); + $this->assertInstanceOf(ResultFacetField::class, $facets['keyA']); $this->assertEquals( ['value1' => 12, 'value2' => 3], $facets['keyA']->getValues() ); + $this->assertInstanceOf(ResultFacetQuery::class, $facets['keyB']); $this->assertEquals(23, $facets['keyB']->getValue()); + $this->assertInstanceOf(ResultFacetMultiQuery::class, $facets['keyC']); $this->assertEquals( ['keyC_A' => 25, 'keyC_B' => 16], $facets['keyC']->getValues() ); + $this->assertInstanceOf(ResultFacetRange::class, $facets['keyD']); $this->assertEquals( ['1.0' => 1, '101.0' => 2, '201.0' => 1], $facets['keyD']->getValues() @@ -151,11 +169,9 @@ public function testParse(): void $this->assertEquals(3, $facets['keyD']->getBefore()); $this->assertEquals(4, $facets['keyD']->getBetween()); $this->assertEquals(5, $facets['keyD']->getAfter()); - $this->assertEquals(1, \count($facets['keyE'])); - $this->assertEquals(23, $result->getFacet('keyB')->getValue()); - - $facet = $result->getFacet('keyD_A')->getPivot()->getPivot()[0]; + $this->assertInstanceOf(ResultFacetRange::class, $facets['keyD_A']); + $facet = $facets['keyD_A']->getPivot()->getPivot()[0]; $this->assertEquals('cat', $facet->getField()); $this->assertEquals('abc', $facet->getValue()); @@ -168,6 +184,15 @@ public function testParse(): void $this->assertEquals('+1YEAR', $range->getGap()); $this->assertEquals(['2018-01-01T00:00:00Z' => 0, '2019-01-01T00:00:00Z' => 1], $range->getValues()); + + $this->assertInstanceOf(ResultFacetPivot::class, $facets['keyE']); + $this->assertCount(1, $facets['keyE']); + + $this->assertInstanceOf(ResultFacetInterval::class, $facets['keyG']); + $this->assertEquals( + ['1-5' => 3, '6-10' => 4], + $facets['keyG']->getValues() + ); } public function testParseExtractFromResponse(): void @@ -219,6 +244,12 @@ public function testParseExtractFromResponse(): void ], ], ], + 'facet_intervals' => [ + 'price' => [ + '[0,10]' => 3, + '(10,100]' => 4, + ], + ], ], ]; @@ -226,32 +257,36 @@ public function testParseExtractFromResponse(): void $facetSet->setExtractFromResponse(true); $result = $this->parser->parse($this->query, $facetSet, $data); - /** @var FacetInterface[] $facets */ $facets = $result->getFacets(); - $this->assertEquals(['keyA', 'keyB', 'keyC_A', 'keyC_B', 'keyD', 'cat,price'], array_keys($facets)); + $this->assertEquals(['keyA', 'keyB', 'keyC_A', 'keyC_B', 'keyD', 'cat,price', 'price'], array_keys($facets)); + $this->assertInstanceOf(ResultFacetField::class, $facets['keyA']); $this->assertEquals( ['value1' => 12, 'value2' => 3], $facets['keyA']->getValues() ); + $this->assertInstanceOf(ResultFacetQuery::class, $facets['keyB']); $this->assertEquals( 23, $facets['keyB']->getValue() ); // As the multiquery facet is a Solarium virtual facet type, it cannot be detected based on Solr response data + $this->assertInstanceOf(ResultFacetQuery::class, $facets['keyC_A']); $this->assertEquals( 25, $facets['keyC_A']->getValue() ); + $this->assertInstanceOf(ResultFacetQuery::class, $facets['keyC_B']); $this->assertEquals( 16, $facets['keyC_B']->getValue() ); + $this->assertInstanceOf(ResultFacetRange::class, $facets['keyD']); $this->assertEquals( ['1.0' => 1, '101.0' => 2, '201.0' => 1], $facets['keyD']->getValues() @@ -277,20 +312,45 @@ public function testParseExtractFromResponse(): void $facets['cat,price'] ); + $this->assertInstanceOf(ResultFacetPivot::class, $facets['cat,price']); $pivots = $facets['cat,price']->getPivot(); $this->assertCount( 2, $pivots[0]->getStats() ); + + $this->assertInstanceOf(ResultFacetInterval::class, $facets['price']); + $this->assertEquals( + ['[0,10]' => 3, '(10,100]' => 4], + $facets['price']->getValues() + ); } public function testParseNoData(): void { $result = $this->parser->parse($this->query, $this->facetSet, []); + $this->assertEquals([], $result->getFacets()); } + public function testParseInvalidFacetIdentifier(): void + { + $data = [ + 'facet_counts' => [ + 'facet_foo' => [ + 'bar' => 42, + ], + ], + ]; + + $facetSet = new FacetSet(); + $facetSet->setExtractFromResponse(true); + + $this->expectException(RuntimeException::class); + $this->parser->parse($this->query, $facetSet, $data); + } + public function testInvalidFacetType(): void { $facetStub = $this->createMock(Field::class); @@ -311,6 +371,7 @@ public function testParseJsonFacet(): void { $data = [ 'facets' => [ + 'count' => 16, 'top_genres' => [ 'buckets' => [ [ @@ -422,17 +483,39 @@ public function testParseJsonFacet(): void 'count' => 14, ], ], + 'categories' => [ + 'missing' => [ + 'count' => 8, + ], + 'buckets' => [ + [ + 'val' => 'electronics', + 'count' => 12, + ], + [ + 'val' => 'currency', + 'count' => 4, + ], + ], + ], ], ]; $price_range = new JsonRange(['local_key' => 'price_range', 'field' => 'price', 'start' => 1, 'end' => 300, 'gap' => 100, 'other' => JsonRange::OTHER_ALL]); $this->facetSet->addFacet($price_range); + $categories = new JsonTerms(['local_key' => 'categories', 'field' => 'cat', 'missing' => true]); + $this->facetSet->addFacet($categories); + $result = $this->parser->parse($this->query, $this->facetSet, $data); $facets = $result->getFacets(); - $this->assertEquals(['top_genres', 'stock', 'empty_buckets_with_numBuckets', 'price_range'], array_keys($facets)); + $this->assertEqualsCanonicalizing(array_diff(array_keys($data['facets']), ['empty_buckets']), array_keys($facets)); + $this->assertInstanceOf(ResultFacetAggregation::class, $facets['count']); + $this->assertEquals(16, $facets['count']->getValue()); + + $this->assertInstanceOf(ResultFacetBuckets::class, $facets['top_genres']); $buckets = $facets['top_genres']->getBuckets(); $this->assertEquals( @@ -452,16 +535,22 @@ public function testParseJsonFacet(): void $this->assertTrue(isset($facets['empty_buckets_with_numBuckets'])); + $this->assertInstanceOf(ResultFacetBuckets::class, $result->getFacet('empty_buckets_with_numBuckets')); + $this->assertEquals(12, $result->getFacet('empty_buckets_with_numBuckets')->getNumBuckets()); + $this->assertInstanceOf(ResultFacetBuckets::class, $result->getFacet('stock')); + $this->assertEquals(2, $result->getFacet('stock')->getNumBuckets()); $this->assertNull($facets['top_genres']->getNumBuckets()); - $this->assertEquals('Fantasy', $result->getFacet('top_genres')->getBuckets()[0]->getValue()); + $this->assertEquals('Fantasy', $facets['top_genres']->getBuckets()[0]->getValue()); $this->assertInstanceOf(ResultFacetJsonRange::class, $result->getFacet('price_range')); + $this->assertInstanceOf(ResultFacetBuckets::class, $facets['price_range']); + $range_buckets = $facets['price_range']->getBuckets(); $this->assertEquals( @@ -476,6 +565,19 @@ public function testParseJsonFacet(): void $this->assertEquals(0, $result->getFacet('price_range')->getBefore()); $this->assertEquals(2, $result->getFacet('price_range')->getAfter()); $this->assertEquals(14, $result->getFacet('price_range')->getBetween()); + + $this->assertInstanceOf(ResultFacetBuckets::class, $facets['categories']); + + $terms_buckets = $facets['categories']->getBuckets(); + + $this->assertEquals( + 'electronics', + $terms_buckets[0]->getValue() + ); + $this->assertEquals( + 12, + $terms_buckets[0]->getCount() + ); } public function testParseFacetPivotStats(): void @@ -554,6 +656,7 @@ public function testParseFacetPivotStats(): void $result = $this->parser->parse($this->query, $facetSet, $data); $pivot = $result->getFacet($key); + $this->assertInstanceOf(ResultFacetPivot::class, $pivot); $first = $pivot->getPivot()[0]; $this->assertContainsOnlyInstancesOf(Result::class, $first->getStats()->getResults()); @@ -622,6 +725,7 @@ public function testParseFacetPivotStatsWithFieldNamedStatsFields(): void $result = $this->parser->parse($this->query, $facetSet, $data); $pivot = $result->getFacet($key); + $this->assertInstanceOf(ResultFacetPivot::class, $pivot); $first = $pivot->getPivot()[0]; $this->assertInstanceOf(Result::class, $first->getStats()->getResult('stats_fields')); diff --git a/tests/Component/ResponseParser/GroupingTest.php b/tests/Component/ResponseParser/GroupingTest.php index 9334e424e..ff8bfa7b5 100644 --- a/tests/Component/ResponseParser/GroupingTest.php +++ b/tests/Component/ResponseParser/GroupingTest.php @@ -3,7 +3,7 @@ namespace Solarium\Tests\Component\ResponseParser; use PHPUnit\Framework\TestCase; -use Solarium\Component\Grouping as Component; +use Solarium\Component\Grouping; use Solarium\Component\ResponseParser\Grouping as Parser; use Solarium\Component\Result\Grouping\FieldGroup; use Solarium\Component\Result\Grouping\QueryGroup; @@ -16,7 +16,7 @@ class GroupingTest extends TestCase protected Query $query; - protected Component $grouping; + protected Grouping $grouping; protected Result $result; @@ -160,6 +160,7 @@ public function testQueryGroupParsingFixForSolr13839(): void public function testParseNoData(): void { $result = $this->parser->parse($this->query, $this->grouping, []); + $this->assertEquals([], $result->getGroups()); } @@ -236,7 +237,7 @@ public function testsParseWithSimpleFormat(): void ], ]; - $this->grouping->setFormat(Component::FORMAT_SIMPLE); + $this->grouping->setFormat(Grouping::FORMAT_SIMPLE); $result = $this->parser->parse($this->query, $this->grouping, $data); diff --git a/tests/Component/ResponseParser/HighlightingTest.php b/tests/Component/ResponseParser/HighlightingTest.php index cf3aca9f1..b14709f36 100644 --- a/tests/Component/ResponseParser/HighlightingTest.php +++ b/tests/Component/ResponseParser/HighlightingTest.php @@ -3,16 +3,24 @@ namespace Solarium\Tests\Component\ResponseParser; use PHPUnit\Framework\TestCase; +use Solarium\Component\Highlighting\Highlighting; use Solarium\Component\ResponseParser\Highlighting as Parser; use Solarium\Component\Result\Highlighting\Result; +use Solarium\QueryType\Select\Query\Query; class HighlightingTest extends TestCase { protected Parser $parser; + protected Query $query; + + protected Highlighting $highlighting; + public function setUp(): void { $this->parser = new Parser(); + $this->query = new Query(); + $this->highlighting = $this->query->getHighlighting(); } public function testParse(): void @@ -24,14 +32,14 @@ public function testParse(): void 'key2' => new Result(['dummy2']), ]; - $result = $this->parser->parse(null, null, $data); + $result = $this->parser->parse($this->query, $this->highlighting, $data); $this->assertEquals($expected, $result->getResults()); } public function testParseNoData(): void { - $result = $this->parser->parse(null, null, []); + $result = $this->parser->parse($this->query, $this->highlighting, []); $this->assertEquals([], $result->getResults()); } diff --git a/tests/Component/ResponseParser/MoreLikeThisTest.php b/tests/Component/ResponseParser/MoreLikeThisTest.php index c0c04e88e..380f92f81 100644 --- a/tests/Component/ResponseParser/MoreLikeThisTest.php +++ b/tests/Component/ResponseParser/MoreLikeThisTest.php @@ -22,7 +22,7 @@ public function setUp(): void { $this->parser = new Parser(); $this->query = new Query(); - $this->mlt = new MoreLikeThis(); + $this->mlt = $this->query->getMoreLikeThis(); } public function testParse(): void diff --git a/tests/Component/ResponseParser/SpellcheckTest.php b/tests/Component/ResponseParser/SpellcheckTest.php index 2ec8b170e..9e38fcc4a 100644 --- a/tests/Component/ResponseParser/SpellcheckTest.php +++ b/tests/Component/ResponseParser/SpellcheckTest.php @@ -4,6 +4,7 @@ use PHPUnit\Framework\TestCase; use Solarium\Component\ResponseParser\Spellcheck as Parser; +use Solarium\Component\Spellcheck; use Solarium\QueryType\Select\Query\Query; class SpellcheckTest extends TestCase @@ -12,10 +13,13 @@ class SpellcheckTest extends TestCase protected Query $query; + protected Spellcheck $spellcheck; + public function setUp(): void { - $this->query = new Query(); $this->parser = new Parser(); + $this->query = new Query(); + $this->spellcheck = $this->query->getSpellcheck(); } /** @@ -25,7 +29,7 @@ public function setUp(): void */ public function testParseExtended($data): void { - $result = $this->parser->parse($this->query, null, $data); + $result = $this->parser->parse($this->query, $this->spellcheck, $data); $suggestions = $result->getSuggestions(); $this->assertFalse($result->getCorrectlySpelled()); @@ -220,7 +224,7 @@ public static function providerParseExtended(): array */ public function testParse($data): void { - $result = $this->parser->parse($this->query, null, $data); + $result = $this->parser->parse($this->query, $this->spellcheck, $data); $suggestions = $result->getSuggestions(); $this->assertFalse($result->getCorrectlySpelled()); @@ -319,7 +323,7 @@ public static function providerParse(): array */ public function testParseSingleCollation($data): void { - $result = $this->parser->parse($this->query, null, $data); + $result = $this->parser->parse($this->query, $this->spellcheck, $data); $collations = $result->getCollations(); $this->assertEquals('dell ultrasharp', $collations[0]->getQuery()); @@ -414,7 +418,7 @@ public static function providerParseSingleCollation(): array public function testParseNoData(): void { - $result = $this->parser->parse($this->query, null, []); + $result = $this->parser->parse($this->query, $this->spellcheck, []); $this->assertNull($result); } diff --git a/tests/Component/ResponseParser/StatsTest.php b/tests/Component/ResponseParser/StatsTest.php index 7c2cbc238..119b20b18 100644 --- a/tests/Component/ResponseParser/StatsTest.php +++ b/tests/Component/ResponseParser/StatsTest.php @@ -4,7 +4,7 @@ use PHPUnit\Framework\TestCase; use Solarium\Component\ResponseParser\Stats as Parser; -use Solarium\Exception\InvalidArgumentException; +use Solarium\Component\Stats\Stats; use Solarium\QueryType\Select\Query\Query; class StatsTest extends TestCase @@ -13,10 +13,13 @@ class StatsTest extends TestCase protected Query $query; + protected Stats $stats; + public function setUp(): void { $this->parser = new Parser(); $this->query = new Query(); + $this->stats = $this->query->getStats(); } public function testParse(): void @@ -59,7 +62,7 @@ public function testParse(): void ], ]; - $result = $this->parser->parse($this->query, null, $data); + $result = $this->parser->parse($this->query, $this->stats, $data); $this->assertEquals(3.0, $result->getResult('fieldA')->getMin()); $this->assertEquals(4.0, $result->getResult('fieldB')->getMin()); @@ -87,14 +90,8 @@ public function testParse(): void public function testParseNoData(): void { - $result = $this->parser->parse($this->query, null, []); - $this->assertCount(0, $result); - } + $result = $this->parser->parse($this->query, $this->stats, []); - public function testParseNoQuery(): void - { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('A valid query object needs to be provided.'); - $this->parser->parse(null, null, []); + $this->assertCount(0, $result); } } diff --git a/tests/Component/ResponseParser/SuggesterTest.php b/tests/Component/ResponseParser/SuggesterTest.php index b17d3da47..4d6678213 100644 --- a/tests/Component/ResponseParser/SuggesterTest.php +++ b/tests/Component/ResponseParser/SuggesterTest.php @@ -4,6 +4,7 @@ use PHPUnit\Framework\TestCase; use Solarium\Component\ResponseParser\Suggester as Parser; +use Solarium\Component\Suggester; use Solarium\QueryType\Select\Query\Query; use Solarium\QueryType\Suggester\Result\Dictionary; use Solarium\QueryType\Suggester\Result\Term; @@ -14,10 +15,13 @@ class SuggesterTest extends TestCase protected Query $query; + protected Suggester $suggester; + public function setUp(): void { - $this->query = new Query(); $this->parser = new Parser(); + $this->query = new Query(); + $this->suggester = $this->query->getSuggester(); } /** @@ -27,7 +31,7 @@ public function setUp(): void */ public function testParse($data): void { - $result = $this->parser->parse($this->query, null, $data); + $result = $this->parser->parse($this->query, $this->suggester, $data); $expected = new Dictionary([ 'foo' => new Term(2, [['term' => 'foo'], ['term' => 'foobar']]), @@ -99,7 +103,7 @@ public static function providerParse(): array public function testParseNoData(): void { - $result = $this->parser->parse($this->query, null, []); + $result = $this->parser->parse($this->query, $this->suggester, []); $this->assertNull($result); } diff --git a/tests/Component/ResponseParser/TermVectorTest.php b/tests/Component/ResponseParser/TermVectorTest.php index 79210015e..4bf575617 100644 --- a/tests/Component/ResponseParser/TermVectorTest.php +++ b/tests/Component/ResponseParser/TermVectorTest.php @@ -3,14 +3,13 @@ namespace Solarium\Tests\Component\ResponseParser; use PHPUnit\Framework\TestCase; -use Solarium\Component\TermVector; use Solarium\Component\ResponseParser\TermVector as Parser; use Solarium\Component\Result\TermVector\Document; use Solarium\Component\Result\TermVector\Field; use Solarium\Component\Result\TermVector\Result; use Solarium\Component\Result\TermVector\Term; use Solarium\Component\Result\TermVector\Warnings; -use Solarium\Exception\InvalidArgumentException; +use Solarium\Component\TermVector; use Solarium\QueryType\Select\Query\Query; class TermVectorTest extends TestCase @@ -25,7 +24,7 @@ public function setUp(): void { $this->parser = new Parser(); $this->query = new Query(); - $this->tv = new TermVector(); + $this->tv = $this->query->getTermVector(); } /** @@ -563,11 +562,4 @@ public function testParseNoData(): void $this->assertNull($result); } - - public function testParseNoQuery(): void - { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('A valid query object needs to be provided.'); - $this->parser->parse(null, $this->tv, []); - } } diff --git a/tests/Component/ResponseParser/TermsTest.php b/tests/Component/ResponseParser/TermsTest.php new file mode 100644 index 000000000..b5010d680 --- /dev/null +++ b/tests/Component/ResponseParser/TermsTest.php @@ -0,0 +1,89 @@ +parser = new Parser(); + $this->query = new Query(); + $this->terms = new Terms(); + } + + public function testParse(): void + { + $data = [ + 'terms' => [ + 'name' => [ + 'one', + 5, + '184', + 3, + '1gb', + 3, + '3200', + 3, + '400', + 3, + 'ddr', + 3, + 'gb', + 3, + 'ipod', + 3, + 'memory', + 3, + 'pc', + 3, + ], + ], + ]; + + $result = $this->parser->parse($this->query, $this->terms, $data); + + $this->assertEquals([ + 'one', + 184, + '1gb', + 3200, + 400, + 'ddr', + 'gb', + 'ipod', + 'memory', + 'pc', + ], $result->getField('name')->getTerms()); + + $this->assertEquals([ + 'one' => 5, + 184 => 3, + '1gb' => 3, + 3200 => 3, + 400 => 3, + 'ddr' => 3, + 'gb' => 3, + 'ipod' => 3, + 'memory' => 3, + 'pc' => 3, + ], $result->getAll()['name']); + } + + public function testParseNoData(): void + { + $result = $this->parser->parse($this->query, $this->terms, []); + + $this->assertNull($result); + } +} diff --git a/tests/Core/Client/Adapter/CurlTest.php b/tests/Core/Client/Adapter/CurlTest.php index 54db7e0f1..66d1b3996 100644 --- a/tests/Core/Client/Adapter/CurlTest.php +++ b/tests/Core/Client/Adapter/CurlTest.php @@ -84,7 +84,7 @@ public function testExecute(): void $request = new Request(); $endpoint = new Endpoint(); - /** @var Curl&MockObject $mock */ + /** @var MockObject&Curl $mock */ $mock = $this->getMockBuilder(Curl::class) ->onlyMethods(['getData']) ->getMock(); @@ -134,13 +134,16 @@ public static function methodProvider(): array ]; } - public function testCreateHandleForPostRequestWithFileUpload(): void + /** + * @dataProvider methodWithFileUploadProvider + */ + public function testCreateHandleWithFileUpload(string $method): void { $tmpfname = tempnam(sys_get_temp_dir(), 'tst'); file_put_contents($tmpfname, 'Test file contents'); $request = new Request(); - $request->setMethod(Request::METHOD_POST); + $request->setMethod($method); $request->setFileUpload($tmpfname); $request->setIsServerRequest(true); $endpoint = new Endpoint(); @@ -150,6 +153,14 @@ public function testCreateHandleForPostRequestWithFileUpload(): void $this->assertInstanceOf(\CurlHandle::class, $handle); } + public static function methodWithFileUploadProvider(): array + { + return [ + [Request::METHOD_POST], + [Request::METHOD_PUT], + ]; + } + public function testCreateHandleWithCustomRequestHeaders(): void { $request = new Request(); diff --git a/tests/Core/Client/Adapter/HttpTest.php b/tests/Core/Client/Adapter/HttpTest.php index 477caa392..22e7428c3 100644 --- a/tests/Core/Client/Adapter/HttpTest.php +++ b/tests/Core/Client/Adapter/HttpTest.php @@ -30,7 +30,7 @@ public function testExecute(): void $request->setIsServerRequest(true); $endpoint = new Endpoint(); - /** @var Http&MockObject $mock */ + /** @var MockObject&Http $mock */ $mock = $this->getMockBuilder(Http::class) ->onlyMethods(['getData']) ->getMock(); @@ -49,7 +49,7 @@ public function testExecuteErrorResponse(): void $request->setIsServerRequest(true); $endpoint = new Endpoint(); - /** @var Http&MockObject $mock */ + /** @var MockObject&Http $mock */ $mock = $this->getMockBuilder(Http::class) ->onlyMethods(['getData']) ->getMock(); diff --git a/tests/Core/Client/ClientTest.php b/tests/Core/Client/ClientTest.php index 2a0e361ba..4dbc3f95c 100644 --- a/tests/Core/Client/ClientTest.php +++ b/tests/Core/Client/ClientTest.php @@ -533,7 +533,9 @@ public function preCreateRequest(PreCreateRequestEvent $event): self }; $this->client->registerPlugin('testplugin', $observer); - $this->client->getEventDispatcher()->addListener( + /** @var EventDispatcher $dispatcher */ + $dispatcher = $this->client->getEventDispatcher(); + $dispatcher->addListener( Events::PRE_CREATE_REQUEST, [$observer, 'preCreateRequest'] ); @@ -564,7 +566,9 @@ public function postCreateRequest(PostCreateRequestEvent $event): self }; $this->client->registerPlugin('testplugin', $observer); - $this->client->getEventDispatcher()->addListener( + /** @var EventDispatcher $dispatcher */ + $dispatcher = $this->client->getEventDispatcher(); + $dispatcher->addListener( Events::POST_CREATE_REQUEST, [$observer, 'postCreateRequest'] ); @@ -586,7 +590,9 @@ public function testCreateRequestWithOverridingPlugin(): void } $test = $this; - $this->client->getEventDispatcher()->addListener( + /** @var EventDispatcher $dispatcher */ + $dispatcher = $this->client->getEventDispatcher(); + $dispatcher->addListener( Events::PRE_CREATE_REQUEST, function (PreCreateRequestEvent $event) use ($test, $expectedRequest, $expectedEvent): void { $test->assertEquals($expectedEvent, $event); @@ -633,7 +639,9 @@ public function preCreateResult(PreCreateResultEvent $event): self }; $this->client->registerPlugin('testplugin', $observer); - $this->client->getEventDispatcher()->addListener( + /** @var EventDispatcher $dispatcher */ + $dispatcher = $this->client->getEventDispatcher(); + $dispatcher->addListener( Events::PRE_CREATE_RESULT, [$observer, 'preCreateResult'] ); @@ -665,7 +673,9 @@ public function postCreateResult(PostCreateResultEvent $event): self }; $this->client->registerPlugin('testplugin', $observer); - $this->client->getEventDispatcher()->addListener( + /** @var EventDispatcher $dispatcher */ + $dispatcher = $this->client->getEventDispatcher(); + $dispatcher->addListener( Events::POST_CREATE_RESULT, [$observer, 'postCreateResult'] ); @@ -686,7 +696,9 @@ public function testCreateResultWithOverridingPlugin(): void $expectedResult = new Result($query, $response); $test = $this; - $this->client->getEventDispatcher()->addListener( + /** @var EventDispatcher $dispatcher */ + $dispatcher = $this->client->getEventDispatcher(); + $dispatcher->addListener( Events::PRE_CREATE_RESULT, function (PreCreateResultEvent $event) use ($test, $expectedResult, $expectedEvent): void { $test->assertEquals($expectedEvent, $event); @@ -778,7 +790,9 @@ public function preExecute(PreExecuteEvent $event): self } }; - $mock->getEventDispatcher()->addListener(Events::PRE_EXECUTE, [$observer, 'preExecute']); + /** @var EventDispatcher $dispatcher */ + $dispatcher = $mock->getEventDispatcher(); + $dispatcher->addListener(Events::PRE_EXECUTE, [$observer, 'preExecute']); if (method_exists($expectedEvent, 'setDispatcher')) { $expectedEvent->setName(Events::PRE_EXECUTE); @@ -824,7 +838,9 @@ public function postExecute(PostExecuteEvent $event): self } }; - $mock->getEventDispatcher()->addListener(Events::POST_EXECUTE, [$observer, 'postExecute']); + /** @var EventDispatcher $dispatcher */ + $dispatcher = $mock->getEventDispatcher(); + $dispatcher->addListener(Events::POST_EXECUTE, [$observer, 'postExecute']); if (method_exists($expectedEvent, 'setDispatcher')) { $expectedEvent->setName(Events::POST_EXECUTE); @@ -847,7 +863,9 @@ public function testExecuteWithOverridingPlugin(): void } $test = $this; - $this->client->getEventDispatcher()->addListener( + /** @var EventDispatcher $dispatcher */ + $dispatcher = $this->client->getEventDispatcher(); + $dispatcher->addListener( Events::PRE_EXECUTE, function (PreExecuteEvent $event) use ($test, $expectedResult, $expectedEvent): void { $test->assertEquals($expectedEvent, $event); @@ -916,7 +934,9 @@ public function preExecuteRequest(PreExecuteRequestEvent $event): self } }; - $this->client->getEventDispatcher()->addListener( + /** @var EventDispatcher $dispatcher */ + $dispatcher = $this->client->getEventDispatcher(); + $dispatcher->addListener( Events::PRE_EXECUTE_REQUEST, [$observer, 'preExecuteRequest'] ); @@ -956,7 +976,9 @@ public function postExecuteRequest(PostExecuteRequestEvent $event): self } }; - $this->client->getEventDispatcher()->addListener( + /** @var EventDispatcher $dispatcher */ + $dispatcher = $this->client->getEventDispatcher(); + $dispatcher->addListener( Events::POST_EXECUTE_REQUEST, [$observer, 'postExecuteRequest'] ); @@ -977,7 +999,9 @@ public function testExecuteRequestWithOverridingPlugin(): void } $test = $this; - $this->client->getEventDispatcher()->addListener( + /** @var EventDispatcher $dispatcher */ + $dispatcher = $this->client->getEventDispatcher(); + $dispatcher->addListener( Events::PRE_EXECUTE_REQUEST, function (PreExecuteRequestEvent $event) use ($test, $response, $expectedEvent): void { $test->assertEquals($expectedEvent, $event); @@ -1283,7 +1307,9 @@ public function preCreateQuery(PreCreateQueryEvent $event): self } }; - $this->client->getEventDispatcher()->addListener( + /** @var EventDispatcher $dispatcher */ + $dispatcher = $this->client->getEventDispatcher(); + $dispatcher->addListener( Events::PRE_CREATE_QUERY, [$observer, 'preCreateQuery'] ); @@ -1305,7 +1331,9 @@ public function testCreateQueryWithOverridingPlugin(): void } $test = $this; - $this->client->getEventDispatcher()->addListener( + /** @var EventDispatcher $dispatcher */ + $dispatcher = $this->client->getEventDispatcher(); + $dispatcher->addListener( Events::PRE_CREATE_QUERY, function (PreCreateQueryEvent $event) use ($test, $expectedQuery, $expectedEvent): void { $test->assertEquals($expectedEvent, $event); @@ -1343,7 +1371,9 @@ public function postCreateQuery(PostCreateQueryEvent $event): self } }; - $this->client->getEventDispatcher()->addListener( + /** @var EventDispatcher $dispatcher */ + $dispatcher = $this->client->getEventDispatcher(); + $dispatcher->addListener( Events::POST_CREATE_QUERY, [$observer, 'postCreateQuery'] ); diff --git a/tests/Integration/AbstractCloudTestCase.php b/tests/Integration/AbstractCloudTestCase.php index 7176f4575..b8aafb1a1 100644 --- a/tests/Integration/AbstractCloudTestCase.php +++ b/tests/Integration/AbstractCloudTestCase.php @@ -3,6 +3,12 @@ namespace Solarium\Tests\Integration; use Solarium\Core\Client\State\ClusterState; +use Solarium\QueryType\Server\Collections\Result\ClusterStatusResult; +use Solarium\QueryType\Server\Collections\Result\CreateResult; +use Solarium\QueryType\Server\Collections\Result\DeleteResult; +use Solarium\QueryType\Server\Collections\Result\ReloadResult; +use Solarium\QueryType\Server\Configsets\Result\ConfigsetsResult; +use Solarium\QueryType\Server\Configsets\Result\ListConfigsetsResult; /** * Abstract base class. @@ -76,6 +82,7 @@ public function testConfigsetsApi(): void $action = $configsetsQuery->createList(); $configsetsQuery->setAction($action); $result = self::$client->configsets($configsetsQuery); + $this->assertInstanceOf(ListConfigsetsResult::class, $result); $this->assertTrue($result->getWasSuccessful()); $this->assertContains('_default', $result->getConfigSets()); @@ -86,11 +93,13 @@ public function testConfigsetsApi(): void $action->setName('copy_of_techproducts')->setBaseConfigSet('techproducts'); $configsetsQuery->setAction($action); $result = self::$client->configsets($configsetsQuery); + $this->assertInstanceOf(ConfigsetsResult::class, $result); $this->assertTrue($result->getWasSuccessful()); $action = $configsetsQuery->createList(); $configsetsQuery->setAction($action); $result = self::$client->configsets($configsetsQuery); + $this->assertInstanceOf(ListConfigsetsResult::class, $result); $this->assertTrue($result->getWasSuccessful()); $this->assertContains('_default', $result->getConfigSets()); $this->assertContains('techproducts', $result->getConfigSets()); @@ -106,12 +115,14 @@ public function testCreateDelete(): void $action->setNumShards(1); $collectionsQuery->setAction($action); $result = self::$client->collections($collectionsQuery); + $this->assertInstanceOf(CreateResult::class, $result); $this->assertTrue($result->getWasSuccessful()); $action = $collectionsQuery->createDelete(); $action->setName('test'); $collectionsQuery->setAction($action); $result = self::$client->collections($collectionsQuery); + $this->assertInstanceOf(DeleteResult::class, $result); $this->assertTrue($result->getWasSuccessful()); } @@ -123,6 +134,7 @@ public function testReload(): void $action->setName(self::$name); $collectionsQuery->setAction($action); $result = self::$client->collections($collectionsQuery); + $this->assertInstanceOf(ReloadResult::class, $result); $this->assertTrue($result->getWasSuccessful()); } @@ -133,6 +145,7 @@ public function testClusterStatus(): void $action = $collectionsQuery->createClusterStatus(); $collectionsQuery->setAction($action); $result = self::$client->collections($collectionsQuery); + $this->assertInstanceOf(ClusterStatusResult::class, $result); $this->assertTrue($result->getWasSuccessful()); $clusterState = $result->getClusterState(); $this->assertInstanceOf(ClusterState::class, $clusterState); diff --git a/tests/Integration/AbstractTechproductsTestCase.php b/tests/Integration/AbstractTechproductsTestCase.php index 945b27bdb..6ea74e1aa 100644 --- a/tests/Integration/AbstractTechproductsTestCase.php +++ b/tests/Integration/AbstractTechproductsTestCase.php @@ -7,12 +7,14 @@ use Solarium\Component\Highlighting\Highlighting; use Solarium\Component\QueryTraits\GroupingTrait; use Solarium\Component\QueryTraits\TermsTrait; -use Solarium\Component\Result\Facet\Pivot\PivotItem; +use Solarium\Component\Result\Facet\Field as FieldFacet; +use Solarium\Component\Result\Facet\Pivot\Pivot as PivotFacet; use Solarium\Component\Result\Grouping\FieldGroup; use Solarium\Component\Result\Grouping\QueryGroup; use Solarium\Component\Result\Grouping\Result as GroupingResult; use Solarium\Component\Result\Grouping\ValueGroup; use Solarium\Component\Result\Terms\Result as TermsResult; +use Solarium\Component\Terms; use Solarium\Client; use Solarium\Core\Client\Adapter\ConnectionTimeoutAwareInterface; use Solarium\Core\Client\Adapter\Curl; @@ -20,11 +22,12 @@ use Solarium\Core\Client\Request; use Solarium\Core\Client\Response; use Solarium\Core\Event\Events; +use Solarium\Core\Event\PreExecute as PreExecuteEvent; +use Solarium\Core\Event\PreExecuteRequest as PreExecuteRequestEvent; use Solarium\Core\Query\AbstractDocument; use Solarium\Core\Query\AbstractQuery; use Solarium\Core\Query\Helper; use Solarium\Core\Query\RequestBuilderInterface; -use Solarium\Core\Query\Status4xxNoExceptionInterface; use Solarium\Exception\HttpException; use Solarium\Exception\RuntimeException; use Solarium\Exception\UnexpectedValueException; @@ -45,6 +48,7 @@ use Solarium\Plugin\Loadbalancer\Event\Events as LoadbalancerEvents; use Solarium\Plugin\Loadbalancer\Loadbalancer; use Solarium\Plugin\MinimumScoreFilter\MinimumScoreFilter; +use Solarium\Plugin\MinimumScoreFilter\Query as MinimumScoreFilterQuery; use Solarium\Plugin\ParallelExecution\ParallelExecution; use Solarium\Plugin\PrefetchIterator; use Solarium\Plugin\PostBigExtractRequest; @@ -53,18 +57,41 @@ use Solarium\QueryType\Luke\Result\Doc\DocInfo as LukeDocInfo; use Solarium\QueryType\Luke\Result\Fields\FieldInfo as LukeFieldInfo; use Solarium\QueryType\Luke\Result\Index\Index as LukeIndexResult; +use Solarium\QueryType\Luke\Result\Schema\Field\CopyFieldDestInterface; +use Solarium\QueryType\Luke\Result\Schema\Field\DynamicBasedField; use Solarium\QueryType\Luke\Result\Schema\Schema as LukeSchemaResult; +use Solarium\QueryType\ManagedResources\Query\Command\Config as StopwordsConfig; +use Solarium\QueryType\ManagedResources\Query\Command\Config as SynonymsConfig; +use Solarium\QueryType\ManagedResources\Query\Command\Delete as StopwordsDelete; +use Solarium\QueryType\ManagedResources\Query\Command\Delete as SynonymsDelete; +use Solarium\QueryType\ManagedResources\Query\Command\Exists as StopwordsExists; +use Solarium\QueryType\ManagedResources\Query\Command\Exists as SynonymsExists; +use Solarium\QueryType\ManagedResources\Query\Command\Remove as StopwordsRemove; +use Solarium\QueryType\ManagedResources\Query\Command\Remove as SynonymsRemove; +use Solarium\QueryType\ManagedResources\Query\Command\Stopwords\Add as StopwordsAdd; +use Solarium\QueryType\ManagedResources\Query\Command\Stopwords\Create as StopwordsCreate; +use Solarium\QueryType\ManagedResources\Query\Command\Synonyms\Add as SynonymsAdd; +use Solarium\QueryType\ManagedResources\Query\Command\Synonyms\Create as SynonymsCreate; use Solarium\QueryType\ManagedResources\Query\Synonyms\Synonyms; +use Solarium\QueryType\ManagedResources\Result\Command as ManagedResourcesCommandResult; use Solarium\QueryType\ManagedResources\Result\Resources\Resource as ResourceResultItem; +use Solarium\QueryType\ManagedResources\Result\Resources\ResourceList as ResourceResult; +use Solarium\QueryType\ManagedResources\Result\Stopwords\WordSet as StopwordsResult; +use Solarium\QueryType\ManagedResources\Result\Synonyms\SynonymMappings as SynonymsResult; use Solarium\QueryType\ManagedResources\Result\Synonyms\Synonyms as SynonymsResultItem; use Solarium\QueryType\Select\Query\Query as SelectQuery; use Solarium\QueryType\Select\Result\Document; use Solarium\QueryType\Select\Result\Result as SelectResult; +use Solarium\QueryType\Server\Api\Result as ApiResult; +use Solarium\QueryType\Update\Query\Command\Add; +use Solarium\QueryType\Update\Query\Command\Commit; +use Solarium\QueryType\Update\Query\Document as UpdateDocument; use Solarium\QueryType\Update\Query\Query as UpdateQuery; use Solarium\QueryType\Update\RequestBuilder\Xml as XmlUpdateRequestBuilder; use Solarium\Support\Utility; use Solarium\Tests\Integration\Plugin\EventTimer; use Symfony\Contracts\EventDispatcher\Event; +use Symfony\Component\EventDispatcher\EventDispatcher; use TRegx\PhpUnit\DataProviders\DataProvider; abstract class AbstractTechproductsTestCase extends TestCase @@ -172,6 +199,7 @@ public static function setUpBeforeClass(): void if (9 <= self::$solrVersion) { $update = self::$client->createUpdate(); + /** @var UpdateDocument $utf8test */ $utf8test = $update->createDocument(); $utf8test->setField('id', 'UTF8TEST'); $utf8test->setField('manu', 'Apache Software Foundation'); @@ -363,6 +391,7 @@ public function testEscapes(string $requestFormat, string $responseWriter): void $update = self::$client->createUpdate(); $update->setRequestFormat($requestFormat); $update->setResponseWriter($responseWriter); + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setField('id', 'solarium-test-escapes'); $doc->setField('name', 'Solarium Test Escapes'); @@ -414,6 +443,7 @@ public function testPhraseQuery(string $requestFormat, string $responseWriter): $update = self::$client->createUpdate(); $update->setResponseWriter($responseWriter); $update->setRequestFormat($requestFormat); + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setField('id', 'solarium-test-phrase'); $doc->setField('name', 'Solarium Test Phrase Query'); @@ -473,7 +503,7 @@ public function testLocalParamValueEscapes(string $requestFormat, string $respon 'space: the final frontier', "'single-quote", '"double-quote', - 'escaped backslash \\', + 'escaped backslash \\\\', 'right-curly-bracket}', // \ in and of itself and {! don't need escaping 'unescaped-backslash-\\', @@ -483,6 +513,7 @@ public function testLocalParamValueEscapes(string $requestFormat, string $respon $update = self::$client->createUpdate(); $update->setResponseWriter($responseWriter); $update->setRequestFormat($requestFormat); + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setField('id', 'solarium-test-localparamvalue-escapes'); $doc->setField('name', 'Solarium Test Local Param Value Escapes'); @@ -511,10 +542,12 @@ public function testLocalParamValueEscapes(string $requestFormat, string $respon $result = self::$client->select($select); foreach ($categories as $cat) { + /** @var FieldFacet $facet */ $facet = $result->getFacetSet()->getFacet($cat); $this->assertEquals([$cat => 1], $facet->getValues()); } + /** @var FieldFacet $facet */ $facet = $result->getFacetSet()->getFacet('electronics'); $this->assertEquals(['electronics and computer1' => 1], $facet->getValues()); @@ -787,8 +820,9 @@ public function testFacetPivotsWithStatsComponent(string $responseWriter): void $stats->createField('{!tag=piv1 min=true max=true mean=true}popularity'); $result = self::$client->select($select); - /** @var PivotItem $pivotItem */ - $pivotItem = $result->getFacetSet()->getFacet('piv1')->getPivot()[0]; + /** @var PivotFacet $pivotFacet */ + $pivotFacet = $result->getFacetSet()->getFacet('piv1'); + $pivotItem = $pivotFacet->getPivot()[0]; $pivotStats = $pivotItem->getStats(); $this->assertCount(2, $pivotStats->getResults()); @@ -1003,6 +1037,7 @@ public function testGroupingComponent(string $responseWriter): void $doc = $docIterator->current(); $this->assertSame('VS1GB400C3', $doc->getFields()['id']); + /** @var GroupingTestQuery $select */ $select = self::$client->createQuery('grouping'); $select->setQuery('memory'); $select->setFields('id,price'); @@ -1029,6 +1064,7 @@ public function testGroupingComponent(string $responseWriter): void 'price' => 74.99, ], $doc); + /** @var QueryGroup $queryGroup */ $queryGroup = $groupingComponentResult->getGroup('price:[100 TO *]'); $this->assertSame(5, $queryGroup->getMatches()); $this->assertSame(3, $queryGroup->getNumFound()); @@ -1459,7 +1495,7 @@ public function testSuggesterBuildAll(): void if ($adapter instanceof TimeoutAwareInterface) { $this->assertSame($timeout, $adapter->getTimeout()); if ($adapter instanceof Curl) { - $this->assertTrue(self::$client->getAdapter()->getOption('return_transfer')); + $this->assertTrue($adapter->getOption('return_transfer')); } } } @@ -1501,6 +1537,7 @@ public function testTermsComponent(string $responseWriter): void { self::$client->registerQueryType('test', TermsTestQuery::class); $select = self::$client->createQuery('test'); + $this->assertInstanceOf(TermsTestQuery::class, $select); $select->setResponseWriter($responseWriter); // Setting distrib to true in a non cloud setup causes exceptions. @@ -1667,12 +1704,14 @@ public function testUpdate(string $requestFormat, string $responseWriter): void $update = self::$client->createUpdate(); $update->setRequestFormat($requestFormat); $update->setResponseWriter($responseWriter); + /** @var UpdateDocument $doc1 */ $doc1 = $update->createDocument(); $doc1->setField('id', 'solarium-test-1'); $doc1->setField('name', 'Solarium Test 1'); $doc1->setField('cat', 'solarium-test'); $doc1->setField('price', 3.14); $doc1->setField('content', ['foo', 'bar']); + /** @var UpdateDocument $doc2 */ $doc2 = $update->createDocument(); $doc2->setField('id', 'solarium-test-2'); $doc2->setField('name', 'Solarium Test 2'); @@ -1748,6 +1787,7 @@ public function testUpdate(string $requestFormat, string $responseWriter): void $update = self::$client->createUpdate(); $update->setRequestFormat($requestFormat); $update->setResponseWriter($responseWriter); + /** @var UpdateDocument $doc1 */ $doc1 = $update->createDocument(); $doc1->setField('id', 'solarium-test-1'); $doc1->setField('name', 'Solarium Test 1'); @@ -1892,6 +1932,7 @@ public function testModifiers(string $requestFormat): void $update = self::$client->createUpdate(); $update->setRequestFormat($requestFormat); + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setField('id', 'solarium-test'); $doc->setField('name', 'Solarium Test'); @@ -1912,6 +1953,7 @@ public function testModifiers(string $requestFormat): void ], $result->getIterator()->current()); // set + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-test'); $doc->setField('cat', 'modifier-set'); @@ -1933,6 +1975,7 @@ public function testModifiers(string $requestFormat): void ], $result->getIterator()->current()); // add & inc + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-test'); $doc->setField('cat', 'modifier-add'); @@ -1955,6 +1998,7 @@ public function testModifiers(string $requestFormat): void ], $result->getIterator()->current()); // add multiple values (non-distinct) + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-test'); $doc->setField('cat', ['modifier-add', 'modifier-add-another']); @@ -1977,6 +2021,7 @@ public function testModifiers(string $requestFormat): void ], $result->getIterator()->current()); // add-distinct + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-test'); $doc->setField('cat', 'modifier-add'); @@ -2001,6 +2046,7 @@ public function testModifiers(string $requestFormat): void // add-distinct with multiple values can add duplicates in Solr 7 cloud mode (SOLR-14550) if (7 === self::$solrVersion && $this instanceof AbstractCloudTestCase) { // we still have to emulate a successful atomic update for the remainder of this test to pass + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-test'); $doc->setField('cat', 'modifier-add-distinct'); @@ -2010,6 +2056,7 @@ public function testModifiers(string $requestFormat): void self::$client->update($update); } else { // add-distinct multiple values + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-test'); $doc->setField('cat', ['modifier-add', 'modifier-add-another', 'modifier-add-distinct']); @@ -2034,6 +2081,7 @@ public function testModifiers(string $requestFormat): void ], $result->getIterator()->current()); // remove & negative inc + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-test'); $doc->setField('cat', 'modifier-set'); @@ -2058,6 +2106,7 @@ public function testModifiers(string $requestFormat): void ], $result->getIterator()->current()); // remove multiple values + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-test'); $doc->setField('cat', ['modifier-add', 'modifier-add-another']); @@ -2078,6 +2127,7 @@ public function testModifiers(string $requestFormat): void ], $result->getIterator()->current()); // removeregex + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-test'); $doc->setField('cat', '^.+-add$'); @@ -2097,6 +2147,7 @@ public function testModifiers(string $requestFormat): void ], $result->getIterator()->current()); // set to empty list + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-test'); $doc->setField('cat', []); @@ -2113,6 +2164,7 @@ public function testModifiers(string $requestFormat): void ], $result->getIterator()->current()); // add to missing field + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-test'); $doc->setField('cat', ['solarium-test']); @@ -2132,6 +2184,7 @@ public function testModifiers(string $requestFormat): void ], $result->getIterator()->current()); // set to null + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-test'); $doc->setField('cat', [null]); @@ -2206,6 +2259,7 @@ public function testNestedDocuments(string $requestFormat): void $update = self::$client->createUpdate(); $update->setRequestFormat($requestFormat); + /** @var UpdateDocument $doc */ $doc = $update->createDocument($data); $update->addDocument($doc); $update->addCommit(true, true); @@ -2471,6 +2525,7 @@ public function testNestedDocuments(string $requestFormat): void 'weight' => 4.0, ], ]; + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-parent'); $doc->setField('cat', 'updated-1'); @@ -2518,6 +2573,7 @@ public function testNestedDocuments(string $requestFormat): void 'cat' => ['solarium-nested-document', 'child', 'added'], 'weight' => 5.0, ]; + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-parent'); $doc->setField('cat', 'updated-2'); @@ -2576,6 +2632,7 @@ public function testNestedDocuments(string $requestFormat): void 'weight' => 7.0, ], ]; + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-parent'); $doc->setField('cat', 'updated-3'); @@ -2649,6 +2706,7 @@ public function testNestedDocuments(string $requestFormat): void 'weight' => 5.4, ], ]; + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-parent'); $doc->setField('cat', 'updated-4'); @@ -2714,6 +2772,7 @@ public function testNestedDocuments(string $requestFormat): void 'cat' => ['solarium-nested-document', 'child', 'added'], 'weight' => 5.0, ]; + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-parent'); $doc->setField('cat', 'updated-5'); @@ -2774,6 +2833,7 @@ public function testNestedDocuments(string $requestFormat): void } else { // atomic update tests are designed to cancel each other out for any Solr version // but the remainder of the test assumes 'cat' has been updated every time + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-parent'); $doc->setField('cat', ['updated-4', 'updated-5']); @@ -2786,6 +2846,7 @@ public function testNestedDocuments(string $requestFormat): void $removeChild = [ 'id' => 'solarium-child-3', ]; + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-parent'); $doc->setField('cat', 'updated-6'); @@ -2848,6 +2909,7 @@ public function testNestedDocuments(string $requestFormat): void 'id' => 'solarium-child-7', ], ]; + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-parent'); $doc->setField('cat', 'updated-7'); @@ -2897,6 +2959,7 @@ public function testNestedDocuments(string $requestFormat): void 'cat' => ['solarium-nested-document', 'child', 'updated-8'], 'weight' => 0.8, ]; + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-parent'); $doc->setField('cat', 'updated-8'); @@ -2935,6 +2998,7 @@ public function testNestedDocuments(string $requestFormat): void ], $iterator->current()); // atomic update: remove a single child document from a pseudo-field + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-parent'); $doc->setField('cat', 'updated-9'); @@ -2969,6 +3033,7 @@ public function testNestedDocuments(string $requestFormat): void } // atomic update: removing all child documents from a pseudo-field + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-parent'); $doc->setField('cat', 'updated-10'); @@ -3208,6 +3273,7 @@ public function testUpdateCbor(): void // add $update = self::$client->createUpdate(); $update->setRequestFormat($update::REQUEST_FORMAT_CBOR); + /** @var UpdateDocument $doc1 */ $doc1 = $update->createDocument(); $doc1->setField('id', 'solarium-cbor-test-1'); $doc1->setField('name', 'Sølåríùm CBOR Tëst 1'); @@ -3216,6 +3282,7 @@ public function testUpdateCbor(): void $doc1->setField('popularity', 5); $doc1->setField('inStock', true); $doc1->setField('content', ['foo', 'bar']); + /** @var UpdateDocument $doc2 */ $doc2 = $update->createDocument(); $doc2->setField('id', 'solarium-cbor-test-2'); $doc2->setField('name', 'Sølåríùm CBOR Tëst 2'); @@ -3261,6 +3328,7 @@ public function testUpdateCbor(): void try { $update = self::$client->createUpdate(); $update->setRequestFormat($update::REQUEST_FORMAT_CBOR); + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setKey('id', 'solarium-cbor-test-1'); $doc->setField('popularity', -1); @@ -3317,6 +3385,7 @@ public function testUpdateCbor(): void ]; $update = self::$client->createUpdate(); $update->setRequestFormat($update::REQUEST_FORMAT_CBOR); + /** @var UpdateDocument $doc */ $doc = $update->createDocument($data); $update->addDocument($doc); $update->addParam('commit', true); @@ -3431,10 +3500,14 @@ public function testBufferedAdd(): void $update = self::$client->createUpdate(); // can't be null at this point because phpstan analyses the ADD_DOCUMENT listener with this value even though it's never executed with it + /** @var UpdateDocument $document */ $document = $update->createDocument(); $weight = 0; - self::$client->getEventDispatcher()->addListener( + /** @var EventDispatcher $dispatcher */ + $dispatcher = self::$client->getEventDispatcher(); + + $dispatcher->addListener( BufferedAddEvents::ADD_DOCUMENT, $addDocument = function (BufferedAddAddDocumentEvent $event) use (&$document, &$weight) { $this->assertSame($document, $event->getDocument()); @@ -3442,7 +3515,7 @@ public function testBufferedAdd(): void } ); - self::$client->getEventDispatcher()->addListener( + $dispatcher->addListener( BufferedAddEvents::PRE_FLUSH, $preFlush = function (BufferedAddPreFlushEvent $event) use ($bufferSize, &$document, &$weight) { static $i = 0; @@ -3461,22 +3534,25 @@ public function testBufferedAdd(): void } ); - self::$client->getEventDispatcher()->addListener( + $dispatcher->addListener( BufferedAddEvents::POST_FLUSH, $postFlush = function (BufferedAddPostFlushEvent $event) use ($bufferSize) { $result = $event->getResult(); $this->assertSame(0, $result->getStatus()); $query = $result->getQuery(); + $this->assertInstanceOf(UpdateQuery::class, $query); + $commands = $query->getCommands(); $this->assertCount(1, $commands); + $this->assertInstanceOf(Add::class, $commands[0]); $this->assertSame(UpdateQuery::COMMAND_ADD, $commands[0]->getType()); // we added 1 document to the full buffer in PRE_FLUSH $this->assertCount($bufferSize + 1, $commands[0]->getDocuments()); } ); - self::$client->getEventDispatcher()->addListener( + $dispatcher->addListener( BufferedAddEvents::PRE_COMMIT, $preCommit = function (BufferedAddPreCommitEvent $event) use ($bufferSize, $totalDocs, &$document, &$weight) { static $i = 0; @@ -3495,16 +3571,20 @@ public function testBufferedAdd(): void } ); - self::$client->getEventDispatcher()->addListener( + $dispatcher->addListener( BufferedAddEvents::POST_COMMIT, $postCommit = function (BufferedAddPostCommitEvent $event) use ($bufferSize, $totalDocs) { $result = $event->getResult(); $this->assertSame(0, $result->getStatus()); $query = $result->getQuery(); + $this->assertInstanceOf(UpdateQuery::class, $query); + $commands = $query->getCommands(); $this->assertCount(2, $commands); + $this->assertInstanceOf(Add::class, $commands[0]); $this->assertSame(UpdateQuery::COMMAND_ADD, $commands[0]->getType()); + $this->assertInstanceOf(Commit::class, $commands[1]); $this->assertSame(UpdateQuery::COMMAND_COMMIT, $commands[1]->getType()); // we added 1 document to the remaining buffer in PRE_COMMIT $this->assertCount(($totalDocs % $bufferSize) + 1, $commands[0]->getDocuments()); @@ -3578,11 +3658,11 @@ public function testBufferedAdd(): void ], $ids); // cleanup - self::$client->getEventDispatcher()->removeListener(BufferedAddEvents::ADD_DOCUMENT, $addDocument); - self::$client->getEventDispatcher()->removeListener(BufferedAddEvents::PRE_FLUSH, $preFlush); - self::$client->getEventDispatcher()->removeListener(BufferedAddEvents::POST_FLUSH, $postFlush); - self::$client->getEventDispatcher()->removeListener(BufferedAddEvents::PRE_COMMIT, $preCommit); - self::$client->getEventDispatcher()->removeListener(BufferedAddEvents::POST_COMMIT, $postCommit); + $dispatcher->removeListener(BufferedAddEvents::ADD_DOCUMENT, $addDocument); + $dispatcher->removeListener(BufferedAddEvents::PRE_FLUSH, $preFlush); + $dispatcher->removeListener(BufferedAddEvents::POST_FLUSH, $postFlush); + $dispatcher->removeListener(BufferedAddEvents::PRE_COMMIT, $preCommit); + $dispatcher->removeListener(BufferedAddEvents::POST_COMMIT, $postCommit); self::$client->removePlugin('bufferedadd'); } @@ -3606,7 +3686,10 @@ public function testBufferedDelete(): void $id = ''; $query = ''; - self::$client->getEventDispatcher()->addListener( + /** @var EventDispatcher $dispatcher */ + $dispatcher = self::$client->getEventDispatcher(); + + $dispatcher->addListener( BufferedDeleteEvents::ADD_DELETE_BY_ID, $addDeleteById = function (BufferedDeleteAddDeleteByIdEvent $event) use (&$id) { $this->assertSame($id, $event->getId()); @@ -3615,7 +3698,7 @@ public function testBufferedDelete(): void } ); - self::$client->getEventDispatcher()->addListener( + $dispatcher->addListener( BufferedDeleteEvents::ADD_DELETE_QUERY, $addDeleteQuery = function (BufferedDeleteAddDeleteQueryEvent $event) use (&$query) { $this->assertSame($query, $event->getQuery()); @@ -3661,8 +3744,8 @@ public function testBufferedDelete(): void ], $ids); // cleanup - self::$client->getEventDispatcher()->removeListener(BufferedDeleteEvents::ADD_DELETE_BY_ID, $addDeleteById); - self::$client->getEventDispatcher()->removeListener(BufferedDeleteEvents::ADD_DELETE_QUERY, $addDeleteQuery); + $dispatcher->removeListener(BufferedDeleteEvents::ADD_DELETE_BY_ID, $addDeleteById); + $dispatcher->removeListener(BufferedDeleteEvents::ADD_DELETE_QUERY, $addDeleteQuery); $buffer->addDeleteQuery('cat:solarium-bufferedadd'); $buffer->commit(null, true, true); self::$client->removePlugin('buffereddelete'); @@ -3688,14 +3771,19 @@ public function testBufferedAddAndDelete(string $requestFormat): void $weight = 0; - self::$client->getEventDispatcher()->addListener( + /** @var EventDispatcher $dispatcher */ + $dispatcher = self::$client->getEventDispatcher(); + + $dispatcher->addListener( BufferedAddEvents::ADD_DOCUMENT, $addDocument = function (BufferedAddAddDocumentEvent $event) use (&$weight) { - $event->getDocument()->setField('weight', ++$weight); + $doc = $event->getDocument(); + $this->assertInstanceOf(UpdateDocument::class, $doc); + $doc->setField('weight', ++$weight); } ); - self::$client->getEventDispatcher()->addListener( + $dispatcher->addListener( BufferedDeleteEvents::ADD_DELETE_QUERY, $addDeleteQuery = function (BufferedDeleteAddDeleteQueryEvent $event) { // other documents in techproducts must never be deleted by this test @@ -3777,8 +3865,8 @@ public function testBufferedAddAndDelete(string $requestFormat): void ], $ids); // cleanup - self::$client->getEventDispatcher()->removeListener(BufferedAddEvents::ADD_DOCUMENT, $addDocument); - self::$client->getEventDispatcher()->removeListener(BufferedDeleteEvents::ADD_DELETE_QUERY, $addDeleteQuery); + $dispatcher->removeListener(BufferedAddEvents::ADD_DOCUMENT, $addDocument); + $dispatcher->removeListener(BufferedDeleteEvents::ADD_DELETE_QUERY, $addDeleteQuery); $delBuffer->addDeleteQuery('cat:solarium-bufferedadd'); $delBuffer->commit(null, true, true); self::$client->removePlugin('bufferedadd'); @@ -3805,11 +3893,13 @@ public function testBufferedAddLite(): int $this->fail(sprintf('BufferedAddLite isn\'t supposed to trigger %s', \get_class($event))); }; - self::$client->getEventDispatcher()->addListener(BufferedAddEvents::ADD_DOCUMENT, $failListener); - self::$client->getEventDispatcher()->addListener(BufferedAddEvents::PRE_FLUSH, $failListener); - self::$client->getEventDispatcher()->addListener(BufferedAddEvents::POST_FLUSH, $failListener); - self::$client->getEventDispatcher()->addListener(BufferedAddEvents::PRE_COMMIT, $failListener); - self::$client->getEventDispatcher()->addListener(BufferedAddEvents::POST_COMMIT, $failListener); + /** @var EventDispatcher $dispatcher */ + $dispatcher = self::$client->getEventDispatcher(); + $dispatcher->addListener(BufferedAddEvents::ADD_DOCUMENT, $failListener); + $dispatcher->addListener(BufferedAddEvents::PRE_FLUSH, $failListener); + $dispatcher->addListener(BufferedAddEvents::POST_FLUSH, $failListener); + $dispatcher->addListener(BufferedAddEvents::PRE_COMMIT, $failListener); + $dispatcher->addListener(BufferedAddEvents::POST_COMMIT, $failListener); /** @var BufferedAddLite $buffer */ $buffer = self::$client->getPlugin('bufferedaddlite'); @@ -3871,11 +3961,11 @@ public function testBufferedAddLite(): int ], $ids); // cleanup - self::$client->getEventDispatcher()->removeListener(BufferedAddEvents::ADD_DOCUMENT, $failListener); - self::$client->getEventDispatcher()->removeListener(BufferedAddEvents::PRE_FLUSH, $failListener); - self::$client->getEventDispatcher()->removeListener(BufferedAddEvents::POST_FLUSH, $failListener); - self::$client->getEventDispatcher()->removeListener(BufferedAddEvents::PRE_COMMIT, $failListener); - self::$client->getEventDispatcher()->removeListener(BufferedAddEvents::POST_COMMIT, $failListener); + $dispatcher->removeListener(BufferedAddEvents::ADD_DOCUMENT, $failListener); + $dispatcher->removeListener(BufferedAddEvents::PRE_FLUSH, $failListener); + $dispatcher->removeListener(BufferedAddEvents::POST_FLUSH, $failListener); + $dispatcher->removeListener(BufferedAddEvents::PRE_COMMIT, $failListener); + $dispatcher->removeListener(BufferedAddEvents::POST_COMMIT, $failListener); self::$client->removePlugin('bufferedaddlite'); return $totalDocs; @@ -3900,12 +3990,14 @@ public function testBufferedDeleteLite(int $totalDocs): void $this->fail(sprintf('BufferedDeleteLite isn\'t supposed to trigger %s', \get_class($event))); }; - self::$client->getEventDispatcher()->addListener(BufferedDeleteEvents::ADD_DELETE_BY_ID, $failListener); - self::$client->getEventDispatcher()->addListener(BufferedDeleteEvents::ADD_DELETE_QUERY, $failListener); - self::$client->getEventDispatcher()->addListener(BufferedDeleteEvents::PRE_FLUSH, $failListener); - self::$client->getEventDispatcher()->addListener(BufferedDeleteEvents::POST_FLUSH, $failListener); - self::$client->getEventDispatcher()->addListener(BufferedDeleteEvents::PRE_COMMIT, $failListener); - self::$client->getEventDispatcher()->addListener(BufferedDeleteEvents::POST_COMMIT, $failListener); + /** @var EventDispatcher $dispatcher */ + $dispatcher = self::$client->getEventDispatcher(); + $dispatcher->addListener(BufferedDeleteEvents::ADD_DELETE_BY_ID, $failListener); + $dispatcher->addListener(BufferedDeleteEvents::ADD_DELETE_QUERY, $failListener); + $dispatcher->addListener(BufferedDeleteEvents::PRE_FLUSH, $failListener); + $dispatcher->addListener(BufferedDeleteEvents::POST_FLUSH, $failListener); + $dispatcher->addListener(BufferedDeleteEvents::PRE_COMMIT, $failListener); + $dispatcher->addListener(BufferedDeleteEvents::POST_COMMIT, $failListener); /** @var BufferedDeleteLite $buffer */ $buffer = self::$client->getPlugin('buffereddeletelite'); @@ -3926,12 +4018,12 @@ public function testBufferedDeleteLite(int $totalDocs): void $this->assertSame(0, $result->getNumFound()); // cleanup - self::$client->getEventDispatcher()->removeListener(BufferedDeleteEvents::ADD_DELETE_BY_ID, $failListener); - self::$client->getEventDispatcher()->removeListener(BufferedDeleteEvents::ADD_DELETE_QUERY, $failListener); - self::$client->getEventDispatcher()->removeListener(BufferedDeleteEvents::PRE_FLUSH, $failListener); - self::$client->getEventDispatcher()->removeListener(BufferedDeleteEvents::POST_FLUSH, $failListener); - self::$client->getEventDispatcher()->removeListener(BufferedDeleteEvents::PRE_COMMIT, $failListener); - self::$client->getEventDispatcher()->removeListener(BufferedDeleteEvents::POST_COMMIT, $failListener); + $dispatcher->removeListener(BufferedDeleteEvents::ADD_DELETE_BY_ID, $failListener); + $dispatcher->removeListener(BufferedDeleteEvents::ADD_DELETE_QUERY, $failListener); + $dispatcher->removeListener(BufferedDeleteEvents::PRE_FLUSH, $failListener); + $dispatcher->removeListener(BufferedDeleteEvents::POST_FLUSH, $failListener); + $dispatcher->removeListener(BufferedDeleteEvents::PRE_COMMIT, $failListener); + $dispatcher->removeListener(BufferedDeleteEvents::POST_COMMIT, $failListener); self::$client->removePlugin('buffereddeletelite'); } @@ -4050,6 +4142,7 @@ public function testBufferedAddCbor(): void $bufferSize = 10; $totalDocs = 25; + /** @var BufferedAddLite $buffer */ $buffer = self::$client->getPlugin('bufferedaddlite'); $buffer->setRequestFormat(UpdateQuery::REQUEST_FORMAT_CBOR); $buffer->setBufferSize($bufferSize); @@ -4137,7 +4230,9 @@ public function testLoadbalancerFailover(): void $loadbalancer->setForcedEndpointForNextQuery('invalid'); $invalidEndpointListenerCalled = 0; - self::$client->getEventDispatcher()->addListener( + /** @var EventDispatcher $dispatcher */ + $dispatcher = self::$client->getEventDispatcher(); + $dispatcher->addListener( LoadbalancerEvents::ENDPOINT_FAILURE, $invalidEndpointListener = function (LoadbalancerEndpointFailureEvent $event) use (&$invalidEndpoint, &$invalidEndpointListenerCalled) { ++$invalidEndpointListenerCalled; @@ -4153,7 +4248,7 @@ public function testLoadbalancerFailover(): void $this->assertSame('localhost', $loadbalancer->getLastEndpoint()); // cleanup - self::$client->getEventDispatcher()->removeListener(LoadbalancerEvents::ENDPOINT_FAILURE, $invalidEndpointListener); + $dispatcher->removeListener(LoadbalancerEvents::ENDPOINT_FAILURE, $invalidEndpointListener); self::$client->removePlugin('loadbalancer'); self::$client->removeEndpoint('invalid'); } @@ -4168,6 +4263,9 @@ public function testMinimumScoreFilterWithGrouping(string $responseWriter): void /** @var MinimumScoreFilter $filter */ $filter = self::$client->getPlugin('minimumscorefilter'); $query = self::$client->createQuery($filter::QUERY_TYPE); + + $this->assertInstanceOf(MinimumScoreFilterQuery::class, $query); + $query->setResponseWriter($responseWriter); $query->setQuery('*:*'); @@ -4255,9 +4353,11 @@ public function testParallelExecution(): void $serverResult = self::$client->execute($serverQuery); // events should be dispatched as usual - self::$client->getEventDispatcher()->addListener( + /** @var EventDispatcher $dispatcher */ + $dispatcher = self::$client->getEventDispatcher(); + $dispatcher->addListener( Events::PRE_EXECUTE, - $overrideResult = function (Event $event) use ($resultOverrideResult) { + $overrideResult = function (PreExecuteEvent $event) use ($resultOverrideResult) { $query = $event->getQuery(); // if this test fails, the listener will remain active and would cause errors for other QueryTypes if ($query instanceof SelectQuery && 'id:parallel-1' === $query->getQuery()) { @@ -4265,9 +4365,9 @@ public function testParallelExecution(): void } } ); - self::$client->getEventDispatcher()->addListener( + $dispatcher->addListener( Events::PRE_EXECUTE_REQUEST, - $overrideResponse = function (Event $event) use ($responseOverrideResponse) { + $overrideResponse = function (PreExecuteRequestEvent $event) use ($responseOverrideResponse) { if ('id:parallel-2' === $event->getRequest()->getParam('q')) { $event->setResponse($responseOverrideResponse); } @@ -4315,8 +4415,8 @@ public function testParallelExecution(): void $this->assertEquals($serverResult, $results['server']); // cleanup - self::$client->getEventDispatcher()->removeListener(Events::PRE_EXECUTE, $overrideResult); - self::$client->getEventDispatcher()->removeListener(Events::PRE_EXECUTE_REQUEST, $overrideResponse); + $dispatcher->removeListener(Events::PRE_EXECUTE, $overrideResult); + $dispatcher->removeListener(Events::PRE_EXECUTE_REQUEST, $overrideResponse); self::$client->removePlugin('parallelexecution'); self::$client->removePlugin('postbigrequest'); self::$client->removeEndpoint('invalid'); @@ -4940,6 +5040,8 @@ public function testLuke(string $responseWriter): void $price = $schema->getField('price'); $price_c = $price->getCopyDests()[0]; $_c = $schema->getDynamicField('*_c'); + $this->assertInstanceOf(CopyFieldDestInterface::class, $price_c); + $this->assertInstanceOf(DynamicBasedField::class, $price_c); $this->assertContains($price, $price_c->getCopySources()); $this->assertSame($_c, $price_c->getDynamicBase()); @@ -5031,6 +5133,7 @@ public function testV2Api(): void 'version' => Request::API_V2, 'handler' => 'node/_introspect', ]); + /** @var ApiResult $response */ $response = self::$client->execute($query); $this->assertSame('This response format is experimental. It is likely to change in the future.', $response->getWarning()); } else { @@ -5053,6 +5156,7 @@ public function testInputEncoding(): void // input encoding: UTF-8 (default) $update = self::$client->createUpdate(); $update->setRequestFormat(UpdateQuery::REQUEST_FORMAT_XML); + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setField('id', 'solarium-test-1'); $doc->setField('name', 'Sølåríùm Tëst 1'); @@ -5089,6 +5193,7 @@ public function testInputEncoding(): void $update = self::$client->createUpdate(); $update->setRequestFormat(UpdateQuery::REQUEST_FORMAT_XML); $update->setInputEncoding('ISO-8859-1'); + /** @var UpdateDocument $doc */ $doc = $update->createDocument(); $doc->setField('id', iconv('UTF-8', 'ISO-8859-1', 'solarium-test-2')); $doc->setField('name', iconv('UTF-8', 'ISO-8859-1', 'Sølåríùm Tëst 2')); @@ -5167,22 +5272,28 @@ public function testManagedStopwords(): void $term = '\'tis'; // Check that stopword list exists + /** @var StopwordsExists $exists */ $exists = $query->createCommand($query::COMMAND_EXISTS, $this->getManagedResourcesExistsCommandOptions()); $query->setCommand($exists); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); // Add stopwords + /** @var StopwordsAdd $add */ $add = $query->createCommand($query::COMMAND_ADD); $add->setStopwords([$term]); $query->setCommand($add); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); // Check that added stopword exists + /** @var StopwordsExists $exists */ $exists = $query->createCommand($query::COMMAND_EXISTS, $this->getManagedResourcesExistsCommandOptions()); $exists->setTerm($term); $query->setCommand($exists); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); @@ -5190,33 +5301,40 @@ public function testManagedStopwords(): void $query->removeCommand(); // List stopwords + /** @var StopwordsResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); $this->assertContains($term, $result->getItems()); // List added stopword only $query->setTerm($term); + /** @var StopwordsResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); $this->assertSame([$term], $result->getItems()); // Delete added stopword + /** @var StopwordsDelete $delete */ $delete = $query->createCommand($query::COMMAND_DELETE); $delete->setTerm($term); $query->setCommand($delete); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); // Check that added stopword is gone + /** @var StopwordsExists $exists */ $exists = $query->createCommand($query::COMMAND_EXISTS, $this->getManagedResourcesExistsCommandOptions()); $exists->setTerm($term); $query->setCommand($exists); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertFalse($result->getWasSuccessful()); // List no longer added stopword $query->setTerm($term); $query->removeCommand(); + /** @var StopwordsResult $result */ $result = self::$client->execute($query); $this->assertFalse($result->getWasSuccessful()); $this->assertSame([], $result->getItems()); @@ -5237,72 +5355,91 @@ public function testManagedStopwordsCreation(string $name, string $term): void $query->setName($name.uniqid()); // Check that stopword list doesn't exist + /** @var StopwordsExists $exists */ $exists = $query->createCommand($query::COMMAND_EXISTS, $this->getManagedResourcesExistsCommandOptions()); $query->setCommand($exists); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertFalse($result->getWasSuccessful()); // Create a new stopword list + /** @var StopwordsCreate $create */ $create = $query->createCommand($query::COMMAND_CREATE); $query->setCommand($create); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); // Configure the new list to be case sensitive $initArgs = $query->createInitArgs(); $initArgs->setIgnoreCase(false); + /** @var StopwordsConfig $config */ $config = $query->createCommand($query::COMMAND_CONFIG); $config->setInitArgs($initArgs); $query->setCommand($config); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); // Check that stopword list was created + /** @var StopwordsExists $exists */ $exists = $query->createCommand($query::COMMAND_EXISTS, $this->getManagedResourcesExistsCommandOptions()); $query->setCommand($exists); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); // Check the configuration $query->removeCommand(); + /** @var StopwordsResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); $this->assertFalse($result->isIgnoreCase()); // Check that we can add to it + /** @var StopwordsAdd $add */ $add = $query->createCommand($query::COMMAND_ADD); $add->setStopwords([$term]); $query->setCommand($add); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); // Check that added stopword exists in its original lowercase form + /** @var StopwordsExists $exists */ $exists = $query->createCommand($query::COMMAND_EXISTS, $this->getManagedResourcesExistsCommandOptions()); $exists->setTerm($term); $query->setCommand($exists); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); // Check that added stopword DOESN'T exist in uppercase form $exists->setTerm(strtoupper($term)); $query->setCommand($exists); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertFalse($result->getWasSuccessful()); // Remove the stopword list + /** @var StopwordsRemove $remove */ $remove = $query->createCommand($query::COMMAND_REMOVE); $query->setCommand($remove); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); // Check that stopword list is gone + /** @var StopwordsExists $exists */ $exists = $query->createCommand($query::COMMAND_EXISTS, $this->getManagedResourcesExistsCommandOptions()); $query->setCommand($exists); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertFalse($result->getWasSuccessful()); // Check that list can no longer be listed $query->removeCommand(); + /** @var StopwordsResult $result */ $result = self::$client->execute($query); $this->assertFalse($result->getWasSuccessful()); $this->assertSame([], $result->getItems()); @@ -5316,25 +5453,31 @@ public function testManagedSynonyms(): void $synonymList = ['bar', 'pub']; // Check that synonym map exists + /** @var SynonymsExists $exists */ $exists = $query->createCommand($query::COMMAND_EXISTS, $this->getManagedResourcesExistsCommandOptions()); $query->setCommand($exists); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); // Add synonym mapping + /** @var SynonymsAdd $add */ $add = $query->createCommand($query::COMMAND_ADD); $synonyms = new Synonyms(); $synonyms->setTerm($term); $synonyms->setSynonyms($synonymList); $add->setSynonyms($synonyms); $query->setCommand($add); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); // Check that added synonym mapping exsists + /** @var SynonymsExists $exists */ $exists = $query->createCommand($query::COMMAND_EXISTS, $this->getManagedResourcesExistsCommandOptions()); $exists->setTerm($term); $query->setCommand($exists); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); @@ -5342,6 +5485,7 @@ public function testManagedSynonyms(): void $query->removeCommand(); // List synonyms + /** @var SynonymsResult $result */ $result = self::$client->execute($query); $items = $result->getItems(); $this->assertTrue($result->getWasSuccessful()); @@ -5359,6 +5503,7 @@ public function testManagedSynonyms(): void // List added synonym mapping only $query->setTerm($term); + /** @var SynonymsResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); $this->assertEquals( @@ -5367,22 +5512,27 @@ public function testManagedSynonyms(): void ); // Delete added synonym mapping + /** @var SynonymsDelete $delete */ $delete = $query->createCommand($query::COMMAND_DELETE); $delete->setTerm($term); $query->setCommand($delete); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); // Check that added synonym mapping is gone + /** @var SynonymsExists $exists */ $exists = $query->createCommand($query::COMMAND_EXISTS, $this->getManagedResourcesExistsCommandOptions()); $exists->setTerm($term); $query->setCommand($exists); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertFalse($result->getWasSuccessful()); // List no longer added synonym mapping $query->setTerm($term); $query->removeCommand(); + /** @var SynonymsResult $result */ $result = self::$client->execute($query); $this->assertFalse($result->getWasSuccessful()); $this->assertSame([], $result->getItems()); @@ -5403,14 +5553,18 @@ public function testManagedSynonymsCreation(string $name, string $term): void $query->setName($name.uniqid()); // Check that synonym map doesn't exist + /** @var SynonymsExists $exists */ $exists = $query->createCommand($query::COMMAND_EXISTS, $this->getManagedResourcesExistsCommandOptions()); $query->setCommand($exists); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertFalse($result->getWasSuccessful()); // Create a new synonym map + /** @var SynonymsCreate $create */ $create = $query->createCommand($query::COMMAND_CREATE); $query->setCommand($create); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); @@ -5418,62 +5572,77 @@ public function testManagedSynonymsCreation(string $name, string $term): void $initArgs = $query->createInitArgs(); $initArgs->setIgnoreCase(false); $initArgs->setFormat($initArgs::FORMAT_SOLR); + /** @var SynonymsConfig $config */ $config = $query->createCommand($query::COMMAND_CONFIG); $config->setInitArgs($initArgs); $query->setCommand($config); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); // Check that synonym map was created + /** @var SynonymsExists $exists */ $exists = $query->createCommand($query::COMMAND_EXISTS, $this->getManagedResourcesExistsCommandOptions()); $query->setCommand($exists); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); // Check the configuration $query->removeCommand(); + /** @var SynonymsResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); $this->assertFalse($result->isIgnoreCase()); $this->assertEquals($initArgs::FORMAT_SOLR, $result->getFormat()); // Check that we can add to it + /** @var SynonymsAdd $add */ $add = $query->createCommand($query::COMMAND_ADD); $synonyms = new Synonyms(); $synonyms->setTerm($term); $synonyms->setSynonyms(['managed_synonym', 'synonym_test']); $add->setSynonyms($synonyms); $query->setCommand($add); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); // Check that synonym exists in its original lowercase form + /** @var SynonymsExists $exists */ $exists = $query->createCommand($query::COMMAND_EXISTS, $this->getManagedResourcesExistsCommandOptions()); $exists->setTerm($term); $query->setCommand($exists); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); // Check that synonym DOESN'T exist in uppercase form $exists->setTerm(strtoupper($term)); $query->setCommand($exists); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertFalse($result->getWasSuccessful()); // Remove the synonym map + /** @var SynonymsRemove $remove */ $remove = $query->createCommand($query::COMMAND_REMOVE); $query->setCommand($remove); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertTrue($result->getWasSuccessful()); // Check that synonym map is gone + /** @var SynonymsExists $exists */ $exists = $query->createCommand($query::COMMAND_EXISTS, $this->getManagedResourcesExistsCommandOptions()); $query->setCommand($exists); + /** @var ManagedResourcesCommandResult $result */ $result = self::$client->execute($query); $this->assertFalse($result->getWasSuccessful()); // Check that map can no longer be listed $query->removeCommand(); + /** @var SynonymsResult $result */ $result = self::$client->execute($query); $this->assertFalse($result->getWasSuccessful()); $this->assertSame([], $result->getItems()); @@ -5482,6 +5651,7 @@ public function testManagedSynonymsCreation(string $name, string $term): void public function testManagedResources(): void { $query = self::$client->createManagedResources(); + /** @var ResourceResult $result */ $result = self::$client->execute($query); $items = $result->getItems(); @@ -5515,11 +5685,11 @@ public function testManagedResources(): void public function testGetBodyOnHttpError(): void { - /** @var Status4xxNoExceptionInterface $query */ $query = self::$client->createManagedSynonyms(); $query->setName('english'); $query->setTerm('foo'); + /** @var SynonymsResult $result */ $result = self::$client->execute($query); $this->assertFalse($result->getWasSuccessful()); @@ -5581,7 +5751,7 @@ class TermsTestQuery extends SelectQuery public function __construct(?array $options = null) { parent::__construct($options); - $this->componentTypes[ComponentAwareQueryInterface::COMPONENT_TERMS] = 'Solarium\Component\Terms'; + $this->componentTypes[ComponentAwareQueryInterface::COMPONENT_TERMS] = Terms::class; // Unfortunately the terms request Handler is the only one containing a terms component. $this->setHandler('terms'); } diff --git a/tests/Integration/ConnectionReuseTest.php b/tests/Integration/ConnectionReuseTest.php index 776f2e1ce..26659323c 100644 --- a/tests/Integration/ConnectionReuseTest.php +++ b/tests/Integration/ConnectionReuseTest.php @@ -5,6 +5,7 @@ use PHPUnit\Framework\TestCase; use Solarium\Client; use Solarium\Core\Client\Request; +use Solarium\QueryType\Server\Api\Result; /** * Test connection reuse with PSR-18 adapter. @@ -76,6 +77,8 @@ public static function setUpBeforeClass(): void 'version' => Request::API_V2, 'handler' => self::$isNewLoggingApi ? 'node/logging/levels' : 'node/logging', ]); + + /** @var Result $result */ $result = self::$client->execute($query); $connectionLogger = array_values(array_filter( $result->getData()['loggers'], @@ -101,6 +104,8 @@ function (array $logger): bool { ], ] )); + + /** @var Result $result */ $result = self::$client->execute($query); if (!$result->getWasSuccessful()) { @@ -112,6 +117,8 @@ function (array $logger): bool { 'handler' => 'node/logging', ]); $query->addParam('set', 'org.eclipse.jetty.io.AbstractConnection:DEBUG'); + + /** @var Result $result */ $result = self::$client->execute($query); if (!$result->getWasSuccessful()) { @@ -125,6 +132,8 @@ function (array $logger): bool { 'handler' => self::$isNewLoggingApi ? 'node/logging/messages' : 'node/logging', ]); $query->addParam('since', self::$since); + + /** @var Result $result */ $result = self::$client->execute($query); self::$origThreshold = $result->getData()['info']['threshold'] ?? 'WARN'; @@ -141,6 +150,8 @@ function (array $logger): bool { 'level' => 'DEBUG', ] )); + + /** @var Result $result */ $result = self::$client->execute($query); if (!$result->getWasSuccessful()) { @@ -153,6 +164,8 @@ function (array $logger): bool { ]); $query->addParam('since', self::$since); $query->addParam('threshold', 'DEBUG'); + + /** @var Result $result */ $result = self::$client->execute($query); if (!$result->getWasSuccessful()) { @@ -166,6 +179,8 @@ function (array $logger): bool { 'handler' => self::$isNewLoggingApi ? 'node/logging/messages' : 'node/logging', ]); $query->addParam('since', self::$since); + + /** @var Result $result */ $result = self::$client->execute($query); self::$since = $result->getData()['info']['last']; } diff --git a/tests/Integration/Plugin/EventTimer.php b/tests/Integration/Plugin/EventTimer.php index 3e02af885..c0d050c3b 100644 --- a/tests/Integration/Plugin/EventTimer.php +++ b/tests/Integration/Plugin/EventTimer.php @@ -5,6 +5,7 @@ use Solarium\Core\Event\Events; use Solarium\Core\Plugin\AbstractPlugin; use Solarium\Plugin\ParallelExecution\Event\Events as ParallelExecutionEvents; +use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Contracts\EventDispatcher\Event; /** @@ -31,6 +32,7 @@ class EventTimer extends AbstractPlugin */ protected function initPluginType(): void { + /** @var EventDispatcher $dispatcher */ $dispatcher = $this->client->getEventDispatcher(); $dispatcher->addListener(Events::PRE_CREATE_REQUEST, $this->events['preCrReq'] = function () { $this->log('preCreateRequest'); }); $dispatcher->addListener(Events::POST_CREATE_REQUEST, $this->events['postCrReq'] = function () { $this->log('postCreateRequest'); }); @@ -55,6 +57,7 @@ protected function initPluginType(): void */ public function deinitPlugin(): void { + /** @var EventDispatcher $dispatcher */ $dispatcher = $this->client->getEventDispatcher(); $dispatcher->removeListener(Events::PRE_CREATE_REQUEST, $this->events['preCrReq']); $dispatcher->removeListener(Events::POST_CREATE_REQUEST, $this->events['postCrReq']); diff --git a/tests/Integration/Proxy/AbstractProxyTestCase.php b/tests/Integration/Proxy/AbstractProxyTestCase.php index 0f51d9e44..767bcc50c 100644 --- a/tests/Integration/Proxy/AbstractProxyTestCase.php +++ b/tests/Integration/Proxy/AbstractProxyTestCase.php @@ -4,7 +4,9 @@ use PHPUnit\Framework\TestCase; use Solarium\Client; +use Solarium\Core\Client\Adapter\ProxyAwareInterface; use Solarium\Core\Client\Request; +use Solarium\QueryType\Server\Api\Result; /** * Abstract test for connecting through a proxy. @@ -48,6 +50,12 @@ public static function setUpBeforeClass(): void public function assertPreConditions(): void { + $this->assertInstanceOf( + ProxyAwareInterface::class, + self::$client->getAdapter(), + 'Client adapter must implement ProxyAwareInterface!' + ); + $this->assertNotNull( self::$client->getAdapter()->getProxy(), 'Proxy test must set a proxy on the Client adapter!' @@ -62,6 +70,7 @@ public function testConnection(): void ]); $result = self::$client->execute($query); + $this->assertInstanceOf(Result::class, $result); $this->assertTrue($result->getWasSuccessful()); } } diff --git a/tests/Integration/Proxy/CurlTest.php b/tests/Integration/Proxy/CurlTest.php index ae364e18b..820e3dfbc 100644 --- a/tests/Integration/Proxy/CurlTest.php +++ b/tests/Integration/Proxy/CurlTest.php @@ -2,8 +2,10 @@ namespace Solarium\Tests\Integration\Proxy; +use Solarium\Core\Client\Adapter\ProxyAwareInterface; use Solarium\Core\Client\Request; use Solarium\Plugin\ParallelExecution\ParallelExecution; +use Solarium\QueryType\Server\Api\Result; use Solarium\Tests\Integration\TestClientFactory; /** @@ -21,6 +23,7 @@ protected static function createClient(): void protected static function setProxy(): void { + self::assertInstanceOf(ProxyAwareInterface::class, self::$client->getAdapter()); self::$client->getAdapter()->setProxy(sprintf('%s:%d', self::$proxy_server, self::$proxy_port)); } @@ -41,7 +44,9 @@ public function testParallelConnections(): void $parallel->addQuery('query2', $query2); $results = $parallel->execute(); + $this->assertInstanceOf(Result::class, $results['query1']); $this->assertTrue($results['query1']->getWasSuccessful()); + $this->assertInstanceOf(Result::class, $results['query2']); $this->assertTrue($results['query2']->getWasSuccessful()); self::$client->removePlugin('parallelexecution'); diff --git a/tests/Integration/Proxy/CustomizedCurlTest.php b/tests/Integration/Proxy/CustomizedCurlTest.php index c021c8694..367f65966 100644 --- a/tests/Integration/Proxy/CustomizedCurlTest.php +++ b/tests/Integration/Proxy/CustomizedCurlTest.php @@ -3,6 +3,7 @@ namespace Solarium\Tests\Integration\Proxy; use Solarium\Core\Client\Adapter\Curl; +use Solarium\Core\Client\Adapter\ProxyAwareInterface; use Solarium\Core\Client\Endpoint; use Solarium\Core\Client\Request; use Solarium\Tests\Integration\TestClientFactory; @@ -23,6 +24,7 @@ protected static function createClient(): void protected static function setProxy(): void { + self::assertInstanceOf(ProxyAwareInterface::class, self::$client->getAdapter()); self::$client->getAdapter()->setProxy(['server' => self::$proxy_server, 'port' => self::$proxy_port]); } } diff --git a/tests/Integration/Proxy/CustomizedHttpTest.php b/tests/Integration/Proxy/CustomizedHttpTest.php index 84edba5d3..9cd29f53f 100644 --- a/tests/Integration/Proxy/CustomizedHttpTest.php +++ b/tests/Integration/Proxy/CustomizedHttpTest.php @@ -3,6 +3,7 @@ namespace Solarium\Tests\Integration\Proxy; use Solarium\Core\Client\Adapter\Http; +use Solarium\Core\Client\Adapter\ProxyAwareInterface; use Solarium\Core\Client\Endpoint; use Solarium\Core\Client\Request; use Solarium\Tests\Integration\TestClientFactory; @@ -23,6 +24,7 @@ protected static function createClient(): void protected static function setProxy(): void { + self::assertInstanceOf(ProxyAwareInterface::class, self::$client->getAdapter()); self::$client->getAdapter()->setProxy(['server' => self::$proxy_server, 'port' => self::$proxy_port]); } } diff --git a/tests/Integration/Proxy/HttpTest.php b/tests/Integration/Proxy/HttpTest.php index 7c94acdd5..b1f03453a 100644 --- a/tests/Integration/Proxy/HttpTest.php +++ b/tests/Integration/Proxy/HttpTest.php @@ -2,6 +2,7 @@ namespace Solarium\Tests\Integration\Proxy; +use Solarium\Core\Client\Adapter\ProxyAwareInterface; use Solarium\Tests\Integration\TestClientFactory; /** @@ -19,6 +20,7 @@ protected static function createClient(): void protected static function setProxy(): void { + self::assertInstanceOf(ProxyAwareInterface::class, self::$client->getAdapter()); self::$client->getAdapter()->setProxy(sprintf('%s:%d', self::$proxy_server, self::$proxy_port)); } } diff --git a/tests/Plugin/BufferedAdd/BufferedAddLiteTest.php b/tests/Plugin/BufferedAdd/BufferedAddLiteTest.php index 156fd2884..1eb8fbaca 100644 --- a/tests/Plugin/BufferedAdd/BufferedAddLiteTest.php +++ b/tests/Plugin/BufferedAdd/BufferedAddLiteTest.php @@ -329,7 +329,7 @@ public function testFlush(string $requestFormat): void $doc2 = new Document(['id' => '456', 'name' => 'test 2']); $doc3 = new Document(['id' => '789', 'name' => 'test 3']); - /** @var Query|MockObject $mockUpdate */ + /** @var MockObject&Query $mockUpdate */ $mockUpdate = $this->getMockBuilder(Query::class) ->onlyMethods(['add']) ->getMock(); @@ -365,7 +365,7 @@ public function testCommit(string $requestFormat): void $doc2 = new Document(['id' => '456', 'name' => 'test 2']); $doc3 = new Document(['id' => '789', 'name' => 'test 3']); - /** @var Query|MockObject $mockUpdate */ + /** @var MockObject&Query $mockUpdate */ $mockUpdate = $this->getMockBuilder(Query::class) ->onlyMethods(['add', 'addCommit']) ->getMock(); @@ -418,7 +418,7 @@ public function testCommitWithOptionalValues(string $requestFormat): void $doc1 = new Document(['id' => '123', 'name' => 'test 1']); $doc2 = new Document(['id' => '456', 'name' => 'test 2']); - /** @var Query|MockObject $mockUpdate */ + /** @var MockObject&Query $mockUpdate */ $mockUpdate = $this->getMockBuilder(Query::class) ->onlyMethods(['add', 'addCommit']) ->getMock(); diff --git a/tests/Plugin/BufferedDelete/BufferedDeleteLiteTest.php b/tests/Plugin/BufferedDelete/BufferedDeleteLiteTest.php index 7526587ba..ab8a7943a 100644 --- a/tests/Plugin/BufferedDelete/BufferedDeleteLiteTest.php +++ b/tests/Plugin/BufferedDelete/BufferedDeleteLiteTest.php @@ -10,8 +10,8 @@ use Solarium\Exception\DomainException; use Solarium\Exception\InvalidArgumentException; use Solarium\Exception\RuntimeException; -use Solarium\Plugin\BufferedDelete\AbstractDelete; use Solarium\Plugin\BufferedDelete\BufferedDeleteLite; +use Solarium\Plugin\BufferedDelete\DeleteInterface; use Solarium\Plugin\BufferedDelete\Delete\Id as DeleteById; use Solarium\Plugin\BufferedDelete\Delete\Query as DeleteQuery; use Solarium\QueryType\Update\Query\Command\Delete as DeleteCommand; @@ -341,7 +341,7 @@ public function testFlushEmptyBuffer(): void */ public function testFlush(string $requestFormat): void { - /** @var Query|MockObject $mockUpdate */ + /** @var MockObject&Query $mockUpdate */ $mockUpdate = $this->getMockBuilder(Query::class) ->onlyMethods(['add']) ->getMock(); @@ -384,7 +384,7 @@ public function testFlushUnknownType(): void */ public function testCommit(string $requestFormat): void { - /** @var Query|MockObject $mockUpdate */ + /** @var MockObject&Query $mockUpdate */ $mockUpdate = $this->getMockBuilder(Query::class) ->onlyMethods(['add', 'addCommit']) ->getMock(); @@ -419,7 +419,7 @@ public function testCommit(string $requestFormat): void */ public function testCommitWithOptionalValues(string $requestFormat): void { - /** @var Query|MockObject $mockUpdate */ + /** @var MockObject&Query $mockUpdate */ $mockUpdate = $this->getMockBuilder(Query::class) ->onlyMethods(['add', 'addCommit']) ->getMock(); @@ -523,7 +523,7 @@ public function addUnknownDeleteType(): void } } -class DeleteDummy extends AbstractDelete +class DeleteDummy implements DeleteInterface { public function getType(): string { diff --git a/tests/Plugin/BufferedDelete/Delete/IdTest.php b/tests/Plugin/BufferedDelete/Delete/IdTest.php index 38631cc7f..327843181 100644 --- a/tests/Plugin/BufferedDelete/Delete/IdTest.php +++ b/tests/Plugin/BufferedDelete/Delete/IdTest.php @@ -3,7 +3,7 @@ namespace Solarium\Tests\Plugin\BufferedDelete\Delete; use PHPUnit\Framework\TestCase; -use Solarium\Plugin\BufferedDelete\AbstractDelete; +use Solarium\Plugin\BufferedDelete\DeleteInterface; use Solarium\Plugin\BufferedDelete\Delete\Id; class IdTest extends TestCase @@ -20,8 +20,8 @@ public function setUp(): void public function testGetType(): void { - $this->assertSame(AbstractDelete::TYPE_ID, $this->intId->getType()); - $this->assertSame(AbstractDelete::TYPE_ID, $this->stringId->getType()); + $this->assertSame(DeleteInterface::TYPE_ID, $this->intId->getType()); + $this->assertSame(DeleteInterface::TYPE_ID, $this->stringId->getType()); } public function testGetId(): void diff --git a/tests/Plugin/BufferedDelete/Delete/QueryTest.php b/tests/Plugin/BufferedDelete/Delete/QueryTest.php index 9731d3d18..2d2a64a3a 100644 --- a/tests/Plugin/BufferedDelete/Delete/QueryTest.php +++ b/tests/Plugin/BufferedDelete/Delete/QueryTest.php @@ -3,7 +3,7 @@ namespace Solarium\Tests\Plugin\BufferedDelete\Delete; use PHPUnit\Framework\TestCase; -use Solarium\Plugin\BufferedDelete\AbstractDelete; +use Solarium\Plugin\BufferedDelete\DeleteInterface; use Solarium\Plugin\BufferedDelete\Delete\Query; class QueryTest extends TestCase @@ -17,7 +17,7 @@ public function setUp(): void public function testGetType(): void { - $this->assertSame(AbstractDelete::TYPE_QUERY, $this->query->getType()); + $this->assertSame(DeleteInterface::TYPE_QUERY, $this->query->getType()); } public function testGetQuery(): void diff --git a/tests/Plugin/CustomizeRequest/CustomizeRequestTest.php b/tests/Plugin/CustomizeRequest/CustomizeRequestTest.php index 1191e7338..d797ff8b2 100644 --- a/tests/Plugin/CustomizeRequest/CustomizeRequestTest.php +++ b/tests/Plugin/CustomizeRequest/CustomizeRequestTest.php @@ -13,6 +13,7 @@ use Solarium\Plugin\CustomizeRequest\CustomizeRequest; use Solarium\QueryType\Ping\Query; use Solarium\Tests\Integration\TestClientFactory; +use Symfony\Component\EventDispatcher\EventDispatcher; class CustomizeRequestTest extends TestCase { @@ -69,6 +70,8 @@ public function testInitPlugin(): Client { $client = TestClientFactory::createWithCurlAdapter(); $plugin = $client->getPlugin('customizerequest'); + /** @var EventDispatcher $eventDispatcher */ + $eventDispatcher = $client->getEventDispatcher(); $this->assertInstanceOf(CustomizeRequest::class, $plugin); @@ -83,7 +86,7 @@ public function testInitPlugin(): Client $this->assertSame( $expectedListeners, - $client->getEventDispatcher()->getListeners() + $eventDispatcher->getListeners() ); return $client; @@ -95,10 +98,12 @@ public function testInitPlugin(): Client public function testDeinitPlugin(Client $client): void { $client->removePlugin('customizerequest'); + /** @var EventDispatcher $eventDispatcher */ + $eventDispatcher = $client->getEventDispatcher(); $this->assertSame( [], - $client->getEventDispatcher()->getListeners() + $eventDispatcher->getListeners() ); } diff --git a/tests/Plugin/Loadbalancer/LoadbalancerTest.php b/tests/Plugin/Loadbalancer/LoadbalancerTest.php index a3d8e57b6..ae2de33d0 100644 --- a/tests/Plugin/Loadbalancer/LoadbalancerTest.php +++ b/tests/Plugin/Loadbalancer/LoadbalancerTest.php @@ -23,6 +23,7 @@ use Solarium\QueryType\Select\Query\Query as SelectQuery; use Solarium\QueryType\Update\Query\Query as UpdateQuery; use Solarium\Tests\Integration\TestClientFactory; +use Symfony\Component\EventDispatcher\EventDispatcher; class LoadbalancerTest extends TestCase { @@ -96,6 +97,8 @@ public function testInitPlugin(): Client { $client = TestClientFactory::createWithCurlAdapter(); $plugin = $client->getPlugin('loadbalancer'); + /** @var EventDispatcher $eventDispatcher */ + $eventDispatcher = $client->getEventDispatcher(); $this->assertInstanceOf(Loadbalancer::class, $plugin); @@ -116,7 +119,7 @@ public function testInitPlugin(): Client $this->assertSame( $expectedListeners, - $client->getEventDispatcher()->getListeners() + $eventDispatcher->getListeners() ); return $client; @@ -128,10 +131,12 @@ public function testInitPlugin(): Client public function testDeinitPlugin(Client $client): void { $client->removePlugin('loadbalancer'); + /** @var EventDispatcher $eventDispatcher */ + $eventDispatcher = $client->getEventDispatcher(); $this->assertSame( [], - $client->getEventDispatcher()->getListeners() + $eventDispatcher->getListeners() ); } @@ -514,7 +519,9 @@ public function testFailoverOnEndpointFailure(): void $this->plugin->setFailoverEnabled(true); $endpointFailureListenerCalled = 0; - $this->client->getEventDispatcher()->addListener( + /** @var EventDispatcher $eventDispatcher */ + $eventDispatcher = $this->client->getEventDispatcher(); + $eventDispatcher->addListener( LoadbalancerEvents::ENDPOINT_FAILURE, function (EndpointFailureEvent $event) use (&$endpointFailureListenerCalled): void { ++$endpointFailureListenerCalled; @@ -550,7 +557,9 @@ public function testFailoverOnStatusCodeFailure(): void $this->plugin->addFailoverStatusCode(504); $statusCodeFailureListenerCalled = 0; - $this->client->getEventDispatcher()->addListener( + /** @var EventDispatcher $eventDispatcher */ + $eventDispatcher = $this->client->getEventDispatcher(); + $eventDispatcher->addListener( LoadbalancerEvents::STATUS_CODE_FAILURE, function (StatusCodeFailureEvent $event) use (&$statusCodeFailureListenerCalled): void { ++$statusCodeFailureListenerCalled; diff --git a/tests/Plugin/MinimumScoreFilter/DocumentTest.php b/tests/Plugin/MinimumScoreFilter/DocumentTest.php index 75639727d..780172275 100644 --- a/tests/Plugin/MinimumScoreFilter/DocumentTest.php +++ b/tests/Plugin/MinimumScoreFilter/DocumentTest.php @@ -2,12 +2,18 @@ namespace Solarium\Tests\Plugin\MinimumScoreFilter; +use Solarium\Core\Query\DocumentInterface; use Solarium\Plugin\MinimumScoreFilter\Document as FilterDocument; use Solarium\QueryType\Select\Result\Document; use Solarium\Tests\QueryType\Select\Result\AbstractDocumentTestCase; class DocumentTest extends AbstractDocumentTestCase { + /** + * @var FilterDocument + */ + protected DocumentInterface $doc; + public function setUp(): void { $doc = new Document($this->fields); @@ -25,26 +31,8 @@ public function testMarkedAsLowScore(): void public function testMethodCallForwarding(): void { - $doc = new class($this->fields) extends Document { - protected int $value = 0; - - public function setTestValue(int $value): void - { - $this->value = $value; - } - - public function addTestValues(int $value1, int $value2): void - { - $this->value += $value1; - $this->value += $value2; - } - - public function getTestValue(): int - { - return $this->value; - } - }; - $filterDoc = new FilterDocument($doc, true); + $doc = new TestDocument($this->fields); + $filterDoc = new TestFilterDocument($doc, true); $filterDoc->setTestValue(42); $this->assertSame(42, $filterDoc->getTestValue()); @@ -53,3 +41,33 @@ public function getTestValue(): int $this->assertSame(49, $filterDoc->getTestValue()); } } + +/** + * @internal extends FilterDocument to mixin TestDocument for PHPStan + * + * @mixin TestDocument + */ +class TestFilterDocument extends FilterDocument +{ +} + +class TestDocument extends Document +{ + protected int $value = 0; + + public function setTestValue(int $value): void + { + $this->value = $value; + } + + public function addTestValues(int $value1, int $value2): void + { + $this->value += $value1; + $this->value += $value2; + } + + public function getTestValue(): int + { + return $this->value; + } +} diff --git a/tests/Plugin/MinimumScoreFilter/QueryTest.php b/tests/Plugin/MinimumScoreFilter/QueryTest.php index c3fd784e1..c2c31e77c 100644 --- a/tests/Plugin/MinimumScoreFilter/QueryTest.php +++ b/tests/Plugin/MinimumScoreFilter/QueryTest.php @@ -2,14 +2,21 @@ namespace Solarium\Tests\Plugin\MinimumScoreFilter; +use PHPUnit\Framework\MockObject\MockObject; use Solarium\Component\Grouping; use Solarium\Plugin\MinimumScoreFilter\Query; use Solarium\Plugin\MinimumScoreFilter\QueryGroupResult; use Solarium\Plugin\MinimumScoreFilter\ValueGroupResult; +use Solarium\QueryType\Select\Query\Query as SelectQuery; use Solarium\Tests\QueryType\Select\Query\AbstractQueryTestCase; class QueryTest extends AbstractQueryTestCase { + /** + * @var Query + */ + protected SelectQuery $query; + public function setUp(): void { $this->query = new Query(); @@ -72,7 +79,7 @@ public function testAddFieldsAsStringWithTrim(): void public function testGetComponentsWithGrouping(): void { - /** @var Grouping&MockObject $mock */ + /** @var MockObject&Grouping $mock */ $mock = $this->getMockBuilder(Grouping::class) ->onlyMethods(['setOption']) ->getMock(); diff --git a/tests/Plugin/NoWaitForResponseRequestTest.php b/tests/Plugin/NoWaitForResponseRequestTest.php index 1ead30e19..dee9b70d9 100644 --- a/tests/Plugin/NoWaitForResponseRequestTest.php +++ b/tests/Plugin/NoWaitForResponseRequestTest.php @@ -16,6 +16,7 @@ use Solarium\Plugin\NoWaitForResponseRequest; use Solarium\QueryType\Suggester\Query; use Solarium\Tests\Integration\TestClientFactory; +use Symfony\Component\EventDispatcher\EventDispatcher; class NoWaitForResponseRequestTest extends TestCase { @@ -36,6 +37,8 @@ public function testInitPlugin(): Client { $client = TestClientFactory::createWithCurlAdapter(); $plugin = $client->getPlugin('nowaitforresponserequest'); + /** @var EventDispatcher $eventDispatcher */ + $eventDispatcher = $client->getEventDispatcher(); $this->assertInstanceOf(NoWaitForResponseRequest::class, $plugin); @@ -50,7 +53,7 @@ public function testInitPlugin(): Client $this->assertSame( $expectedListeners, - $client->getEventDispatcher()->getListeners() + $eventDispatcher->getListeners() ); return $client; @@ -62,10 +65,12 @@ public function testInitPlugin(): Client public function testDeinitPlugin(Client $client): void { $client->removePlugin('nowaitforresponserequest'); + /** @var EventDispatcher $eventDispatcher */ + $eventDispatcher = $client->getEventDispatcher(); $this->assertSame( [], - $client->getEventDispatcher()->getListeners() + $eventDispatcher->getListeners() ); } @@ -88,8 +93,10 @@ public function testExecuteRequest(): void // The client should be configured with defaults again, after these // settings changed within the event subscriber. - $this->assertSame(TimeoutAwareInterface::DEFAULT_TIMEOUT, $this->client->getAdapter()->getTimeout()); - $this->assertTrue($this->client->getAdapter()->getOption('return_transfer')); + /** @var Curl $adapter */ + $adapter = $this->client->getAdapter(); + $this->assertSame(TimeoutAwareInterface::DEFAULT_TIMEOUT, $adapter->getTimeout()); + $this->assertTrue($adapter->getOption('return_transfer')); } public function testSetFastTimeout(): void diff --git a/tests/Plugin/ParallelExecution/ParallelExecutionTest.php b/tests/Plugin/ParallelExecution/ParallelExecutionTest.php index 4c6550c2d..93da2d79c 100644 --- a/tests/Plugin/ParallelExecution/ParallelExecutionTest.php +++ b/tests/Plugin/ParallelExecution/ParallelExecutionTest.php @@ -57,8 +57,10 @@ public function testInitPluginTypeKeepsTimeoutOptions(): void $client->setAdapter($adapter); $client->registerPlugin('parallelexecution', $this->plugin); - $this->assertSame(15, $client->getAdapter()->getTimeOut()); - $this->assertSame(5, $client->getAdapter()->getConnectionTimeOut()); + /** @var TimeoutAndConnectionTimeoutAwareAdapter $adapter */ + $adapter = $client->getAdapter(); + $this->assertSame(15, $adapter->getTimeOut()); + $this->assertSame(5, $adapter->getConnectionTimeOut()); } public function testAddAndGetQueries(): void diff --git a/tests/Plugin/PostBigExtractRequestTest.php b/tests/Plugin/PostBigExtractRequestTest.php index 8394e4df5..ae47299cf 100644 --- a/tests/Plugin/PostBigExtractRequestTest.php +++ b/tests/Plugin/PostBigExtractRequestTest.php @@ -18,6 +18,7 @@ use Solarium\Plugin\PostBigExtractRequest; use Solarium\QueryType\Extract\Query; use Solarium\Tests\Integration\TestClientFactory; +use Symfony\Component\EventDispatcher\EventDispatcher; class PostBigExtractRequestTest extends TestCase { @@ -39,6 +40,8 @@ public function testInitPlugin(): Client { $client = TestClientFactory::createWithCurlAdapter(); $plugin = $client->getPlugin('postbigextractrequest'); + /** @var EventDispatcher $eventDispatcher */ + $eventDispatcher = $client->getEventDispatcher(); $this->assertInstanceOf(PostBigExtractRequest::class, $plugin); @@ -53,7 +56,7 @@ public function testInitPlugin(): Client $this->assertSame( $expectedListeners, - $client->getEventDispatcher()->getListeners() + $eventDispatcher->getListeners() ); return $client; @@ -65,10 +68,12 @@ public function testInitPlugin(): Client public function testDeinitPlugin(Client $client): void { $client->removePlugin('postbigextractrequest'); + /** @var EventDispatcher $eventDispatcher */ + $eventDispatcher = $client->getEventDispatcher(); $this->assertSame( [], - $client->getEventDispatcher()->getListeners() + $eventDispatcher->getListeners() ); } diff --git a/tests/Plugin/PostBigRequestTest.php b/tests/Plugin/PostBigRequestTest.php index c5648bf25..fb5369e8d 100644 --- a/tests/Plugin/PostBigRequestTest.php +++ b/tests/Plugin/PostBigRequestTest.php @@ -11,6 +11,7 @@ use Solarium\Plugin\PostBigRequest; use Solarium\QueryType\Select\Query\Query; use Solarium\Tests\Integration\TestClientFactory; +use Symfony\Component\EventDispatcher\EventDispatcher; class PostBigRequestTest extends TestCase { @@ -32,6 +33,8 @@ public function testInitPlugin(): Client { $client = TestClientFactory::createWithCurlAdapter(); $plugin = $client->getPlugin('postbigrequest'); + /** @var EventDispatcher $eventDispatcher */ + $eventDispatcher = $client->getEventDispatcher(); $this->assertInstanceOf(PostBigRequest::class, $plugin); @@ -46,7 +49,7 @@ public function testInitPlugin(): Client $this->assertSame( $expectedListeners, - $client->getEventDispatcher()->getListeners() + $eventDispatcher->getListeners() ); return $client; @@ -58,10 +61,12 @@ public function testInitPlugin(): Client public function testDeinitPlugin(Client $client): void { $client->removePlugin('postbigrequest'); + /** @var EventDispatcher $eventDispatcher */ + $eventDispatcher = $client->getEventDispatcher(); $this->assertSame( [], - $client->getEventDispatcher()->getListeners() + $eventDispatcher->getListeners() ); } diff --git a/tests/QueryType/Extract/RequestBuilderTest.php b/tests/QueryType/Extract/RequestBuilderTest.php index 29bc7b3c0..a8208ef22 100644 --- a/tests/QueryType/Extract/RequestBuilderTest.php +++ b/tests/QueryType/Extract/RequestBuilderTest.php @@ -7,6 +7,7 @@ use Solarium\Exception\RuntimeException; use Solarium\QueryType\Extract\Query; use Solarium\QueryType\Extract\RequestBuilder; +use Solarium\QueryType\Update\Query\Document; class RequestBuilderTest extends TestCase { @@ -213,7 +214,9 @@ public function testDocumentFieldAndBoostParams(): void public function testDocumentWithBoostThrowsException(): void { + /** @var Document $document */ $document = $this->query->createDocument(); + // @phpstan-ignore method.deprecated (we're calling a deprecated method on purpose) $document->setBoost(4); $this->query->setDocument($document); diff --git a/tests/QueryType/Extract/ResultTest.php b/tests/QueryType/Extract/ResultTest.php index 5e887a1a5..1b4a451da 100644 --- a/tests/QueryType/Extract/ResultTest.php +++ b/tests/QueryType/Extract/ResultTest.php @@ -2,12 +2,18 @@ namespace Solarium\Tests\QueryType\Extract; +use Solarium\Core\Query\Result\QueryType as Result; use Solarium\QueryType\Extract\Query as ExtractQuery; use Solarium\QueryType\Extract\Result as ExtractResult; use Solarium\Tests\QueryType\Update\AbstractResultTestCase; class ResultTest extends AbstractResultTestCase { + /** + * @var ExtractResult + */ + protected Result $result; + public function setUp(): void { $this->result = new ExtractResultDummy(); diff --git a/tests/QueryType/Luke/ResponseParser/SchemaTest.php b/tests/QueryType/Luke/ResponseParser/SchemaTest.php index a2337b520..bdc2a4cc9 100644 --- a/tests/QueryType/Luke/ResponseParser/SchemaTest.php +++ b/tests/QueryType/Luke/ResponseParser/SchemaTest.php @@ -496,15 +496,18 @@ public function testReferences(Schema $schema): void $this->assertSame($schema->getType('type_untokenized'), $schema->getField('flags_a')->getType()); $this->assertSame($schema->getField('copy_to'), $schema->getField('copy_from')->getCopyDests()[0]); + $this->assertInstanceOf(DynamicBasedField::class, $schema->getField('copy_from')->getCopyDests()[1]); $this->assertSame($schema->getDynamicField('*_copy_to'), $schema->getField('copy_from')->getCopyDests()[1]->getDynamicBase()); $this->assertSame($schema->getField('copy_from'), $schema->getField('copy_to')->getCopySources()[0]); + $this->assertInstanceOf(DynamicBasedField::class, $schema->getField('copy_to')->getCopySources()[1]); $this->assertSame($schema->getDynamicField('*_copy_from'), $schema->getField('copy_to')->getCopySources()[1]->getDynamicBase()); $this->assertSame($schema->getDynamicField('*_copy_from'), $schema->getField('copy_to')->getCopySources()[2]); $this->assertSame($schema->getType('type_tokenized'), $schema->getDynamicField('*_pos_inc_gap')->getType()); $this->assertSame($schema->getField('copy_to'), $schema->getDynamicField('*_copy_from')->getCopyDests()[0]); + $this->assertInstanceOf(DynamicBasedField::class, $schema->getDynamicField('*_copy_from')->getCopyDests()[1]); $this->assertSame($schema->getDynamicField('*_copy_to'), $schema->getDynamicField('*_copy_from')->getCopyDests()[1]->getDynamicBase()); $this->assertSame($schema->getDynamicField('*_copy_to'), $schema->getDynamicField('*_copy_from')->getCopyDests()[2]); diff --git a/tests/QueryType/Luke/Result/Schema/Field/DynamicBasedFieldTest.php b/tests/QueryType/Luke/Result/Schema/Field/DynamicBasedFieldTest.php index c62c63eae..c6ceed6b4 100644 --- a/tests/QueryType/Luke/Result/Schema/Field/DynamicBasedFieldTest.php +++ b/tests/QueryType/Luke/Result/Schema/Field/DynamicBasedFieldTest.php @@ -11,7 +11,10 @@ class DynamicBasedFieldTest extends AbstractFieldTestCase { - protected AbstractField|DynamicBasedField $field; + /** + * @var DynamicBasedField + */ + protected AbstractField $field; public function setUp(): void { diff --git a/tests/QueryType/Luke/Result/Schema/Field/DynamicFieldTest.php b/tests/QueryType/Luke/Result/Schema/Field/DynamicFieldTest.php index 5885f2d45..83367828c 100644 --- a/tests/QueryType/Luke/Result/Schema/Field/DynamicFieldTest.php +++ b/tests/QueryType/Luke/Result/Schema/Field/DynamicFieldTest.php @@ -13,7 +13,10 @@ class DynamicFieldTest extends AbstractFieldTestCase { - protected AbstractField|DynamicField $field; + /** + * @var DynamicField + */ + protected AbstractField $field; public function setUp(): void { diff --git a/tests/QueryType/MoreLikeThis/QueryTest.php b/tests/QueryType/MoreLikeThis/QueryTest.php index 1aff82dfd..80f86356d 100644 --- a/tests/QueryType/MoreLikeThis/QueryTest.php +++ b/tests/QueryType/MoreLikeThis/QueryTest.php @@ -6,6 +6,8 @@ use Solarium\Component\Debug; use Solarium\Component\DisMax; use Solarium\Component\DistributedSearch; +use Solarium\Component\Facet\Field as FieldFacet; +use Solarium\Component\Facet\Query as QueryFacet; use Solarium\Component\FacetSet; use Solarium\Component\Grouping; use Solarium\Component\Highlighting\Highlighting; @@ -17,6 +19,8 @@ use Solarium\Exception\InvalidArgumentException; use Solarium\Exception\OutOfBoundsException; use Solarium\QueryType\MoreLikeThis\Query; +use Solarium\QueryType\MoreLikeThis\RequestBuilder; +use Solarium\QueryType\MoreLikeThis\ResponseParser; use Solarium\QueryType\Select\Query\FilterQuery; class QueryTest extends TestCase @@ -35,12 +39,12 @@ public function testGetType(): void public function testGetResponseParser(): void { - $this->assertInstanceOf('Solarium\QueryType\MoreLikeThis\ResponseParser', $this->query->getResponseParser()); + $this->assertInstanceOf(ResponseParser::class, $this->query->getResponseParser()); } public function testGetRequestBuilder(): void { - $this->assertInstanceOf('Solarium\QueryType\MoreLikeThis\RequestBuilder', $this->query->getRequestBuilder()); + $this->assertInstanceOf(RequestBuilder::class, $this->query->getRequestBuilder()); } public function testSetAndGetStart(): void @@ -241,7 +245,7 @@ public function testAddAndGetFilterQueryWithKey(): void { $key = 'fq1'; - $fq = $this->query->createFilterQuery($key, true); + $fq = $this->query->createFilterQuery($key); $fq->setQuery('category:1'); $this->assertSame( @@ -448,10 +452,18 @@ public function testConfigMode(): void $this->assertSame('online:true', $query->getFilterQuery('online')->getQuery()); $facets = $query->getFacetSet()->getFacets(); + $this->assertInstanceOf( + FieldFacet::class, + $facets['categories'] + ); $this->assertSame( 'category', $facets['categories']->getField() ); + $this->assertInstanceOf( + QueryFacet::class, + $facets['category13'] + ); $this->assertSame( 'category:13', $facets['category13']->getQuery() @@ -570,7 +582,7 @@ public function testRegisterComponentType(): void $components = $this->query->getComponentTypes(); $components['mykey'] = 'mycomponent'; - $this->query->registerComponentType('mykey', 'mycomponent', 'mybuilder', 'myparser'); + $this->query->registerComponentType('mykey', 'mycomponent'); $this->assertSame( $components, diff --git a/tests/QueryType/Select/Query/AbstractQueryTestCase.php b/tests/QueryType/Select/Query/AbstractQueryTestCase.php index 4de99bb0f..ea1158811 100644 --- a/tests/QueryType/Select/Query/AbstractQueryTestCase.php +++ b/tests/QueryType/Select/Query/AbstractQueryTestCase.php @@ -7,6 +7,8 @@ use Solarium\Component\Debug; use Solarium\Component\DisMax; use Solarium\Component\DistributedSearch; +use Solarium\Component\Facet\Field as FieldFacet; +use Solarium\Component\Facet\Query as QueryFacet; use Solarium\Component\FacetSet; use Solarium\Component\Grouping; use Solarium\Component\Highlighting\Highlighting; @@ -479,10 +481,18 @@ public function testConfigMode(): void $this->assertSame('online:true', $query->getFilterQuery('online')->getQuery()); $facets = $query->getFacetSet()->getFacets(); + $this->assertInstanceOf( + FieldFacet::class, + $facets['categories'] + ); $this->assertSame( 'category', $facets['categories']->getField() ); + $this->assertInstanceOf( + QueryFacet::class, + $facets['category13'] + ); $this->assertSame( 'category:13', $facets['category13']->getQuery() diff --git a/tests/QueryType/Server/Collections/ReponseParser/CreateTest.php b/tests/QueryType/Server/Collections/ReponseParser/CreateTest.php index c6022deb1..01077b7e4 100644 --- a/tests/QueryType/Server/Collections/ReponseParser/CreateTest.php +++ b/tests/QueryType/Server/Collections/ReponseParser/CreateTest.php @@ -41,7 +41,7 @@ public function testParse(): void $this->assertSame(1693, $result->getQueryTime()); $this->assertSame($data, $result->getCreateStatus()); - // @phpstan-ignore-next-line Will no longer override QueryType::getStatus() in Solarium 8. + // @phpstan-ignore method.deprecated (will no longer override QueryType::getStatus() in Solarium 8) $this->assertSame($data, $result->getStatus()); } } diff --git a/tests/QueryType/Server/Collections/ReponseParser/DeleteTest.php b/tests/QueryType/Server/Collections/ReponseParser/DeleteTest.php index 57403b0ef..8d2a184dc 100644 --- a/tests/QueryType/Server/Collections/ReponseParser/DeleteTest.php +++ b/tests/QueryType/Server/Collections/ReponseParser/DeleteTest.php @@ -38,7 +38,7 @@ public function testParse(): void $this->assertSame(579, $result->getQueryTime()); $this->assertSame($data, $result->getDeleteStatus()); - // @phpstan-ignore-next-line Will no longer override QueryType::getStatus() in Solarium 8. + // @phpstan-ignore method.deprecated (will no longer override QueryType::getStatus() in Solarium 8) $this->assertSame($data, $result->getStatus()); } } diff --git a/tests/QueryType/Server/Collections/ReponseParser/ReloadTest.php b/tests/QueryType/Server/Collections/ReponseParser/ReloadTest.php index 74947b15c..f6ac76132 100644 --- a/tests/QueryType/Server/Collections/ReponseParser/ReloadTest.php +++ b/tests/QueryType/Server/Collections/ReponseParser/ReloadTest.php @@ -38,7 +38,7 @@ public function testParse(): void $this->assertSame(559, $result->getQueryTime()); $this->assertSame($data, $result->getReloadStatus()); - // @phpstan-ignore-next-line Will no longer override QueryType::getStatus() in Solarium 8. + // @phpstan-ignore method.deprecated (will no longer override QueryType::getStatus() in Solarium 8) $this->assertSame($data, $result->getStatus()); } } diff --git a/tests/QueryType/Server/CoreAdmin/Result/ResultTest.php b/tests/QueryType/Server/CoreAdmin/Result/ResultTest.php index 1a5b59be0..13e4a2157 100644 --- a/tests/QueryType/Server/CoreAdmin/Result/ResultTest.php +++ b/tests/QueryType/Server/CoreAdmin/Result/ResultTest.php @@ -7,11 +7,11 @@ class ResultTest extends TestCase { - protected Result $result; + protected CoreAdminDummyResult $result; public function setUp(): void { - $this->result = new CoreAdminDummy(); + $this->result = new CoreAdminDummyResult(); } public function testGetWasSuccessful(): void @@ -62,7 +62,7 @@ public function testAccessOtherProperty(): void } } -class CoreAdminDummy extends Result +class CoreAdminDummyResult extends Result { protected bool $parsed = true; diff --git a/tests/QueryType/Update/Query/QueryTest.php b/tests/QueryType/Update/Query/QueryTest.php index b412230d6..d44147c9e 100644 --- a/tests/QueryType/Update/Query/QueryTest.php +++ b/tests/QueryType/Update/Query/QueryTest.php @@ -6,7 +6,11 @@ use Solarium\Core\Client\Client; use Solarium\Exception\InvalidArgumentException; use Solarium\Exception\RuntimeException; +use Solarium\QueryType\Update\Query\Command\Add; use Solarium\QueryType\Update\Query\Command\Commit; +use Solarium\QueryType\Update\Query\Command\Delete; +use Solarium\QueryType\Update\Query\Command\Optimize; +use Solarium\QueryType\Update\Query\Command\RawXml; use Solarium\QueryType\Update\Query\Command\Rollback; use Solarium\QueryType\Update\Query\Document; use Solarium\QueryType\Update\Query\Query; @@ -113,6 +117,10 @@ public function testConfigMode(): void ); $delete = $commands['key1']; + $this->assertInstanceOf( + Delete::class, + $delete + ); $this->assertSame( [1, 2], $delete->getIds() @@ -123,6 +131,10 @@ public function testConfigMode(): void ); $commit = $commands['key2']; + $this->assertInstanceOf( + Commit::class, + $commit + ); $this->assertTrue( $commit->getSoftCommit() ); @@ -134,6 +146,10 @@ public function testConfigMode(): void ); $optimize = $commands['key3']; + $this->assertInstanceOf( + Optimize::class, + $optimize + ); $this->assertTrue( $optimize->getSoftCommit() ); @@ -266,6 +282,11 @@ public function testAddDeleteQuery(): void $this->query->addDeleteQuery('*:*'); $commands = $this->query->getCommands(); + $this->assertInstanceOf( + Delete::class, + $commands[0] + ); + $this->assertSame( Query::COMMAND_DELETE, $commands[0]->getType() @@ -282,6 +303,11 @@ public function testAddDeleteQueryWithBind(): void $this->query->addDeleteQuery('id:%1%', [678]); $commands = $this->query->getCommands(); + $this->assertInstanceOf( + Delete::class, + $commands[0] + ); + $this->assertSame( Query::COMMAND_DELETE, $commands[0]->getType() @@ -298,6 +324,11 @@ public function testAddDeleteQueries(): void $this->query->addDeleteQueries(['id:1', 'id:2']); $commands = $this->query->getCommands(); + $this->assertInstanceOf( + Delete::class, + $commands[0] + ); + $this->assertSame( Query::COMMAND_DELETE, $commands[0]->getType() @@ -314,6 +345,11 @@ public function testAddDeleteById(): void $this->query->addDeleteById(1); $commands = $this->query->getCommands(); + $this->assertInstanceOf( + Delete::class, + $commands[0] + ); + $this->assertSame( Query::COMMAND_DELETE, $commands[0]->getType() @@ -330,6 +366,11 @@ public function testAddDeleteByIds(): void $this->query->addDeleteByIds([1, 2]); $commands = $this->query->getCommands(); + $this->assertInstanceOf( + Delete::class, + $commands[0] + ); + $this->assertSame( Query::COMMAND_DELETE, $commands[0]->getType() @@ -348,6 +389,11 @@ public function testAddDocument(): void $this->query->addDocument($doc); $commands = $this->query->getCommands(); + $this->assertInstanceOf( + Add::class, + $commands[0] + ); + $this->assertSame( Query::COMMAND_ADD, $commands[0]->getType() @@ -367,6 +413,11 @@ public function testAddDocuments(): void $this->query->addDocuments([$doc1, $doc2], true, 100); $commands = $this->query->getCommands(); + $this->assertInstanceOf( + Add::class, + $commands[0] + ); + $this->assertSame( Query::COMMAND_ADD, $commands[0]->getType() @@ -392,6 +443,11 @@ public function testAddCommit(): void $this->query->addCommit(true, false, true); $commands = $this->query->getCommands(); + $this->assertInstanceOf( + Commit::class, + $commands[0] + ); + $this->assertSame( Query::COMMAND_COMMIT, $commands[0]->getType() @@ -415,6 +471,11 @@ public function testAddOptimize(): void $this->query->addOptimize(true, false, 10); $commands = $this->query->getCommands(); + $this->assertInstanceOf( + Optimize::class, + $commands[0] + ); + $this->assertSame( Query::COMMAND_OPTIMIZE, $commands[0]->getType() @@ -439,6 +500,11 @@ public function testAddRawXmlCommand(): void $this->query->addRawXmlCommand('1'); $commands = $this->query->getCommands(); + $this->assertInstanceOf( + RawXml::class, + $commands[0] + ); + $this->assertSame( Query::COMMAND_RAWXML, $commands[0]->getType() @@ -455,6 +521,11 @@ public function testAddRawXmlCommands(): void $this->query->addRawXmlCommands(['1', '2']); $commands = $this->query->getCommands(); + $this->assertInstanceOf( + RawXml::class, + $commands[0] + ); + $this->assertSame( Query::COMMAND_RAWXML, $commands[0]->getType() @@ -474,6 +545,11 @@ public function testAddRawXmlFile(): void $this->query->addRawXmlFile($tmpfname); $commands = $this->query->getCommands(); + $this->assertInstanceOf( + RawXml::class, + $commands[0] + ); + $this->assertSame( Query::COMMAND_RAWXML, $commands[0]->getType() @@ -527,10 +603,10 @@ public function testCreateDocument(): void public function testCreateDocumentWithCustomClass(): void { - $this->query->setDocumentClass(__NAMESPACE__.'\\MyCustomDoc'); + $this->query->setDocumentClass(MyCustomDoc::class); $doc = $this->query->createDocument(); - $this->assertInstanceOf(__NAMESPACE__.'\\MyCustomDoc', $doc); + $this->assertInstanceOf(MyCustomDoc::class, $doc); } public function testCreateDocumentWithFieldsAndBoostsAndModifiers(): void @@ -539,6 +615,7 @@ public function testCreateDocumentWithFieldsAndBoostsAndModifiers(): void $boosts = ['name' => 2.7]; $modifiers = ['name' => 'set']; + /** @var Document $doc */ $doc = $this->query->createDocument($fields, $boosts, $modifiers); $doc->setKey('id');