From c851ec14006821e0a9ba25ccbfca3c0002468632 Mon Sep 17 00:00:00 2001 From: Bertrand Dunogier Date: Tue, 13 Nov 2018 15:52:26 +0100 Subject: [PATCH] Handled different coverage of field criteria across search engines The Legacy and Solr search engines don't support the same fields as field criteria. This delegates checking for that to SearchFeature objects specialized depending on the engine type. --- .../Factory/SearchFeaturesFactory.php | 34 ++++++++ src/Resources/config/services.yml | 17 ++++ .../AddFieldDefinitionToCollectionFilters.php | 87 +++++++++++++++++++ src/Search/LegacySearchFeatures.php | 23 +++++ src/Search/SearchFeatures.php | 16 ++++ src/Search/SolrSearchFeatures.php | 12 +++ 6 files changed, 189 insertions(+) create mode 100644 src/DependencyInjection/Factory/SearchFeaturesFactory.php create mode 100644 src/Schema/Domain/Content/Worker/FieldDefinition/AddFieldDefinitionToCollectionFilters.php create mode 100644 src/Search/LegacySearchFeatures.php create mode 100644 src/Search/SearchFeatures.php create mode 100644 src/Search/SolrSearchFeatures.php diff --git a/src/DependencyInjection/Factory/SearchFeaturesFactory.php b/src/DependencyInjection/Factory/SearchFeaturesFactory.php new file mode 100644 index 00000000..4c6e829a --- /dev/null +++ b/src/DependencyInjection/Factory/SearchFeaturesFactory.php @@ -0,0 +1,34 @@ +configurationProvider = $configurationProvider; + $this->searchFeatures = $searchFeatures; + } + + public function build() + { + $searchEngine = $this->configurationProvider->getRepositoryConfig()['search']['engine']; + + if (isset($this->searchFeatures[$searchEngine])) { + return $this->searchFeatures[$searchEngine]; + } else { + throw new \InvalidArgumentException("Search engine not found"); + } + } +} \ No newline at end of file diff --git a/src/Resources/config/services.yml b/src/Resources/config/services.yml index 297d9b54..db399c41 100644 --- a/src/Resources/config/services.yml +++ b/src/Resources/config/services.yml @@ -20,3 +20,20 @@ services: - { name: "overblog_graphql.mutation", alias: "DeleteSection", method: "deleteSection" } EzSystems\EzPlatformGraphQL\GraphQL\InputMapper\SearchQueryMapper: ~ + + EzSystems\EzPlatformGraphQL\DependencyInjection\Factory\SearchFeaturesFactory: + arguments: + $configurationProvider: '@ezpublish.api.repository_configuration_provider' + $searchFeatures: + solr: '@EzSystems\EzPlatformGraphQL\Search\SolrSearchFeatures' + legacy: '@EzSystems\EzPlatformGraphQL\Search\LegacySearchFeatures' + + EzSystems\EzPlatformGraphQL\Search\SearchFeatures: + factory: ['@EzSystems\EzPlatformGraphQL\DependencyInjection\Factory\SearchFeaturesFactory', build] + + EzSystems\EzPlatformGraphQL\Search\LegacySearchFeatures: + arguments: + $converterRegistry: '@ezpublish.persistence.legacy.field_value_converter.registry' + + EzSystems\EzPlatformGraphQL\Search\SolrSearchFeatures: ~ + diff --git a/src/Schema/Domain/Content/Worker/FieldDefinition/AddFieldDefinitionToCollectionFilters.php b/src/Schema/Domain/Content/Worker/FieldDefinition/AddFieldDefinitionToCollectionFilters.php new file mode 100644 index 00000000..58a78231 --- /dev/null +++ b/src/Schema/Domain/Content/Worker/FieldDefinition/AddFieldDefinitionToCollectionFilters.php @@ -0,0 +1,87 @@ +searchFeatures = $searchFeatures; + } + + public function work(Builder $schema, array $args) + { + $domainGroupName = $this->getNameHelper()->domainGroupName($args['ContentTypeGroup']); + $domainContentCollectionField = $this->getNameHelper()->domainContentCollectionField($args['ContentType']); + $fieldDefinitionField = $this->getNameHelper()->fieldDefinitionField($args['FieldDefinition']); + + $schema->addFieldToType( + $domainGroupName, + new Builder\Input\Field( + $domainContentCollectionField, + $this->getFilterType($args['FieldDefinition']), + ['description' => 'Filter content based on the ' . $args['FieldDefinition']->identifier . ' field'] + ) + ); + } + + public function canWork(Builder $schema, array $args) + { + return + isset($args['FieldDefinition']) + && $args['FieldDefinition'] instanceof FieldDefinition + & isset($args['ContentType']) + && $args['ContentType'] instanceof ContentType + && $this->searchFeatures->supportsFieldCriterion($args['FieldDefinition']); + } + + /** + * @param ContentType $contentType + * @return string + */ + protected function getDomainContentName(ContentType $contentType): string + { + return $this->getNameHelper()->domainContentName($contentType); + } + + /** + * @param FieldDefinition $fieldDefinition + * @return string + */ + protected function getFieldDefinitionField(FieldDefinition $fieldDefinition): string + { + return $this->getNameHelper()->fieldDefinitionField($fieldDefinition); + } + + private function isSearchable(FieldDefinition $fieldDefinition): bool + { + return $fieldDefinition->isSearchable + // should only be verified if legacy is the current search engine + && $this->converterRegistry->getConverter($fieldDefinition->fieldTypeIdentifier)->getIndexColumn() !== false; + } + + private function getFilterType(FieldDefinition $fieldDefinition) + { + switch ($fieldDefinition->fieldTypeIdentifier) + { + case 'ezboolean': + return 'Boolean'; + default: + return 'String'; + } + } +} \ No newline at end of file diff --git a/src/Search/LegacySearchFeatures.php b/src/Search/LegacySearchFeatures.php new file mode 100644 index 00000000..8841ac8a --- /dev/null +++ b/src/Search/LegacySearchFeatures.php @@ -0,0 +1,23 @@ +converterRegistry = $converterRegistry; + } + + public function supportsFieldCriterion(FieldDefinition $fieldDefinition) + { + return $this->converterRegistry->getConverter($fieldDefinition->fieldTypeIdentifier)->getIndexColumn() !== false; + } +} \ No newline at end of file diff --git a/src/Search/SearchFeatures.php b/src/Search/SearchFeatures.php new file mode 100644 index 00000000..b8af35ed --- /dev/null +++ b/src/Search/SearchFeatures.php @@ -0,0 +1,16 @@ +