Passed
Pull Request — master (#17)
by BENOIT
02:08
created

PHPStorage::getMessagesAfterId()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 5

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 8
nc 4
nop 2
dl 0
loc 12
ccs 1
cts 1
cp 1
crap 5
rs 9.6111
c 1
b 0
f 0
1
<?php
2
3
namespace BenTools\MercurePHP\Storage\PHP;
4
5
use BenTools\MercurePHP\Model\Message;
6
use BenTools\MercurePHP\Model\Subscription;
7
use BenTools\MercurePHP\Security\TopicMatcher;
8
use BenTools\MercurePHP\Storage\StorageInterface;
9
use React\Promise\PromiseInterface;
10
11
use function React\Promise\resolve;
12
13
final class PHPStorage implements StorageInterface
14
{
15
    private int $messagesMaxSize;
16
    private int $currentMessagesSize = 0;
17
    private array $messages = [];
18
19
    /**
20
     * @var Subscription[]
21
     */
22 5
    private array $subscriptions = [];
23
24 5
    public function __construct(int $size)
25 5
    {
26
        $this->messagesMaxSize = $size;
27 1
    }
28
29 1
    public function retrieveMessagesAfterId(string $id, array $subscribedTopics): PromiseInterface
30 1
    {
31
        if (self::EARLIEST === $id) {
32
            return resolve($this->getAllMessages($subscribedTopics));
33 1
        }
34
35
        return resolve($this->getMessagesAfterId($id, $subscribedTopics));
36 4
    }
37
38 4
    public function storeMessage(string $topic, Message $message): PromiseInterface
39 1
    {
40
        if (0 === $this->messagesMaxSize) {
41
            return resolve(true);
42 3
        }
43 1
44
        if ($this->currentMessagesSize >= $this->messagesMaxSize) {
45 3
            \array_shift($this->messages);
46 3
        }
47
        $this->messages[] = [$topic, $message];
48 3
        $this->currentMessagesSize++;
49
50
        return resolve(true);
51 1
    }
52
53 1
    public function storeSubscriptions(array $subscriptions): PromiseInterface
54 1
    {
55 1
        foreach ($subscriptions as $subscription) {
56 1
            $this->subscriptions[] = $subscription;
57 1
        }
58
59 1
        return resolve();
60 1
    }
61
62 1
    public function findSubscriptionsBySubscriber(string $subscriber): PromiseInterface
63
    {
64 1
        return resolve((function (string $subscriber) {
65
            foreach ($this->subscriptions as $subscription) {
66 1
                if ($subscription->getSubscriber() === $subscriber) {
67
                    yield $subscription;
68 1
                }
69 1
            }
70 1
        })($subscriber));
71
    }
72 1
73
    private function getMessagesAfterId(string $id, array $subscribedTopics): iterable
74 1
    {
75
        $ignore = true;
76
        foreach ($this->messages as [$topic, $message]) {
77
            if ($message->getId() === $id) {
78
                $ignore = false;
79
                continue;
80
            }
81
            if ($ignore || !TopicMatcher::matchesTopicSelectors($topic, $subscribedTopics)) {
82
                continue;
83
            }
84
            yield $topic => $message;
85
        }
86
    }
87
88
    private function getAllMessages(array $subscribedTopics): iterable
89
    {
90
        foreach ($this->messages as [$topic, $message]) {
91
            if (!TopicMatcher::matchesTopicSelectors($topic, $subscribedTopics)) {
92
                continue;
93
            }
94
            yield $topic => $message;
95
        }
96
    }
97
}
98