mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
Add support for RFC 5464 regarding issue #152 Kolab
This commit is contained in:
parent
33f42cc34d
commit
73eb89b4ee
3 changed files with 139 additions and 3 deletions
|
|
@ -47,6 +47,11 @@ class Folder
|
||||||
*/
|
*/
|
||||||
private $aExtended = array();
|
private $aExtended = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RFC 5464
|
||||||
|
*/
|
||||||
|
private $aMetadata = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
|
* @throws \MailSo\Base\Exceptions\InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
|
|
@ -139,4 +144,20 @@ class Folder
|
||||||
{
|
{
|
||||||
return isset($this->aExtended[$sName]) ? $this->aExtended[$sName] : null;
|
return isset($this->aExtended[$sName]) ? $this->aExtended[$sName] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $mData
|
||||||
|
*/
|
||||||
|
public function SetMetadata(string $sName, string $sData) : void
|
||||||
|
{
|
||||||
|
$this->aMetadata[$sName] = $sData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function GetMetadata(string $sName) : ?string
|
||||||
|
{
|
||||||
|
return isset($this->aMetadata[$sName]) ? $this->aMetadata[$sName] : null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -304,6 +304,8 @@ class ImapClient extends \MailSo\Net\NetClient
|
||||||
* URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED
|
* URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED
|
||||||
* I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH
|
* I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH
|
||||||
* LIST-STATUS BINARY MOVE SNIPPET=FUZZY PREVIEW=FUZZY STATUS=SIZE LITERAL+ NOTIFY SPECIAL-USE
|
* LIST-STATUS BINARY MOVE SNIPPET=FUZZY PREVIEW=FUZZY STATUS=SIZE LITERAL+ NOTIFY SPECIAL-USE
|
||||||
|
* STARTTLS AUTH= LOGIN LOGINDISABLED QUOTA
|
||||||
|
* METADATA METADATA-SERVER
|
||||||
*
|
*
|
||||||
* @throws \MailSo\Net\Exceptions\Exception
|
* @throws \MailSo\Net\Exceptions\Exception
|
||||||
* @throws \MailSo\Imap\Exceptions\Exception
|
* @throws \MailSo\Imap\Exceptions\Exception
|
||||||
|
|
@ -463,7 +465,18 @@ class ImapClient extends \MailSo\Net\NetClient
|
||||||
$bUseListStatus = false;
|
$bUseListStatus = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->SendRequestGetResponse($sCmd, $aParameters)->getFoldersResult($sCmd, $bUseListStatus);
|
$aReturn = $this->SendRequestGetResponse($sCmd, $aParameters)->getFoldersResult($sCmd, $bUseListStatus);
|
||||||
|
|
||||||
|
// RFC 5464
|
||||||
|
if ($this->IsSupported('METADATA')) {
|
||||||
|
foreach ($aReturn as $oFolder) {
|
||||||
|
foreach ($this->FolderGetMetadata($oFolder->FullNameRaw(), ['/shared', '/private'], ['DEPTH'=>'infinity']) as $key => $value) {
|
||||||
|
$oFolder->SetMetadata($key, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $aReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1717,13 +1730,96 @@ class ImapClient extends \MailSo\Net\NetClient
|
||||||
return self::TAG_PREFIX.$this->iTagCount;
|
return self::TAG_PREFIX.$this->iTagCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function EscapeString(string $sStringForEscape) : string
|
public function EscapeString(?string $sStringForEscape) : string
|
||||||
{
|
{
|
||||||
return '"'.\str_replace(array('\\', '"'), array('\\\\', '\\"'), $sStringForEscape).'"';
|
if (null === $sStringForEscape) {
|
||||||
|
return 'NIL';
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// literal-string
|
||||||
|
if (\preg_match('/[\r\n\x00\x80-\xFF]/', $sStringForEscape)) {
|
||||||
|
return \sprintf("{%d}\r\n%s", \strlen($sStringForEscape), $sStringForEscape);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
// quoted-string
|
||||||
|
return '"' . \addcslashes($sStringForEscape, '\\"') . '"';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getLogName() : string
|
protected function getLogName() : string
|
||||||
{
|
{
|
||||||
return 'IMAP';
|
return 'IMAP';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RFC 5464
|
||||||
|
*/
|
||||||
|
|
||||||
|
const
|
||||||
|
ADMIN_SHARED = '/shared/admin', // Server
|
||||||
|
COMMENT_SHARED = '/shared/comment', // Server & Mailbox
|
||||||
|
COMMENT_PRIVATE = '/private/comment', // Mailbox
|
||||||
|
// RFC 6154
|
||||||
|
SPECIALUSE_PRIVATE = '/private/specialuse',
|
||||||
|
// Kolab
|
||||||
|
KOLAB_CTYPE_KEY_SHARED = '/shared/vendor/kolab/folder-type',
|
||||||
|
KOLAB_CTYPE_KEY_PRIVATE = '/private/vendor/kolab/folder-type',
|
||||||
|
KOLAB_COLOR_KEY_SHARED = '/shared/vendor/kolab/color',
|
||||||
|
KOLAB_COLOR_KEY_PRIVATE = '/private/vendor/kolab/color',
|
||||||
|
KOLAB_NAME_KEY_SHARED = '/shared/vendor/kolab/displayname',
|
||||||
|
KOLAB_NAME_KEY_PRIVATE = '/private/vendor/kolab/displayname',
|
||||||
|
KOLAB_UID_KEY_SHARED = '/shared/vendor/kolab/uniqueid',
|
||||||
|
CYRUS_UID_KEY_SHARED = '/shared/vendor/cmu/cyrus-imapd/uniqueid';
|
||||||
|
|
||||||
|
public function FolderGetMetadata(string $sFolderName, array $aEntries, array $aOptions = []) : array
|
||||||
|
{
|
||||||
|
if (!$this->IsSupported('METADATA') && !(!\strlen($sFolderName) && $this->IsSupported('METADATA-SERVER'))) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$arguments = [];
|
||||||
|
|
||||||
|
if ($aOptions) {
|
||||||
|
$options = [];
|
||||||
|
$aOptions = \array_intersect_key(
|
||||||
|
\array_change_key_case($aOptions, CASE_UPPER),
|
||||||
|
['MAXSIZE' => 0, 'DEPTH' => 0]
|
||||||
|
);
|
||||||
|
if (isset($aOptions['MAXSIZE']) && 0 < \intval($aOptions['MAXSIZE'])) {
|
||||||
|
$options[] = 'MAXSIZE ' . \intval($aOptions['MAXSIZE']);
|
||||||
|
}
|
||||||
|
if (isset($aOptions['DEPTH']) && (1 == $aOptions['DEPTH'] || 'infinity' === $aOptions['DEPTH'])) {
|
||||||
|
$options[] = "DEPTH {$aOptions['DEPTH']}";
|
||||||
|
}
|
||||||
|
if ($options) {
|
||||||
|
$arguments[] = '(' . \implode(' ', $options) . ')';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$arguments[] = $this->EscapeString($sFolderName);
|
||||||
|
|
||||||
|
$arguments[] = '(' . \implode(' ', \array_map([$this, 'EscapeString'], $aEntries)) . ')';
|
||||||
|
return $this->SendRequestGetResponse('GETMETADATA', $arguments)->getFolderMetadataResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function FolderSetMetadata(string $sFolderName, array $aEntries)
|
||||||
|
{
|
||||||
|
if (!$aEntries) {
|
||||||
|
throw new \MailSo\Base\Exceptions\InvalidArgumentException("Wrong argument for SETMETADATA command");
|
||||||
|
}
|
||||||
|
|
||||||
|
$arguments = [$this->EscapeString($sFolderName)];
|
||||||
|
|
||||||
|
\array_walk($aEntries, function(&$v, $k){
|
||||||
|
$v = $this->EscapeString($k) . ' ' . $this->EscapeString($v);
|
||||||
|
});
|
||||||
|
$arguments[] = '(' . \implode(' ', $aEntries) . ')';
|
||||||
|
|
||||||
|
$result = $this->SendRequestGetResponse('SETMETADATA', $arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function FolderDeleteMetadata($sFolderName, array $aEntries)
|
||||||
|
{
|
||||||
|
$this->SetMetadata($sFolderName, \array_fill_keys(\array_keys($aEntries), null));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,25 @@ class ResponseCollection extends \MailSo\Base\Collection
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getFolderMetadataResult() : array
|
||||||
|
{
|
||||||
|
$aReturn = array();
|
||||||
|
foreach ($this as $oResponse) {
|
||||||
|
if (\MailSo\Imap\Enumerations\ResponseType::UNTAGGED === $oResponse->ResponseType
|
||||||
|
&& 4 === \count($oResponse->ResponseList)
|
||||||
|
&& 'METADATA' === $oResponse->ResponseList[1]
|
||||||
|
&& \is_array($oResponse->ResponseList[3]))
|
||||||
|
{
|
||||||
|
$c = \count($oResponse->ResponseList[3]);
|
||||||
|
for ($i = 0; $i < $c; $i += 2) {
|
||||||
|
$value = $oResponse->ResponseList[3][$i+1];
|
||||||
|
$aReturn[$oResponse->ResponseList[3][$i]] = ('NIL' === $value) ? null : $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $aReturn;
|
||||||
|
}
|
||||||
|
|
||||||
public function getFoldersResult(string $sStatus, bool $bUseListStatus = false) : array
|
public function getFoldersResult(string $sStatus, bool $bUseListStatus = false) : array
|
||||||
{
|
{
|
||||||
$aReturn = array();
|
$aReturn = array();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue