Skip to content

Commit 7fd2fce

Browse files
author
Mikhail Sazanov
committed
add flags management, check, close, expunge commands
1 parent 62dc8fd commit 7fd2fce

File tree

8 files changed

+225
-5
lines changed

8 files changed

+225
-5
lines changed

src/Commands/CheckCommand.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Sazanof\PhpImapSockets\Commands;
4+
5+
class CheckCommand extends Command
6+
{
7+
protected string $name = 'CHECK';
8+
}

src/Commands/CloseCommand.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Sazanof\PhpImapSockets\Commands;
4+
5+
class CloseCommand extends Command
6+
{
7+
protected string $name = 'CLOSE';
8+
}

src/Commands/ExpungeCommand.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Sazanof\PhpImapSockets\Commands;
4+
5+
class ExpungeCommand extends Command
6+
{
7+
protected string $name = 'EXPUNGE';
8+
}

src/Commands/StoreCommand.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Sazanof\PhpImapSockets\Commands;
4+
5+
class StoreCommand extends Command
6+
{
7+
protected string $name = 'STORE';
8+
9+
public const STORE_SILENT = 'SILENT';
10+
public const APPEND_FLAGS = '+';
11+
12+
public function __construct(array $msgNumbers, array $flags, bool $append = false, bool $silent = false)
13+
{
14+
$command = 'FLAGS';
15+
if ($append == self::APPEND_FLAGS) {
16+
$command = self::APPEND_FLAGS . $command;
17+
}
18+
if ($silent) {
19+
$command .= '.' . self::STORE_SILENT;
20+
}
21+
$this->setArguments(implode(',', $msgNumbers) . ' ' . $command . ' (' . implode(' ', $flags) . ')');
22+
}
23+
}

src/Connection.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,21 @@
1111
use ReflectionException;
1212
use ReflectionMethod;
1313
use Sazanof\PhpImapSockets\Collections\MailboxCollection;
14+
use Sazanof\PhpImapSockets\Commands\CheckCommand;
15+
use Sazanof\PhpImapSockets\Commands\CloseCommand;
1416
use Sazanof\PhpImapSockets\Commands\Command;
1517
use Sazanof\PhpImapSockets\Commands\CreateCommand;
1618
use Sazanof\PhpImapSockets\Commands\DeleteCommand;
1719
use Sazanof\PhpImapSockets\Commands\ExamineCommand;
20+
use Sazanof\PhpImapSockets\Commands\ExpungeCommand;
1821
use Sazanof\PhpImapSockets\Commands\ListCommand;
1922
use Sazanof\PhpImapSockets\Commands\LoginCommand;
2023
use Sazanof\PhpImapSockets\Commands\LogoutCommand;
2124
use Sazanof\PhpImapSockets\Commands\LsubCommand;
2225
use Sazanof\PhpImapSockets\Commands\NoopCommand;
2326
use Sazanof\PhpImapSockets\Commands\RenameCommand;
2427
use Sazanof\PhpImapSockets\Commands\SelectCommand;
28+
use Sazanof\PhpImapSockets\Commands\StoreCommand;
2529
use Sazanof\PhpImapSockets\Commands\SubscribeCommand;
2630
use Sazanof\PhpImapSockets\Commands\UnsubscribeCommand;
2731
use Sazanof\PhpImapSockets\Exceptions\ConnectionException;
@@ -459,6 +463,31 @@ public function subscribeMailbox(string $name): bool
459463
return $response->isOk();
460464
}
461465

466+
public function checkMailbox()
467+
{
468+
return $this->command(CheckCommand::class)->isOk();
469+
}
470+
471+
/**
472+
* Delete messages with \Deleted flags and reset state to auth complete
473+
* @return bool
474+
* @throws ReflectionException
475+
*/
476+
public function closeMailbox(): bool
477+
{
478+
return $this->command(CloseCommand::class)->isOk();
479+
}
480+
481+
/**
482+
* Delete messages with \Deleted flags and reset state to auth complete. Changed imap msg mnums
483+
* @return bool
484+
* @throws ReflectionException
485+
*/
486+
public function expungeMailbox(): bool
487+
{
488+
return $this->command(ExpungeCommand::class)->isOk();
489+
}
490+
462491
/**
463492
* @param string $name
464493
* @return bool
@@ -473,4 +502,18 @@ public function unsubscribeMailbox(string $name): bool
473502
}
474503
return $response->isOk();
475504
}
505+
506+
/**
507+
* Update flags on messages
508+
* @param array $msgNums
509+
* @param array $flags
510+
* @param bool $append
511+
* @param bool $silent
512+
* @return Response
513+
* @throws ReflectionException
514+
*/
515+
public function store(array $msgNums, array $flags, bool $append = false, bool $silent = false): Response
516+
{
517+
return $this->command(StoreCommand::class, [$msgNums, $flags, $append, $silent]);
518+
}
476519
}

src/Models/Header.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class Header
66
{
77
protected string $key;
88
protected ?string $value;
9-
protected string $charset = '';
9+
protected ?string $charset = null;
1010

1111
public function __construct(string $headerLine)
1212
{
@@ -37,10 +37,15 @@ public function __construct(string $headerLine)
3737
}
3838
}
3939
/////////////////// IN METHOD WHICH DETECT DECODING
40-
} elseif (preg_match('/^(.+?): ;?\r\n/', $headerLine, $matches)) {
40+
} elseif (preg_match('/^(.+?): \r\n/', $headerLine, $matches)) {
4141
// if comes string aka "Subject: \r\n" - no subject
4242
$this->key = strtolower($matches[1]);
4343
$this->value = null;
44+
} else {
45+
preg_match('/^(.+?):$/', $headerLine, $matches);
46+
$this->key = $matches[1];
47+
$this->value = null;
48+
$this->charset = null;
4449
}
4550
}
4651

@@ -59,7 +64,7 @@ public function isUtf8(string $string)
5964
*/
6065
public function getKey(): string
6166
{
62-
return $this->key;
67+
return $this->key ?? '';
6368
}
6469

6570
/**
@@ -69,4 +74,12 @@ public function getValue(): ?string
6974
{
7075
return $this->value;
7176
}
77+
78+
/**
79+
* @return string|null
80+
*/
81+
public function getCharset(): ?string
82+
{
83+
return $this->charset;
84+
}
7285
}

src/Models/Mailbox.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,37 @@ public function unsubscribe(string $name = null): bool
181181
return $this->getConnection()->unsubscribeMailbox($name);
182182
}
183183

184+
/**
185+
* @return bool
186+
* @throws ReflectionException
187+
*/
188+
public function close(): bool
189+
{
190+
return $this->getConnection()->closeMailbox();
191+
}
192+
193+
/**
194+
* @return bool
195+
* @throws ReflectionException
196+
*/
197+
public function expunge(): bool
198+
{
199+
return $this->getConnection()->expungeMailbox();
200+
}
201+
202+
/**
203+
* @param array $msgNums
204+
* @param array $flags
205+
* @param bool $append
206+
* @param bool $silent
207+
* @return Response
208+
* @throws ReflectionException
209+
*/
210+
public function store(array $msgNums, array $flags, bool $append = false, bool $silent = false): Response
211+
{
212+
return $this->getConnection()->store($msgNums, $flags, $append, $silent);
213+
}
214+
184215
/**
185216
* @param SearchQuery $query
186217
* @return SearchResponse

src/Models/Message.php

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@
88
namespace Sazanof\PhpImapSockets\Models;
99

1010
use Sazanof\PhpImapSockets\Collections\AddressesCollection;
11-
use Sazanof\PhpImapSockets\Collections\Collection;
1211
use Sazanof\PhpImapSockets\Collections\MessageHeadersCollection;
1312
use Sazanof\PhpImapSockets\Query\FetchQuery;
1413
use Sazanof\PhpImapSockets\Response\AttachmentBodyResponse;
1514
use Sazanof\PhpImapSockets\Response\BodyResponse;
1615

1716
class Message
1817
{
18+
const FLAG_IMPORTANT = '\flagged';
19+
const FLAG_DELETED = '\deleted';
1920
protected int $uid;
2021
protected int $num;
2122
protected string $messageId;
@@ -31,6 +32,7 @@ class Message
3132
protected string $boundary;
3233
protected string $contentType;
3334
protected bool $hasAttachments = false;
35+
protected bool $isImportant = false;
3436
protected array $flags;
3537
protected ?string $body = null;
3638

@@ -87,8 +89,9 @@ public function setMailbox(Mailbox $mailbox): void
8789
/**
8890
* @param string $section
8991
* @return BodyResponse|string|null
92+
* @throws \ReflectionException
9093
*/
91-
public function getBody(string $section)
94+
public function getBody(string $section): BodyResponse|string|null
9295
{
9396
if (!is_null($this->mailbox)) {
9497
$q = new FetchQuery();
@@ -112,6 +115,21 @@ public function isHasAttachments(): bool
112115
public function setFlags(array $flags): void
113116
{
114117
$this->flags = $flags;
118+
$this->updateIsImportant();
119+
}
120+
121+
public function markAsDeleted()
122+
{
123+
$this->addFlags(self::FLAG_DELETED);
124+
return $this;
125+
}
126+
127+
/**
128+
* @return void
129+
*/
130+
public function updateIsImportant(): void
131+
{
132+
$this->isImportant = in_array(self::FLAG_IMPORTANT, $this->getFlags());
115133
}
116134

117135
/**
@@ -163,6 +181,14 @@ public function getSubject(): string
163181
return $this->subject;
164182
}
165183

184+
/**
185+
* @return bool
186+
*/
187+
public function isImportant(): bool
188+
{
189+
return $this->isImportant;
190+
}
191+
166192
/**
167193
* @param string|Address $from
168194
* @return void
@@ -223,6 +249,66 @@ public function getFlags(): array
223249
return $this->flags;
224250
}
225251

252+
public function addFlags(string|array $flag)
253+
{
254+
if (is_array($flag)) {
255+
$this->flags = array_merge($this->flags, $flag);
256+
} else {
257+
if (!in_array($flag, $this->getFlags())) {
258+
$this->flags[] = $flag;
259+
}
260+
}
261+
return $this;
262+
}
263+
264+
public function deleteFlags(string|array $flag)
265+
{
266+
if (is_string($flag)) {
267+
$flag = [$flag];
268+
}
269+
$this->flags = array_diff($this->flags, $flag);
270+
return $this;
271+
}
272+
273+
public function clearFlags()
274+
{
275+
$this->flags = [];
276+
return $this;
277+
}
278+
279+
public function replaceFlags(string|array $flag)
280+
{
281+
if (is_string($flag)) {
282+
$flag = [$flag];
283+
}
284+
$this->flags = $flag;
285+
return $this;
286+
}
287+
288+
public function saveFlags()
289+
{
290+
return $this->getMailbox()->store([$this->getNum()], $this->getFlags(), false, true);
291+
}
292+
293+
/**
294+
* @return $this
295+
*/
296+
public function setImportant()
297+
{
298+
$this->isImportant = true;
299+
return $this->addFlags(self::FLAG_IMPORTANT);
300+
}
301+
302+
/**
303+
* @return $this
304+
*/
305+
public function unsetImportant()
306+
{
307+
$this->isImportant = false;
308+
return $this->deleteFlags(self::FLAG_IMPORTANT);
309+
}
310+
311+
226312
/**
227313
* @return string
228314
*/

0 commit comments

Comments
 (0)