FactFinderNgSuggestToElasticaMapper   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 254
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 18
eloc 100
c 2
b 0
f 0
dl 0
loc 254
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A mapElasticaCompletion() 0 23 2
A mapSearchResultToElasticaResponseArray() 0 7 1
A mapElasticaProductBucket() 0 29 4
A mapElasticaSuggestion() 0 16 2
A mapHit() 0 27 1
A mapBucket() 0 10 1
A __construct() 0 11 1
A map() 0 18 2
A findSuggestItemsByType() 0 10 3
A mapElasticaAggregations() 0 7 1
1
<?php
2
3
/**
4
 * MIT License
5
 * For full license information, please view the LICENSE file that was distributed with this source code.
6
 */
7
8
namespace SprykerEco\Client\FactFinderNg\Mapper\Elastica;
9
10
use Elastica\Query;
11
use Elastica\Response;
12
use Elastica\ResultSet;
13
use Elastica\ResultSet\DefaultBuilder;
14
use ErrorException;
15
use Generated\Shared\Transfer\StoreTransfer;
0 ignored issues
show
Bug introduced by
The type Generated\Shared\Transfer\StoreTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use Spryker\Client\Search\Plugin\Elasticsearch\QueryExpander\CompletionQueryExpanderPlugin;
17
use Spryker\Client\Search\Plugin\Elasticsearch\QueryExpander\SuggestionByTypeQueryExpanderPlugin;
18
use SprykerEco\Client\FactFinderNg\Dependency\Client\FactFinderNgToPriceProductStorageClientInterface;
19
use SprykerEco\Client\FactFinderNg\Dependency\Client\FactFinderNgToProductImageStorageClientInterface;
20
use SprykerEco\Client\FactFinderNg\Dependency\Client\FactFinderNgToProductStorageClientInterface;
21
22
class FactFinderNgSuggestToElasticaMapper extends AbstractFactFinderToElasticaMapper implements FactFinderToElasticaMapperInterface
23
{
24
    /**
25
     * @var \Elastica\ResultSet\DefaultBuilder
26
     */
27
    protected $elasticaDefaultBuilder;
28
29
    /**
30
     * @var \SprykerEco\Client\FactFinderNg\Dependency\Client\FactFinderNgToProductStorageClientInterface
31
     */
32
    protected $productStorageClient;
33
34
    /**
35
     * @var \SprykerEco\Client\FactFinderNg\Dependency\Client\FactFinderNgToProductImageStorageClientInterface
36
     */
37
    protected $productImageStorageClient;
38
39
    /**
40
     * @param \Elastica\ResultSet\DefaultBuilder $elasticaDefaultBuilder
41
     * @param \SprykerEco\Client\FactFinderNg\Dependency\Client\FactFinderNgToProductStorageClientInterface $productStorageClient
42
     * @param \SprykerEco\Client\FactFinderNg\Dependency\Client\FactFinderNgToProductImageStorageClientInterface $productImageStorageClient
43
     * @param \SprykerEco\Client\FactFinderNg\Dependency\Client\FactFinderNgToPriceProductStorageClientInterface $priceProductStorageClient
44
     */
45
    public function __construct(
46
        DefaultBuilder $elasticaDefaultBuilder,
47
        FactFinderNgToProductStorageClientInterface $productStorageClient,
48
        FactFinderNgToProductImageStorageClientInterface $productImageStorageClient,
49
        FactFinderNgToPriceProductStorageClientInterface $priceProductStorageClient
50
    ) {
51
        parent::__construct($priceProductStorageClient);
52
53
        $this->elasticaDefaultBuilder = $elasticaDefaultBuilder;
54
        $this->productStorageClient = $productStorageClient;
55
        $this->productImageStorageClient = $productImageStorageClient;
56
    }
57
58
    /**
59
     * @param array $searchResult
60
     * @param \Elastica\Query $elasticaQuery
61
     * @param string $currentLocale
62
     * @param \Generated\Shared\Transfer\StoreTransfer $currentStore
63
     *
64
     * @return \Elastica\ResultSet
65
     */
66
    public function map(
67
        array $searchResult,
68
        Query $elasticaQuery,
69
        string $currentLocale,
70
        StoreTransfer $currentStore
71
    ): ResultSet {
72
        $this->currentLocale = $currentLocale;
73
        $this->currentStore = $currentStore;
74
75
        try {
76
            $elasticaResponseArray = $this->mapSearchResultToElasticaResponseArray($searchResult);
77
        } catch (ErrorException $e) {
78
            $elasticaResponseArray = [];
79
        }
80
81
        $elasticaResponse = new Response($elasticaResponseArray, 200);
82
83
        return $this->elasticaDefaultBuilder->buildResultSet($elasticaResponse, $elasticaQuery);
84
    }
85
86
    /**
87
     * @param array $searchResult
88
     *
89
     * @return array
90
     */
91
    protected function mapSearchResultToElasticaResponseArray(array $searchResult): array
92
    {
93
        $elasticaResponseArray = [];
94
        $elasticaResponseArray[static::KEY_HITS] = [];
95
        $elasticaResponseArray[static::KEY_AGGREGATIONS] = $this->mapElasticaAggregations($searchResult);
96
97
        return $elasticaResponseArray;
98
    }
99
100
    /**
101
     * @param array $searchResult
102
     *
103
     * @return array
104
     */
105
    protected function mapElasticaAggregations(array $searchResult): array
106
    {
107
        $aggregations = [];
108
        $aggregations[CompletionQueryExpanderPlugin::AGGREGATION_NAME] = $this->mapElasticaCompletion($searchResult);
109
        $aggregations[SuggestionByTypeQueryExpanderPlugin::AGGREGATION_NAME] = $this->mapElasticaSuggestion($searchResult);
110
111
        return $aggregations;
112
    }
113
114
    /**
115
     * @param array $searchResult
116
     *
117
     * @return array
118
     */
119
    protected function mapElasticaCompletion(array $searchResult): array
120
    {
121
        $buckets = [];
122
        $ffSuggestCategoryItems = $this->findSuggestItemsByType($searchResult, static::KEY_CATEGORY);
123
        $ffSuggestBrandItems = $this->findSuggestItemsByType($searchResult, static::KEY_BRAND);
124
        $ffSuggestItems = array_merge($ffSuggestCategoryItems, $ffSuggestBrandItems);
125
126
        foreach ($ffSuggestItems as $ffSuggestItem) {
127
            $bucket = [
128
                static::KEY_KEY => $ffSuggestItem[static::KEY_NAME],
129
                static::KEY_DOC_COUNT => $ffSuggestItem[static::KEY_HIT_COUNT],
130
            ];
131
132
            $buckets[] = $bucket;
133
        }
134
135
        $completion = [
136
            static::KEY_DOC_COUNT_ERROR_UPPER_BOUND => 0,
137
            static::KEY_SUM_OTHER_DOC_COUNT => count($buckets),
138
            static::KEY_BUCKETS => $buckets,
139
        ];
140
141
        return $completion;
142
    }
143
144
    /**
145
     * @param array $searchResult
146
     *
147
     * @return array
148
     */
149
    protected function mapElasticaSuggestion(array $searchResult): array
150
    {
151
        $buckets = [];
152
        $bucket = $this->mapElasticaProductBucket($searchResult);
153
154
        if ($bucket) {
155
            $buckets[] = $bucket;
156
        }
157
158
        $suggestion = [
159
            static::KEY_DOC_COUNT_ERROR_UPPER_BOUND => 0,
160
            static::KEY_SUM_OTHER_DOC_COUNT => 0,
161
            static::KEY_BUCKETS => $buckets,
162
        ];
163
164
        return $suggestion;
165
    }
166
167
    /**
168
     * @param array $searchResult
169
     *
170
     * @return array
171
     */
172
    protected function mapElasticaProductBucket(array $searchResult): array
173
    {
174
        $ffSuggestItems = $this->findSuggestItemsByType($searchResult, static::KEY_PRODUCT_NAME);
175
        $hits = [];
176
        $maxScore = 0;
177
178
        foreach ($ffSuggestItems as $ffSuggestItem) {
179
            $productAbstract = $this->productStorageClient
180
                ->findProductAbstractStorageDataByMapping(
181
                    static::SKU_MAPPING_TYPE,
182
                    $ffSuggestItem[static::KEY_ATTRIBUTES][static::KEY_MASTER_ID],
183
                    $this->currentLocale
184
                );
185
186
            if ($productAbstract === null) {
187
                continue;
188
            }
189
            $maxScore = max($maxScore, $ffSuggestItem[static::KEY_SCORE]);
190
191
            $hits[] = $this->mapHit($productAbstract, $ffSuggestItem);
192
        }
193
194
        $hitsCount = count($hits);
195
196
        if (!$hitsCount) {
197
            return [];
198
        }
199
200
        return $this->mapBucket($hitsCount, $maxScore, $hits);
201
    }
202
203
    /**
204
     * @param array $searchResult
205
     * @param string $ffSuggestType
206
     *
207
     * @return array
208
     */
209
    protected function findSuggestItemsByType(array $searchResult, string $ffSuggestType): array
210
    {
211
        $ffSuggestItems = [];
212
        foreach ($searchResult as $ffSuggestItem) {
213
            if ($ffSuggestItem[static::KEY_OPTION_TYPE] == $ffSuggestType) {
214
                $ffSuggestItems[] = $ffSuggestItem;
215
            }
216
        }
217
218
        return $ffSuggestItems;
219
    }
220
221
    /**
222
     * @param array $productAbstract
223
     * @param array $ffSuggestItem
224
     *
225
     * @return array
226
     */
227
    protected function mapHit(array $productAbstract, array $ffSuggestItem): array
228
    {
229
        return [
230
            static::KEY_INDEX => $this->currentLocale . static::KEY_SEARCH,
231
            static::KEY_TYPE => static::KEY_PAGE,
232
            static::KEY_ID => $productAbstract[static::KEY_ID_PRODUCT_ABSTRACT],
233
            static::KEY_OPTION_SCORE => $ffSuggestItem[static::KEY_SCORE],
234
            static::KEY_SOURCE => [
235
                static::KEY_STORE => $this->currentStore->getName(),
236
                static::KEY_LOCALE => $this->currentLocale,
237
                static::KEY_OPTION_TYPE => static::KEY_PRODUCT_ABSTRACT,
238
                static::KEY_IS_ACTIVE => true,
239
                static::KEY_SEARCH_RESULT_DATA =>
240
                    [
241
                        static::KEY_ID_PRODUCT_ABSTRACT => $productAbstract[static::KEY_ID_PRODUCT_ABSTRACT],
242
                        static::KEY_ABSTRACT_SKU => $productAbstract[static::KEY_SKU],
243
                        static::KEY_ABSTRACT_NAME => $productAbstract[static::KEY_NAME],
244
                        static::KEY_URL => $productAbstract[static::KEY_URL],
245
                        static::KEY_OPTION_TYPE => static::KEY_PRODUCT_ABSTRACT,
246
                        static::KEY_PRICE => 0,
247
                        static::KEY_PRICES => $this->mapElasticaPrices($productAbstract),
248
                        static::KEY_IMAGES => $this->mapElasticaImages($this->productImageStorageClient
0 ignored issues
show
Bug introduced by
It seems like $this->productImageStora..., $this->currentLocale) can also be of type null; however, parameter $productAbstractImageStorageTransfer of SprykerEco\Client\FactFi...er::mapElasticaImages() does only seem to accept Generated\Shared\Transfe...actImageStorageTransfer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

248
                        static::KEY_IMAGES => $this->mapElasticaImages(/** @scrutinizer ignore-type */ $this->productImageStorageClient
Loading history...
249
                            ->findProductImageAbstractStorageTransfer(
250
                                $productAbstract[static::KEY_ID_PRODUCT_ABSTRACT],
251
                                $this->currentLocale
252
                            )),
253
                        static::KEY_ID_PRODUCT_LABELS => [],
254
                    ],
255
            ],
256
        ];
257
    }
258
259
    /**
260
     * @param int $hitsCount
261
     * @param int $maxScore
262
     * @param array $hits
263
     *
264
     * @return array
265
     */
266
    protected function mapBucket(int $hitsCount, int $maxScore, array $hits): array
267
    {
268
        return [
269
            static::KEY_KEY => static::KEY_PRODUCT_ABSTRACT,
270
            static::KEY_DOC_COUNT => $hitsCount,
271
            static::KEY_TOP_HITS => [
272
                static::KEY_HITS => [
273
                    static::KEY_TOTAL => $hitsCount,
274
                    static::KEY_MAX_SCORE => $maxScore,
275
                    static::KEY_HITS => $hits,
276
                ],
277
            ],
278
        ];
279
    }
280
}
281