Passed
Push — master ( bc3840...800ced )
by Camilo
01:52
created

EventManager::addCandidate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
126
    {
127
        $this->logger->debug('Checking ping');
128
        if ($client->isItPingTime()) {
129
            $this->logger->notice('Sending ping');
130
            $client->setBlocking(true);
131
            $client->sendData(new PingReq($this->logger));
132
            $client->setBlocking(false);
133
        }
134
135
        return true;
136
    }
137
}
138