23
23
use Smile \ElasticsuiteCatalog \Model \Attribute \Source \FilterSortOrder ;
24
24
use Magento \Framework \Data \Form \Element \Fieldset ;
25
25
use Magento \Catalog \Api \Data \EavAttributeInterface ;
26
+ use Smile \ElasticsuiteCatalog \Model \Attribute \Source \TextScoringAlgorithm ;
26
27
use Smile \ElasticsuiteCore \Api \Index \Mapping \FieldInterface ;
27
28
28
29
/**
29
- * Plugin that happend custom fields dedicated to search configuration
30
+ * Plugin that append custom fields dedicated to search configuration
30
31
*
31
32
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
32
33
*
@@ -74,6 +75,11 @@ class FrontPlugin
74
75
*/
75
76
private $ filterBooleanLogic ;
76
77
78
+ /**
79
+ * @var TextScoringAlgorithm
80
+ */
81
+ private $ textScoringAlgorithm ;
82
+
77
83
/**
78
84
* @var UrlInterface
79
85
*/
@@ -82,27 +88,30 @@ class FrontPlugin
82
88
/**
83
89
* Class constructor
84
90
*
85
- * @param Yesno $booleanSource The YesNo source.
86
- * @param Weight $weightSource Weight source.
87
- * @param Registry $coreRegistry Core registry.
88
- * @param FilterSortOrder $filterSortOrder Filter Sort Order.
89
- * @param FilterBooleanLogic $filterBooleanLogic Filter boolean logic source model.
90
- * @param UrlInterface $urlBuilder Url Builder.
91
+ * @param Yesno $booleanSource The YesNo source.
92
+ * @param Weight $weightSource Weight source.
93
+ * @param Registry $coreRegistry Core registry.
94
+ * @param FilterSortOrder $filterSortOrder Filter Sort Order.
95
+ * @param FilterBooleanLogic $filterBooleanLogic Filter boolean logic source model.
96
+ * @param TextScoringAlgorithm $textScoringAlgorithm Text scoring algorithm source model.
97
+ * @param UrlInterface $urlBuilder Url Builder.
91
98
*/
92
99
public function __construct (
93
100
Yesno $ booleanSource ,
94
101
Weight $ weightSource ,
95
102
Registry $ coreRegistry ,
96
103
FilterSortOrder $ filterSortOrder ,
97
104
FilterBooleanLogic $ filterBooleanLogic ,
105
+ TextScoringAlgorithm $ textScoringAlgorithm ,
98
106
UrlInterface $ urlBuilder
99
107
) {
100
108
$ this ->weightSource = $ weightSource ;
101
109
$ this ->booleanSource = $ booleanSource ;
102
110
$ this ->coreRegistry = $ coreRegistry ;
103
111
$ this ->filterSortOrder = $ filterSortOrder ;
104
- $ this ->filterBooleanLogic = $ filterBooleanLogic ;
105
- $ this ->urlBuilder = $ urlBuilder ;
112
+ $ this ->filterBooleanLogic = $ filterBooleanLogic ;
113
+ $ this ->textScoringAlgorithm = $ textScoringAlgorithm ;
114
+ $ this ->urlBuilder = $ urlBuilder ;
106
115
}
107
116
108
117
/**
@@ -153,6 +162,12 @@ public function afterSetForm(Front $subject, Front $result, Form $form)
153
162
$ this ->addDisableNormsField ($ advancedFieldset );
154
163
}
155
164
165
+ if (in_array ($ this ->getAttribute ()->getBackendType (), ['varchar ' , 'text ' ])
166
+ || in_array ($ this ->getAttribute ()->getFrontendInput (), ['select ' , 'multiselect ' ])
167
+ ) {
168
+ $ this ->addScoringAlgorithmField ($ advancedFieldset );
169
+ }
170
+
156
171
$ this ->appendFieldsDependency ($ subject );
157
172
158
173
return $ result ;
@@ -635,6 +650,57 @@ private function addDisableNormsField(Fieldset $fieldset)
635
650
return $ this ;
636
651
}
637
652
653
+ /**
654
+ * Add field allowing to configure a non-default similarity/text scoring model.
655
+ *
656
+ * @param Fieldset $fieldset Target fieldset
657
+ *
658
+ * @return FrontPlugin
659
+ */
660
+ private function addScoringAlgorithmField (Fieldset $ fieldset )
661
+ {
662
+ $ link = sprintf (
663
+ '<a href="%s" target="_blank">%s</a> ' ,
664
+ $ this ->urlBuilder ->getUrl (
665
+ 'adminhtml/system_config/edit ' ,
666
+ [
667
+ 'section ' => 'smile_elasticsuite_catalogsearch_settings ' ,
668
+ '_fragment ' => 'smile_elasticsuite_catalogsearch_settings_catalogsearch-link ' ,
669
+ ]
670
+ ),
671
+ implode (' > ' , [__ ('ElasticSuite ' ), __ ('Catalog Search ' ), __ ('Catalog Search Configuration ' )])
672
+ );
673
+
674
+ // @codingStandardsIgnoreStart
675
+ $ scoringAlgorithmNote = __ (
676
+ 'The text scoring algorithm (or "similarity") determines how the relevance score is computed for a field during search. '
677
+ . '<br/> Selecting "Default" will let your server apply the default scoring algorithm which takes into account every occurence of a search term in a field. '
678
+ . ' Eg: a product with "dress" 3 times in its description should be scored higher than a product with "dress" only 1 time. '
679
+ . '<br/> You can opt for a "Boolean" scoring model that produces at most a score of 1 (before the "Search weight" is applied) for the whole field whatever the number of matches. '
680
+ . ' Eg: the product with "dress" 3 times in its description would be scored the same as the product with "dress" only 1 time in its description. '
681
+ )
682
+ . '<br /> '
683
+ . __ (
684
+ '<strong>Warning</strong>: a searchable attribute data is always copied to some searchable "collector fields" whose behavior will not be impacted by the change you do here. '
685
+ . '<br />So you might want to also look at the specific "<strong>Text scoring algorithm for collector fields</strong>" setting in the Stores Configuration section %1. ' ,
686
+ $ link
687
+ );
688
+ // @codingStandardsIgnoreEnd
689
+ $ fieldset ->addField (
690
+ 'scoring_algorithm ' ,
691
+ 'select ' ,
692
+ [
693
+ 'name ' => 'scoring_algorithm ' ,
694
+ 'label ' => __ ('Text scoring algorithm ' ),
695
+ 'values ' => $ this ->textScoringAlgorithm ->toOptionArray (),
696
+ 'note ' => $ scoringAlgorithmNote ,
697
+ ],
698
+ 'norms_disabled '
699
+ );
700
+
701
+ return $ this ;
702
+ }
703
+
638
704
/**
639
705
* Add field allowing to configure if a field can be used for span queries.
640
706
*
@@ -709,13 +775,15 @@ private function appendFieldsDependency($subject)
709
775
->addFieldMap ('is_spannable ' , 'is_spannable ' )
710
776
->addFieldMap ('norms_disabled ' , 'norms_disabled ' )
711
777
->addFieldMap ('default_analyzer ' , 'default_analyzer ' )
778
+ ->addFieldMap ('scoring_algorithm ' , 'scoring_algorithm ' )
712
779
->addFieldMap ('search_weight ' , 'search_weight ' )
713
780
->addFieldDependence ('is_displayed_in_autocomplete ' , 'is_filterable_in_search ' , '1 ' )
714
781
->addFieldDependence ('is_used_in_spellcheck ' , 'is_searchable ' , '1 ' )
715
782
->addFieldDependence ('is_spannable ' , 'is_searchable ' , '1 ' )
716
783
->addFieldDependence ('norms_disabled ' , 'is_searchable ' , '1 ' )
717
784
->addFieldDependence ('search_weight ' , 'is_searchable ' , '1 ' )
718
785
->addFieldDependence ('default_analyzer ' , 'is_searchable ' , '1 ' )
786
+ ->addFieldDependence ('scoring_algorithm ' , 'is_searchable ' , '1 ' )
719
787
->addFieldDependence ('sort_order_asc_missing ' , 'used_for_sort_by ' , '1 ' )
720
788
->addFieldDependence ('sort_order_desc_missing ' , 'used_for_sort_by ' , '1 ' )
721
789
->addFieldDependence ('is_display_rel_nofollow ' , 'is_filterable ' , '1 ' );
0 commit comments