From 02d2e58df8d7409263d412530d6e4ffabd741ffb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dawid=20Parafi=C5=84ski?= Date: Thu, 19 Dec 2024 09:33:48 +0100 Subject: [PATCH] [CI] Added phpstan (#32) --- .github/workflows/ci.yaml | 3 + composer.json | 14 +- phpstan-baseline.neon | 139 ++++++++++++++++++ phpstan.neon | 14 ++ .../FieldDefinitionIdentifierMatcherSpec.php | 1 + spec/ContentView/QueryResultsInjectorSpec.php | 1 + spec/ExceptionSafeQueryFieldServiceSpec.php | 1 + .../ContentQueryFieldDefinitionMapperSpec.php | 1 + spec/GraphQL/QueryFieldResolverSpec.php | 1 + .../Converter/QueryConverterSpec.php | 1 + spec/QueryFieldServiceSpec.php | 6 +- .../Controller/QueryFieldRestController.php | 18 ++- .../ConfigurableFieldDefinitionMapperPass.php | 6 +- ...eldDefinitionIdentifierViewMatcherPass.php | 3 +- .../Compiler/QueryTypesListPass.php | 9 +- .../IbexaFieldTypeQueryExtension.php | 8 +- src/bundle/IbexaFieldTypeQueryBundle.php | 3 +- src/contracts/QueryFieldLocationService.php | 5 +- src/contracts/QueryFieldServiceInterface.php | 17 +-- .../FieldDefinitionIdentifierMatcher.php | 1 + src/lib/ContentView/QueryResultsInjector.php | 14 +- .../QueryResultsPagerFantaAdapter.php | 1 + ...ryResultsWithLocationPagerFantaAdapter.php | 1 + src/lib/ExceptionSafeQueryFieldService.php | 3 +- src/lib/FieldType/Form/QueryFieldFormType.php | 5 +- .../Mapper/ParametersTransformer.php | 4 + src/lib/FieldType/Mapper/QueryFormMapper.php | 13 +- src/lib/FieldType/Query/Type.php | 56 ++----- src/lib/FieldType/Query/Value.php | 1 + .../ContentQueryFieldDefinitionMapper.php | 5 +- src/lib/GraphQL/QueryFieldResolver.php | 16 +- .../FieldValue/Converter/QueryConverter.php | 46 +----- src/lib/QueryFieldPaginationService.php | 1 + src/lib/QueryFieldService.php | 27 ++-- 34 files changed, 290 insertions(+), 155 deletions(-) create mode 100644 phpstan-baseline.neon create mode 100644 phpstan.neon diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4fd01ab..58ffc20 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -70,3 +70,6 @@ jobs: - name: Run unit test suite run: composer test + + - name: Run PHPStan analysis + run: composer run-script phpstan diff --git a/composer.json b/composer.json index 16ffd46..9392ae8 100644 --- a/composer.json +++ b/composer.json @@ -41,17 +41,22 @@ "ibexa/doctrine-schema": "~4.6.0@dev", "ibexa/design-engine": "~4.6.0@dev", "ibexa/fieldtype-richtext": "~4.6.0@dev", + "ibexa/phpstan": "~4.6.0@dev", "ibexa/search": "~4.6.0@dev", "ibexa/user": "~4.6.0@dev", "ibexa/http-cache": "~4.6.0@dev", "phpspec/phpspec": "^7.1", "ibexa/code-style": "^1.0", - "friendsofphp/php-cs-fixer": "^3.0" + "friendsofphp/php-cs-fixer": "^3.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-symfony": "^2.0" }, "scripts": { "fix-cs": "php-cs-fixer fix --config=.php-cs-fixer.php -v --show-progress=dots", "check-cs": "@fix-cs --dry-run", - "test": "phpspec run --format=pretty" + "test": "phpspec run --format=pretty", + "phpstan": "phpstan analyse" }, "extra": { "branch-alias": { @@ -59,8 +64,7 @@ } }, "config": { - "allow-plugins": { - "composer/package-versions-deprecated": true - } + "sort-packages": true, + "allow-plugins": false } } diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 0000000..f3fca47 --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,139 @@ +parameters: + ignoreErrors: + - + message: '#^Parameter \#1 \$href of method Ibexa\\Rest\\RequestParser\:\:parseHref\(\) expects string, string\|null given\.$#' + identifier: argument.type + count: 1 + path: src/bundle/Controller/QueryFieldRestController.php + + - + message: '#^Parameter \#1 \$locationId of method Ibexa\\Contracts\\Core\\Repository\\LocationService\:\:loadLocation\(\) expects int, int\|null given\.$#' + identifier: argument.type + count: 1 + path: src/bundle/Controller/QueryFieldRestController.php + + - + message: '#^Argument of an invalid type array\|bool\|float\|int\|string\|null supplied for foreach, only iterables are supported\.$#' + identifier: foreach.nonIterable + count: 1 + path: src/bundle/DependencyInjection/Compiler/FieldDefinitionIdentifierViewMatcherPass.php + + - + message: '#^Cannot access offset \(int\|string\) on non\-empty\-array\|bool\|float\|int\|string\|null\.$#' + identifier: offsetAccess.nonOffsetAccessible + count: 1 + path: src/bundle/DependencyInjection/Compiler/FieldDefinitionIdentifierViewMatcherPass.php + + - + message: '#^Parameter \#2 \$callback of function array_filter expects \(callable\(int\|string\)\: bool\)\|null, Closure\(mixed\)\: \(0\|1\|false\) given\.$#' + identifier: argument.type + count: 1 + path: src/bundle/DependencyInjection/Compiler/FieldDefinitionIdentifierViewMatcherPass.php + + - + message: '#^Parameter \#1 \$queryTypeIdentifier of method Ibexa\\Bundle\\FieldTypeQuery\\DependencyInjection\\Compiler\\QueryTypesListPass\:\:buildQueryTypeName\(\) expects string, int\|string given\.$#' + identifier: argument.type + count: 1 + path: src/bundle/DependencyInjection/Compiler/QueryTypesListPass.php + + - + message: '#^Parameter \#1 \$input of static method Symfony\\Component\\Yaml\\Yaml\:\:parse\(\) expects string, string\|false given\.$#' + identifier: argument.type + count: 1 + path: src/bundle/DependencyInjection/IbexaFieldTypeQueryExtension.php + + - + message: '#^Method Ibexa\\FieldTypeQuery\\ContentView\\QueryResultsInjector\:\:__construct\(\) has parameter \$views with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/lib/ContentView/QueryResultsInjector.php + + - + message: '#^Property Ibexa\\FieldTypeQuery\\ContentView\\QueryResultsInjector\:\:\$queryFieldService \(Ibexa\\Contracts\\FieldTypeQuery\\QueryFieldLocationService&Ibexa\\Contracts\\FieldTypeQuery\\QueryFieldServiceInterface\) does not accept Ibexa\\Contracts\\FieldTypeQuery\\QueryFieldServiceInterface\.$#' + identifier: assign.propertyType + count: 1 + path: src/lib/ContentView/QueryResultsInjector.php + + - + message: '#^Property Ibexa\\FieldTypeQuery\\ContentView\\QueryResultsInjector\:\:\$views type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/lib/ContentView/QueryResultsInjector.php + + - + message: '#^Property Ibexa\\FieldTypeQuery\\ExceptionSafeQueryFieldService\:\:\$inner \(Ibexa\\Contracts\\FieldTypeQuery\\QueryFieldLocationService&Ibexa\\Contracts\\FieldTypeQuery\\QueryFieldServiceInterface\) does not accept Ibexa\\Contracts\\FieldTypeQuery\\QueryFieldServiceInterface\.$#' + identifier: assign.propertyType + count: 1 + path: src/lib/ExceptionSafeQueryFieldService.php + + - + message: '#^Class Ibexa\\FieldTypeQuery\\FieldType\\Form\\QueryFieldFormType extends generic class Symfony\\Component\\Form\\AbstractType but does not specify its types\: TData$#' + identifier: missingType.generics + count: 1 + path: src/lib/FieldType/Form/QueryFieldFormType.php + + - + message: '#^Generator expects key type string, string\|null given\.$#' + identifier: generator.keyType + count: 1 + path: src/lib/FieldType/Mapper/QueryFormMapper.php + + - + message: '#^Method Ibexa\\FieldTypeQuery\\FieldType\\Mapper\\QueryFormMapper\:\:mapFieldDefinitionForm\(\) has parameter \$fieldDefinitionForm with generic interface Symfony\\Component\\Form\\FormInterface but does not specify its types\: TData$#' + identifier: missingType.generics + count: 1 + path: src/lib/FieldType/Mapper/QueryFormMapper.php + + - + message: '#^Property Ibexa\\Core\\Persistence\\Legacy\\Content\\StorageFieldValue\:\:\$dataText \(string\) does not accept array\|bool\|float\|int\|string\|null\.$#' + identifier: assign.propertyType + count: 1 + path: src/lib/Persistence/Legacy/Content/FieldValue/Converter/QueryConverter.php + + - + message: '#^Anonymous function should return Ibexa\\Contracts\\Core\\Repository\\Values\\Content\\Content but returns Ibexa\\Contracts\\Core\\Repository\\Values\\ValueObject\.$#' + identifier: return.type + count: 1 + path: src/lib/QueryFieldService.php + + - + message: '#^Method Ibexa\\FieldTypeQuery\\QueryFieldService\:\:isExpression\(\) has parameter \$expression with no type specified\.$#' + identifier: missingType.parameter + count: 1 + path: src/lib/QueryFieldService.php + + - + message: '#^Method Ibexa\\FieldTypeQuery\\QueryFieldService\:\:prepareQuery\(\) has parameter \$extraParameters with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/lib/QueryFieldService.php + + - + message: '#^Method Ibexa\\FieldTypeQuery\\QueryFieldService\:\:resolveExpression\(\) has no return type specified\.$#' + identifier: missingType.return + count: 1 + path: src/lib/QueryFieldService.php + + - + message: '#^Method Ibexa\\FieldTypeQuery\\QueryFieldService\:\:resolveExpression\(\) has parameter \$variables with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/lib/QueryFieldService.php + + - + message: '#^Method Ibexa\\FieldTypeQuery\\QueryFieldService\:\:resolveParameters\(\) has parameter \$expressions with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/lib/QueryFieldService.php + + - + message: '#^Method Ibexa\\FieldTypeQuery\\QueryFieldService\:\:resolveParameters\(\) has parameter \$variables with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/lib/QueryFieldService.php + + - + message: '#^Method Ibexa\\FieldTypeQuery\\QueryFieldService\:\:resolveParameters\(\) return type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: src/lib/QueryFieldService.php diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..dd102a8 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,14 @@ +includes: + - phpstan-baseline.neon + - vendor/phpstan/phpstan-phpunit/extension.neon + - vendor/phpstan/phpstan-symfony/extension.neon + - vendor/ibexa/phpstan/extension.neon + +parameters: + ignoreErrors: + - + message: "#^Cannot call method (log|debug|info|notice|warning|error|critical|alert|emergency)\\(\\) on Psr\\\\Log\\\\LoggerInterface\\|null\\.$#" + level: 8 + paths: + - src + treatPhpDocTypesAsCertain: false diff --git a/spec/ContentView/FieldDefinitionIdentifierMatcherSpec.php b/spec/ContentView/FieldDefinitionIdentifierMatcherSpec.php index 3b60867..31d3fdc 100644 --- a/spec/ContentView/FieldDefinitionIdentifierMatcherSpec.php +++ b/spec/ContentView/FieldDefinitionIdentifierMatcherSpec.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace spec\Ibexa\FieldTypeQuery\ContentView; use Ibexa\Contracts\Core\Repository\ContentTypeService; diff --git a/spec/ContentView/QueryResultsInjectorSpec.php b/spec/ContentView/QueryResultsInjectorSpec.php index 04146fd..c509094 100644 --- a/spec/ContentView/QueryResultsInjectorSpec.php +++ b/spec/ContentView/QueryResultsInjectorSpec.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace spec\Ibexa\FieldTypeQuery\ContentView; use Ibexa\Contracts\FieldTypeQuery\QueryFieldServiceInterface; diff --git a/spec/ExceptionSafeQueryFieldServiceSpec.php b/spec/ExceptionSafeQueryFieldServiceSpec.php index deb6012..92260b3 100644 --- a/spec/ExceptionSafeQueryFieldServiceSpec.php +++ b/spec/ExceptionSafeQueryFieldServiceSpec.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace spec\Ibexa\FieldTypeQuery; use Ibexa\Contracts\FieldTypeQuery\QueryFieldServiceInterface; diff --git a/spec/GraphQL/ContentQueryFieldDefinitionMapperSpec.php b/spec/GraphQL/ContentQueryFieldDefinitionMapperSpec.php index 3769c47..c696fc8 100644 --- a/spec/GraphQL/ContentQueryFieldDefinitionMapperSpec.php +++ b/spec/GraphQL/ContentQueryFieldDefinitionMapperSpec.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace spec\Ibexa\FieldTypeQuery\GraphQL; use Ibexa\Contracts\Core\Repository\ContentTypeService; diff --git a/spec/GraphQL/QueryFieldResolverSpec.php b/spec/GraphQL/QueryFieldResolverSpec.php index 05f9091..8e1b02a 100644 --- a/spec/GraphQL/QueryFieldResolverSpec.php +++ b/spec/GraphQL/QueryFieldResolverSpec.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace spec\Ibexa\FieldTypeQuery\GraphQL; use Ibexa\Contracts\FieldTypeQuery\QueryFieldServiceInterface; diff --git a/spec/Persistence/Legacy/Content/FieldValue/Converter/QueryConverterSpec.php b/spec/Persistence/Legacy/Content/FieldValue/Converter/QueryConverterSpec.php index f21cd38..cf5e971 100644 --- a/spec/Persistence/Legacy/Content/FieldValue/Converter/QueryConverterSpec.php +++ b/spec/Persistence/Legacy/Content/FieldValue/Converter/QueryConverterSpec.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace spec\Ibexa\FieldTypeQuery\Persistence\Legacy\Content\FieldValue\Converter; use Ibexa\Contracts\Core\Persistence\Content\Type\FieldDefinition; diff --git a/spec/QueryFieldServiceSpec.php b/spec/QueryFieldServiceSpec.php index ea58caa..930c55e 100644 --- a/spec/QueryFieldServiceSpec.php +++ b/spec/QueryFieldServiceSpec.php @@ -4,10 +4,10 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace spec\Ibexa\FieldTypeQuery; use Ibexa\Contracts\Core\Repository\ContentTypeService; -use Ibexa\Contracts\Core\Repository\LocationService; use Ibexa\Contracts\Core\Repository\SearchService; use Ibexa\Contracts\Core\Repository\Values\Content\ContentInfo; use Ibexa\Contracts\Core\Repository\Values\Content\Query as ApiContentQuery; @@ -38,7 +38,6 @@ class QueryFieldServiceSpec extends ObjectBehavior public function let( SearchService $searchService, ContentTypeService $contentTypeService, - LocationService $locationService, QueryTypeRegistry $queryTypeRegistry, QueryType $queryType ) { @@ -60,12 +59,11 @@ public function let( $contentTypeWithoutPagination = $this->getContentType($parameters, false, 10); $contentTypeService->loadContentType(self::CONTENT_TYPE_ID_WITHOUT_PAGINATION)->willReturn($contentTypeWithoutPagination); - $locationService->loadLocation(self::LOCATION_ID)->willReturn($location); $queryTypeRegistry->getQueryType(self::QUERY_TYPE_IDENTIFIER)->willReturn($queryType); $queryType->getQuery(Argument::any())->willReturn(new ApiQuery()); // @todo this should fail. It does not. $searchService->findContent(Argument::any())->willReturn($this->searchResult); - $this->beConstructedWith($searchService, $contentTypeService, $locationService, $queryTypeRegistry); + $this->beConstructedWith($searchService, $contentTypeService, $queryTypeRegistry); } public function it_is_initializable() diff --git a/src/bundle/Controller/QueryFieldRestController.php b/src/bundle/Controller/QueryFieldRestController.php index 8968749..c9950bb 100644 --- a/src/bundle/Controller/QueryFieldRestController.php +++ b/src/bundle/Controller/QueryFieldRestController.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace Ibexa\Bundle\FieldTypeQuery\Controller; use Ibexa\Contracts\Core\Repository\ContentService; @@ -15,6 +16,7 @@ use Ibexa\Contracts\Core\Repository\Values\ContentType\ContentType; use Ibexa\Contracts\Rest\Exceptions\NotFoundException; use Ibexa\FieldTypeQuery\QueryFieldService; +use function Ibexa\PolyfillPhp82\iterator_to_array; use Ibexa\Rest\RequestParser; use Ibexa\Rest\Server\Values as RestValues; use Symfony\Component\HttpFoundation\Request; @@ -50,10 +52,14 @@ public function __construct( $this->requestParser = $requestParser; } - public function getResults(Request $request, $contentId, $versionNumber, $fieldDefinitionIdentifier): RestValues\ContentList - { - $offset = (int)$request->query->get('offset', 0); - $limit = (int)$request->query->get('limit', -1); + public function getResults( + Request $request, + int $contentId, + int $versionNumber, + string $fieldDefinitionIdentifier + ): RestValues\ContentList { + $offset = (int)$request->query->get('offset', '0'); + $limit = (int)$request->query->get('limit', '-1'); if ($request->query->has('location')) { $location = $this->loadLocationByPath($request); @@ -89,10 +95,10 @@ function (Content $content) { $this->locationService->loadLocation($content->contentInfo->mainLocationId), $content, $this->getContentType($content->contentInfo), - $this->contentService->loadRelations($content->getVersionInfo()) + iterator_to_array($this->contentService->loadRelations($content->getVersionInfo())) ); }, - $items + iterator_to_array($items) ), $this->queryFieldService->countContentItems($content, $fieldDefinitionIdentifier) ); diff --git a/src/bundle/DependencyInjection/Compiler/ConfigurableFieldDefinitionMapperPass.php b/src/bundle/DependencyInjection/Compiler/ConfigurableFieldDefinitionMapperPass.php index 705cce7..b74430c 100644 --- a/src/bundle/DependencyInjection/Compiler/ConfigurableFieldDefinitionMapperPass.php +++ b/src/bundle/DependencyInjection/Compiler/ConfigurableFieldDefinitionMapperPass.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace Ibexa\Bundle\FieldTypeQuery\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; @@ -17,13 +18,16 @@ class ConfigurableFieldDefinitionMapperPass implements CompilerPassInterface { public const PARAMETER = 'ibexa.graphql.schema.content.mapping.field_definition_type'; - public function process(ContainerBuilder $container) + public function process(ContainerBuilder $container): void { if (!$container->hasParameter(self::PARAMETER)) { return; } $parameter = $container->getParameter(self::PARAMETER); + if (!is_array($parameter)) { + return; + } $parameter['ezcontentquery'] = [ 'definition_type' => 'QueryFieldDefinition', 'value_resolver' => 'resolver("QueryFieldValue", [field, content])', diff --git a/src/bundle/DependencyInjection/Compiler/FieldDefinitionIdentifierViewMatcherPass.php b/src/bundle/DependencyInjection/Compiler/FieldDefinitionIdentifierViewMatcherPass.php index 8d9beb9..28a8d4d 100644 --- a/src/bundle/DependencyInjection/Compiler/FieldDefinitionIdentifierViewMatcherPass.php +++ b/src/bundle/DependencyInjection/Compiler/FieldDefinitionIdentifierViewMatcherPass.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace Ibexa\Bundle\FieldTypeQuery\DependencyInjection\Compiler; use Ibexa\FieldTypeQuery\ContentView\FieldDefinitionIdentifierMatcher; @@ -18,7 +19,7 @@ class FieldDefinitionIdentifierViewMatcherPass implements CompilerPassInterface private const LONG_IDENTIFIER = '@' . FieldDefinitionIdentifierMatcher::class; private const SHORT_IDENTIFIER = 'Identifier\FieldDefinition'; - public function process(ContainerBuilder $container) + public function process(ContainerBuilder $container): void { $configKeys = array_filter( array_keys($container->getParameterBag()->all()), diff --git a/src/bundle/DependencyInjection/Compiler/QueryTypesListPass.php b/src/bundle/DependencyInjection/Compiler/QueryTypesListPass.php index 1709f17..773b4be 100644 --- a/src/bundle/DependencyInjection/Compiler/QueryTypesListPass.php +++ b/src/bundle/DependencyInjection/Compiler/QueryTypesListPass.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace Ibexa\Bundle\FieldTypeQuery\DependencyInjection\Compiler; use Ibexa\Core\QueryType\ArrayQueryTypeRegistry; @@ -24,7 +25,7 @@ public function __construct() $this->nameConverter = new CamelCaseToSnakeCaseNameConverter(); } - public function process(ContainerBuilder $container) + public function process(ContainerBuilder $container): void { if (!$container->has(ArrayQueryTypeRegistry::class) || !$container->has(QueryFormMapper::class)) { return; @@ -47,12 +48,8 @@ public function process(ContainerBuilder $container) /** * Builds a human readable name out of a query type identifier. - * - * @param $queryTypeIdentifier - * - * @return string */ - private function buildQueryTypeName($queryTypeIdentifier) + private function buildQueryTypeName(string $queryTypeIdentifier): string { return ucfirst( str_replace('_', ' ', $this->nameConverter->normalize($queryTypeIdentifier)) diff --git a/src/bundle/DependencyInjection/IbexaFieldTypeQueryExtension.php b/src/bundle/DependencyInjection/IbexaFieldTypeQueryExtension.php index c7d8317..35efa0d 100644 --- a/src/bundle/DependencyInjection/IbexaFieldTypeQueryExtension.php +++ b/src/bundle/DependencyInjection/IbexaFieldTypeQueryExtension.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace Ibexa\Bundle\FieldTypeQuery\DependencyInjection; use Symfony\Component\Config\FileLocator; @@ -16,7 +17,7 @@ final class IbexaFieldTypeQueryExtension extends Extension implements PrependExtensionInterface { - public function load(array $configs, ContainerBuilder $container) + public function load(array $configs, ContainerBuilder $container): void { $loader = new YamlFileLoader( $container, @@ -32,7 +33,7 @@ public function load(array $configs, ContainerBuilder $container) $this->addContentViewConfig($container); } - public function prepend(ContainerBuilder $container) + public function prepend(ContainerBuilder $container): void { $this->prependFieldTemplateConfig($container); $this->prependJMSTranslationConfig($container); @@ -46,6 +47,9 @@ public function prepend(ContainerBuilder $container) protected function addContentViewConfig(ContainerBuilder $container): void { $contentViewDefaults = $container->getParameter('ibexa.site_access.config.default.content_view_defaults'); + if (!is_array($contentViewDefaults)) { + return; + } $contentViewDefaults['content_query_field'] = [ 'default' => [ 'template' => '@IbexaFieldTypeQuery/content/contentquery.html.twig', diff --git a/src/bundle/IbexaFieldTypeQueryBundle.php b/src/bundle/IbexaFieldTypeQueryBundle.php index 86db802..e5b1f47 100644 --- a/src/bundle/IbexaFieldTypeQueryBundle.php +++ b/src/bundle/IbexaFieldTypeQueryBundle.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace Ibexa\Bundle\FieldTypeQuery; use Ibexa\Bundle\FieldTypeQuery\DependencyInjection\Compiler; @@ -12,7 +13,7 @@ final class IbexaFieldTypeQueryBundle extends Bundle { - public function build(ContainerBuilder $container) + public function build(ContainerBuilder $container): void { $container->addCompilerPass(new Compiler\QueryTypesListPass()); $container->addCompilerPass(new Compiler\ConfigurableFieldDefinitionMapperPass()); diff --git a/src/contracts/QueryFieldLocationService.php b/src/contracts/QueryFieldLocationService.php index 5b51451..1d964da 100644 --- a/src/contracts/QueryFieldLocationService.php +++ b/src/contracts/QueryFieldLocationService.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace Ibexa\Contracts\FieldTypeQuery; use Ibexa\Contracts\Core\Repository\Values\Content\Location; @@ -16,14 +17,14 @@ interface QueryFieldLocationService /** * Returns the query results for the given location. * - * @return iterable An iterable that yields Content items. + * @return iterable<\Ibexa\Contracts\Core\Repository\Values\Content\Content> */ public function loadContentItemsForLocation(Location $location, string $fieldDefinitionIdentifier): iterable; /** * Returns a slice of the query results for the given location. * - * @return iterable An iterable that yields Content items. + * @return iterable<\Ibexa\Contracts\Core\Repository\Values\Content\Content> */ public function loadContentItemsSliceForLocation(Location $location, string $fieldDefinitionIdentifier, int $offset, int $limit): iterable; diff --git a/src/contracts/QueryFieldServiceInterface.php b/src/contracts/QueryFieldServiceInterface.php index 0c43df0..22ac165 100644 --- a/src/contracts/QueryFieldServiceInterface.php +++ b/src/contracts/QueryFieldServiceInterface.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace Ibexa\Contracts\FieldTypeQuery; use Ibexa\Contracts\Core\Repository\Values\Content\Content; @@ -16,9 +17,6 @@ interface QueryFieldServiceInterface /** * Executes the query without pagination and returns the content items. * - * @param \Ibexa\Contracts\Core\Repository\Values\Content\Location $content - * @param string $fieldDefinitionIdentifier - * * @return \Ibexa\Contracts\Core\Repository\Values\Content\Content[] * * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException @@ -28,11 +26,6 @@ public function loadContentItems(Content $content, string $fieldDefinitionIdenti /** * Counts the total results of a query. * - * @param \Ibexa\Contracts\Core\Repository\Values\Content\Content $content - * @param string $fieldDefinitionIdentifier - * - * @return int - * * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException */ public function countContentItems(Content $content, string $fieldDefinitionIdentifier): int; @@ -40,11 +33,6 @@ public function countContentItems(Content $content, string $fieldDefinitionIdent /** * Executes a paginated query and return the requested content items slice. * - * @param \Ibexa\Contracts\Core\Repository\Values\Content\Content $content - * @param string $fieldDefinitionIdentifier - * @param int $offset - * @param int $limit - * * @return \Ibexa\Contracts\Core\Repository\Values\Content\Content[] * * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException @@ -52,9 +40,6 @@ public function countContentItems(Content $content, string $fieldDefinitionIdent public function loadContentItemsSlice(Content $content, string $fieldDefinitionIdentifier, int $offset, int $limit): iterable; /** - * @param \Ibexa\Contracts\Core\Repository\Values\Content\Content $content - * @param string $fieldDefinitionIdentifier - * * @return int The page size, or 0 if pagination is disabled. * * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException diff --git a/src/lib/ContentView/FieldDefinitionIdentifierMatcher.php b/src/lib/ContentView/FieldDefinitionIdentifierMatcher.php index f839344..e97797f 100644 --- a/src/lib/ContentView/FieldDefinitionIdentifierMatcher.php +++ b/src/lib/ContentView/FieldDefinitionIdentifierMatcher.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace Ibexa\FieldTypeQuery\ContentView; use Ibexa\Contracts\Core\Repository\Values\Content\ContentInfo; diff --git a/src/lib/ContentView/QueryResultsInjector.php b/src/lib/ContentView/QueryResultsInjector.php index b26695b..01d8efb 100644 --- a/src/lib/ContentView/QueryResultsInjector.php +++ b/src/lib/ContentView/QueryResultsInjector.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace Ibexa\FieldTypeQuery\ContentView; use Ibexa\Contracts\FieldTypeQuery\QueryFieldLocationService; @@ -19,7 +20,7 @@ final class QueryResultsInjector implements EventSubscriberInterface { - /** @var \Ibexa\FieldTypeQuery\QueryFieldService */ + /** @var \Ibexa\Contracts\FieldTypeQuery\QueryFieldServiceInterface&\Ibexa\Contracts\FieldTypeQuery\QueryFieldLocationService */ private $queryFieldService; /** @var array */ @@ -47,7 +48,7 @@ public static function getSubscribedEvents() /** * {@inheritdoc} */ - public function injectQueryResults(FilterViewParametersEvent $event) + public function injectQueryResults(FilterViewParametersEvent $event): void { if ($event->getView()->getViewType() === $this->views['field']) { $builderParameters = $event->getBuilderParameters(); @@ -70,20 +71,23 @@ public function injectQueryResults(FilterViewParametersEvent $event) /** * @param \Ibexa\Core\MVC\Symfony\View\Event\FilterViewParametersEvent $event * - * @return iterable + * @return iterable<\Ibexa\Contracts\Core\Repository\Values\Content\Content> * * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException */ private function buildResults(FilterViewParametersEvent $event): iterable { $view = $event->getView(); - $location = $view instanceof LocationValueView ? $location = $view->getLocation() : null; + $location = $view instanceof LocationValueView ? $view->getLocation() : null; $content = $view instanceof ContentValueView ? $view->getContent() : null; + if ($location === null && $content === null) { + throw new \Exception('No content nor location to get query results for'); + } $viewParameters = $event->getBuilderParameters(); $fieldDefinitionIdentifier = $viewParameters['queryFieldDefinitionIdentifier']; - $paginationLimit = $this->queryFieldService->getPaginationConfiguration($content, $fieldDefinitionIdentifier); + $paginationLimit = $this->queryFieldService->getPaginationConfiguration($content ?? $location->getContent(), $fieldDefinitionIdentifier); $enablePagination = ($viewParameters['enablePagination'] === true); $disablePagination = ($viewParameters['disablePagination'] === true); diff --git a/src/lib/ContentView/QueryResultsPagerFantaAdapter.php b/src/lib/ContentView/QueryResultsPagerFantaAdapter.php index eeff42b..a49cf9a 100644 --- a/src/lib/ContentView/QueryResultsPagerFantaAdapter.php +++ b/src/lib/ContentView/QueryResultsPagerFantaAdapter.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace Ibexa\FieldTypeQuery\ContentView; use Ibexa\Contracts\Core\Repository\Values\Content\Content; diff --git a/src/lib/ContentView/QueryResultsWithLocationPagerFantaAdapter.php b/src/lib/ContentView/QueryResultsWithLocationPagerFantaAdapter.php index 1430023..fbcbd88 100644 --- a/src/lib/ContentView/QueryResultsWithLocationPagerFantaAdapter.php +++ b/src/lib/ContentView/QueryResultsWithLocationPagerFantaAdapter.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace Ibexa\FieldTypeQuery\ContentView; use Ibexa\Contracts\Core\Repository\Values\Content\Location; diff --git a/src/lib/ExceptionSafeQueryFieldService.php b/src/lib/ExceptionSafeQueryFieldService.php index e88dce6..7b71087 100644 --- a/src/lib/ExceptionSafeQueryFieldService.php +++ b/src/lib/ExceptionSafeQueryFieldService.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace Ibexa\FieldTypeQuery; use Ibexa\Contracts\Core\Repository\Values\Content\Content; @@ -22,7 +23,7 @@ final class ExceptionSafeQueryFieldService implements QueryFieldServiceInterface { use LoggerAwareTrait; - /** @var \Ibexa\Contracts\FieldTypeQuery\QueryFieldServiceInterface */ + /** @var \Ibexa\Contracts\FieldTypeQuery\QueryFieldServiceInterface&\Ibexa\Contracts\FieldTypeQuery\QueryFieldLocationService */ private $inner; public function __construct(QueryFieldServiceInterface $inner, ?LoggerInterface $logger = null) diff --git a/src/lib/FieldType/Form/QueryFieldFormType.php b/src/lib/FieldType/Form/QueryFieldFormType.php index 3686b8d..286e2c8 100644 --- a/src/lib/FieldType/Form/QueryFieldFormType.php +++ b/src/lib/FieldType/Form/QueryFieldFormType.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace Ibexa\FieldTypeQuery\FieldType\Form; use Ibexa\AdminUi\Form\DataTransformer\FieldType\FieldValueTransformer; @@ -22,7 +23,7 @@ public function __construct(FieldTypeService $fieldTypeService) $this->fieldTypeService = $fieldTypeService; } - public function getName() + public function getName(): string { return $this->getBlockPrefix(); } @@ -37,7 +38,7 @@ public function getParent() return TextType::class; } - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->addModelTransformer(new FieldValueTransformer($this->fieldTypeService->getFieldType('ezcontentquery'))); } diff --git a/src/lib/FieldType/Mapper/ParametersTransformer.php b/src/lib/FieldType/Mapper/ParametersTransformer.php index ad017a0..fd9f456 100644 --- a/src/lib/FieldType/Mapper/ParametersTransformer.php +++ b/src/lib/FieldType/Mapper/ParametersTransformer.php @@ -4,11 +4,15 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace Ibexa\FieldTypeQuery\FieldType\Mapper; use Symfony\Component\Form\DataTransformerInterface; use Symfony\Component\Yaml\Yaml; +/** + * @implements DataTransformerInterface + */ final class ParametersTransformer implements DataTransformerInterface { public function transform($value) diff --git a/src/lib/FieldType/Mapper/QueryFormMapper.php b/src/lib/FieldType/Mapper/QueryFormMapper.php index f7eebd0..47afbb4 100644 --- a/src/lib/FieldType/Mapper/QueryFormMapper.php +++ b/src/lib/FieldType/Mapper/QueryFormMapper.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace Ibexa\FieldTypeQuery\FieldType\Mapper; use Ibexa\AdminUi\FieldType\FieldDefinitionFormMapperInterface; @@ -21,10 +22,13 @@ final class QueryFormMapper implements FieldDefinitionFormMapperInterface /** * List of query types. * - * @var array + * @var array */ private $queryTypes; + /** + * @param array $queryTypes + */ public function __construct(ContentTypeService $contentTypeService, array $queryTypes = []) { $this->contentTypeService = $contentTypeService; @@ -87,7 +91,7 @@ public function mapFieldDefinitionForm(FormInterface $fieldDefinitionForm, Field ->add($parametersForm); } - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver ->setDefaults([ @@ -95,7 +99,10 @@ public function configureOptions(OptionsResolver $resolver) ]); } - private function getContentTypes() + /** + * @return iterable + */ + private function getContentTypes(): iterable { foreach ($this->contentTypeService->loadContentTypeGroups() as $contentTypeGroup) { foreach ($this->contentTypeService->loadContentTypes($contentTypeGroup) as $contentType) { diff --git a/src/lib/FieldType/Query/Type.php b/src/lib/FieldType/Query/Type.php index 5610d7f..80f96c2 100644 --- a/src/lib/FieldType/Query/Type.php +++ b/src/lib/FieldType/Query/Type.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace Ibexa\FieldTypeQuery\FieldType\Query; use Ibexa\Contracts\Core\FieldType\Value as SPIValue; @@ -47,13 +48,6 @@ public function __construct(QueryTypeRegistry $queryTypeRegistry, ContentTypeSer $this->identifier = $identifier; } - /** - * Validates the validatorConfiguration of a FieldDefinitionCreateStruct or FieldDefinitionUpdateStruct. - * - * @param mixed $validatorConfiguration - * - * @return \Ibexa\Contracts\Core\FieldType\ValidationError[] - */ public function validateValidatorConfiguration($validatorConfiguration) { $validationErrors = []; @@ -61,59 +55,33 @@ public function validateValidatorConfiguration($validatorConfiguration) return $validationErrors; } - /** - * Validates a field based on the validators in the field definition. - * - * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException - * - * @param \Ibexa\Contracts\Core\Repository\Values\ContentType\FieldDefinition $fieldDefinition The field definition of the field - * @param \Ibexa\Core\FieldType\TextLine\Value $fieldValue The field value for which an action is performed - * - * @return \Ibexa\Contracts\Core\FieldType\ValidationError[] - */ public function validate(FieldDefinition $fieldDefinition, SPIValue $fieldValue) { return []; } - /** - * Returns the field type identifier for this field type. - * - * @return string - */ public function getFieldTypeIdentifier() { return $this->identifier; } /** - * Returns the name of the given field value. - * - * It will be used to generate content name and url alias if current field is designated - * to be used in the content name/urlAlias pattern. - * * @param \Ibexa\FieldTypeQuery\FieldType\Query\Value $value - * - * @return string */ public function getName(SPIValue $value, FieldDefinition $fieldDefinition, string $languageCode): string { return (string)$value->text; } - public function getEmptyValue() + /** + * @return \Ibexa\FieldTypeQuery\FieldType\Query\Value + */ + public function getEmptyValue(): BaseValue { return new Value(); } - /** - * Returns if the given $value is considered empty by the field type. - * - * @param mixed $value - * - * @return bool - */ - public function isEmptyValue(SPIValue $value) + public function isEmptyValue(SPIValue $value): bool { return false; } @@ -132,9 +100,9 @@ protected function createValueFromInput($inputValue) * * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException if the value does not match the expected structure * - * @param \Ibexa\Core\FieldType\TextLine\Value $value + * @param \Ibexa\FieldTypeQuery\FieldType\Query\Value $value */ - protected function checkValueStructure(BaseValue $value) + protected function checkValueStructure(BaseValue $value): void { if (!is_string($value->text)) { throw new InvalidArgumentType( @@ -146,11 +114,7 @@ protected function checkValueStructure(BaseValue $value) } /** - * Returns information for FieldValue->$sortKey relevant to the field type. - * - * @param \Ibexa\Core\FieldType\TextLine\Value $value - * - * @return array + * @param \Ibexa\FieldTypeQuery\FieldType\Query\Value $value */ protected function getSortInfo(BaseValue $value) { @@ -162,7 +126,7 @@ protected function getSortInfo(BaseValue $value) * * @param mixed $hash * - * @return \Ibexa\Core\FieldType\TextLine\Value $value + * @return \Ibexa\FieldTypeQuery\FieldType\Query\Value $value */ public function fromHash($hash) { diff --git a/src/lib/FieldType/Query/Value.php b/src/lib/FieldType/Query/Value.php index 1e5ec90..698fd9e 100644 --- a/src/lib/FieldType/Query/Value.php +++ b/src/lib/FieldType/Query/Value.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace Ibexa\FieldTypeQuery\FieldType\Query; use Ibexa\Core\FieldType\Value as BaseValue; diff --git a/src/lib/GraphQL/ContentQueryFieldDefinitionMapper.php b/src/lib/GraphQL/ContentQueryFieldDefinitionMapper.php index c795dc8..72e734b 100644 --- a/src/lib/GraphQL/ContentQueryFieldDefinitionMapper.php +++ b/src/lib/GraphQL/ContentQueryFieldDefinitionMapper.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace Ibexa\FieldTypeQuery\GraphQL; use Ibexa\Contracts\Core\Repository\ContentTypeService; @@ -92,14 +93,14 @@ protected function getFieldTypeIdentifier(): string return $this->fieldTypeIdentifier; } - private function nameValueType($typeIdentifier): string + private function nameValueType(string $typeIdentifier): string { return $this->nameHelper->domainContentName( $this->contentTypeService->loadContentTypeByIdentifier($typeIdentifier) ); } - private function nameValueConnectionType($typeIdentifier): string + private function nameValueConnectionType(string $typeIdentifier): string { return $this->nameHelper->domainContentConnection( $this->contentTypeService->loadContentTypeByIdentifier($typeIdentifier) diff --git a/src/lib/GraphQL/QueryFieldResolver.php b/src/lib/GraphQL/QueryFieldResolver.php index ed71ab3..c9e206f 100644 --- a/src/lib/GraphQL/QueryFieldResolver.php +++ b/src/lib/GraphQL/QueryFieldResolver.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace Ibexa\FieldTypeQuery\GraphQL; use Ibexa\Contracts\Core\Repository\Values\Content\Content; @@ -22,15 +23,21 @@ public function __construct(QueryFieldServiceInterface $queryFieldService) $this->queryFieldService = $queryFieldService; } - public function resolveQueryField(Field $field, Content $content) + /** + * @return iterable<\Ibexa\Contracts\Core\Repository\Values\Content\Content> + */ + public function resolveQueryField(Field $field, Content $content): iterable { return $this->queryFieldService->loadContentItems($content, $field->fieldDefIdentifier); } + /** + * @return \GraphQL\Executor\Promise\Promise|\Overblog\GraphQLBundle\Relay\Connection\Output\Connection|null + */ public function resolveQueryFieldConnection(Argument $args, ?Field $field, Content $content) { if ($field === null) { - return null; + return null; } if (!isset($args['first'])) { @@ -49,6 +56,11 @@ function () use ($content, $field) { ); } + /** + * @param array $parameters + * + * @return array + */ public function resolveQueryFieldDefinitionParameters(array $parameters): array { $return = []; diff --git a/src/lib/Persistence/Legacy/Content/FieldValue/Converter/QueryConverter.php b/src/lib/Persistence/Legacy/Content/FieldValue/Converter/QueryConverter.php index 6a3b557..6b68ec2 100644 --- a/src/lib/Persistence/Legacy/Content/FieldValue/Converter/QueryConverter.php +++ b/src/lib/Persistence/Legacy/Content/FieldValue/Converter/QueryConverter.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace Ibexa\FieldTypeQuery\Persistence\Legacy\Content\FieldValue\Converter; use Ibexa\Contracts\Core\Persistence\Content\FieldValue; @@ -28,52 +29,28 @@ public static function create() return new self(); } - /** - * Converts data from $value to $storageFieldValue. - * - * @param \Ibexa\Contracts\Core\Persistence\Content\FieldValue $value - * @param \Ibexa\Core\Persistence\Legacy\Content\StorageFieldValue $storageFieldValue - */ - public function toStorageValue(FieldValue $value, StorageFieldValue $storageFieldValue) + public function toStorageValue(FieldValue $value, StorageFieldValue $storageFieldValue): void { $storageFieldValue->dataText = $value->data; - $storageFieldValue->sortKeyString = $value->sortKey; + $storageFieldValue->sortKeyString = (string)$value->sortKey; } - /** - * Converts data from $value to $fieldValue. - * - * @param \Ibexa\Core\Persistence\Legacy\Content\StorageFieldValue $value - * @param \Ibexa\Contracts\Core\Persistence\Content\FieldValue $fieldValue - */ - public function toFieldValue(StorageFieldValue $value, FieldValue $fieldValue) + public function toFieldValue(StorageFieldValue $value, FieldValue $fieldValue): void { $fieldValue->data = $value->dataText; $fieldValue->sortKey = $value->sortKeyString; } - /** - * Converts field definition data in $fieldDef into $storageFieldDef. - * - * @param \Ibexa\Contracts\Core\Persistence\Content\Type\FieldDefinition $fieldDef - * @param \Ibexa\Core\Persistence\Legacy\Content\StorageFieldDefinition $storageDef - */ - public function toStorageFieldDefinition(FieldDefinition $fieldDef, StorageFieldDefinition $storageDef) + public function toStorageFieldDefinition(FieldDefinition $fieldDef, StorageFieldDefinition $storageDef): void { $storageDef->dataText1 = $fieldDef->fieldTypeConstraints->fieldSettings['QueryType']; $storageDef->dataText2 = $fieldDef->fieldTypeConstraints->fieldSettings['ReturnedType']; - $storageDef->dataText5 = \json_encode($fieldDef->fieldTypeConstraints->fieldSettings['Parameters']); + $storageDef->dataText5 = \json_encode($fieldDef->fieldTypeConstraints->fieldSettings['Parameters']) ?: ''; $storageDef->dataInt1 = (int)$fieldDef->fieldTypeConstraints->fieldSettings['EnablePagination']; $storageDef->dataInt2 = $fieldDef->fieldTypeConstraints->fieldSettings['ItemsPerPage']; } - /** - * Converts field definition data in $storageDef into $fieldDef. - * - * @param \Ibexa\Core\Persistence\Legacy\Content\StorageFieldDefinition $storageDef - * @param \Ibexa\Contracts\Core\Persistence\Content\Type\FieldDefinition $fieldDef - */ - public function toFieldDefinition(StorageFieldDefinition $storageDef, FieldDefinition $fieldDef) + public function toFieldDefinition(StorageFieldDefinition $storageDef, FieldDefinition $fieldDef): void { $fieldDef->fieldTypeConstraints->fieldSettings = [ 'QueryType' => $storageDef->dataText1 ?: null, @@ -84,15 +61,6 @@ public function toFieldDefinition(StorageFieldDefinition $storageDef, FieldDefin ]; } - /** - * Returns the name of the index column in the attribute table. - * - * Returns the name of the index column the datatype uses, which is either - * "sort_key_int" or "sort_key_string". This column is then used for - * filtering and sorting for this type. - * - * @return string - */ public function getIndexColumn() { return 'sort_key_string'; diff --git a/src/lib/QueryFieldPaginationService.php b/src/lib/QueryFieldPaginationService.php index 8cf8f35..04eaf89 100644 --- a/src/lib/QueryFieldPaginationService.php +++ b/src/lib/QueryFieldPaginationService.php @@ -4,6 +4,7 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace Ibexa\FieldTypeQuery; /** diff --git a/src/lib/QueryFieldService.php b/src/lib/QueryFieldService.php index 819f14e..d13609a 100644 --- a/src/lib/QueryFieldService.php +++ b/src/lib/QueryFieldService.php @@ -4,10 +4,10 @@ * @copyright Copyright (C) Ibexa AS. All rights reserved. * @license For full copyright and license information view LICENSE file distributed with this source code. */ + namespace Ibexa\FieldTypeQuery; use Ibexa\Contracts\Core\Repository\ContentTypeService; -use Ibexa\Contracts\Core\Repository\LocationService; use Ibexa\Contracts\Core\Repository\SearchService; use Ibexa\Contracts\Core\Repository\Values\Content\Content; use Ibexa\Contracts\Core\Repository\Values\Content\Location; @@ -35,26 +35,23 @@ final class QueryFieldService implements QueryFieldServiceInterface, QueryFieldL /** @var \Ibexa\Contracts\Core\Repository\ContentTypeService */ private $contentTypeService; - /** - * @var \Ibexa\Contracts\Core\Repository\LocationService - */ - private $locationService; - public function __construct( SearchService $searchService, ContentTypeService $contentTypeService, - LocationService $locationService, QueryTypeRegistry $queryTypeRegistry ) { $this->searchService = $searchService; $this->contentTypeService = $contentTypeService; - $this->locationService = $locationService; $this->queryTypeRegistry = $queryTypeRegistry; } public function loadContentItems(Content $content, string $fieldDefinitionIdentifier): iterable { - $query = $this->prepareQuery($content, $content->contentInfo->getMainLocation(), $fieldDefinitionIdentifier); + $mainLocation = $content->contentInfo->getMainLocation(); + if ($mainLocation === null) { + return []; + } + $query = $this->prepareQuery($content, $mainLocation, $fieldDefinitionIdentifier); return $this->executeQueryAndMapResult($query); } @@ -68,7 +65,11 @@ public function loadContentItemsForLocation(Location $location, string $fieldDef public function countContentItems(Content $content, string $fieldDefinitionIdentifier): int { - $query = $this->prepareQuery($content, $content->contentInfo->getMainLocation(), $fieldDefinitionIdentifier); + $mainLocation = $content->contentInfo->getMainLocation(); + if ($mainLocation === null) { + return 0; + } + $query = $this->prepareQuery($content, $mainLocation, $fieldDefinitionIdentifier); $query->limit = 0; $count = $this->searchService->findContent($query)->totalCount - $query->offset; @@ -88,7 +89,11 @@ public function countContentItemsForLocation(Location $location, string $fieldDe public function loadContentItemsSlice(Content $content, string $fieldDefinitionIdentifier, int $offset, int $limit): iterable { - $query = $this->prepareQuery($content, $content->contentInfo->getMainLocation(), $fieldDefinitionIdentifier); + $mainLocation = $content->contentInfo->getMainLocation(); + if ($mainLocation === null) { + return []; + } + $query = $this->prepareQuery($content, $mainLocation, $fieldDefinitionIdentifier); $query->offset += $offset; $query->limit = $limit;