Conversation::getNextStep()   A
last analyzed

Complexity

Conditions 4
Paths 6

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 20
c 0
b 0
f 0
rs 9.2
ccs 11
cts 11
cp 1
nc 6
cc 4
eloc 11
nop 3
crap 4
1
<?php
2
3
namespace Tgallice\Wit;
4
5
use Tgallice\Wit\Exception\BadResponseException;
6
use Tgallice\Wit\Exception\ConversationException;
7
use Tgallice\Wit\Exception\InvalidStepException;
8
use Tgallice\Wit\Exception\MaxIterationException;
9
use Tgallice\Wit\Model\Context;
10
use Tgallice\Wit\Model\Step;
11
use Tgallice\Wit\Model\Step\Action;
12
use Tgallice\Wit\Model\Step\Merge;
13
use Tgallice\Wit\Model\Step\Message;
14
use Tgallice\Wit\Model\Step\Stop;
15
16
class Conversation
17
{
18
    const MAX_STEPS_ITERATION = 5;
19
20
    /**
21
     * @var ConverseApi
22
     */
23
    private $converseApi;
24
25
    /**
26
     * @var ActionMapping
27
     */
28
    private $actionMapping;
29
30 10
    public function __construct(ConverseApi $converseApi, ActionMapping $actionMapping)
31
    {
32 10
        $this->converseApi = $converseApi;
33 10
        $this->actionMapping = $actionMapping;
34 10
    }
35
36
    /**
37
     * @param string $sessionId
38
     * @param string|null $message
39
     * @param Context|null $context
40
     * @param int $stepIteration
41
     *
42
     * @return Context The new Context
43
     */
44 9
    public function converse($sessionId, $message = null, Context $context = null, $stepIteration = self::MAX_STEPS_ITERATION)
45
    {
46 9
        $context = (null !== $context) ? $context : new Context();
47
48 9
        if ($stepIteration <= 0) {
49 1
            $error = new MaxIterationException("Max iteration exceeded");
50 1
            $this->actionMapping->error($sessionId, $context, $error);
51
52 1
            return $context;
53
        }
54
55
        try {
56 9
            $step = $this->getNextStep($sessionId, $message, $context);
57 9
        } catch (\Exception $e) {
58
            // Trigger the error action
59 2
            $stepData = $e instanceof ConversationException ? $e->getStepData() : [];
60 2
            $this->actionMapping->error($sessionId, $context, $e, $stepData);
61
62 2
            return new Context();
63
        }
64
65 7
        return $this->performStep($sessionId, $step, $context, $stepIteration);
66
    }
67
68
    /**
69
     * @param string $sessionId
70
     * @param string|null $message
71
     * @param Context $context
72
     *
73
     * @return Step Step object
74
     *
75
     * @throws BadResponseException
76
     * @throws ConversationException
77
     */
78 9
    private function getNextStep($sessionId, $message, Context $context)
79
    {
80 9
        $stepData = $this->converseApi->converse($sessionId, $message, $context);
81
82 9
        if (null === $stepData) {
83 1
            $stepData = [];
84 1
        }
85
86 9
        if (isset($stepData['error'])) {
87 1
            throw new ConversationException($stepData['error'], $sessionId, $context, $stepData);
88
        }
89
90
        try {
91 8
            $step = StepFactory::create($stepData);
92 8
        } catch (InvalidStepException $e) {
93 1
            throw new ConversationException($e->getMessage(), $sessionId, $context, $e->getStepData());
94
        }
95
96 7
        return $step;
97
    }
98
99
    /**
100
     * @param $sessionId
101
     * @param Step $step
102
     * @param Context $context
103
     * @param int $currentIteration
104
     *
105
     * @return Context
106
     */
107 7
    private function performStep($sessionId, Step $step, Context $context, $currentIteration)
108
    {
109 7
        switch (true) {
110 7 View Code Duplication
            case $step instanceof Merge:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
111 3
                $newContext = $this->actionMapping->merge($sessionId, $context, $step);
112 3
                $context = $this->converse($sessionId, null, $newContext, --$currentIteration);
113 3
                break;
114 6 View Code Duplication
            case $step instanceof Message:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
115 1
                $this->actionMapping->say($sessionId, $context, $step);
116 1
                $context = $this->converse($sessionId, null, $context, --$currentIteration);
117 1
                break;
118 6 View Code Duplication
            case $step instanceof Action:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
119 1
                $newContext = $this->actionMapping->action($sessionId, $context, $step);
120 1
                $context = $this->converse($sessionId, null, $newContext, --$currentIteration);
121 1
                break;
122 6
            case $step instanceof Stop:
123 6
                $this->actionMapping->stop($sessionId, $context, $step);
124 6
                break;
125
        }
126
127 7
        return $context;
128
    }
129
}
130