Passed
Push — develop ( ec92a4...023af3 )
by Johnny
01:57
created

Output::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
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
introduced by
The trait Axiom\Rivescript\Traits\Tags requires some properties which are not provided by Axiom\Rivescript\Cortex\Output: $memory, $brain
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()->brain->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
108
        $org = $trigger;
0 ignored issues
show
Unused Code introduced by
The assignment to $org is dead and can be removed.
Loading history...
109
        $topic = synapse()->memory->shortTerm()->get('topic') ?? 'random';
110
        $all = synapse()->brain->topic($topic)->triggers();
0 ignored issues
show
Unused Code introduced by
The assignment to $all is dead and can be removed.
Loading history...
111
        $originalTrigger = synapse()->brain->topic($topic)->triggers()->get($trigger);
112
113
        // FIXME: Temp fix for rsts
114
        if (isset($originalTrigger['responses']) === false) {
115
            $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...
116
            return $this->output;
117
        }
118
        /**
119
         * Get the best suitable response from
120
         * the ResponseQueue.
121
         */
122
        $response = $originalTrigger['responses']->process();
123
        $output = $this->parseResponse($response);
124
125
        /**
126
         * It could be possible that tags have altered the trigger.
127
         * If so evaluate possible changes.
128
         */
129
        $processedTrigger = synapse()->brain->topic()->triggers()->get($trigger);
130
131
        if (isset($processedTrigger['redirect'])) {
132
            //$output .= $this->getResponse($processedTrigger['redirect']);
133
            /**
134
             * If we redirect from Trigger A to Trigger B the context of the
135
             * user input changes from the line that triggered "Trigger A" to
136
             * be "Trigger A" as the user input.
137
             */
138
            synapse()->brain->say("{trigger} triggered a redirect to {$processedTrigger['redirect']}");
139
140
            $input = new Input($processedTrigger['redirect'], 0);
141
            $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...
142
            synapse()->input = new Input($processedTrigger['redirect'], 0);
143
            $this->process();
144
        }
145
146
        return $output;
147
    }
148
149
    /**
150
     * Parse the response through the available tags.
151
     *
152
     * @param string $response
153
     *
154
     * @return string
155
     */
156
    protected function parseResponse(string $response): string
157
    {
158
        synapse()->brain->say("Start response is {$response}");
159
        synapse()->tags->each(
160
            function ($tag) use (&$response) {
161
                $class = "\\Axiom\\Rivescript\\Cortex\\Tags\\$tag";
162
                $tagClass = new $class();
163
164
                $response = $tagClass->parse($response, synapse()->input);
165
                synapse()->brain->say("Response is {$response} used tag {$tag}");
166
            }
167
        );
168
169
        return $response;
170
    }
171
}
172