Passed
Pull Request — master (#2)
by Johnny
03:52 queued 02:03
created

Output   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 135
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 42
dl 0
loc 135
rs 10
c 2
b 0
f 0
wmc 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A process() 0 12 4
A searchTriggers() 0 14 2
A getResponse() 0 41 3
A parseResponse() 0 12 1
1
<?php
2
/*
3
 * This file is part of Rivescript-php
4
 *
5
 * (c) Shea Lewis <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Axiom\Rivescript\Cortex;
12
13
use Axiom\Rivescript\Traits\Regex;
14
use Axiom\Rivescript\Traits\Tags;
15
16
/**
17
 * Output class
18
 *
19
 * This class is responsible for generating the
20
 * bot response.
21
 *
22
 * PHP version 7.4 and higher.
23
 *
24
 * @category Core
25
 * @package  Cortext
26
 * @author   Shea Lewis <[email protected]>
27
 * @license  https://opensource.org/licenses/MIT MIT
28
 * @link     https://github.com/axiom-labs/rivescript-php
29
 * @since    0.3.0
30
 */
31
class Output
32
{
33
34
    use Regex;
35
    use Tags;
0 ignored issues
show
Bug introduced by
The trait Axiom\Rivescript\Traits\Tags requires the property $memory which is not provided by Axiom\Rivescript\Cortex\Output.
Loading history...
36
37
    /**
38
     * The output string
39
     *
40
     * @var string
41
     */
42
    protected string $output = 'Error: Response could not be determined.';
43
44
    /**
45
     * Keep track of the recursion
46
     * in the output.
47
     *
48
     * @var int
49
     */
50
    protected int $recursion = 0;
51
52
    /**
53
     * Process the correct output response by the interpreter.
54
     *
55
     * @return string
56
     */
57
    public function process(): string
58
    {
59
        $triggers = synapse()->brain->topic()->triggers();
60
61
        foreach ($triggers as $trigger => $data) {
62
            $this->searchTriggers($trigger);
63
            if ($this->output !== 'Error: Response could not be determined.' && $this->output !== '') {
64
                break;
65
            }
66
        }
67
68
        return $this->output;
69
    }
70
71
    /**
72
     * Search through available triggers to find a possible match.
73
     *
74
     * @param string $trigger The trigger to find responses for.
75
     *
76
     * @return void
77
     */
78
    protected function searchTriggers(string $trigger): void
79
    {
80
        synapse()->triggers->each(
81
            function ($class) use ($trigger) {
82
                $triggerClass = "\\Axiom\\Rivescript\\Cortex\\Triggers\\$class";
83
                $triggerClass = new $triggerClass(synapse()->input);
84
85
                $found = $triggerClass->parse($trigger, synapse()->input);
86
87
                if ($found === true) {
88
                    synapse()->rivescript->say("Found trigger {$trigger}...");
89
                    synapse()->memory->shortTerm()->put('trigger', $trigger);
90
                    $this->output = $this->getResponse($trigger);
91
                    return false;
92
                }
93
            }
94
        );
95
    }
96
97
    /**
98
     * Fetch a response from the found trigger.
99
     *
100
     * @param string $trigger The trigger to get a response for.
101
     *
102
     * @return string
103
     */
104
    protected function getResponse(string $trigger): string
105
    {
106
107
        $topic = synapse()->memory->shortTerm()->get('topic') ?? 'random';
108
        $originalTrigger = synapse()->brain->topic($topic)->triggers()->get($trigger);
109
110
        // FIXME: Temp fix for rsts
111
        if (isset($originalTrigger['responses']) === false) {
112
            $this->output = false;
0 ignored issues
show
Documentation Bug introduced by
The property $output was declared of type string, but false is of type false. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
113
            return $this->output;
114
        }
115
        /**
116
         * Get the best suitable response from
117
         * the ResponseQueue.
118
         */
119
        $response = $originalTrigger['responses']->process();
120
        $output = $this->parseResponse($response);
121
122
        /**
123
         * It could be possible that tags have altered the trigger.
124
         * If so evaluate possible changes.
125
         */
126
        $processedTrigger = synapse()->brain->topic()->triggers()->get($trigger);
127
128
        if (isset($processedTrigger['redirect'])) {
129
            //$output .= $this->getResponse($processedTrigger['redirect']);
130
            /**
131
             * If we redirect from Trigger A to Trigger B the context of the
132
             * user input changes from the line that triggered "Trigger A" to
133
             * be "Trigger A" as the user input.
134
             */
135
            synapse()->rivescript->say("{trigger} triggered a redirect to {$processedTrigger['redirect']}");
136
137
            $input = new Input($processedTrigger['redirect'], 0);
138
            $this->input = $input;
0 ignored issues
show
Bug Best Practice introduced by
The property input does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
139
            synapse()->input = new Input($processedTrigger['redirect'], 0);
140
141
            $output .= $this->getResponse($processedTrigger['redirect']);
142
        }
143
144
        return $output;
145
    }
146
147
    /**
148
     * Parse the response through the available tags.
149
     *
150
     * @param string $response
151
     *
152
     * @return string
153
     */
154
    protected function parseResponse(string $response): string
155
    {
156
        synapse()->tags->each(
157
            function ($tag) use (&$response) {
158
                $class = "\\Axiom\\Rivescript\\Cortex\\Tags\\$tag";
159
                $tagClass = new $class();
160
161
                $response = $tagClass->parse($response, synapse()->input);
162
            }
163
        );
164
165
        return $response;
166
    }
167
}
168