Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
changebasketitemaction.php
1<?php
2
4
9
17{
18 private function checkParams(array $fields): Sale\Result
19 {
20 $result = new Sale\Result();
21
22 if (empty($fields['SITE_ID']))
23 {
24 $result->addError(
25 new Main\Error(
26 'siteId not found',
28 )
29 );
30 }
31
32 if (empty($fields['FUSER_ID']) || (int)$fields['FUSER_ID'] <= 0)
33 {
34 $result->addError(
35 new Main\Error(
36 'fuserId not found',
38 )
39 );
40 }
41
42 if (empty($fields['BASKET_ID']) || (int)$fields['BASKET_ID'] <= 0)
43 {
44 $result->addError(
45 new Main\Error(
46 'basketId not found',
48 )
49 );
50 }
51
52 if (empty($fields['PRODUCT_ID']) || (int)$fields['PRODUCT_ID'] <= 0)
53 {
54 $result->addError(
55 new Main\Error(
56 'productId not found',
58 )
59 );
60 }
61
62 return $result;
63 }
64
65 public function run(array $fields)
66 {
67 $result = [];
68
69 $changeBasketItemResult = $this->changeBasketItem($fields);
70 if (!$changeBasketItemResult->isSuccess())
71 {
72 $this->addErrors($changeBasketItemResult->getErrors());
73 return $result;
74 }
75
76 $changeBasketItemData = $changeBasketItemResult->getData();
78 $basketItem = $changeBasketItemData['basketItem'];
79 return Sale\Helpers\Controller\Action\Entity\Order::getOrderProductByBasketItem($basketItem);
80 }
81
82 public function changeBasketItem(array $fields): Sale\Result
83 {
84 $result = new Sale\Result();
85
86 $checkParamsResult = $this->checkParams($fields);
87 if (!$checkParamsResult->isSuccess())
88 {
89 $result->addErrors($checkParamsResult->getErrors());
90 return $result;
91 }
92
93 $basketId = $fields['BASKET_ID'];
94 $productId = $fields['PRODUCT_ID'];
95 $fuserId = $fields['FUSER_ID'];
96 $siteId = $fields['SITE_ID'];
97
98 $basket = $this->getBasketByFuserId($fuserId, $siteId);
100 $currentBasketItem = $basket->getItemByBasketCode($basketId);
101 if (!$currentBasketItem)
102 {
103 $result->addError(
104 new Main\Error(
105 'basket item load error',
107 )
108 );
109 return $result;
110 }
111
112 $currentOfferId = $currentBasketItem->getProductId();
113 $parent = \CCatalogSku::getProductList($currentOfferId, 0);
114 if (empty($parent[$currentOfferId]))
115 {
116 $result->addError(
117 new Main\Error(
118 'parent product load error',
120 )
121 );
122 return $result;
123 }
124
125 $parent = $parent[$currentOfferId];
126
127 $offerPropertyCodeList = self::getOfferPropertyCodeList();
128
129 $newProduct = self::selectOfferById($parent['IBLOCK_ID'], $parent['ID'], $productId, $offerPropertyCodeList);
130 if (!$newProduct)
131 {
132 $result->addError(
133 new Main\Error(
134 'product load error',
136 )
137 );
138 return $result;
139 }
140
141 $setFieldsResult = $currentBasketItem->setFields([
142 'PRODUCT_ID' => $newProduct['ID'],
143 'NAME' => $newProduct['NAME'],
144 'PRODUCT_XML_ID' => $newProduct['XML_ID'],
145 ]);
146 if (!$setFieldsResult->isSuccess())
147 {
148 foreach ($setFieldsResult->getErrors() as $error)
149 {
150 $result->addError(
151 new Main\Error(
152 $error->getMessage(),
154 )
155 );
156 }
157 return $result;
158 }
159
160 $refreshBasketResult = $basket->refresh(
161 Sale\Basket\RefreshFactory::createSingle($currentBasketItem->getBasketCode())
162 );
163 if (!$refreshBasketResult->isSuccess())
164 {
165 foreach ($refreshBasketResult->getErrors() as $error)
166 {
167 $result->addError(
168 new Main\Error(
169 $error->getMessage(),
171 )
172 );
173 }
174 return $result;
175 }
176
177 $basketProperties = self::getBasketProperties($parent['IBLOCK_ID'], $newProduct['ID'], $offerPropertyCodeList);
178 $basketProperties['PRODUCT.XML_ID'] = [
179 'NAME' => 'Product XML_ID',
180 'CODE' => 'PRODUCT.XML_ID',
181 'VALUE' => $currentBasketItem->getField('PRODUCT_XML_ID'),
182 ];
183
184 self::setBasketProperties($currentBasketItem, $basketProperties);
185
186 $saveBasketResult = $basket->save();
187 if ($saveBasketResult->isSuccess())
188 {
189 $result->setData([
190 'basket' => $basket,
191 'basketItem' => $currentBasketItem,
192 ]);
193 }
194 else
195 {
197 foreach ($saveBasketResult->getErrors() as $error)
198 {
199 // save basket error
200 $result->addError(
201 new Main\Error(
202 $error->getMessage(),
204 )
205 );
206 }
207 }
208
209 return $result;
210 }
211
212 private function getBasketByFuserId($fuserId, $siteId): Sale\BasketBase
213 {
214 $registry = Sale\Registry::getInstance(Sale\Registry::REGISTRY_TYPE_ORDER);
215
217 $basketClassName = $registry->getBasketClassName();
218 return $basketClassName::loadItemsForFUser($fuserId, $siteId);
219 }
220
221 private static function getOfferPropertyCodeList(): array
222 {
223 $result = [];
224
225 if (Main\Loader::includeModule('iblock') && Iblock\Model\PropertyFeature::isEnabledFeatures())
226 {
227 $iterator = Catalog\CatalogIblockTable::getList([
228 'select' => ['IBLOCK_ID'],
229 'filter' => ['!=PRODUCT_IBLOCK_ID' => 0],
230 ]);
231 while ($row = $iterator->fetch())
232 {
233 $list = Catalog\Product\PropertyCatalogFeature::getOfferTreePropertyCodes(
234 $row['IBLOCK_ID'],
235 ['CODE' => 'Y']
236 );
237
238 if (!empty($list) && is_array($list))
239 {
240 $result[] = $list;
241 }
242 }
243
244 if ($result)
245 {
246 $result = array_merge(...$result);
247 }
248 }
249
250 return $result;
251 }
252
253 private static function selectOfferById(int $iblockId, int $parentId, int $productId, array $offerPropertyCodeList = [])
254 {
255 $offers = \CCatalogSku::getOffersList(
256 $parentId,
257 $iblockId,
258 [
259 'ACTIVE' => 'Y',
260 'ACTIVE_DATE' => 'Y',
261 'CATALOG_AVAILABLE' => 'Y',
262 'CHECK_PERMISSIONS' => 'Y',
263 'MIN_PERMISSION' => 'R',
264 ],
265 ['ID', 'IBLOCK_ID', 'XML_ID', 'NAME'],
266 ['CODE' => $offerPropertyCodeList]
267 );
268
269 if (empty($offers[$parentId][$productId]))
270 {
271 return null;
272 }
273
274 $result = [
275 'ID' => $offers[$parentId][$productId]['ID'],
276 'IBLOCK_ID' => $offers[$parentId][$productId]['IBLOCK_ID'],
277 'NAME' => $offers[$parentId][$productId]['NAME'],
278 'XML_ID' => $offers[$parentId][$productId]['XML_ID'],
279 'PROPERTIES' => $offers[$parentId][$productId]['PROPERTIES'],
280 ];
281
282 if (mb_strpos($result['XML_ID'], '#') === false)
283 {
284 $parentData = Iblock\ElementTable::getList([
285 'select' => ['ID', 'XML_ID'],
286 'filter' => ['ID' => $parentId],
287 ])->fetch();
288 if (!empty($parentData))
289 {
290 $result['XML_ID'] = $parentData['XML_ID'].'#'.$result['XML_ID'];
291 }
292 }
293
294 return $result;
295 }
296
297 private static function getBasketProperties(int $iblockId, int $productId, array $offerPropertyCodeList)
298 {
299 $newProperties = \CIBlockPriceTools::GetOfferProperties(
300 $productId,
301 $iblockId,
302 $offerPropertyCodeList
303 );
304
305 $basketProperties = [];
306 foreach ($newProperties as $row)
307 {
308 $codeExist = false;
309 foreach ($offerPropertyCodeList as $code)
310 {
311 if ($code === $row['CODE'])
312 {
313 $codeExist = true;
314 break;
315 }
316 }
317
318 if (!$codeExist)
319 {
320 continue;
321 }
322
323 $basketProperties[$row['CODE']] = [
324 'NAME' => $row['NAME'],
325 'CODE' => $row['CODE'],
326 'VALUE' => $row['VALUE'],
327 'SORT' => $row['SORT'],
328 ];
329 }
330
331 return $basketProperties;
332 }
333
334 private static function setBasketProperties(Sale\BasketItem $basketItem, array $basketProperties)
335 {
336 $properties = $basketItem->getPropertyCollection();
337 if ($properties)
338 {
339 $oldProperties = $properties->getPropertyValues();
340 if (empty($oldProperties))
341 {
342 $oldProperties = $basketProperties;
343 }
344 else
345 {
346 $oldProperties = self::updateOffersProperties($oldProperties, $basketProperties);
347 }
348
349 $properties->redefine($oldProperties);
350 }
351 }
352
353 private static function updateOffersProperties($oldProps, $newProps): array
354 {
355 if (!is_array($oldProps) || !is_array($newProps))
356 {
357 return [];
358 }
359
360 $result = [];
361
362 if (empty($newProps))
363 {
364 return $oldProps;
365 }
366
367 if (empty($oldProps))
368 {
369 return $newProps;
370 }
371
372 foreach (array_keys($oldProps) as $code)
373 {
374 $oldValue = $oldProps[$code];
375 $found = false;
376 $key = false;
377 $propId = (isset($oldValue['CODE']) ? (string)$oldValue['CODE'] : '').':'.$oldValue['NAME'];
378
379 foreach ($newProps as $newKey => $newValue)
380 {
381 $newId = (isset($newValue['CODE']) ? (string)$newValue['CODE'] : '').':'.$newValue['NAME'];
382 if ($newId === $propId)
383 {
384 $key = $newKey;
385 $found = true;
386 break;
387 }
388 }
389
390 if ($found)
391 {
392 $oldValue['VALUE'] = $newProps[$key]['VALUE'];
393 unset($newProps[$key]);
394 }
395
396 $result[$code] = $oldValue;
397 unset($oldValue);
398 }
399
400 if (!empty($newProps))
401 {
402 foreach (array_keys($newProps) as $code)
403 {
404 $result[$code] = $newProps[$code];
405 }
406 }
407
408 return $result;
409 }
410}
addErrors(array $errors)
Definition action.php:213