Test Failed
Push — master ( bdaab5...176ee2 )
by Vladimir
06:36
created

ConversationManager::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 0
cts 0
cp 0
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace FondBot\Conversation;
6
7
use FondBot\Foundation\Kernel;
8
use FondBot\Drivers\ReceivedMessage;
9
use FondBot\Drivers\Exceptions\InvalidRequest;
10
11
class ConversationManager
12
{
13
    /**
14
     * Determine if conversation transitioned.
15
     *
16
     * @var bool
17
     */
18
    private $transitioned = false;
19
20
    private $kernel;
21
22
    public function __construct(Kernel $kernel)
23
    {
24
        $this->kernel = $kernel;
25
    }
26
27
    /**
28
     * Handle received message.
29
     *
30 4
     * @param ReceivedMessage $message
31
     */
32
    public function handle(ReceivedMessage $message): void
33
    {
34 4
        try {
35
            if (!$this->isInConversation()) {
36
                $this->converse(
37 4
                    $this->findIntent($message)
0 ignored issues
show
Bug introduced by
It seems like $this->findIntent($message) can be null; however, converse() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
38
                );
39 4
            } else {
40 4
                $this->converse(
41
                    session()->getInteraction()
0 ignored issues
show
Bug introduced by
It seems like session()->getInteraction() can be null; however, converse() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
42 4
                );
43 4
            }
44
45
            // Close session if conversation has not been transitioned
46 4
            // Otherwise, save session state
47 1
            if (!$this->transitioned) {
48
                $this->kernel->closeSession();
49
            } else {
50
                $this->kernel->saveSession();
51 3
            }
52
        } catch (InvalidRequest $exception) {
53
            logger()->warning('ConversationManager[handle] - Invalid Request', ['message' => $exception->getMessage()]);
54 2
        }
55
    }
56 2
57 1
    /**
58 1
     * Start conversation.
59
     *
60
     * @param Conversable|mixed $conversable
61 1
     */
62 1
    public function converse(Conversable $conversable): void
63
    {
64
        if ($conversable instanceof Intent) {
65
            $session = $this->kernel->getSession();
66
            $session->setIntent($conversable);
67
            $session->setInteraction(null);
68 2
            $session->setContext([]);
69 2
70
            $this->kernel->setSession($session);
0 ignored issues
show
Bug introduced by
It seems like $session defined by $this->kernel->getSession() on line 65 can be null; however, FondBot\Foundation\Kernel::setSession() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
71 2
72
            $conversable->handle($this->kernel);
73 1
        } elseif ($conversable instanceof Interaction) {
74 1
            $conversable->handle($this->kernel);
75
        } else {
76
            $conversable->handle($this->kernel);
77 3
        }
78
    }
79
80
    /**
81
     * Transition to intent or interaction.
82
     *
83
     * @param Conversable $conversable
84
     */
85 5
    public function transition(Conversable $conversable): void
86
    {
87 5
        $this->converse($conversable);
88 2
        $this->transitioned = true;
89 2
    }
90 2
91 2
    /**
92
     * Restart intent or interaction.
93 2
     *
94
     * @param Conversable|mixed $conversable
95 2
     */
96
    public function restart(Conversable $conversable): void
97 2
    {
98
        switch (true) {
99 1
            case $conversable instanceof Intent:
100
                $this->converse($conversable);
101 5
102
                $this->transitioned = true;
103
                break;
104
            case $conversable instanceof Interaction:
105
                $session = $this->kernel->getSession();
106
                $session->setInteraction(null);
107
                $session->setContext([]);
108 1
109
                $this->kernel->setSession($session);
0 ignored issues
show
Bug introduced by
It seems like $session defined by $this->kernel->getSession() on line 105 can be null; however, FondBot\Foundation\Kernel::setSession() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
110 1
111 1
                $this->transitioned = true;
112 1
113
                $this->converse($conversable);
114
                break;
115
        }
116
    }
117
118
    /**
119 2
     * Find matching intent.
120
     *
121
     * @param ReceivedMessage $message
122 2
     *
123 1
     * @return Intent|null
124
     */
125 1
    private function findIntent(ReceivedMessage $message): Intent
126 1
    {
127
        /** @var IntentManager $intentManager */
128 1
        $intentManager = $this->kernel->resolve(IntentManager::class);
129 1
130 1
        return $intentManager->find($message);
131
    }
132 1
133
    /**
134 1
     * Determine if conversation started.
135
     *
136 1
     * @return bool
137 1
     */
138
    private function isInConversation(): bool
139 2
    {
140
        return $this->kernel->getSession()->getInteraction() !== null;
141
    }
142
}
143