Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
mailboxdirectoryhelper.php
1<?php
2
3namespace Bitrix\Mail\Helper;
4
10
12{
13 private $mailboxId = null;
14 private $storage = null;
16 private $errors = [];
17
18 public function __construct($mailboxId)
19 {
20 $this->mailboxId = $mailboxId;
21 $this->storage = new MailboxDirectoryStorage($mailboxId);
22 $this->errors = new ErrorCollection();
23 }
24
25 public function getDirs()
26 {
27 return $this->storage->get('all', []);
28 }
29
30 public function setDirs(array $dirs)
31 {
32 $this->storage->set($dirs);
33 }
34
35 public function reloadDirs()
36 {
37 $this->storage->init();
38 }
39
40 public function getErrors()
41 {
42 return $this->errors;
43 }
44
45 public function getDrafts()
46 {
47 $list = $this->storage->get('draft', []);
48
49 return reset($list);
50 }
51
52 public function getIncome()
53 {
54 $list = $this->storage->get('income', []);
55
56 return reset($list);
57 }
58
59 public function getOutcome()
60 {
61 $list = $this->storage->get('outcome', []);
62
63 return reset($list);
64 }
65
66 public function getSpam()
67 {
68 $list = $this->storage->get('spam', []);
69
70 return reset($list);
71 }
72
73 public function getTrash()
74 {
75 $list = $this->storage->get('trash', []);
76
77 return reset($list);
78 }
79
80 public function getIncomePath($emojiEncode = false)
81 {
82 $dir = $this->getIncome();
83
84 if ($dir != null)
85 {
86 return $dir->getPath($emojiEncode);
87 }
88
89 return null;
90 }
91
92 public function getOutcomePath($emojiEncode = false)
93 {
94 $dir = $this->getOutcome();
95
96 if ($dir != null)
97 {
98 return $dir->getPath($emojiEncode);
99 }
100
101 return null;
102 }
103
104 public function getDraftsPath($emojiEncode = false)
105 {
106 $dir = $this->getDrafts();
107
108 if ($dir != null)
109 {
110 return $dir->getPath($emojiEncode);
111 }
112
113 return null;
114 }
115
116 public function getSpamPath($emojiEncode = false)
117 {
118 $dir = $this->getSpam();
119
120 if ($dir != null)
121 {
122 return $dir->getPath($emojiEncode);
123 }
124
125 return null;
126 }
127
128 public function getTrashPath($emojiEncode = false)
129 {
130 $dir = $this->getTrash();
131
132 if ($dir != null)
133 {
134 return $dir->getPath($emojiEncode);
135 }
136
137 return null;
138 }
139
140 public function getDirPathByHash($hash)
141 {
142 $dir = $this->storage->getByHash($hash);
143
144 if ($dir != null)
145 {
146 return $dir->getPath();
147 }
148
149 return null;
150 }
151
152 public function getDirByHash($hash)
153 {
154 $dir = $this->storage->getByHash($hash);
155
156 if ($dir != null)
157 {
158 return $dir;
159 }
160
161 return null;
162 }
163
164 public function getDirPathByType($type)
165 {
166 switch ($type)
167 {
168 case MailboxDirectoryTable::TYPE_INCOME:
169 return $this->getIncomePath();
170 break;
171 case MailboxDirectoryTable::TYPE_OUTCOME:
172 return $this->getOutcomePath();
173 break;
174 case MailboxDirectoryTable::TYPE_SPAM:
175 return $this->getSpamPath();
176 break;
177 case MailboxDirectoryTable::TYPE_TRASH:
178 return $this->getTrashPath();
179 break;
180 default:
181 return '';
182 }
183 }
184
185 public function getDirByPath(?string $path)
186 {
187 if (!$path)
188 {
189 return null;
190 }
191
192 $dir = $this->storage->getByPath($path);
193
194 if ($dir != null)
195 {
196 return $dir;
197 }
198
199 return null;
200 }
201
202 public function getSyncDirs()
203 {
204 return array_filter($this->getDirs(), function ($item)
205 {
206 return $item->isSync();
207 });
208 }
209
210 public function getSyncDirsOrderByTime($excludeDirPath = null)
211 {
212 return array_filter($this->orderByTime($this->getSyncDirs()), function ($item) use ($excludeDirPath)
213 {
214 return $item->getPath() !== $excludeDirPath;
215 });
216 }
217
218 public function getSyncDirsPath($emojiEncode = false)
219 {
220 $list = [];
221
222 foreach ($this->getDirs() as $item)
223 {
224 if ($item->isSync())
225 {
226 $list[] = $item->getPath($emojiEncode);
227 }
228 }
229
230 return $list;
231 }
232
233 public function getAllOneLevel()
234 {
235 $list = [];
236
237 foreach ($this->getDirs() as $item)
238 {
239 if ((int)$item->getLevel() === 1)
240 {
241 $list[$item->getPath()] = $item;
242 }
243 }
244
245 return $list;
246 }
247
248 private function orderByDefault($dirs)
249 {
250 usort($dirs, function ($a, $b)
251 {
252 $aSort = $this->getOrderByDefault($a);
253 $bSort = $this->getOrderByDefault($b);
254
255 if ($aSort === $bSort)
256 {
257 return 0;
258 }
259
260 return $aSort > $bSort ? 1 : -1;
261 });
262
263 return $dirs;
264 }
265
266 public function getOrderByDefault($dir)
267 {
268 return $dir->isIncome() ? 10 : ($dir->isOutcome() ? 2000 : ($dir->isTrash() ? 3000 : ($dir->isSpam() ? 4000 : ($dir->isDraft() ? 5000 : $dir->getLevel() * 100))));
269 }
270
271 private function orderByName($dirs)
272 {
273 usort($dirs, function ($a, $b)
274 {
275 $aSort = $a->getName();
276 $bSort = $b->getName();
277
278 if (
279 $a->isSpam() ||
280 $a->isTrash() ||
281 $a->isDraft() ||
282 $a->isOutcome()
283 )
284 {
285 $aSort = 1000;
286 }
287
288 if (
289 $b->isSpam() ||
290 $b->isTrash() ||
291 $b->isDraft() ||
292 $b->isOutcome()
293 )
294 {
295 $bSort = 1000;
296 }
297
298 if ($aSort === $bSort)
299 {
300 return 0;
301 }
302
303 return $aSort > $bSort ? 1 : -1;
304 });
305
306 return $dirs;
307 }
308
309 private function orderByTime($dirs)
310 {
311 usort($dirs, function ($a, $b)
312 {
313 $aSort = $a->getSyncTime() ?: ($a->isIncome() ? 100 : ($a->isOutcome() ? 200 : ($a->isTrash() ? 300 : ($a->isSpam() ? 400 : $a->getLevel() * 1000))));
314 $bSort = $b->getSyncTime() ?: ($b->isIncome() ? 100 : ($b->isOutcome() ? 200 : ($b->isTrash() ? 300 : ($b->isSpam() ? 400 : $b->getLevel() * 1000))));
315
316 if ($aSort === $bSort)
317 {
318 return 0;
319 }
320
321 return $aSort > $bSort ? 1 : -1;
322 });
323
324 return $dirs;
325 }
326
327 public function getLastSyncDirByDefault($excludeDirPath = null)
328 {
329 $list = $this->orderByDefault($this->getSyncDirs());
330 $list = array_filter($list, function ($item) use ($excludeDirPath)
331 {
332 return $item->getPath() !== $excludeDirPath;
333 });
334
335 return end($list);
336 }
337
338 public function getCurrentSyncDirByTime()
339 {
340 $list = $this->orderByTime($this->getSyncDirs());
341
342 return reset($list);
343 }
344
345 public function getCurrentSyncDirPositionByDefault(string $path, $excludeDirPath = null)
346 {
347 $list = $this->orderByDefault($this->getSyncDirs());
348 $list = array_filter($list, function ($item) use ($excludeDirPath)
349 {
350 return $item->getPath() !== $excludeDirPath;
351 });
352
353 $getIndex = function ($list, $path)
354 {
355 foreach ($list as $index => $item)
356 {
357 if ($item->getPath() === $path)
358 {
359 return $index;
360 }
361 }
362
363 return -1;
364 };
365
366 return $getIndex($list, $path);
367 }
368
369 public function removeDirsLikePath(array $dirs)
370 {
371 $removeRows = [];
372
373 foreach ($dirs as $item)
374 {
375 $removeRows[] = [
376 '=PATH' => $item->getPath(true),
377 ];
378 //deleting subfolders
379 $removeRows[] = [
380 '%=PATH' => $item->getPath(true) . $item->getDelimiter() . '%',
381 ];
382 }
383
384 if (!empty($removeRows))
385 {
386 $removeRows = array_merge(['LOGIC' => 'OR'], $removeRows);
387
388 $filter = array_merge([
389 'LOGIC' => 'AND',
390 '=MAILBOX_ID' => $this->mailboxId,
391 ], [$removeRows]);
392
394 }
395 }
396
397 public function getDefaultDir()
398 {
399 $inboxDir = $this->getIncome();
400 $sendDir = $this->getOutcome();
401 $dirs = $this->getDirs();
402
403 foreach ([$inboxDir, $sendDir] as $dir)
404 {
405 if ($dir != null && !$dir->isDisabled() && $dir->isSync())
406 {
407 return $dir;
408 }
409 }
410
411 foreach ($dirs as $dir)
412 {
413 if (!$dir->isDisabled() && $dir->isSync())
414 {
415 return $dir;
416 }
417 }
418
419 return '';
420 }
421
422 public function getDefaultDirPath($emojiEncode = false)
423 {
424 $dir = $this->getDefaultDir();
425
426 if($dir !== '')
427 {
428 return $dir->getPath($emojiEncode);
429 }
430
431 return '';
432 }
433
434 public function buildTreeDirs()
435 {
436 $list = [];
437 $result = [];
438 $dirs = $this->getDirs();
439
440 foreach ($dirs as $dir)
441 {
442 $list[$dir->getId()] = $dir;
443 }
444
445 foreach ($list as $id => $dir)
446 {
447 if (!empty($list[$dir->getParentId()]))
448 {
449 $list[$dir->getParentId()]->addChild($dir);
450 }
451 else
452 {
453 $result[$dir->getId()] = $dir;
454 }
455 }
456
457 return $this->orderByDefault($result);
458 }
459
460 public function syncChildren($parent)
461 {
462 $pattern = sprintf('%s%s%%', $parent->getPath(), $parent->getDelimiter());
463 $mailboxHelper = Mailbox::createInstance($this->mailboxId);
464 $dirs = $mailboxHelper->listDirs($pattern);
465
466 if ($dirs === false)
467 {
468 $this->errors = $mailboxHelper->getErrors();
469
470 return false;
471 }
472
473 $dbDirs = $this->getOneLevelByParentId($parent);
474
475 $params = [
476 'level' => $parent->getLevel() + 1,
477 'parent_id' => $parent->getId(),
478 'root_id' => $parent->getRootId() ?: $parent->getId(),
479 'is_sync' => MailboxDirectoryTable::INACTIVE,
480 ];
481
482 $dirs = array_map(function ($item) use ($params)
483 {
484 return array_merge($item, $params);
485 }, $dirs);
486
487 $this->addSyncDirs($dirs, $dbDirs);
488
489 if (!empty($dbDirs))
490 {
491 $this->updateSyncDirs($dirs, $dbDirs);
492 $this->removeSyncDirs($dirs, $dbDirs);
493 }
494
495 return true;
496 }
497
498 public function getOneLevelByParentId($parent)
499 {
501 $this->mailboxId,
502 $parent->getId(),
503 $parent->getLevel() + 1
504 );
505 }
506
507 public function getAllLevelByParentId($parent)
508 {
510 $this->mailboxId,
511 $parent->getPath(true) . $parent->getDelimiter() . '%',
512 $parent->getLevel() + 1
513 );
514 }
515
516 public function addSyncDirs($dirs, $dbDirs)
517 {
518 $diffDirs = array_diff_key($dirs, $dbDirs);
519
520 $addRows = array_map(
521 function ($dir)
522 {
523 if (!isset($dir['is_sync']))
524 {
525 $dir['is_sync'] = !preg_grep('/^ \x5c ( Drafts | Trash | Junk | Spam ) $/ix', $dir['flags']);
526 }
527
528 return [
529 'MAILBOX_ID' => $this->mailboxId,
530 'NAME' => Emoji::encode($dir['name']),
531 'PATH' => Emoji::encode($dir['path']),
532 'LEVEL' => isset($dir['level']) ? $dir['level'] : 1,
533 'PARENT_ID' => isset($dir['parent_id']) ? $dir['parent_id'] : null,
534 'ROOT_ID' => isset($dir['root_id']) ? $dir['root_id'] : null,
535 'FLAGS' => MailboxDirectoryHelper::getFlags($dir['flags']),
536 'DELIMITER' => $dir['delim'],
537 'DIR_MD5' => md5(Emoji::encode($dir['path'])),
538 'IS_SYNC' => $dir['is_sync'],
539 'IS_INCOME' => mb_strtoupper($dir['name']) === 'INBOX',
540 'IS_OUTCOME' => preg_grep('/^ \x5c Sent $/ix', $dir['flags']),
541 'IS_DRAFT' => preg_grep('/^ \x5c Drafts $/ix', $dir['flags']),
542 'IS_TRASH' => preg_grep('/^ \x5c Trash $/ix', $dir['flags']),
543 'IS_SPAM' => preg_grep('/^ \x5c ( Junk | Spam ) $/ix', $dir['flags']),
544 'IS_DISABLED' => preg_grep('/^ \x5c Noselect $/ix', $dir['flags']),
545 ];
546 },
547 $diffDirs
548 );
549
550 if (!empty($addRows))
551 {
552 MailboxDirectory::addMulti($addRows, true);
553 }
554 }
555
556 public function updateSyncDirs($dirs, $dbDirs)
557 {
558 $updateRows = array_udiff_assoc($dirs, $dbDirs, function ($a, $b)
559 {
560 $flagsA = MailboxDirectoryHelper::getFlags($a['flags']);
561 $flagsB = $b->getFlags();
562
563 $delimA = $a['delim'];
564 $delimB = $b->getDelimiter();
565
566 if ($flagsA !== $flagsB)
567 {
568 return $flagsA > $flagsB ? 1 : -1;
569 }
570 else if ($delimA !== $delimB)
571 {
572 return $delimA > $delimB ? 1 : -1;
573 }
574
575 return 0;
576 });
577
578 foreach ($updateRows as $row)
579 {
580 $dbDir = $this->getDirByPath(Emoji::encode($row['path']));
581
582 if (!$dbDir)
583 {
584 continue;
585 }
586
588 $dbDir->getId(),
589 [
590 'DELIMITER' => $row['delim'],
591 'FLAGS' => MailboxDirectoryHelper::getFlags($row['flags']),
592 ]
593 );
594 }
595 }
596
597 public function removeSyncDirs($dirs, $dbDirs)
598 {
599 $diffDirs = array_diff_key($dbDirs, $dirs);
600
601 if (!empty($diffDirs))
602 {
603 $this->removeDirsLikePath($diffDirs);
604 }
605 }
606
607 public function toggleSyncDirs($dirs)
608 {
609 $enableRows = [];
610 $disableRows = [];
611
612 foreach ($dirs as $dir)
613 {
614 $hash = isset($dir['dirMd5']) ? $dir['dirMd5'] : null;
615 $value = isset($dir['value']) ? intval($dir['value']) : 0;
616
617 if (!$hash || !in_array($value, [MailboxDirectoryTable::ACTIVE, MailboxDirectoryTable::INACTIVE]))
618 {
619 continue;
620 }
621
622 if ($value === MailboxDirectoryTable::ACTIVE)
623 {
624 $enableRows[] = $hash;
625 }
626 else
627 {
628 $disableRows[] = $hash;
629 }
630 }
631
632 if (!empty($enableRows))
633 {
634 MailboxDirectory::updateSyncDirs($enableRows, MailboxDirectoryTable::ACTIVE, $this->mailboxId);
635 }
636
637 if (!empty($disableRows))
638 {
639 MailboxDirectory::updateSyncDirs($disableRows, MailboxDirectoryTable::INACTIVE, $this->mailboxId);
640 }
641
642 $mailboxHelper = Mailbox::createInstance($this->mailboxId);
643 $mailboxHelper->activateSync();
644 }
645
646 public function saveDirsTypes($dirs)
647 {
648 foreach ($dirs as $dir)
649 {
650 $type = !empty($dir['type']) ? $dir['type'] : null;
651 $hash = !empty($dir['dirMd5']) ? $dir['dirMd5'] : null;
652
653 if (!MailboxDirectoryHelper::isDirsTypes($type) || !$hash)
654 {
655 continue;
656 }
657
658 $result = MailboxDirectory::fetchOneByMailboxIdAndHash($this->mailboxId, $hash);
659
660 if ($result != null)
661 {
662 MailboxDirectory::resetDirsTypes($this->mailboxId, $type);
663
665 $result->getId(),
666 [
667 $type => MailboxDirectoryTable::ACTIVE
668 ]
669 );
670 }
671 }
672 }
673
674 public function syncDbDirs($dirs)
675 {
676 $dbDirs = $this->getAllOneLevel();
677
678 $this->addSyncDirs($dirs, $dbDirs);
679 $this->updateSyncDirs($dirs, $dbDirs);
680 $this->removeSyncDirs($dirs, $dbDirs);
681 }
682
683 public function updateMessageCount($id, $count)
684 {
686 }
687
688 public static function isDirsTypes($name)
689 {
690 if (in_array(
691 $name,
692 [
693 MailboxDirectoryTable::TYPE_OUTCOME,
694 MailboxDirectoryTable::TYPE_TRASH,
695 MailboxDirectoryTable::TYPE_SPAM
696 ],
697 true
698 ))
699 {
700 return true;
701 }
702
703 return false;
704 }
705
706 public static function getFlags(array $flags)
707 {
708 sort($flags);
709 return implode(' ', $flags);
710 }
711
712 public static function getMaxLevelDirs()
713 {
714 return (int)\Bitrix\Main\Config\Option::get('mail', 'maxLevelDirs', 20);
715 }
716
717 public static function setMaxLevelDirs(int $val)
718 {
719 \Bitrix\Main\Config\Option::set('mail', 'maxLevelDirs', $val);
720 }
721
722 public static function getCurrentSyncDir()
723 {
724 return \Bitrix\Main\Config\Option::get('mail', 'currentSyncDir', '');
725 }
726
727 public static function setCurrentSyncDir(string $path)
728 {
729 \Bitrix\Main\Config\Option::set('mail', 'currentSyncDir', $path);
730 }
731}
getCurrentSyncDirPositionByDefault(string $path, $excludeDirPath=null)
static createInstance($id, $throw=true)
Definition mailbox.php:101
static fetchAllLevelByParentId($mailboxId, $path, $level)
static deleteList(array $filter)
static resetDirsTypes($mailboxId, $type)
static addMulti($rows, $ignoreEvents=false)
static fetchOneLevelByParentId($mailboxId, $id, $level)
static updateSyncDirs(array $values, $val, $mailboxId)
static fetchOneByMailboxIdAndHash($mailboxId, $hash)
if(!function_exists(__NAMESPACE__.'\\___1034172934'))
Definition license.php:1