1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
catalog.php
См. документацию.
1<?php
8
9namespace Bitrix\Main\Analytics;
10use Bitrix\Catalog\CatalogViewedProductTable;
11use Bitrix\Main\Application;
12use Bitrix\Main\Config\Option;
13use Bitrix\Main\Context;
14use Bitrix\Main\Event;
15use Bitrix\Main\Loader;
16use Bitrix\Main\UserTable;
17use Bitrix\Sale\BasketItem;
18use Bitrix\Sale\Order;
19use Bitrix\Sale\OrderTable;
20
21if (!Loader::includeModule('catalog'))
22 return;
23
29{
30 protected static $cookieLogName = 'RCM_PRODUCT_LOG';
31
32 // basket (sale:OnSaleBasketItemSaved)
33 public static function catchCatalogBasket(Event $event)
34 {
35 $isNew = $event->getParameter("IS_NEW");
36
37 // new items only
38 if (!$isNew)
39 {
40 return;
41 }
42
43 // exclude empty cookie
44 if (!static::getBxUserId())
45 {
46 return;
47 }
48
49 // alter b_sale_basket - add recommendation, update it here
50 if (!static::isOn())
51 {
52 return;
53 }
54
56 $basketItem = $event->getParameter("ENTITY");
57
58 // get product id by offer id
59 $iblockId = 0;
60 $realProductId = $basketItem->getProductId();
61 $isCatalog = $basketItem->getField('MODULE') == 'catalog';
62
63 if ($isCatalog)
64 {
65 $productInfo = \CCatalogSKU::GetProductInfo($realProductId);
66
67 if (!empty($productInfo['ID']))
68 {
69 $realProductId = $productInfo['ID'];
70 $iblockId = $productInfo['IBLOCK_ID'];
71 }
72 else
73 {
74 // get iblock id
76 'select' => array('IBLOCK_ID'),
77 'filter' => array('=ID' => $realProductId)
78 ));
79
80 if (!empty($element))
81 {
82 $iblockId = $element['IBLOCK_ID'];
83 }
84 }
85 }
86
87 // select site user id & recommendation id
88 $siteUserId = 0;
89 $recommendationId = '';
90
91 // first, try to find in cookies
92 $recommendationCookie = Context::getCurrent()->getRequest()->getCookie(static::getCookieLogName());
93
94 if (!empty($recommendationCookie))
95 {
96 $recommendations = static::decodeProductLog($recommendationCookie);
97
98 if (is_array($recommendations) && isset($recommendations[$realProductId]))
99 {
100 $recommendationId = $recommendations[$realProductId][0];
101 }
102 }
103
104 if (empty($recommendationId) && $isCatalog)
105 {
106 // ok then, lets see in views history
107 //if(\COption::GetOptionString("sale", "encode_fuser_id", "N") == "Y")
108 if (!is_numeric($basketItem->getFUserId()))
109 {
110 $filter = array('CODE' => $basketItem->getFUserId());
111 }
112 else
113 {
114 $filter = array('ID' => $basketItem->getFUserId());
115 }
116
117 $result = \CSaleUser::getList($filter);
118
119 if (!empty($result))
120 {
121 $siteUserId = $result['USER_ID'];
122
123 // select recommendation id
124 $fuser = $result['ID'];
125
126 $viewResult = CatalogViewedProductTable::getList(array(
127 'select' => array('RECOMMENDATION'),
128 'filter' => array(
129 '=FUSER_ID' => $fuser,
130 '=PRODUCT_ID' => $basketItem->getProductId()
131 ),
132 'order' => array('DATE_VISIT' => 'DESC')
133 ))->fetch();
134
135 if (!empty($viewResult['RECOMMENDATION']))
136 {
137 $recommendationId = $viewResult['RECOMMENDATION'];
138 }
139 }
140 }
141
142 // prepare data
143 $data = array(
144 'product_id' => $realProductId,
145 'iblock_id' => $iblockId,
146 'user_id' => $siteUserId,
147 'bx_user_id' => static::getBxUserId(),
148 'domain' => Context::getCurrent()->getServer()->getHttpHost(),
149 'recommendation' => $recommendationId,
150 'date' => date(DATE_ISO8601)
151 );
152
153 // debug info
154 global $USER;
155
156 $data['real_user_id'] = (int)$USER?->getId();
157 $data['is_admin'] = (int)$USER?->IsAdmin();
158 $data['admin_section'] = (int) (defined('ADMIN_SECTION') && ADMIN_SECTION);
159 $data['admin_panel'] = (int) \CTopPanel::shouldShowPanel();
160
161 // try to guess unnatural baskets
162 $data['artificial_basket'] = (int) (
163 ($data['user_id'] > 0 && $data['user_id'] != $data['real_user_id'])
164 || $data['is_admin'] || $data['admin_section'] || $data['admin_panel']
165 );
166
167 // save
169 'TYPE' => 'basket',
170 'DATA' => $data
171 ));
172
173 // update basket with recommendation id
174 if (!empty($recommendationId))
175 {
177 $helper = $conn->getSqlHelper();
178
179 $conn->query(
180 "UPDATE ".$helper->quote('b_sale_basket')
181 ." SET RECOMMENDATION='".$helper->forSql($recommendationId)."' WHERE ID=".(int) $basketItem->getId()
182 );
183 }
184 }
185
186 // order detailed info (sale:OnSaleOrderSaved)
187 public static function catchCatalogOrder(Event $event)
188 {
189 if (!static::isOn())
190 {
191 return;
192 }
193
194 $isNew = $event->getParameter("IS_NEW");
195
196 if (!$isNew)
197 {
198 // only new orders
199 return;
200 }
201
203 $orderItem = $event->getParameter("ENTITY");
204
205 $data = static::getOrderInfo($orderItem->getId());
206
207 if (empty($data['products']))
208 {
209 return;
210 }
211
212 // add bxuid
213 $data['bx_user_id'] = static::getBxUserId();
214
215 if (empty($data['bx_user_id']) && !empty($data['user_id']))
216 {
217 $orderUser = UserTable::getRow(array(
218 'select' => array('BX_USER_ID'),
219 'filter' => array('=ID' => $data['user_id'])
220 ));
221
222 if (!empty($orderUser) && !empty($orderUser['BX_USER_ID']))
223 {
224 $data['bx_user_id'] = $orderUser['BX_USER_ID'];
225 }
226 }
227
228 // add general info
229 $data['paid'] = '0';
230 $data['domain'] = Context::getCurrent()->getServer()->getHttpHost();
231 $data['date'] = date(DATE_ISO8601);
232
233 // add debug info
234 global $USER;
235
236 $data['real_user_id'] = (int)$USER?->getId();
237 $data['is_admin'] = (int)$USER?->IsAdmin();
238 $data['cookie_size'] = count($_COOKIE);
239 $data['admin_section'] = (int) (defined('ADMIN_SECTION') && ADMIN_SECTION);
240 $data['admin_panel'] = (int) \CTopPanel::shouldShowPanel();
241
242 // try to guess unnatural orders
243 $data['artificial_order'] = (int) (
244 ($data['user_id'] != $data['real_user_id']) || !$data['cookie_size']
245 || $data['is_admin'] || $data['admin_section'] || $data['admin_panel']
246 );
247
249 'TYPE' => 'order',
250 'DATA' => $data
251 ));
252
253 // set bxuid to the order
254 if (!empty($data['bx_user_id']))
255 {
256 // if sale version is fresh enough
257 if (OrderTable::getEntity()->hasField('BX_USER_ID'))
258 {
259 OrderTable::update($data['order_id'], array('BX_USER_ID' => $data['bx_user_id']));
260 }
261 }
262 }
263
264 // order payment (sale:OnSaleOrderPaid)
265 public static function catchCatalogOrderPayment(Event $event)
266 {
267 if (!static::isOn())
268 {
269 return;
270 }
271
273 $orderItem = $event->getParameter("ENTITY");
274
275 $data = static::getOrderInfo($orderItem->getId());
276
277 if (empty($data['products']))
278 {
279 return;
280 }
281
282 // add bxuid
283 $data['bx_user_id'] = static::getBxUserId();
284
285 if (empty($data['bx_user_id']) && OrderTable::getEntity()->hasField('BX_USER_ID'))
286 {
287 $order = OrderTable::getRow(array(
288 'select' => array('BX_USER_ID'),
289 'filter' => array('=ID' => $orderItem->getId())
290 ));
291
292 if (!empty($order) && !empty($order['BX_USER_ID']))
293 {
294 $data['bx_user_id'] = $order['BX_USER_ID'];
295 }
296 }
297
298 // add general info
299 $data['paid'] = '1';
300 $data['domain'] = Context::getCurrent()->getServer()->getHttpHost();
301 $data['date'] = date(DATE_ISO8601);
302
304 'TYPE' => 'order_pay',
305 'DATA' => $data
306 ));
307 }
308
309 public static function getOrderInfo($orderId)
310 {
311 // order itself
312 $order = \CSaleOrder::getById($orderId);
313
314 // buyer info
315 $siteUserId = $order['USER_ID'];
316
317 $phone = '';
318 $phone256 = '';
319 $phone256_e164 = '';
320
321 $email = '';
322 $email256 = '';
323
325 while ($row = $result->fetch())
326 {
327 if (empty($phone) && mb_stripos($row['CODE'], 'PHONE') !== false)
328 {
329 $stPhone = static::normalizePhoneNumber($row['VALUE']);
330
331 if (!empty($stPhone))
332 {
333 $phone = sha1($stPhone);
334 $phone256 = hash('sha256', $stPhone);
335 $phone256_e164 = hash('sha256', '+'.$stPhone);
336 }
337 }
338
339 if (empty($email) && mb_stripos($row['CODE'], 'EMAIL') !== false)
340 {
341 if (!empty($row['VALUE']))
342 {
343 $email = sha1($row['VALUE']);
344 $email256 = hash('sha256', mb_strtolower(trim($row['VALUE'])));
345 }
346 }
347 }
348
349 // products info
350 $products = array();
351
352 $result = \CSaleBasket::getList(
353 array(), array('ORDER_ID' => $orderId), false, false,
354 array('PRODUCT_ID', 'RECOMMENDATION', 'QUANTITY', 'PRICE', 'CURRENCY', 'MODULE')
355 );
356
357 while ($row = $result->fetch())
358 {
359 $realProductId = $row['PRODUCT_ID'];
360 $iblockId = 0;
361
362 // get iblock id for catalog products
363 if ($row['MODULE'] == 'catalog')
364 {
365 $productInfo = \CCatalogSKU::GetProductInfo($row['PRODUCT_ID']);
366
367 if (!empty($productInfo['ID']))
368 {
369 $realProductId = $productInfo['ID'];
370 $iblockId = $productInfo['IBLOCK_ID'];
371 }
372 else
373 {
374 // get iblock id
376 'select' => array('IBLOCK_ID'),
377 'filter' => array('=ID' => $realProductId)
378 ));
379
380 if (!empty($element))
381 {
382 $iblockId = $element['IBLOCK_ID'];
383 }
384 }
385 }
386
387 $products[] = array(
388 'product_id' => $realProductId,
389 'iblock_id' => $iblockId,
390 'quantity' => $row['QUANTITY'],
391 'price' => $row['PRICE'],
392 'currency' => $row['CURRENCY'],
393 'recommendation' => $row['RECOMMENDATION']
394 );
395 }
396
397 // all together
398 $data = array(
399 'order_id' => $orderId,
400 'user_id' => $siteUserId,
401 'phone' => $phone,
402 'phone256' => $phone256,
403 'phone256_e164' => $phone256_e164,
404 'email' => $email,
405 'email256' => $email256,
406 'products' => $products,
407 'price' => $order['PRICE'],
408 'currency' => $order['CURRENCY']
409 );
410
411 return $data;
412 }
413
414 protected static function getBxUserId()
415 {
416 return $_COOKIE['BX_USER_ID'];
417 }
418
419 public static function normalizePhoneNumber($phone)
420 {
421 $phone = preg_replace('/[^\d]/', '', $phone);
422
423 $cleanPhone = \NormalizePhone($phone, 6);
424
425 if (mb_strlen($cleanPhone) == 10)
426 {
427 $cleanPhone = '7'.$cleanPhone;
428 }
429
430 return $cleanPhone;
431 }
432
433 public static function isOn()
434 {
435 return false;
436 }
437
438 public static function getProductIdsByOfferIds($offerIds)
439 {
440 if (empty($offerIds))
441 return array();
442
443 $bestList = array();
444 $iblockGroup = array();
446 'select' => array('ID', 'IBLOCK_ID'),
447 'filter' => array('@ID' => $offerIds, '=ACTIVE'=> 'Y')
448 ));
449 while ($item = $itemIterator->fetch())
450 {
451 if (!isset($iblockGroup[$item['IBLOCK_ID']]))
452 $iblockGroup[$item['IBLOCK_ID']] = array();
453 $iblockGroup[$item['IBLOCK_ID']][] = $item['ID'];
454 $bestList[$item['ID']] = array();
455 }
456
457 if (empty($iblockGroup))
458 {
459 return array();
460 }
461
462 $iblockSku = array();
463 $iblockOffers = array();
464
466 'select' => array('IBLOCK_ID', 'PRODUCT_IBLOCK_ID', 'SKU_PROPERTY_ID', 'VERSION' => 'IBLOCK.VERSION'),
467 'filter' => array('=IBLOCK_ID' => array_keys($iblockGroup), '!=PRODUCT_IBLOCK_ID' => 0)
468 ));
469 while ($iblock = $iblockIterator->fetch())
470 {
471 $iblock['IBLOCK_ID'] = (int)$iblock['IBLOCK_ID'];
472 $iblock['PRODUCT_IBLOCK_ID'] = (int)$iblock['PRODUCT_IBLOCK_ID'];
473 $iblock['SKU_PROPERTY_ID'] = (int)$iblock['SKU_PROPERTY_ID'];
474 $iblock['VERSION'] = (int)$iblock['VERSION'];
475 $iblockSku[$iblock['IBLOCK_ID']] = $iblock;
476 $iblockOffers[$iblock['IBLOCK_ID']] = $iblockGroup[$iblock['IBLOCK_ID']];
477 }
478 unset($iblock, $iblockIterator);
479
480 if (empty($iblockOffers))
481 return array();
482
483 $offerLink = array();
484 foreach ($iblockOffers as $iblockId => $items)
485 {
486 $skuProperty = 'PROPERTY_'.$iblockSku[$iblockId]['SKU_PROPERTY_ID'];
487 $iblockFilter = array(
488 'IBLOCK_ID' => $iblockId,
489 '=ID' => $items
490 );
491 $iblockFields = array('ID', 'IBLOCK_ID', $skuProperty);
492 $skuProperty .= '_VALUE';
493 $offersIterator = \CIBlockElement::getList(
494 array('ID' => 'ASC'),
495 $iblockFilter,
496 false,
497 false,
498 $iblockFields
499 );
500
501 while ($offer = $offersIterator->Fetch())
502 {
503 $productId = (int)$offer[$skuProperty];
504 if ($productId <= 0)
505 {
506 unset($bestList[$offer['ID']]);
507 }
508 else
509 {
510 $bestList[$offer['ID']]['PARENT_ID'] = $productId;
511 $bestList[$offer['ID']]['PARENT_IBLOCK'] = $iblockSku[$iblockId]['PRODUCT_IBLOCK_ID'];
512 if (!isset($offerLink[$productId]))
513 $offerLink[$productId] = array();
514 $offerLink[$productId][] = $offer['ID'];
515 }
516 }
517 }
518 if (!empty($offerLink))
519 {
521 'select' => array('ID'),
522 'filter' => array('@ID' => array_keys($offerLink), '=ACTIVE' => 'N')
523 ));
524 while ($product = $productIterator->fetch())
525 {
526 if (empty($offerLink[$product['ID']]))
527 continue;
528 foreach ($offerLink[$product['ID']] as $value)
529 {
530 unset($bestList[$value]);
531 }
532 }
533 }
534
535 if (empty($bestList))
536 return array();
537
538 $finalIds = array();
539 $dublicate = array();
540 foreach ($bestList as $id => $info)
541 {
542 if (empty($info))
543 {
544 if (!isset($dublicate[$id]))
545 $finalIds[] = $id;
546 $dublicate[$id] = true;
547 }
548 else
549 {
550 if (!isset($dublicate[$id]))
551 $finalIds[] = $info['PARENT_ID'];
552 $dublicate[$info['PARENT_ID']] = true;
553 }
554 }
555 unset($id, $info, $dublicate);
556
557 return $finalIds;
558 }
559
565 public static function encodeProductLog(array $log)
566 {
567 $value = array();
568
569 foreach ($log as $itemId => $recommendation)
570 {
571 $rcmId = $recommendation[0];
572 $rcmTime = $recommendation[1];
573
574 $value[] = $itemId.'-'.$rcmId.'-'.$rcmTime;
575 }
576
577 return join('.', $value);
578 }
579
585 public static function decodeProductLog($log)
586 {
587 $value = array();
588 $tmp = explode('.', $log);
589
590 foreach ($tmp as $tmpval)
591 {
592 $meta = explode('-', $tmpval);
593
594 if (count($meta) > 2)
595 {
596 $itemId = $meta[0];
597 $rcmId = $meta[1];
598 $rcmTime = $meta[2];
599
600 if ($itemId && $rcmId && $rcmTime)
601 {
602 $value[(int)$itemId] = array($rcmId, (int) $rcmTime);
603 }
604 }
605 }
606
607 return $value;
608 }
609
613 public static function getCookieLogName()
614 {
615 return self::$cookieLogName;
616 }
617}
static normalizePhoneNumber($phone)
Определения catalog.php:419
static isOn()
Определения catalog.php:433
static $cookieLogName
Определения catalog.php:30
static getProductIdsByOfferIds($offerIds)
Определения catalog.php:438
static encodeProductLog(array $log)
Определения catalog.php:565
static getCookieLogName()
Определения catalog.php:613
static decodeProductLog($log)
Определения catalog.php:585
static getBxUserId()
Определения catalog.php:414
static getOrderInfo($orderId)
Определения catalog.php:309
static getConnection($name="")
Определения application.php:638
Определения event.php:5
static includeModule($moduleName)
Определения loader.php:67
static getRow(array $parameters)
Определения datamanager.php:398
static getList(array $parameters=array())
Определения datamanager.php:431
static add(array $data)
Определения datamanager.php:877
static GetList($arOrder=array(), $arFilter=array(), $arGroupBy=false, $arNavStartParams=false, $arSelectFields=array())
Определения order_props_values.php:12
static shouldShowPanel()
Определения top_panel.php:1063
if(!is_array($prop["VALUES"])) $tmp
Определения component_props.php:203
$data['IS_AVAILABLE']
Определения .description.php:13
$orderId
Определения payment.php:5
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
$iblockId
Определения iblock_catalog_edit.php:30
if(! $catalogEdit->isSuccess()) $iblock
Определения iblock_catalog_edit.php:38
$filter
Определения iblock_catalog_list.php:54
global $USER
Определения csv_new_run.php:40
if($NS['step']==6) if( $NS[ 'step']==7) if(COption::GetOptionInt('main', 'disk_space', 0) > 0) $info
Определения backup.php:924
NormalizePhone($number, $minLength=10)
Определения tools.php:4959
$order
Определения payment.php:8
$email
Определения payment.php:49
$event
Определения prolog_after.php:141
const ADMIN_SECTION
Определения rss.php:2
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения waybill.php:936
$items
Определения template.php:224