mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-06 07:57:02 +03:00
193 lines
5.4 KiB
PHP
193 lines
5.4 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of MailSo.
|
|
*
|
|
* (c) 2021 DJMaze
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace MailSo\Imap\Traits;
|
|
|
|
/**
|
|
* @category MailSo
|
|
* @package Imap
|
|
* @subpackage Traits
|
|
*
|
|
* https://datatracker.ietf.org/doc/html/rfc3501#section-6.3.10
|
|
* https://datatracker.ietf.org/doc/html/rfc4551#section-3.6
|
|
* https://datatracker.ietf.org/doc/html/rfc8474#section-4
|
|
*/
|
|
trait Status
|
|
{
|
|
public string $FullName;
|
|
|
|
public bool $hasStatus = false;
|
|
|
|
/**
|
|
* The number of messages in the mailbox.
|
|
* This response is named EXISTS as a result of a SELECT or EXAMINE command.
|
|
*/
|
|
public ?int $MESSAGES = null;
|
|
|
|
/**
|
|
* The number of messages with the \Recent flag set.
|
|
* This response also occurs as a result of a SELECT or EXAMINE command.
|
|
* IMAP4rev2 deprecated.
|
|
*/
|
|
public ?int $RECENT = null;
|
|
|
|
/**
|
|
* The next unique identifier value of the mailbox.
|
|
* A 32-bit value
|
|
* This response also occurs as a result of a SELECT or EXAMINE command.
|
|
*/
|
|
public ?int $UIDNEXT = null;
|
|
|
|
/**
|
|
* The unique identifier validity value of the mailbox.
|
|
* This response also occurs as a result of a SELECT or EXAMINE command.
|
|
*/
|
|
public ?int $UIDVALIDITY = null;
|
|
|
|
/**
|
|
* The number of messages which do not have the \Seen flag set.
|
|
* This response also occurs as a result of a IMAP4rev1 SELECT or EXAMINE command,
|
|
* but then it is the message sequence number of the first unseen message.
|
|
* IMAP4rev2 deprecated on SELECT/EXAMINE.
|
|
*/
|
|
public ?int $UNSEEN = null;
|
|
|
|
/**
|
|
* RFC 4551
|
|
* The highest mod-sequence value of all messages in the mailbox.
|
|
* This response also occurs as a result of a SELECT or EXAMINE command.
|
|
* 1*DIGIT Positive unsigned 64-bit integer
|
|
*/
|
|
public ?int $HIGHESTMODSEQ = null;
|
|
|
|
/**
|
|
* RFC 7889
|
|
* Message upload size limit.
|
|
*/
|
|
public ?int $APPENDLIMIT = null;
|
|
|
|
/**
|
|
* RFC 8474
|
|
* A server-allocated unique identifier for the mailbox.
|
|
* This response also occurs as a result of a CREATE, SELECT or EXAMINE command.
|
|
*/
|
|
public ?string $MAILBOXID = null;
|
|
|
|
/**
|
|
* RFC 8438
|
|
* The total size of the mailbox in octets.
|
|
*/
|
|
public ?int $SIZE = null;
|
|
|
|
public ?string $etag = null;
|
|
public function generateETag(\MailSo\Imap\ImapClient $oImapClient) : void
|
|
{
|
|
if (!$this->hasStatus) {
|
|
// UNSEEN undefined when only SELECT/EXAMINE is used
|
|
\error_log("{$this->FullName} STATUS missing " . \print_r(\debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS),true));
|
|
return;
|
|
}
|
|
if (!isset($this->MESSAGES, $this->UIDNEXT)) {
|
|
\error_log("{$this->FullName} MESSAGES or UIDNEXT missing " . \print_r(\debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS),true));
|
|
return;
|
|
}
|
|
$this->etag = \md5('FolderHash/'. \implode('-', [
|
|
$this->FullName,
|
|
$this->MESSAGES,
|
|
$this->UIDNEXT,
|
|
$this->UIDVALIDITY,
|
|
$this->UNSEEN,
|
|
$this->HIGHESTMODSEQ,
|
|
$oImapClient->Hash()
|
|
]));
|
|
}
|
|
|
|
private function setStatusItem(string $name, $value) : bool
|
|
{
|
|
if ('EXISTS' === $name) {
|
|
$name = 'MESSAGES';
|
|
} else if ('X-GUID' === $name) {
|
|
$name = 'MAILBOXID';
|
|
}
|
|
if (\property_exists(__TRAIT__, $name)) {
|
|
if ('MAILBOXID' === $name) {
|
|
// https://github.com/the-djmaze/snappymail/issues/1640
|
|
$value = \is_array($value) ? \reset($value) : $value;
|
|
if (\is_string($value)) {
|
|
$this->MAILBOXID = \base64_encode($value);
|
|
} else {
|
|
\error_log("{$this->FullName} invalid MAILBOXID value");
|
|
}
|
|
} else {
|
|
$this->$name = (int) $value;
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* SELECT https://datatracker.ietf.org/doc/html/rfc3501#section-6.3.1
|
|
* EXAMINE https://datatracker.ietf.org/doc/html/rfc3501#section-6.3.2
|
|
* STATUS https://datatracker.ietf.org/doc/html/rfc3501#section-6.3.10
|
|
*
|
|
* selectOrExamineFolder
|
|
* ResponseList[2] => EXISTS | RECENT
|
|
* OptionalResponse[0] => UNSEEN
|
|
* FolderStatus
|
|
* OptionalResponse[0] => HIGHESTMODSEQ
|
|
* ResponseList[1] => STATUS
|
|
* getFoldersResult LIST-EXTENDED
|
|
* ResponseList[1] => STATUS
|
|
*/
|
|
public function setStatusFromResponse(\MailSo\Imap\Response $oResponse) : bool
|
|
{
|
|
$bResult = false;
|
|
|
|
// OK untagged responses
|
|
if (\is_array($oResponse->OptionalResponse) && \count($oResponse->OptionalResponse) > 1) {
|
|
$bResult = $this->setStatusItem($oResponse->OptionalResponse[0], $oResponse->OptionalResponse[1]);
|
|
}
|
|
|
|
// untagged responses
|
|
else if (\count($oResponse->ResponseList) > 2) {
|
|
// LIST or STATUS command
|
|
if ('STATUS' === $oResponse->ResponseList[1]
|
|
&& isset($oResponse->ResponseList[3])
|
|
&& \is_array($oResponse->ResponseList[3])
|
|
) {
|
|
$c = \count($oResponse->ResponseList[3]) - 1;
|
|
for ($i = 0; $i < $c; $i += 2) {
|
|
if ($c > $i) {
|
|
$bResult |= $this->setStatusItem(
|
|
$oResponse->ResponseList[3][$i],
|
|
$oResponse->ResponseList[3][$i+1]
|
|
);
|
|
} else {
|
|
// https://github.com/the-djmaze/snappymail/issues/1640
|
|
\error_log("{$this->FullName} STATUS missing value for {$oResponse->ResponseList[3][$i]}");
|
|
}
|
|
}
|
|
$this->hasStatus = $bResult;
|
|
}
|
|
// SELECT or EXAMINE command
|
|
else if (\is_numeric($oResponse->ResponseList[1]) && \is_string($oResponse->ResponseList[2])) {
|
|
// UNSEEN deprecated in IMAP4rev2
|
|
if ('UNSEEN' !== $oResponse->ResponseList[2]) {
|
|
$bResult |= $this->setStatusItem($oResponse->ResponseList[2], $oResponse->ResponseList[1]);
|
|
}
|
|
}
|
|
}
|
|
|
|
return $bResult;
|
|
}
|
|
|
|
}
|