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

PHPStorage   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 95
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 40
dl 0
loc 95
ccs 31
cts 31
cp 1
rs 10
c 1
b 0
f 0
wmc 23

8 Methods

Rating   Name   Duplication   Size   Complexity  
A storeMessage() 0 13 3
A storeSubscriptions() 0 7 2
A __construct() 0 3 1
A retrieveMessagesAfterId() 0 7 2
A findSubscriptionsBySubscriber() 0 9 3
A removeSubscriptions() 0 11 4
A getMessagesAfterId() 0 12 5
A getAllMessages() 0 7 3
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 removeSubscriptions(iterable $subscriptions): PromiseInterface
63
    {
64 1
        foreach ($subscriptions as $subscription) {
65
            foreach ($this->subscriptions as $key => $_subscription) {
66 1
                if ($_subscription->getId() === $subscription->getId()) {
67
                    unset($this->subscriptions[$key]);
68 1
                }
69 1
            }
70 1
        }
71
72 1
        return resolve();
73
    }
74 1
75
    public function findSubscriptionsBySubscriber(string $subscriber): PromiseInterface
76
    {
77
        return resolve((function (string $subscriber) {
78
            foreach ($this->subscriptions as $subscription) {
79
                if ($subscription->getSubscriber() === $subscriber) {
80
                    yield $subscription;
81
                }
82
            }
83
        })($subscriber));
84
    }
85
86
    private function getMessagesAfterId(string $id, array $subscribedTopics): iterable
87
    {
88
        $ignore = true;
89
        foreach ($this->messages as [$topic, $message]) {
90
            if ($message->getId() === $id) {
91
                $ignore = false;
92
                continue;
93
            }
94
            if ($ignore || !TopicMatcher::matchesTopicSelectors($topic, $subscribedTopics)) {
95
                continue;
96
            }
97
            yield $topic => $message;
98
        }
99
    }
100
101
    private function getAllMessages(array $subscribedTopics): iterable
102
    {
103
        foreach ($this->messages as [$topic, $message]) {
104
            if (!TopicMatcher::matchesTopicSelectors($topic, $subscribedTopics)) {
105
                continue;
106
            }
107
            yield $topic => $message;
108
        }
109
    }
110
}
111