Completed
Push — master ( 155993...f3fb69 )
by Vladimir
02:50
created

ConversationManager::resolveContext()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 13
nc 4
nop 3
dl 0
loc 24
ccs 0
cts 11
cp 0
crap 12
rs 8.9713
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace FondBot\Conversation;
6
7
use FondBot\Channels\Chat;
8
use FondBot\Channels\User;
9
use FondBot\Channels\Channel;
10
use Illuminate\Cache\Repository;
11
use FondBot\Events\MessageReceived;
12
use FondBot\Contracts\Conversation\Manager;
13
use Illuminate\Contracts\Foundation\Application;
14
15
class ConversationManager implements Manager
16
{
17
    private $intents = [];
18
    private $fallbackIntent;
19
20
    private $application;
21
    private $cache;
22
23 68
    public function __construct(Application $application, Repository $cache)
24
    {
25 68
        $this->application = $application;
26 68
        $this->cache = $cache;
27 68
    }
28
29
    /**
30
     * Register intent.
31
     *
32
     * @param string $class
33
     */
34
    public function registerIntent(string $class): void
35
    {
36
        $this->intents[] = $class;
37
    }
38
39
    /**
40
     * Register fallback intent.
41
     *
42
     * @param string $class
43
     */
44 68
    public function registerFallbackIntent(string $class): void
45
    {
46 68
        $this->fallbackIntent = $class;
47 68
    }
48
49
    /**
50
     * Get all registered intents.
51
     *
52
     * @return array
53
     */
54
    public function getIntents(): array
55
    {
56
        return $this->intents;
57
    }
58
59
    /**
60
     * Match intent by received message.
61
     *
62
     * @param MessageReceived $messageReceived
63
     *
64
     * @return Intent|null
65
     */
66
    public function matchIntent(MessageReceived $messageReceived): ?Intent
67
    {
68
        foreach ($this->intents as $intent) {
69
            /** @var Intent $intent */
70
            $intent = resolve($intent);
0 ignored issues
show
Documentation introduced by
$intent is of type object<FondBot\Conversation\Intent>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
71
72
            foreach ($intent->activators() as $activator) {
73
                if ($activator->matches($messageReceived) && $intent->passesAuthorization($messageReceived)) {
74
                    return $intent;
75
                }
76
            }
77
        }
78
79
        // Otherwise, return fallback intent
80
        return resolve($this->fallbackIntent);
81
    }
82
83
    /**
84
     * Resolve conversation context.
85
     *
86
     * @param Channel $channel
87
     * @param Chat    $chat
88
     * @param User    $user
89
     *
90
     * @return Context|null
91
     */
92
    public function resolveContext(Channel $channel, Chat $chat, User $user): Context
93
    {
94
        $value = $this->cache->get($this->getCacheKeyForContext($channel, $chat, $user), [
95
            'chat' => $chat,
96
            'user' => $user,
97
            'intent' => null,
98
            'interaction' => null,
99
        ]);
100
101
        $context = new Context($channel, $chat, $user);
102
103
        if ($value['intent'] !== null) {
104
            $context->setIntent($value['intent']);
105
        }
106
107
        if ($value['interaction'] !== null) {
108
            $context->setInteraction($value['interaction']);
109
        }
110
111
        // Bind resolved instance to the container
112
        $this->application->instance('fondbot.conversation.context', $context);
113
114
        return $context;
115
    }
116
117
    /**
118
     * Save context.
119
     *
120
     * @param Context $context
121
     */
122
    public function saveContext(Context $context): void
123
    {
124
        $this->cache->forever(
125
            $this->getCacheKeyForContext($context->getChannel(), $context->getChat(), $context->getUser()),
126
            $context->toArray()
127
        );
128
    }
129
130
    private function getCacheKeyForContext(Channel $channel, Chat $chat, User $user): string
131
    {
132
        return implode('.', ['context', $channel->getName(), $chat->getId(), $user->getId()]);
133
    }
134
135
    /**
136
     * Get current context.
137
     *
138
     * @return Context|null
139
     */
140 10
    public function getContext(): ?Context
141
    {
142 10
        if (!$this->application->has('fondbot.conversation.context')) {
143
            return null;
144
        }
145
146 10
        return $this->application->get('fondbot.conversation.context');
147
    }
148
}
149