Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
contact.php
1<?php
8namespace Bitrix\Sender;
9
21
22Loc::loadMessages(__FILE__);
23
43{
45 const CONSENT_STATUS_NEW = 'N';
53 public static function getTableName()
54 {
55 return 'b_sender_contact';
56 }
57
63 public static function getMap()
64 {
65 return array(
66 'ID' => array(
67 'data_type' => 'integer',
68 'primary' => true,
69 'autocomplete' => true,
70 ),
71 'DATE_INSERT' => array(
72 'data_type' => 'datetime',
73 'default_value' => new MainType\DateTime(),
74 'required' => true,
75 ),
76 'DATE_UPDATE' => array(
77 'data_type' => 'datetime',
78 'default_value' => new MainType\DateTime(),
79 ),
80 'TYPE_ID' => array(
81 'data_type' => 'integer',
82 'default_value' => Recipient\Type::EMAIL,
83 'required' => true,
84 ),
85 'CODE' => array(
86 'data_type' => 'string',
87 'required' => true,
88 ),
89 'NAME' => array(
90 'data_type' => 'string',
91 'save_data_modification' => array('\Bitrix\Main\Text\Emoji', 'getSaveModificator'),
92 'fetch_data_modification' => array('\Bitrix\Main\Text\Emoji', 'getFetchModificator'),
93 ),
94 'USER_ID' => array(
95 'data_type' => 'integer',
96 ),
97 'BLACKLISTED' => array(
98 'data_type' => 'boolean',
99 'values' => array('N', 'Y'),
100 'default_value' => 'N',
101 'required' => true,
102 ),
103 'IS_READ' => array(
104 'data_type' => 'boolean',
105 'values' => array('N', 'Y'),
106 'default_value' => 'N',
107 'required' => true,
108 ),
109 'IS_CLICK' => array(
110 'data_type' => 'boolean',
111 'values' => array('N', 'Y'),
112 'default_value' => 'N',
113 'required' => true,
114 ),
115 'IS_UNSUB' => array(
116 'data_type' => 'boolean',
117 'values' => array('N', 'Y'),
118 'default_value' => 'N',
119 'required' => true,
120 ),
121 'IS_SEND_SUCCESS' => array(
122 'data_type' => 'boolean',
123 'values' => array('N', 'Y'),
124 'default_value' => 'N',
125 'required' => true,
126 ),
127 'CONSENT_STATUS' => array(
128 'data_type' => 'string',
129 'default_value' => static::CONSENT_STATUS_NEW,
130 'required' => true,
131 ),
132 'CONSENT_REQUEST' => array(
133 'data_type' => 'integer',
134 'required' => true,
135 'default_value' => 0
136 ),
137 'IP' => array(
138 'data_type' => 'string',
139 ),
140 'AGENT' => array(
141 'data_type' => 'integer',
142 ),
143 'CONTACT_LIST' => array(
144 'data_type' => 'Bitrix\Sender\ContactListTable',
145 'reference' => array('=this.ID' => 'ref.CONTACT_ID'),
146 ),
147 'MAILING_SUBSCRIPTION' => array(
148 'data_type' => 'Bitrix\Sender\MailingSubscriptionTable',
149 'reference' => array('=this.ID' => 'ref.CONTACT_ID', 'ref.IS_UNSUB' => new SqlExpression('?', 'N')),
150 ),
151 'MAILING_UNSUBSCRIPTION' => array(
152 'data_type' => 'Bitrix\Sender\MailingSubscriptionTable',
153 'reference' => array('=this.ID' => 'ref.CONTACT_ID', 'ref.IS_UNSUB' => new SqlExpression('?', 'Y')),
154 ),
155 );
156 }
157
158
164 public static function validateEmail(): array
165 {
166 return array(
167 new Entity\Validator\Length(1, 255),
168 array(__CLASS__, 'checkEmail'),
169 new Entity\Validator\Unique
170 );
171 }
172
179 public static function checkEmail(?string $value)
180 {
181 if(empty($value) || check_email($value))
182 {
183 return true;
184 }
185 else
186 {
187 return Loc::getMessage('SENDER_ENTITY_CONTACT_VALID_EMAIL');
188 }
189 }
190
197 public static function onBeforeAdd(Entity\Event $event): Entity\EventResult
198 {
199 $result = new Entity\EventResult;
200 $data = $event->getParameters();
201 if(isset($data['fields']['EMAIL']))
202 {
203 $result->modifyFields(array('EMAIL' => Recipient\Normalizer::normalizeEmail($data['fields']['EMAIL'])));
204 }
205
206 if(isset($data['fields']['CODE']))
207 {
208 $typeId = $data['fields']['TYPE_ID'] ?? null;
209 $isValid = Recipient\Validator::validate($data['fields']['CODE'], $typeId);
210 if (!$isValid)
211 {
212 $result->addError(new Entity\EntityError(Loc::getMessage('SENDER_ENTITY_CONTACT_VALID_CODE')));
213 }
214 else
215 {
216 $result->modifyFields(array(
217 'CODE' => Recipient\Normalizer::normalize($data['fields']['CODE'], $typeId)
218 ));
219 }
220 }
221
222 return $result;
223 }
224
231 public static function onBeforeUpdate(Entity\Event $event): Entity\EventResult
232 {
233 $result = new Entity\EventResult;
234 $data = $event->getParameters();
235 $modify = [];
236 if(isset($data['fields']['EMAIL']))
237 {
238 $modify += array('EMAIL' => Recipient\Normalizer::normalizeEmail($data['fields']['EMAIL']));
239 $modify += array('CONSENT_STATUS' => 'N');
240 }
241
242 if(isset($data['fields']['CODE']))
243 {
244 $modify += array( 'CONSENT_STATUS' => 'N' );
245 $typeId = $data['fields']['TYPE_ID'] ?? null;
246 if (!$typeId)
247 {
248 $row = static::getRowById($data['primary']['ID']);
249 $typeId = $row['TYPE_ID'];
250 }
251 $isValid = Recipient\Validator::validate($data['fields']['CODE'], $typeId);
252 if (!$isValid)
253 {
254 $result->addError(new Entity\EntityError(Loc::getMessage('SENDER_ENTITY_CONTACT_VALID_CODE')));
255 }
256 else
257 {
258 $modify += array('CODE' => Recipient\Normalizer::normalize($data['fields']['CODE'], $typeId));
259 }
260 }
261 $result->modifyFields($modify);
262
263 return $result;
264 }
265
273 public static function onAfterDelete(Entity\Event $event): Entity\EventResult
274 {
275 $result = new Entity\EventResult;
276 $data = $event->getParameters();
277
278 $primary = array('CONTACT_ID' => $data['primary']['ID']);
281
282 return $result;
283 }
284
292 public static function deleteList(array $filter): \Bitrix\Main\DB\Result
293 {
294 $entity = static::getEntity();
295 $connection = $entity->getConnection();
296
297 \CTimeZone::disable();
298 $sql = sprintf(
299 'DELETE FROM %s WHERE %s',
300 $connection->getSqlHelper()->quote($entity->getDbTableName()),
301 Query::buildFilterSql($entity, $filter)
302 );
303 $res = $connection->query($sql);
304 \CTimeZone::enable();
305
306 return $res;
307 }
308
314 public static function updateConsentStatus($primary, string $contactStatus)
315 {
316 ContactTable::update($primary,[
317 'CONSENT_STATUS' => $contactStatus,
318 'DATE_UPDATE' => new MainType\DateTime(),
319 'CONSENT_REQUEST' => new SqlExpression("CONSENT_REQUEST+1"),
320 ]);
321 }
322
332 public static function addIfNotExist(array $ar)
333 {
334 $id = false;
335 $listId = false;
336
337 if(array_key_exists('LIST_CODE', $ar) && array_key_exists('LIST_NAME', $ar))
338 {
339 $listId = ListTable::addIfNotExist($ar['LIST_CODE'], $ar['LIST_NAME']);
340 unset($ar['LIST_CODE'], $ar['LIST_NAME']);
341 }
342
343 $ar['EMAIL'] = mb_strtolower($ar['EMAIL']);
344 $contactDb = ContactTable::getList(array(
345 'select' => array('ID'),
346 'filter' => array(
347 '=CODE' => $ar['EMAIL'],
348 '=TYPE_ID' => Recipient\Type::EMAIL
349 )
350 ));
351 if($contact = $contactDb->fetch())
352 {
353 $id = $contact['ID'];
354 }
355 else
356 {
357 $ar['TYPE_ID'] = Recipient\Type::EMAIL;
358 $ar['CODE'] = $ar['EMAIL'];
359 unset($ar['EMAIL']);
360
361 $resultAdd = static::add($ar);
362 if($resultAdd->isSuccess())
363 $id = $resultAdd->getId();
364 }
365
366 if($listId && $id)
367 {
369 }
370
371 return $id;
372 }
373
380 public static function checkConnectors()
381 {
382 $connectorList = Connector\Manager::getConnectorList();
383 foreach($connectorList as $connector)
384 {
385 if($connector->requireConfigure()) continue;
386 static::addFromConnector($connector);
387 }
388 }
389
399 public static function addFromConnector(Connector\Base $connector, ?int $pageNumber = null, int $timeout = 0): array
400 {
401 $startTime = getmicrotime();
402 $withoutNav = empty($pageNumber);
403 $result = false;
404 $onlyOneLoop = false;
405 $rowsInPage = 5;
406
407 $countAll = 0;
408 $countProcessed = 0;
409 $countUpdated = 0;
410 $countAdded = 0;
411 $countError = 0;
412
413 $dataDb = $connector->getResult();
414 if($dataDb->resourceCDBResult)
415 {
416 $dataDb = $dataDb->resourceCDBResult;
417 }
418 elseif($dataDb->resource)
419 {
420 $dataDb = new \CDBResult($dataDb->resource);
421 }
422 else
423 {
424 $dataDb = new \CDBResult();
425 $dataDb->initFromArray(array());
426 }
427
428 if(!is_subclass_of($dataDb, 'CDBResultMysql'))
429 {
430 $rowsInPage = 50;
431 $onlyOneLoop = true;
432 }
433
434 while($timeout==0 || getmicrotime()-$startTime < $timeout)
435 {
436 if(!$withoutNav)
437 {
438 $dataDb->navStart($rowsInPage, false, $pageNumber);
439 $countAll = $dataDb->selectedRowsCount();
440 }
441
442 $listId = null;
443 while ($row = $dataDb->fetch())
444 {
445 if($withoutNav)
446 {
447 $countAll++;
448 }
449
450 $countProcessed++;
451
452 if(!$listId)
453 {
454 $listId = ListTable::addIfNotExist(
455 $connector->getModuleId() . '_' . $connector->getCode(),
456 Loc::getMessage('CONTACT_PULL_LIST_PREFIX').$connector->getName()
457 );
458 }
459
460 $id = null;
461 $contactDb = ContactTable::getList(array(
462 'select' => array('ID'),
463 'filter' => array('EMAIL' => $row['EMAIL'])
464 ));
465 if($contactRow = $contactDb->fetch())
466 {
467 $id = $contactRow['ID'];
468 $countUpdated++;
469 }
470 else
471 {
472 $resultAdd = static::add(array(
473 'NAME' => $row['NAME'],
474 'EMAIL' => $row['EMAIL'],
475 'USER_ID' => $row['USER_ID']
476 ));
477 if ($resultAdd->isSuccess())
478 {
479 $id = $resultAdd->getId();
480 $countAdded++;
481 } else
482 {
483 $countError++;
484 }
485 }
486
487 if($id)
489
490 }
491
492
493 if($withoutNav)
494 {
495 $result = false;
496 break;
497 }
498
499 if ($dataDb->NavPageCount <= $pageNumber)
500 {
501 $result = false;
502 break;
503 }
504 else
505 {
506 $pageNumber++;
507 $result = $pageNumber;
508 }
509
510 if($onlyOneLoop)
511 {
512 break;
513 }
514 }
515
516 if($withoutNav)
517 {
518 $countProgress = $countAll;
519 }
520 else
521 {
522 $countProgress = ($pageNumber-1) * $dataDb->NavPageSize;
523 if (!$result || $countProgress > $countAll) $countProgress = $countAll;
524 }
525
526 return array(
527 'STATUS' => $result,
528 'COUNT_ALL' => $countAll,
529 'COUNT_PROGRESS' => $countProgress,
530 'COUNT_PROCESSED' => $countProcessed,
531 'COUNT_NEW' => $countAdded,
532 'COUNT_ERROR' => $countError,
533 );
534 }
535
549 public static function upload(array $list, bool $isBlacklist = false, ?int $listId = null)
550 {
551 $updateCollection = new UpdateContactDtoCollection();
552 $updateItemFactory = new UpdateContactDtoFactory($isBlacklist);
553 foreach ($list as $item)
554 {
555 if (is_string($item))
556 {
557 $item = ['CODE' => $item];
558 }
559
560 if (empty($item['CODE']))
561 {
562 continue;
563 }
564 $code = trim((string)$item['CODE']);
565
566 $updateItem = $updateItemFactory->make($code, $item['NAME'] ?? null);
567 if ($updateItem)
568 {
569 $updateCollection->append($updateItem);
570 }
571 }
572
573 // insert contacts
574 if ($updateCollection->count() === 0)
575 {
576 return 0;
577 }
578
579 (new ContactUpdateService())->updateByCollection($updateCollection);
580
581 if (!$listId)
582 {
583 return $updateCollection->count();
584 }
585
586 $row = ListTable::getRowById($listId);
587 if (!$row)
588 {
589 return false;
590 }
591
592 // insert contacts & lists
593 (new ContactListUpdateService())->updateByCollection($updateCollection, $listId);
594
595 return ContactListTable::getCount(array('=LIST_ID' => $listId));
596 }
597
603 public static function getConflictFields(): array
604 {
605 return [
606 'TYPE_ID',
607 'CODE',
608 ];
609 }
610}
static loadMessages($file)
Definition loc.php:64
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static deleteList(array $filter)
static addIfNotExist($contactId, $listId)
static onBeforeUpdate(Entity\Event $event)
Definition contact.php:231
static deleteList(array $filter)
Definition contact.php:292
static upload(array $list, bool $isBlacklist=false, ?int $listId=null)
Definition contact.php:549
static updateConsentStatus($primary, string $contactStatus)
Definition contact.php:314
static addIfNotExist(array $ar)
Definition contact.php:332
static checkEmail(?string $value)
Definition contact.php:179
static onBeforeAdd(Entity\Event $event)
Definition contact.php:197
static onAfterDelete(Entity\Event $event)
Definition contact.php:273
static addFromConnector(Connector\Base $connector, ?int $pageNumber=null, int $timeout=0)
Definition contact.php:399
static addIfNotExist($code, $name)
Definition list.php:122
static deleteList(array $filter)
Definition mailing.php:899
static normalize($code, $typeId=Type::EMAIL)