1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
mailmessageuid.php
См. документацию.
1<?php
2
3namespace Bitrix\Mail;
4
5use Bitrix\Mail\Helper\Message\MessageInternalDateHandler;
6use Bitrix\Mail\Helper\MessageEventManager;
7use Bitrix\Mail\Internals\MessageUploadQueueTable;
8use Bitrix\Main\DB\Connection;
9use Bitrix\Main\Entity;
10use Bitrix\Main\EventManager;
11use Bitrix\Main\Localization;
12use Bitrix\Main\ORM\Fields\Relations\Reference;
13use Bitrix\Main\ORM\Query\Join;
14
16
33class MailMessageUidTable extends Entity\DataManager
34{
35 public const OLD = 'Y';
36 public const RECENT = 'N';
37 public const DOWNLOADED = 'D';
38 public const MOVING = 'M';
39 public const REMOTE = 'R';
40 public const LOST = 'L';
41
43 self::LOST,
44 self::MOVING,
45 self::REMOTE,
46 self::OLD,
47 ];
48
49 public static function getFilePath()
50 {
51 return __FILE__;
52 }
53
54 public static function getTableName()
55 {
56 return 'b_mail_message_uid';
57 }
58
71 public static function updateList(array $filter, array $fields, array $eventData = [], bool $sendEvent = true)
72 {
73 $entity = static::getEntity();
74 $connection = $entity->getConnection();
75
76 $result = $connection->query(sprintf(
77 "UPDATE %s SET %s WHERE %s",
78 $connection->getSqlHelper()->quote($entity->getDbTableName()),
79 $connection->getSqlHelper()->prepareUpdate($entity->getDbTableName(), $fields)[0],
80 Entity\Query::buildFilterSql($entity, $filter)
81 ));
82 $eventManager = EventManager::getInstance();
83 $eventKey = $eventManager->addEventHandler(
84 'mail',
85 'onMailMessageModified',
86 array(MessageEventManager::class, 'onMailMessageModified')
87 );
88
89 if ($sendEvent)
90 {
91 $event = new \Bitrix\Main\Event('mail', 'onMailMessageModified', array(
92 'MAIL_FIELDS_DATA' => $eventData,
93 'UPDATED_FIELDS_VALUES' => $fields,
94 'UPDATED_BY_FILTER' => $filter,
95 ));
96 $event->send();
97 EventManager::getInstance()->removeEventHandler('mail', 'onMailMessageModified', $eventKey);
98 }
99
100 return $result;
101 }
102
113 public static function deleteList(array $filter, array $messages = [], $limit = false, bool $sendEvent = true): bool
114 {
116
117 $messages = static::selectMessagesToBeDeleted(
119 $filter,
120 $messages,
121 $limit
122 );
123
124 if (empty($messages))
125 {
126 return false;
127 }
128
129 $entity = static::getEntity();
130 $connection = $entity->getConnection();
131
132 $portionLimit = 200;
133
134 $messagesCount = count($messages);
135
136 for ($i = 0; $i < $messagesCount; $i=$i+$portionLimit)
137 {
138 $portion = array_slice($messages, $i, $portionLimit);
139
140 $query = sprintf(
141 ' FROM %s WHERE ID IN (\'' . join("','", array_column($portion, 'ID')) . '\')',
142 $connection->getSqlHelper()->quote($entity->getDbTableName()),
143 );
144
145 self::insertIntoDeleteMessagesQueue($connection, $query);
146
147 $connection->query(sprintf('DELETE %s', $query));
148 }
149
150 $remains=[];
151
152 if($limit === false)
153 {
154 $remains = array_column(
155 static::selectMessagesToBeDeleted(
156 MessageEventManager::getRequiredFieldNamesForEvent($eventName),
157 $filter,
158 $messages
159 ),
160 'MESSAGE_ID'
161 );
162 }
163 else
164 {
165 if ($messagesIds = array_column($messages, 'MESSAGE_ID') )
166 {
167 $remains = array_column(
168 static::getList(
169 [
170 'select' => [
171 'MESSAGE_ID',
172 ],
173 'filter' => [
174 '@MESSAGE_ID' => $messagesIds,
175 ],
176 ]
177 )->fetchAll(),
178 'MESSAGE_ID'
179 );
180 }
181 }
182
183 if ($sendEvent)
184 {
185 //Checking that the values were actually deleted:
186 $deletedMessages = array_filter(
187 $messages,
188 function ($item) use ($remains) {
189 return !in_array($item['MESSAGE_ID'], $remains);
190 }
191 );
192
193 $eventManager = EventManager::getInstance();
194 $eventKey = $eventManager->addEventHandler(
195 'mail',
196 'onMailMessageDeleted',
197 array(MessageEventManager::class, 'onMailMessageDeleted')
198 );
199 $event = new \Bitrix\Main\Event('mail', 'onMailMessageDeleted', array(
200 'MAIL_FIELDS_DATA' => $deletedMessages,
201 'DELETED_BY_FILTER' => $filter,
202 ));
203 $event->send();
204 EventManager::getInstance()->removeEventHandler('mail', 'onMailMessageDeleted', $eventKey);
205 }
206
207 return true;
208 }
209
210 public static function getLocalUID(int $mailboxId, string $dirPath, string $dirUIDv, string $order): int
211 {
212 $additionalFilter = [];
213
214 if (\Bitrix\Mail\Helper\LicenseManager::getSyncOldLimit() > 0)
215 {
216 $additionalFilter = [
217 '>INTERNALDATE' => \Bitrix\Main\Type\Date::createFromTimestamp(strtotime(sprintf('-%u days', \Bitrix\Mail\Helper\LicenseManager::getSyncOldLimit()))),
218 ];
219 }
220
221 $row = self::getRow(
222 [
223 'select' => [
224 'MSG_UID'
225 ],
226 'filter' => array_merge([
227 '=MAILBOX_ID' => $mailboxId,
228 '=DIR_MD5' => md5($dirPath),
229 '=DIR_UIDV' => $dirUIDv,
230 '>MSG_UID' => 0,
231 '=IS_OLD' => 'N',
232 '!=MESSAGE_ID' => 0,
233 '==DELETE_TIME' => 0,
234 ], $additionalFilter),
235 'order' => [
236 'MSG_UID' => $order,
237 ],
238 ]
239 );
240
241 if (!isset($row['MSG_UID']))
242 {
243 return 0;
244 }
245
246 return (int)$row['MSG_UID'];
247 }
248
249 public static function getLastLocalUID(int $mailboxId, string $dirPath, string $dirUIDv): int
250 {
251 return self::getLocalUID($mailboxId, $dirPath, $dirUIDv, 'DESC');
252 }
253
254 public static function getFirstLocalUID(int $mailboxId, string $dirPath, string $dirUIDv): int
255 {
256 return self::getLocalUID($mailboxId, $dirPath, $dirUIDv, 'ASC');
257 }
258
259 public static function getMessage(
260 int $mailboxId,
261 $select,
262 int $id = null,
263 int $uid = null,
264 ): array|null
265 {
266 if (!is_null($id))
267 {
268 $filter = [
269 '=MESSAGE_ID' => $id,
270 '=MAILBOX_ID' => $mailboxId,
271 ];
272 }
273 else if(!is_null($uid))
274 {
275 $filter = [
276 '=MSG_UID' => $uid,
277 '=MAILBOX_ID' => $mailboxId,
278 ];
279 }
280 else
281 {
282 return null;
283 }
284
285 return self::getRow(
286 [
287 'select' => $select,
288 'filter' => $filter,
289 ]
290 );
291 }
292
302 private static function insertIntoDeleteMessagesQueue(Connection $connection, string $query): void
303 {
304 $sqlHelper = $connection->getSqlHelper();
305 $messageDeleteTableName = $sqlHelper->quote(Internals\MessageDeleteQueueTable::getTableName());
306 $insertFields = ' (ID, MAILBOX_ID, MESSAGE_ID) ';
307 $fromSelect = sprintf('(SELECT ID, MAILBOX_ID, MESSAGE_ID %s)', $query);
308 $insertQuery = $sqlHelper->getInsertIgnore($messageDeleteTableName, $insertFields, $fromSelect);
309 $connection->query($insertQuery);
310 }
311
312 public static function getPresetRemoveFilters()
313 {
314 return [
315 '==DELETE_TIME' => 0,
316 ];
317 }
318
326 public static function deleteListSoft(array $filter)
327 {
328 $entity = static::getEntity();
329 $connection = $entity->getConnection();
330 $filter = array_merge($filter , static::getPresetRemoveFilters());
331
332 //mark selected messages for deletion if there are no messages in the download queue
333 $query = sprintf(
334 'UPDATE %s SET %s WHERE %s AND NOT EXISTS (SELECT 1 FROM %s WHERE %s)',
335 $connection->getSqlHelper()->quote($entity->getDbTableName()),
336 $connection->getSqlHelper()->prepareUpdate($entity->getDbTableName(), [
337 'DELETE_TIME' => time(),
338 ])[0],
339 Entity\Query::buildFilterSql(
340 $entity,
341 $filter
342 ),
343 $connection->getSqlHelper()->quote(Internals\MessageUploadQueueTable::getTableName()),
344 Entity\Query::buildFilterSql(
345 $entity,
346 [
347 '=ID' => new \Bitrix\Main\DB\SqlExpression('?#', 'ID'),
348 '=MAILBOX_ID' => new \Bitrix\Main\DB\SqlExpression('?#', 'MAILBOX_ID'),
349 ]
350 )
351 );
352
353 $result = $connection->query($query);
354 $count = $connection->getAffectedRowsCount();
355 $result->setCount($count > 0 ? $count : 0);
356
357 return $result;
358 }
359
370 private static function selectMessagesToBeDeleted($fields, $filter, array $eventData, $limit = false): array
371 {
372 $result = array();
373
374 $primary = array('ID', 'MAILBOX_ID');
375
376 $eventData = array_values($eventData);
377
378 if (empty($eventData))
379 {
380 $select = $fields;
381 }
382 else
383 {
384 $select = array_diff($fields, array_intersect($fields, ...array_map('array_keys', $eventData)));
385
386 if (empty($select))
387 {
388 return $eventData;
389 }
390
391 if (array_diff($primary, array_intersect($primary, ...array_map('array_keys', $eventData))))
392 {
393 $select = $fields;
394 }
395 else
396 {
397 foreach ($eventData as $item)
398 {
399 $key = sprintf('%u:%s', $item['MAILBOX_ID'], $item['ID']);
400 $result[$key] = $item;
401 }
402 }
403 }
404
405 $select = array_unique(array_merge($primary, $select));
406
407 $mailsFilter = $filter;
408 $mailsFilter['==IS_IN_QUEUE'] = false;
409 $queueSubquery = MessageUploadQueueTable::query();
410 $queueSubquery->addFilter('=ID', new \Bitrix\Main\DB\SqlExpression('%s'));
411 $queueSubquery->addFilter('=MAILBOX_ID', new \Bitrix\Main\DB\SqlExpression('%s'));
412 $emailsForDeleteQuery = MailMessageUidTable::query()
413 ->registerRuntimeField(new Entity\ExpressionField(
414 'IS_IN_QUEUE',
415 sprintf('EXISTS(%s)', $queueSubquery->getQuery()),
416 ['ID', 'MAILBOX_ID']
417 ))
418 ->setFilter($mailsFilter);
419
420 if($limit !== false)
421 {
422 $emailsForDeleteQuery->setLimit($limit);
423 }
424
425 foreach ($select as $index => $selectingField)
426 {
427 if (strncmp('MAILBOX_', $selectingField, 8) === 0 && !MailMessageUidTable::getEntity()->hasField($selectingField))
428 {
429 $emailsForDeleteQuery->addSelect('MAILBOX.'.mb_substr($selectingField, 8), $selectingField);
430 continue;
431 }
432 $emailsForDeleteQuery->addSelect($selectingField);
433 }
434
435 $res = $emailsForDeleteQuery->exec();
436 while ($item = $res->fetch())
437 {
438 $key = sprintf('%u:%s', $item['MAILBOX_ID'], $item['ID']);
439 $result[$key] = array_merge((array) $result[$key], $item);
440 }
441
442 return array_values($result);
443 }
444
455 public static function mergeData(array $insert, array $update)
456 {
457 $entity = static::getEntity();
458 $connection = $entity->getConnection();
459 $helper = $connection->getSqlHelper();
460
461 $sql = $helper->prepareMerge($entity->getDBTableName(), $entity->getPrimaryArray(), $insert, $update);
462
463 $sql = current($sql);
464 if($sql <> '')
465 {
466 $connection->queryExecute($sql);
467 $entity->cleanCache();
468 }
469 }
470
471 public static function getMap()
472 {
473 return array(
474 'ID' => array(
475 'data_type' => 'string',
476 'primary' => true,
477 ),
478 'MAILBOX_ID' => array(
479 'data_type' => 'integer',
480 'primary' => true,
481 ),
482 'DIR_MD5' => array(
483 'data_type' => 'string',
484 ),
485 'DIR_UIDV' => array(
486 'data_type' => 'integer',
487 ),
488 'MSG_UID' => array(
489 'data_type' => 'integer',
490 ),
491 'INTERNALDATE' => array(
492 'data_type' => 'datetime',
493 ),
494 'HEADER_MD5' => array(
495 'data_type' => 'string',
496 ),
497 'IS_SEEN' => array(
498 'data_type' => 'enum',
499 'values' => array('Y', 'N', 'S', 'U'),
500 ),
501 'IS_OLD' => array(
502 'data_type' => 'enum',
503 'values' => [
504 self::OLD,
505 self::RECENT,
506 self::DOWNLOADED,
507 self::MOVING,
508 self::REMOTE,
509 self::LOST,
510 ],
511 ),
512 'SESSION_ID' => array(
513 'data_type' => 'string',
514 'required' => true,
515 ),
516 'TIMESTAMP_X' => array(
517 'data_type' => 'datetime',
518 ),
519 'DATE_INSERT' => array(
520 'data_type' => 'datetime',
521 'required' => true,
522 ),
523 'MESSAGE_ID' => array(
524 'data_type' => 'integer',
525 'required' => true,
526 ),
527 'MAILBOX' => array(
528 'data_type' => 'Bitrix\Mail\Mailbox',
529 'reference' => array('=this.MAILBOX_ID' => 'ref.ID'),
530 ),
531 'MESSAGE' => array(
532 'data_type' => 'Bitrix\Mail\MailMessage',
533 'reference' => array('=this.MESSAGE_ID' => 'ref.ID'),
534 ),
535 'DELETE_TIME' => array(
536 'data_type' => 'integer',
537 'default' => 0,
538 ),
539 new Reference(
540 'MESSAGE_TABLE',
541 MailMessageTable::class,
542 Join::on('this.MESSAGE_ID', 'ref.ID')
543 ->whereColumn('this.MAILBOX_ID', 'ref.MAILBOX_ID')
544 ),
545 );
546 }
547
551 public static function onAfterUpdate(Entity\Event $event)
552 {
553 $result = new Entity\EventResult;
554 $parameters = $event->getParameters();
555 if ($parameters['primary'] && is_set($parameters['fields']['IS_OLD']))
556 {
557 $message = self::getByPrimary($parameters['primary'], [
558 'select' => [
559 'MAILBOX_ID',
560 'DIR_MD5',
561 'INTERNALDATE'
562 ],
563 ])->fetch();
564
565 if (!$message)
566 {
567 return $result;
568 }
569
570 $internalDate = $message['INTERNALDATE'];
571 $mailboxId = (int)$message['MAILBOX_ID'];
572 $dirMd5 = $message['DIR_MD5'];
573
574 $startInternalDate = MessageInternalDateHandler::getStartInternalDateForDir($mailboxId, dirMd5: $dirMd5);
575
576 if (!is_null($startInternalDate) && $internalDate <= $startInternalDate)
577 {
578 $updateResult = MessageInternalDateHandler::clearStartInternalDate($mailboxId, $dirMd5);
579 if (!$updateResult->isSuccess())
580 {
581 $result->setErrors($updateResult->getErrors());
582 }
583 }
584 }
585
586 return $result;
587 }
588
589}
return select
Определения access_edit.php:440
$connection
Определения actionsdefinitions.php:38
static getRequiredFieldNamesForEvent($eventName)
Определения messageeventmanager.php:254
const EXCLUDED_COUNTER_STATUSES
Определения mailmessageuid.php:42
static getFilePath()
Определения mailmessageuid.php:49
static deleteList(array $filter, array $messages=[], $limit=false, bool $sendEvent=true)
Определения mailmessageuid.php:113
static updateList(array $filter, array $fields, array $eventData=[], bool $sendEvent=true)
Определения mailmessageuid.php:71
static getTableName()
Определения mailmessageuid.php:54
static loadMessages($file)
Определения loc.php:65
</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
$query
Определения get_search.php:11
$entity
$filter
Определения iblock_catalog_list.php:54
Определения ufield.php:9
$event
Определения prolog_after.php:141
$i
Определения factura.php:643
</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
$messages
Определения template.php:8
$eventManager
Определения include.php:412
$fields
Определения yandex_run.php:501