Passed
Push — master ( 236a58...055c31 )
by Vladimir
07:58
created

ConversationManager::findIntent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 7
ccs 3
cts 3
cp 1
crap 1
rs 9.4285
c 0
b 0
f 0
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 6
    public function __construct(Kernel $kernel)
23
    {
24 6
        $this->kernel = $kernel;
25 6
    }
26
27
    /**
28
     * Handle received message.
29
     *
30
     * @param ReceivedMessage $message
31
     */
32 2
    public function handle(ReceivedMessage $message): void
33
    {
34
        try {
35 2
            if (!$this->isInConversation()) {
36 1
                $this->converse(
37 1
                    $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
            } else {
40 1
                $this->converse(
41 1
                    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
                );
43
            }
44
45
            // Close session if conversation has not been transitioned
46
            // Otherwise, save session state
47 2
            if (!$this->transitioned) {
48 2
                $this->kernel->closeSession();
49 2
                $this->kernel->clearContext();
50
            }
51
        } catch (InvalidRequest $exception) {
52
            logger()->warning('ConversationManager[handle] - Invalid Request', ['message' => $exception->getMessage()]);
53
        }
54 2
    }
55
56
    /**
57
     * Start conversation.
58
     *
59
     * @param Conversable|mixed $conversable
60
     */
61 5
    public function converse(Conversable $conversable): void
62
    {
63 5
        if ($conversable instanceof Intent) {
64 2
            $session = $this->kernel->getSession();
65 2
            $session->setIntent($conversable);
66 2
            $session->setInteraction(null);
67
68 2
            $this->kernel->setSession($session);
0 ignored issues
show
Bug introduced by
It seems like $session defined by $this->kernel->getSession() on line 64 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...
69
70 2
            $conversable->handle($this->kernel);
71 3
        } elseif ($conversable instanceof Interaction) {
72 2
            $conversable->handle($this->kernel);
73
        } else {
74 1
            $conversable->handle($this->kernel);
75
        }
76 5
    }
77
78
    /**
79
     * Transition to intent or interaction.
80
     *
81
     * @param Conversable $conversable
82
     */
83 1
    public function transition(Conversable $conversable): void
84
    {
85 1
        $this->converse($conversable);
86 1
        $this->transitioned = true;
87 1
    }
88
89
    /**
90
     * Restart intent or interaction.
91
     *
92
     * @param Conversable|mixed $conversable
93
     */
94 2
    public function restart(Conversable $conversable): void
95
    {
96
        switch (true) {
97 2
            case $conversable instanceof Intent:
98 1
                $this->converse($conversable);
99
100 1
                $this->transitioned = true;
101 1
                break;
102 1
            case $conversable instanceof Interaction:
103 1
                $session = $this->kernel->getSession();
104 1
                $session->setInteraction(null);
105
106 1
                $this->kernel->setSession($session);
0 ignored issues
show
Bug introduced by
It seems like $session defined by $this->kernel->getSession() on line 103 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...
107
108 1
                $this->transitioned = true;
109
110 1
                $this->converse($conversable);
111 1
                break;
112
        }
113 2
    }
114
115
    /**
116
     * Find matching intent.
117
     *
118
     * @param ReceivedMessage $message
119
     *
120
     * @return Intent|null
121
     */
122 1
    private function findIntent(ReceivedMessage $message): Intent
123
    {
124
        /** @var IntentManager $intentManager */
125 1
        $intentManager = $this->kernel->resolve(IntentManager::class);
126
127 1
        return $intentManager->find($message);
128
    }
129
130
    /**
131
     * Determine if conversation started.
132
     *
133
     * @return bool
134
     */
135 2
    private function isInConversation(): bool
136
    {
137 2
        return $this->kernel->getSession()->getInteraction() !== null;
138
    }
139
}
140