1 | <?php |
||
2 | |||
3 | /** |
||
4 | * Copyright © 2016-present Spryker Systems GmbH. All rights reserved. |
||
5 | * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file. |
||
6 | */ |
||
7 | |||
8 | namespace Spryker\Yves\CmsContentWidgetProductSearchConnector\Plugin; |
||
9 | |||
10 | use Generated\Shared\Transfer\StorageProductTransfer; |
||
11 | use Spryker\Shared\CmsContentWidget\Dependency\CmsContentWidgetConfigurationProviderInterface; |
||
12 | use Spryker\Yves\CmsContentWidget\Dependency\CmsContentWidgetPluginInterface; |
||
13 | use Spryker\Yves\CmsContentWidgetProductSearchConnector\Exception\TemplateIdentifierNotFoundException; |
||
14 | use Spryker\Yves\Kernel\AbstractPlugin; |
||
15 | use Twig\Environment; |
||
16 | |||
17 | /** |
||
18 | * @deprecated Will be removed without replacement. This functionality is obsolete and should not be used. |
||
19 | * |
||
20 | * @method \Spryker\Yves\CmsContentWidgetProductSearchConnector\CmsContentWidgetProductSearchConnectorFactory getFactory() |
||
21 | * @method \Spryker\Yves\CmsContentWidgetProductSearchConnector\CmsContentWidgetProductSearchConnectorConfig getConfig() |
||
22 | */ |
||
23 | class CmsProductSearchContentWidgetPlugin extends AbstractPlugin implements CmsContentWidgetPluginInterface |
||
24 | { |
||
25 | /** |
||
26 | * @var \Spryker\Shared\CmsContentWidget\Dependency\CmsContentWidgetConfigurationProviderInterface |
||
27 | */ |
||
28 | protected $widgetConfiguration; |
||
29 | |||
30 | /** |
||
31 | * @param \Spryker\Shared\CmsContentWidget\Dependency\CmsContentWidgetConfigurationProviderInterface $widgetConfiguration |
||
32 | */ |
||
33 | public function __construct(CmsContentWidgetConfigurationProviderInterface $widgetConfiguration) |
||
34 | { |
||
35 | $this->widgetConfiguration = $widgetConfiguration; |
||
36 | } |
||
37 | |||
38 | /** |
||
39 | * @return callable |
||
40 | */ |
||
41 | public function getContentWidgetFunction() |
||
42 | { |
||
43 | return [$this, 'contentWidgetFunction']; |
||
44 | } |
||
45 | |||
46 | /** |
||
47 | * @param \Twig\Environment $twig |
||
48 | * @param array $context Data related to twig function |
||
49 | * @param string $searchString String for direct search in elastic |
||
50 | * @param string|null $templateIdentifier |
||
51 | * |
||
52 | * @return string |
||
53 | */ |
||
54 | public function contentWidgetFunction( |
||
55 | Environment $twig, |
||
56 | array $context, |
||
57 | $searchString, |
||
58 | $templateIdentifier = null |
||
59 | ) { |
||
60 | return $twig->render( |
||
61 | $this->resolveTemplatePath($templateIdentifier, $context), |
||
62 | $this->getTwigWidgetContent($searchString), |
||
63 | ); |
||
64 | } |
||
65 | |||
66 | /** |
||
67 | * @param string $templateIdentifier |
||
68 | * @param array $context |
||
69 | * |
||
70 | * @throws \Spryker\Yves\CmsContentWidgetProductSearchConnector\Exception\TemplateIdentifierNotFoundException |
||
71 | * |
||
72 | * @return string |
||
73 | */ |
||
74 | protected function resolveTemplatePath($templateIdentifier, array $context) |
||
75 | { |
||
76 | $availableTemplates = $this->widgetConfiguration->getAvailableTemplates(); |
||
77 | $templateIdentifier = $templateIdentifier ?: CmsContentWidgetConfigurationProviderInterface::DEFAULT_TEMPLATE_IDENTIFIER; |
||
78 | |||
79 | if (!array_key_exists($templateIdentifier, $availableTemplates)) { |
||
80 | throw new TemplateIdentifierNotFoundException( |
||
81 | sprintf( |
||
82 | 'Template identifier %s not found. Context: {%s}', |
||
83 | $templateIdentifier, |
||
84 | json_encode($context), |
||
85 | ), |
||
86 | ); |
||
87 | } |
||
88 | |||
89 | return $availableTemplates[$templateIdentifier]; |
||
90 | } |
||
91 | |||
92 | /** |
||
93 | * @param string $productSearchString |
||
94 | * |
||
95 | * @return array |
||
96 | */ |
||
97 | protected function getTwigWidgetContent($productSearchString) |
||
98 | { |
||
99 | $idProductAbstracts = $this->searchIdProductAbstracts($productSearchString); |
||
100 | |||
101 | if (is_array($idProductAbstracts)) { |
||
0 ignored issues
–
show
introduced
by
Loading history...
|
|||
102 | $products = $this->collectProductAbstractList($idProductAbstracts); |
||
103 | |||
104 | $numberOfCollectedProducts = count($products); |
||
105 | if ($numberOfCollectedProducts > 1) { |
||
106 | return ['products' => $products]; |
||
107 | } |
||
108 | if ($numberOfCollectedProducts === 1) { |
||
109 | return ['product' => array_shift($products)]; |
||
110 | } |
||
111 | } |
||
112 | |||
113 | return []; |
||
114 | } |
||
115 | |||
116 | /** |
||
117 | * @param string $productSearchString |
||
118 | * |
||
119 | * @return array<int> |
||
120 | */ |
||
121 | protected function searchIdProductAbstracts($productSearchString) |
||
122 | { |
||
123 | $limit = $this->getConfig() |
||
124 | ->getSearchLimit(); |
||
125 | |||
126 | $elasticResponse = $this->getFactory() |
||
127 | ->getSearchClient() |
||
128 | ->searchQueryString($productSearchString, $limit) |
||
129 | ->getResponse() |
||
130 | ->getData(); |
||
131 | $dataResponse = $elasticResponse['hits']['hits']; |
||
132 | |||
133 | $idProductAbstracts = []; |
||
134 | foreach ($dataResponse as $item) { |
||
135 | if ($item['_source']['type'] !== 'product_abstract') { |
||
136 | continue; |
||
137 | } |
||
138 | |||
139 | $idProductAbstracts[] = $item['_source']['search-result-data']['id_product_abstract']; |
||
140 | } |
||
141 | |||
142 | return $idProductAbstracts; |
||
143 | } |
||
144 | |||
145 | /** |
||
146 | * @param array<int> $idProductAbstracts |
||
147 | * |
||
148 | * @return array |
||
149 | */ |
||
150 | protected function collectProductAbstractList(array $idProductAbstracts) |
||
151 | { |
||
152 | $products = []; |
||
153 | foreach ($idProductAbstracts as $idProductAbstract) { |
||
154 | $productData = $this->findProductAbstractByIdProductAbstract($idProductAbstract); |
||
155 | if (!$productData) { |
||
156 | continue; |
||
157 | } |
||
158 | |||
159 | $productStorageTransfer = $this->hydrateProductStorageTransfer($productData); |
||
160 | |||
161 | $products[] = $productStorageTransfer; |
||
162 | } |
||
163 | |||
164 | return $products; |
||
165 | } |
||
166 | |||
167 | /** |
||
168 | * This method should hydrate all data in product transfer. |
||
169 | * Including availability, images e.t.c. |
||
170 | * |
||
171 | * @param array<string, mixed> $productData |
||
172 | * |
||
173 | * @return \Generated\Shared\Transfer\StorageProductTransfer |
||
174 | */ |
||
175 | protected function hydrateProductStorageTransfer(array $productData) |
||
176 | { |
||
177 | //implement, this method is overwritten and provided in demoshop |
||
178 | return (new StorageProductTransfer())->fromArray($productData, true); |
||
179 | } |
||
180 | |||
181 | /** |
||
182 | * @param int $idProductAbstract |
||
183 | * |
||
184 | * @return array|null |
||
185 | */ |
||
186 | protected function findProductAbstractByIdProductAbstract($idProductAbstract) |
||
187 | { |
||
188 | $productData = $this->getFactory() |
||
189 | ->getProductClient() |
||
190 | ->getProductAbstractFromStorageByIdForCurrentLocale($idProductAbstract); |
||
191 | |||
192 | if (!$productData) { |
||
193 | return null; |
||
194 | } |
||
195 | |||
196 | return $productData; |
||
197 | } |
||
198 | } |
||
199 |