Passed
Push — master ( 49fa37...dabd6a )
by Camilo
02:32
created

EventManager::updateCommunication()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 11
ccs 0
cts 8
cp 0
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 7
nc 2
nop 1
crap 6
1
<?php
2
3
declare(strict_types=1);
4
5
namespace unreal4u\MQTT\Internals;
6
7
use unreal4u\MQTT\Application\EmptyReadableResponse;
8
use unreal4u\MQTT\Exceptions\NonAllowedObject;
9
use unreal4u\MQTT\Protocol\ConnAck;
10
use unreal4u\MQTT\Protocol\Connect;
11
use unreal4u\MQTT\Protocol\Disconnect;
12
use unreal4u\MQTT\Protocol\PingReq;
13
use unreal4u\MQTT\Protocol\PingResp;
14
use unreal4u\MQTT\Protocol\PubAck;
15
use unreal4u\MQTT\Protocol\Publish;
16
use unreal4u\MQTT\Protocol\PubRec;
17
use unreal4u\MQTT\Protocol\SubAck;
18
use unreal4u\MQTT\Protocol\Subscribe;
19
20
/**
21
 * Is able to load in an incoming event and handle it with properly, providing the ability to actively validate
22
 */
23
final class EventManager extends ProtocolBase
24
{
25
    /**
26
     * Current object as an object
27
     * @var ReadableContentInterface
28
     */
29
    private $currentObject;
30
31
    /**
32
     * Current object in string format
33
     * @var string
34
     */
35
    private $currentObjectType = '';
36
37
    /**
38
     * @var ReadableContentInterface[]
39
     */
40
    private $objectCandidates = [];
41
42
    /**
43
     * A list of all Readable objects that this class may instantiate at some point
44
     *
45
     * @see http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc385349209
46
     * @var array
47
     */
48
    private static $readableObjects = [
49
        2 => ConnAck::class,
50
        3 => Publish::class,
51
        4 => PubAck::class,
52
        5 => PubRec::class,
53
        #6 => PubRel::class, TODO Implement PubRel
54
        #7 => PubComp::class, TODO Implement PubComp
55
        9 => SubAck::class,
56
        #11 => UnsubAck::class, TODO Implement UnsubAck
57
        13 => PingResp::class,
58
    ];
59
60
    /**
61
     * Not used in this class but handy to have, will maybe be used in the future?
62
     *
63
     * @see http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc385349209
64
     * @var array
65
     */
66
    private static $writableObjects = [
0 ignored issues
show
introduced by
The private property $writableObjects is not used, and could be removed.
Loading history...
67
        1 => Connect::class,
68
        3 => Publish::class,
69
        4 => PubAck::class,
70
        5 => PubRec::class,
71
        #6 => PubRel::class,
72
        #7 => PubComp::class,
73
        8 => Subscribe::class,
74
        #10 => Unsubscribe::class, TODO Implement Unsubscribe
75
        12 => PingReq::class,
76
        14 => Disconnect::class,
77
    ];
78
79
    /**
80
     * Will check within all the Readable objects whether one of those is the correct packet we are looking for
81
     *
82
     * @param string $rawMQTTHeaders Arbitrary size of minimum 1 incoming byte(s)
83
     * @param ClientInterface $client Used if the object itself needs to process some more stuff
84
     * @return ReadableContentInterface
85
     * @throws \DomainException
86
     */
87
    public function analyzeHeaders(string $rawMQTTHeaders, ClientInterface $client): ReadableContentInterface
88
    {
89
        if ($rawMQTTHeaders === '') {
90
            $this->logger->debug('Empty headers, returning an empty object');
91
            return new EmptyReadableResponse($this->logger);
92
        }
93
        $controlPacketType = \ord($rawMQTTHeaders[0]) >> 4;
94
95
        if (array_key_exists($controlPacketType, self::$readableObjects)) {
96
            $this->currentObjectType = self::$readableObjects[$controlPacketType];
97
            $this->logger->info('Found corresponding object, instantiating', ['type' => $this->currentObjectType]);
98
            $this->currentObject = new $this->currentObjectType($this->logger);
99
            $this->currentObject->instantiateObject($rawMQTTHeaders, $client);
100
        } else {
101
            $this->logger->error('Invalid control packet type found', ['controlPacketType' => $controlPacketType]);
102
            throw new \DomainException(sprintf('Invalid control packet found (%d)', $controlPacketType));
103
        }
104
105
        return $this->currentObject;
106
    }
107
108
    public function addCandidate(ReadableContentInterface ...$restrictionObject): EventManager
109
    {
110
        $this->objectCandidates = $restrictionObject;
111
112
        return $this;
113
    }
114
115
    public function getObject(): ReadableContentInterface
116
    {
117
        foreach ($this->objectCandidates as $restrictionObject) {
118
            $this->logger->debug('Checking whether currentObject is the correct instance', [
119
                'currentObject' => \get_class($this->currentObject),
120
                'objectCheck' => \get_class($restrictionObject),
121
            ]);
122
            if ($this->currentObject instanceof $restrictionObject) {
123
                return $this->currentObject;
124
            }
125
        }
126
127
        throw new NonAllowedObject('An non allowed object has been found');
128
    }
129
}
130