diff --git a/dev/View/Popup/AdvancedSearch.js b/dev/View/Popup/AdvancedSearch.js index 4fc5057ae..5cdb5963c 100644 --- a/dev/View/Popup/AdvancedSearch.js +++ b/dev/View/Popup/AdvancedSearch.js @@ -85,52 +85,33 @@ class AdvancedSearchPopupView extends AbstractViewPopup { buildSearchString() { const - result = new FormData(); - - let value = this.from().trim(); - if (value) { - result.set('from', value); - } - - value = this.to().trim(); - if (value) { - result.set('to', value); - } - - value = this.subject().trim(); - if (value) { - result.set('subject', value); - } - - if (this.hasAttachment()) { - result.set('has', 'attachment'); - } - - if (this.unseen()) { - result.set('is[]', 'unseen'); - } - - if (this.starred()) { - result.set('is[]', 'flagged'); - } + data = new FormData(), + append = (key, value) => value.length && data.append(key, value); + append('from', this.from().trim()); + append('to', this.to().trim()); + append('subject', this.subject().trim()); + append('text', this.text().trim()); + append('in', this.selectedTreeValue()); if (-1 < this.selectedDateValue()) { let d = new Date(); d.setDate(d.getDate() - this.selectedDateValue()); - result.set('date', d.format('Y.m.d') + '/'); + append('date', d.format('Y.m.d') + '/'); } - value = this.selectedTreeValue(); - if (value) { - result.set('in', value); + let result = new URLSearchParams(data).toString(); + + if (this.hasAttachment()) { + result += '&attachment'; + } + if (this.unseen()) { + result += '&unseen'; + } + if (this.starred()) { + result += '&flagged'; } - value = this.text().trim(); - if (value) { - result.set('text', value); - } - - return new URLSearchParams(result).toString(); + return result.replace(/^&+/, ''); } clearPopup() { diff --git a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/SearchCriterias.php b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/SearchCriterias.php index e21b68b39..6a5d51e17 100644 --- a/snappymail/v/0.0.0/app/libraries/MailSo/Imap/SearchCriterias.php +++ b/snappymail/v/0.0.0/app/libraries/MailSo/Imap/SearchCriterias.php @@ -18,6 +18,9 @@ namespace MailSo\Imap; */ class SearchCriterias { + const + RegEx = 'in|e?mail|from|to|subject|has|is|date|text|body|size|larger|bigger|smaller|maxsize|minsize'; + /** https://datatracker.ietf.org/doc/html/rfc3501#section-6.4.4 @@ -135,9 +138,11 @@ class SearchCriterias $iTimeFilter = \gmmktime(1, 1, 1, \gmdate('n', $iD), 1, \gmdate('Y', $iD)); } - if (\strlen(\trim($sSearch))) { - $aLines = static::parseQueryString($sSearch); -// $aLines = static::parseSearchString($sSearch); + $sSearch = \trim($sSearch); + if (\strlen($sSearch)) { + $aLines = \preg_match('/^('.static::RegEx.'):/i', $sSearch) + ? static::parseSearchString($sSearch) + : static::parseQueryString($sSearch); if (!$aLines) { $sValue = static::escapeSearchString($oImapClient, $sSearch); @@ -173,25 +178,14 @@ class SearchCriterias $aCriteriasResult[] = $sValue; unset($aLines['EMAIL']); - } - - if (isset($aLines['TO'])) { - $sValue = static::escapeSearchString($oImapClient, $aLines['TO']); - - $aCriteriasResult[] = 'OR'; - $aCriteriasResult[] = 'TO'; - $aCriteriasResult[] = $sValue; - $aCriteriasResult[] = 'CC'; - $aCriteriasResult[] = $sValue; - + unset($aLines['FROM']); unset($aLines['TO']); } foreach ($aLines as $sName => $sRawValue) { - if ('' === \trim($sRawValue)) { + if (\is_string($sRawValue) && '' === \trim($sRawValue)) { continue; } - $sValue = static::escapeSearchString($oImapClient, $sRawValue); switch ($sName) { case 'FROM': @@ -200,41 +194,34 @@ class SearchCriterias $aCriteriasResult[] = $sValue; break; + case 'TO': + $aCriteriasResult[] = 'OR'; + $aCriteriasResult[] = 'TO'; + $aCriteriasResult[] = $sValue; + $aCriteriasResult[] = 'CC'; + $aCriteriasResult[] = $sValue; + case 'BODY': // $sMainText = \trim(\MailSo\Base\Utils::StripSpaces($sMainText), '"'); $aCriteriasResult[] = 'BODY'; - $aCriteriasResult[] = static::escapeSearchString($oImapClient, $sRawValue); + $aCriteriasResult[] = $sValue; break; - case 'HAS': - $aValue = \explode(',', \strtolower($sRawValue)); - $aValue = \array_map('trim', $aValue); - $aCompareArray = array('file', 'files', 'attachment', 'attachments'); - if (\count($aCompareArray) > \count(\array_diff($aCompareArray, $aValue))) { - // Simple, is not detailed search (Sometimes doesn't work) - $aCriteriasResult[] = 'OR OR OR'; - $aCriteriasResult[] = 'HEADER Content-Type application/'; - $aCriteriasResult[] = 'HEADER Content-Type multipart/m'; - $aCriteriasResult[] = 'HEADER Content-Type multipart/signed'; - $aCriteriasResult[] = 'HEADER Content-Type multipart/report'; - } + case 'ATTACHMENT': + // Simple, is not detailed search (Sometimes doesn't work) + $aCriteriasResult[] = 'OR OR OR'; + $aCriteriasResult[] = 'HEADER Content-Type application/'; + $aCriteriasResult[] = 'HEADER Content-Type multipart/m'; + $aCriteriasResult[] = 'HEADER Content-Type multipart/signed'; + $aCriteriasResult[] = 'HEADER Content-Type multipart/report'; + break; - case 'IS': - $aValue = \explode(',', \strtolower($sRawValue)); - if (\in_array('flagged', $aValue)) { - $aCriteriasResult[] = 'FLAGGED'; - $bUseCache = false; - } else if (\in_array('unflagged', $aValue)) { - $aCriteriasResult[] = 'UNFLAGGED'; - $bUseCache = false; - } - if (\in_array('seen', $aValue)) { - $aCriteriasResult[] = 'SEEN'; - $bUseCache = false; - } else if (\in_array('unseen', $aValue)) { - $aCriteriasResult[] = 'UNSEEN'; - $bUseCache = false; - } + case 'FLAGGED': + case 'UNFLAGGED': + case 'SEEN': + case 'UNSEEN': + $aCriteriasResult[] = $sName; + $bUseCache = false; break; case 'LARGER': @@ -342,32 +329,38 @@ class SearchCriterias if (\is_array($mValue)) { $mValue = \implode(',', $mValue); } - if (\strlen($mValue)) { - $sName = \strtoupper($sName); - if ('MAIL' === $sName) { - $sName = 'EMAIL'; - } else if ('TEXT' === $sName) { - $sName = 'BODY'; - } else if ('SIZE' === $sName || 'BIGGER' === $sName || 'MINSIZE' === $sName) { - $sName = 'LARGER'; - } else if ('MAXSIZE' === $sName) { - $sName = 'SMALLER'; - } - switch ($sName) { - case 'BODY': - case 'EMAIL': - case 'FROM': - case 'TO': - case 'SUBJECT': - case 'IS': - case 'IN': - case 'HAS': - case 'SMALLER': - case 'LARGER': - case 'DATE': + $sName = \strtoupper($sName); + if ('MAIL' === $sName) { + $sName = 'EMAIL'; + } else if ('TEXT' === $sName) { + $sName = 'BODY'; + } else if ('SIZE' === $sName || 'BIGGER' === $sName || 'MINSIZE' === $sName) { + $sName = 'LARGER'; + } else if ('MAXSIZE' === $sName) { + $sName = 'SMALLER'; + } + switch ($sName) { + case 'BODY': + case 'EMAIL': + case 'FROM': + case 'TO': + case 'SUBJECT': + case 'IN': + case 'SMALLER': + case 'LARGER': + case 'DATE': + if (\strlen($mValue)) { $aResult[$sName] = $mValue; - break; - } + } + break; + + case 'ATTACHMENT': + case 'FLAGGED': + case 'UNFLAGGED': + case 'SEEN': + case 'UNSEEN': + $aResult[$sName] = true; + break; } } return $aResult; @@ -382,10 +375,8 @@ class SearchCriterias $aCache = array(); - $sReg = 'in|e?mail|from|to|subject|has|is|date|text|body|size|larger|bigger|smaller|maxsize|minsize'; - $sSearch = \MailSo\Base\Utils::StripSpaces($sSearch); - $sSearch = \trim(\preg_replace('/('.$sReg.'): /i', '\\1:', $sSearch)); + $sSearch = \trim(\preg_replace('/('.static::RegEx.'): /i', '\\1:', $sSearch)); $mMatch = array(); if (\preg_match_all('/".*?(?