Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
mailmessageuid.php
1<?php
2
3namespace Bitrix\Mail;
4
11
12Localization\Loc::loadMessages(__FILE__);
13
30class MailMessageUidTable extends Entity\DataManager
31{
32 const OLD = 'Y';
33 const RECENT = 'N';
34 const DOWNLOADED = 'D';
35 const MOVING = 'M';
36 const REMOTE = 'R';
37
38 public static function getFilePath()
39 {
40 return __FILE__;
41 }
42
43 public static function getTableName()
44 {
45 return 'b_mail_message_uid';
46 }
47
60 public static function updateList(array $filter, array $fields, array $eventData = [])
61 {
62 $entity = static::getEntity();
63 $connection = $entity->getConnection();
64
65 $result = $connection->query(sprintf(
66 "UPDATE %s SET %s WHERE %s",
67 $connection->getSqlHelper()->quote($entity->getDbTableName()),
68 $connection->getSqlHelper()->prepareUpdate($entity->getDbTableName(), $fields)[0],
69 Entity\Query::buildFilterSql($entity, $filter)
70 ));
71 $eventManager = EventManager::getInstance();
72 $eventKey = $eventManager->addEventHandler(
73 'mail',
74 'onMailMessageModified',
75 array(MessageEventManager::class, 'onMailMessageModified')
76 );
77 $event = new \Bitrix\Main\Event('mail', 'onMailMessageModified', array(
78 'MAIL_FIELDS_DATA' => $eventData,
79 'UPDATED_FIELDS_VALUES' => $fields,
80 'UPDATED_BY_FILTER' => $filter,
81 ));
82 $event->send();
83 EventManager::getInstance()->removeEventHandler('mail', 'onMailMessageModified', $eventKey);
84
85 return $result;
86 }
87
98 public static function deleteList(array $filter, array $messages = [], $limit = false): bool
99 {
101
102 $filter = array_merge(
103 $filter,
104 [
105 '!=MESSAGE_ID' => 0,
106 ]
107 );
108
109 $messages = static::selectMessagesToBeDeleted(
111 $filter,
112 $messages,
113 $limit
114 );
115
116 if (empty($messages))
117 {
118 return false;
119 }
120
121 $entity = static::getEntity();
122 $connection = $entity->getConnection();
123
124 $portionLimit = 200;
125
126 $messagesCount = count($messages);
127
128 for ($i = 0; $i < $messagesCount; $i=$i+$portionLimit)
129 {
130 $portion = array_slice($messages, $i, $portionLimit);
131
132 $query = sprintf(
133 ' FROM %s WHERE ID IN (\'' . join("','", array_column($portion, 'ID')) . '\')',
134 $connection->getSqlHelper()->quote($entity->getDbTableName()),
135 );
136
137 self::insertIntoDeleteMessagesQueue($connection, $query);
138
139 $connection->query(sprintf('DELETE %s', $query));
140 }
141
142 $remains=[];
143
144 if($limit === false)
145 {
146 $remains = array_column(
147 static::selectMessagesToBeDeleted(
148 MessageEventManager::getRequiredFieldNamesForEvent($eventName),
149 $filter,
150 $messages
151 ),
152 'MESSAGE_ID'
153 );
154 }
155 else
156 {
157 if ($messagesIds = array_column($messages, 'MESSAGE_ID') )
158 {
159 $remains = array_column(
160 static::getList(
161 [
162 'select' => [
163 'MESSAGE_ID',
164 ],
165 'filter' => [
166 '@MESSAGE_ID' => $messagesIds,
167 ],
168 ]
169 )->fetchAll(),
170 'MESSAGE_ID'
171 );
172 }
173 }
174
175 //Checking that the values were actually deleted:
176 $deletedMessages = array_filter(
177 $messages,
178 function ($item) use ($remains)
179 {
180 return !in_array($item['MESSAGE_ID'], $remains);
181 }
182 );
183
184 $eventManager = EventManager::getInstance();
185 $eventKey = $eventManager->addEventHandler(
186 'mail',
187 'onMailMessageDeleted',
188 array(MessageEventManager::class, 'onMailMessageDeleted')
189 );
190 $event = new \Bitrix\Main\Event('mail', 'onMailMessageDeleted', array(
191 'MAIL_FIELDS_DATA' => $deletedMessages,
192 'DELETED_BY_FILTER' => $filter,
193 ));
194 $event->send();
195 EventManager::getInstance()->removeEventHandler('mail', 'onMailMessageDeleted', $eventKey);
196
197 return true;
198 }
199
209 private static function insertIntoDeleteMessagesQueue(Connection $connection, string $query): void
210 {
211 $sqlHelper = $connection->getSqlHelper();
212 $messageDeleteTableName = $sqlHelper->quote(Internals\MessageDeleteQueueTable::getTableName());
213 $insertFields = ' (ID, MAILBOX_ID, MESSAGE_ID) ';
214 $fromSelect = sprintf('(SELECT ID, MAILBOX_ID, MESSAGE_ID %s)', $query);
215 $insertQuery = $sqlHelper->getInsertIgnore($messageDeleteTableName, $insertFields, $fromSelect);
216 $connection->query($insertQuery);
217 }
218
219 public static function getPresetRemoveFilters()
220 {
221 return [
222 '==DELETE_TIME' => 0,
223 ];
224 }
225
233 public static function deleteListSoft(array $filter)
234 {
235 $entity = static::getEntity();
236 $connection = $entity->getConnection();
237 $filter = array_merge($filter , static::getPresetRemoveFilters());
238
239 //mark selected messages for deletion if there are no messages in the download queue
240 $query = sprintf(
241 'UPDATE %s SET %s WHERE %s AND NOT EXISTS (SELECT 1 FROM %s WHERE %s)',
242 $connection->getSqlHelper()->quote($entity->getDbTableName()),
243 $connection->getSqlHelper()->prepareUpdate($entity->getDbTableName(), [
244 'DELETE_TIME' => time(),
245 ])[0],
246 Entity\Query::buildFilterSql(
247 $entity,
248 $filter
249 ),
250 $connection->getSqlHelper()->quote(Internals\MessageUploadQueueTable::getTableName()),
251 Entity\Query::buildFilterSql(
252 $entity,
253 [
254 '=ID' => new \Bitrix\Main\DB\SqlExpression('?#', 'ID'),
255 '=MAILBOX_ID' => new \Bitrix\Main\DB\SqlExpression('?#', 'MAILBOX_ID'),
256 ]
257 )
258 );
259
260 $result = $connection->query($query);
261 $count = $connection->getAffectedRowsCount();
262 $result->setCount($count > 0 ? $count : 0);
263
264 return $result;
265 }
266
277 private static function selectMessagesToBeDeleted($fields, $filter, array $eventData, $limit = false): array
278 {
279 $result = array();
280
281 $primary = array('ID', 'MAILBOX_ID');
282
283 $eventData = array_values($eventData);
284
285 if (empty($eventData))
286 {
287 $select = $fields;
288 }
289 else
290 {
291 $select = array_diff($fields, array_intersect($fields, ...array_map('array_keys', $eventData)));
292
293 if (empty($select))
294 {
295 return $eventData;
296 }
297
298 if (array_diff($primary, array_intersect($primary, ...array_map('array_keys', $eventData))))
299 {
300 $select = $fields;
301 }
302 else
303 {
304 foreach ($eventData as $item)
305 {
306 $key = sprintf('%u:%s', $item['MAILBOX_ID'], $item['ID']);
307 $result[$key] = $item;
308 }
309 }
310 }
311
312 $select = array_unique(array_merge($primary, $select));
313
314 $mailsFilter = $filter;
315 $mailsFilter['==IS_IN_QUEUE'] = false;
316 $queueSubquery = MessageUploadQueueTable::query();
317 $queueSubquery->addFilter('=ID', new \Bitrix\Main\DB\SqlExpression('%s'));
318 $queueSubquery->addFilter('=MAILBOX_ID', new \Bitrix\Main\DB\SqlExpression('%s'));
319 $emailsForDeleteQuery = MailMessageUidTable::query()
320 ->registerRuntimeField(new Entity\ExpressionField(
321 'IS_IN_QUEUE',
322 sprintf('EXISTS(%s)', $queueSubquery->getQuery()),
323 ['ID', 'MAILBOX_ID']
324 ))
325 ->setFilter($mailsFilter);
326
327 if($limit !== false)
328 {
329 $emailsForDeleteQuery->setLimit($limit);
330 }
331
332 foreach ($select as $index => $selectingField)
333 {
334 if (strncmp('MAILBOX_', $selectingField, 8) === 0 && !MailMessageUidTable::getEntity()->hasField($selectingField))
335 {
336 $emailsForDeleteQuery->addSelect('MAILBOX.'.mb_substr($selectingField, 8), $selectingField);
337 continue;
338 }
339 $emailsForDeleteQuery->addSelect($selectingField);
340 }
341
342 $res = $emailsForDeleteQuery->exec();
343 while ($item = $res->fetch())
344 {
345 $key = sprintf('%u:%s', $item['MAILBOX_ID'], $item['ID']);
346 $result[$key] = array_merge((array) $result[$key], $item);
347 }
348
349 return array_values($result);
350 }
351
362 public static function mergeData(array $insert, array $update)
363 {
364 $entity = static::getEntity();
365 $connection = $entity->getConnection();
366 $helper = $connection->getSqlHelper();
367
368 $sql = $helper->prepareMerge($entity->getDBTableName(), $entity->getPrimaryArray(), $insert, $update);
369
370 $sql = current($sql);
371 if($sql <> '')
372 {
373 $connection->queryExecute($sql);
374 $entity->cleanCache();
375 }
376 }
377
378 public static function getMap()
379 {
380 return array(
381 'ID' => array(
382 'data_type' => 'string',
383 'primary' => true,
384 ),
385 'MAILBOX_ID' => array(
386 'data_type' => 'integer',
387 'primary' => true,
388 ),
389 'DIR_MD5' => array(
390 'data_type' => 'string',
391 ),
392 'DIR_UIDV' => array(
393 'data_type' => 'integer',
394 ),
395 'MSG_UID' => array(
396 'data_type' => 'integer',
397 ),
398 'INTERNALDATE' => array(
399 'data_type' => 'datetime',
400 ),
401 'HEADER_MD5' => array(
402 'data_type' => 'string',
403 ),
404 'IS_SEEN' => array(
405 'data_type' => 'enum',
406 'values' => array('Y', 'N', 'S', 'U'),
407 ),
408 'IS_OLD' => array(
409 'data_type' => 'enum',
410 'values' => array(self::OLD, self::RECENT, self::DOWNLOADED, self::MOVING, self::REMOTE),
411 ),
412 'SESSION_ID' => array(
413 'data_type' => 'string',
414 'required' => true,
415 ),
416 'TIMESTAMP_X' => array(
417 'data_type' => 'datetime',
418 ),
419 'DATE_INSERT' => array(
420 'data_type' => 'datetime',
421 'required' => true,
422 ),
423 'MESSAGE_ID' => array(
424 'data_type' => 'integer',
425 'required' => true,
426 ),
427 'MAILBOX' => array(
428 'data_type' => 'Bitrix\Mail\Mailbox',
429 'reference' => array('=this.MAILBOX_ID' => 'ref.ID'),
430 ),
431 'MESSAGE' => array(
432 'data_type' => 'Bitrix\Mail\MailMessage',
433 'reference' => array('=this.MESSAGE_ID' => 'ref.ID'),
434 ),
435 'DELETE_TIME' => array(
436 'data_type' => 'integer',
437 'default' => 0,
438 ),
439 );
440 }
441
442}
static updateList(array $filter, array $fields, array $eventData=[])
static deleteList(array $filter, array $messages=[], $limit=false)