mirror of
https://github.com/the-djmaze/snappymail.git
synced 2025-01-07 15:27:43 +08:00
54896bf044
And move system folder detection/autocreate to MailboxDetectPlugin because it is hardly used. And by using mailbox.role the default system folder detection is only using (IMAP and JMAP) RFC standards.
219 lines
6.6 KiB
PHP
219 lines
6.6 KiB
PHP
<?php
|
|
|
|
use MailSo\Imap\Enumerations\FolderType;
|
|
use MailSo\Imap\Enumerations\MetadataKeys;
|
|
|
|
class MailboxDetectPlugin extends \RainLoop\Plugins\AbstractPlugin
|
|
{
|
|
const
|
|
NAME = 'MailboxDetect',
|
|
AUTHOR = 'SnappyMail',
|
|
URL = 'https://snappymail.eu/',
|
|
VERSION = '2.1',
|
|
RELEASE = '2022-12-15',
|
|
REQUIRED = '2.23.1',
|
|
CATEGORY = 'General',
|
|
LICENSE = 'MIT',
|
|
DESCRIPTION = 'Autodetect system folders and/or create them when needed';
|
|
|
|
public function Init() : void
|
|
{
|
|
$this->addHook('json.after-folders', 'AfterFolders');
|
|
}
|
|
|
|
protected function configMapping() : array
|
|
{
|
|
return array(
|
|
\RainLoop\Plugins\Property::NewInstance('autocreate_system_folders')->SetLabel('Autocreate system folders')
|
|
->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL)
|
|
->SetDefaultValue(false),
|
|
);
|
|
}
|
|
|
|
public function AfterFolders(array &$aResponse)
|
|
{
|
|
if (!empty($aResponse['Result']['@Collection'])) {
|
|
$oActions = \RainLoop\Api::Actions();
|
|
$oAccount = $oActions->getAccountFromToken();
|
|
if (!$oAccount) {
|
|
\error_log('No Account');
|
|
return;
|
|
}
|
|
$oSettingsLocal = $oActions->SettingsProvider(true)->Load($oAccount);
|
|
$roles = [
|
|
'inbox' => false,
|
|
'sent' => !!$oSettingsLocal->GetConf('SentFolder', ''),
|
|
'drafts' => !!$oSettingsLocal->GetConf('DraftFolder', ''),
|
|
'junk' => !!$oSettingsLocal->GetConf('SpamFolder', ''),
|
|
'trash' => !!$oSettingsLocal->GetConf('TrashFolder', ''),
|
|
'archive' => !!$oSettingsLocal->GetConf('ArchiveFolder', '')
|
|
];
|
|
$types = [
|
|
FolderType::SENT => 'sent',
|
|
FolderType::DRAFTS => 'drafts',
|
|
FolderType::JUNK => 'junk',
|
|
FolderType::TRASH => 'trash',
|
|
FolderType::ARCHIVE => 'archive'
|
|
];
|
|
$found = [
|
|
'inbox' => [],
|
|
'sent' => [],
|
|
'drafts' => [],
|
|
'junk' => [],
|
|
'trash' => [],
|
|
'archive' => []
|
|
];
|
|
$aMap = $this->systemFoldersNames($oAccount);
|
|
$sDelimiter = '';
|
|
foreach ($aResponse['Result']['@Collection'] as $i => $folder) {
|
|
$sDelimiter || ($sDelimiter = $folder['Delimiter']);
|
|
if ($folder['role']) {
|
|
$roles[$folder['role']] = true;
|
|
} else if (\in_array('\\sentmail', $folder['Flags'])) {
|
|
$found['sent'][] = $i;
|
|
} else if (\in_array('\\spam', $folder['Flags'])) {
|
|
$found['junk'][] = $i;
|
|
} else if (\in_array('\\bin', $folder['Flags'])) {
|
|
$found['trash'][] = $i;
|
|
} else if (\in_array('\\starred', $folder['Flags'])) {
|
|
$found['flagged'][] = $i;
|
|
} else {
|
|
// Kolab
|
|
$kolab = $folder['Metadata'][MetadataKeys::KOLAB_CTYPE]
|
|
?? $folder['Metadata'][MetadataKeys::KOLAB_CTYPE_SHARED]
|
|
?? '';
|
|
if ('mail.inbox' === $kolab) {
|
|
$found['inbox'][] = $i;
|
|
} else if ('mail.sentitems' === $kolab /*|| 'mail.outbox' === $kolab*/) {
|
|
$found['sent'][] = $i;
|
|
} else if ('mail.drafts' === $kolab) {
|
|
$found['drafts'][] = $i;
|
|
} else if ('mail.junkemail' === $kolab) {
|
|
$found['junk'][] = $i;
|
|
} else if ('mail.wastebasket' === $kolab) {
|
|
$found['trash'][] = $i;
|
|
} else {
|
|
$iFolderType = 0;
|
|
if (isset($aMap[$folder['FullName']])) {
|
|
$iFolderType = $aMap[$folder['FullName']];
|
|
} else if (isset($aMap[$folder['name']]) || isset($aMap["INBOX{$folder['Delimiter']}{$folder['name']}"])) {
|
|
$iFolderType = $aMap[$folder['name']];
|
|
}
|
|
if ($iFolderType && isset($types[$iFolderType])) {
|
|
$found[$types[$iFolderType]][] = $i;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
foreach ($roles as $role => $hasRole) {
|
|
if ($hasRole) {
|
|
unset($found[$role]);
|
|
}
|
|
}
|
|
if ($found) {
|
|
foreach ($found as $role => $folders) {
|
|
if (isset($folders[0])) {
|
|
// Set the first as default
|
|
// \error_log("Set role {$role}");
|
|
$aResponse['Result']['@Collection'][$folders[0]]['role'] = $role;
|
|
} else if ($this->Config()->Get('plugin', 'autocreate_system_folders', false)) {
|
|
try
|
|
{
|
|
$sParent = \substr($aResponse['Result']['namespace'], 0, -1);
|
|
$sFolderNameToCreate = \ucfirst($role);
|
|
/*
|
|
$this->Manager()->RunHook('filter.folders-system-types', array($oAccount, &$aList));
|
|
$iPos = \strrpos($sFolderNameToCreate, $sDelimiter);
|
|
if (false !== $iPos) {
|
|
$mNewParent = \substr($sFolderNameToCreate, 0, $iPos);
|
|
$mNewFolderNameToCreate = \substr($sFolderNameToCreate, $iPos + 1);
|
|
if (\strlen($mNewFolderNameToCreate)) {
|
|
$sFolderNameToCreate = $mNewFolderNameToCreate;
|
|
}
|
|
|
|
if (\strlen($mNewParent)) {
|
|
$sParent = \strlen($sParent) ? $sParent.$sDelimiter.$mNewParent : $mNewParent;
|
|
}
|
|
}
|
|
*/
|
|
// \error_log("Create mailbox {$sFolderNameToCreate}");
|
|
$oFolder = $oActions->MailClient()->FolderCreate(
|
|
$sFolderNameToCreate,
|
|
$sParent,
|
|
true,
|
|
$sDelimiter
|
|
);
|
|
$aResponse['Result']['@Collection'][] = \json_encode($oFolder);
|
|
}
|
|
catch (\Throwable $oException)
|
|
{
|
|
$this->Logger()->WriteException($oException);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @staticvar array $aCache
|
|
*/
|
|
private function systemFoldersNames(\RainLoop\Model\Account $oAccount) : array
|
|
{
|
|
static $aCache = null;
|
|
if (null === $aCache) {
|
|
$aCache = array(
|
|
'Sent' => FolderType::SENT,
|
|
'Send' => FolderType::SENT,
|
|
'Outbox' => FolderType::SENT,
|
|
'Out box' => FolderType::SENT,
|
|
'Sent Item' => FolderType::SENT,
|
|
'Sent Items' => FolderType::SENT,
|
|
'Send Item' => FolderType::SENT,
|
|
'Send Items' => FolderType::SENT,
|
|
'Sent Mail' => FolderType::SENT,
|
|
'Sent Mails' => FolderType::SENT,
|
|
'Send Mail' => FolderType::SENT,
|
|
'Send Mails' => FolderType::SENT,
|
|
|
|
'Drafts' => FolderType::DRAFTS,
|
|
'Draft' => FolderType::DRAFTS,
|
|
'Draft Mail' => FolderType::DRAFTS,
|
|
'Draft Mails' => FolderType::DRAFTS,
|
|
'Drafts Mail' => FolderType::DRAFTS,
|
|
'Drafts Mails' => FolderType::DRAFTS,
|
|
|
|
'Junk' => FolderType::JUNK,
|
|
'Junk E-mail' => FolderType::JUNK,
|
|
'Spam' => FolderType::JUNK,
|
|
'Spams' => FolderType::JUNK,
|
|
'Bulk Mail' => FolderType::JUNK,
|
|
'Bulk Mails' => FolderType::JUNK,
|
|
|
|
'Trash' => FolderType::TRASH,
|
|
'Deleted' => FolderType::TRASH,
|
|
'Deleted Items' => FolderType::TRASH,
|
|
'Bin' => FolderType::TRASH,
|
|
|
|
'Archive' => FolderType::ARCHIVE,
|
|
'Archives' => FolderType::ARCHIVE,
|
|
|
|
'All' => FolderType::ALL,
|
|
'All Mail' => FolderType::ALL,
|
|
'All Mails' => FolderType::ALL,
|
|
);
|
|
|
|
$aNewCache = array();
|
|
foreach ($aCache as $sKey => $iType) {
|
|
$aNewCache[$sKey] = $iType;
|
|
$aNewCache[\str_replace(' ', '', $sKey)] = $iType;
|
|
}
|
|
|
|
$aCache = $aNewCache;
|
|
|
|
$this->Manager()->RunHook('filter.system-folders-names', array($oAccount, &$aCache));
|
|
}
|
|
|
|
return $aCache;
|
|
}
|
|
}
|