Passed
Push — develop ( 7909c1...ec92a4 )
by Johnny
07:21
created

Output::getResponse()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 34
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 3
eloc 12
nc 3
nop 1
dl 0
loc 34
rs 9.8666
c 2
b 0
f 0
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
     * Information of where the information came from.
39
     *
40
     * @var Input
41
     */
42
    protected Input $input;
43
44
    /**
45
     * The output string
46
     *
47
     * @var string
48
     */
49
    protected string $output = 'Error: Response could not be determined.';
50
51
    /**
52
     * Keep track of the recursion
53
     * in the output.
54
     *
55
     * @var int
56
     */
57
    protected int $recursion = 0;
58
59
    /**
60
     * Create a new Output instance.
61
     *
62
     * @param Input $input
63
     */
64
    public function __construct(Input $input)
65
    {
66
        $this->input = $input;
67
    }
68
69
    /**
70
     * Process the correct output response by the interpreter.
71
     *
72
     * @return string
73
     */
74
    public function process(): string
75
    {
76
        synapse()->brain->topic()->triggers()->each(
77
            function ($data, $trigger) {
78
                $this->searchTriggers($trigger);
79
80
                if ($this->output !== 'Error: Response could not be determined.') {
81
                    return false;
82
                }
83
            }
84
        );
85
86
        return $this->output;
87
    }
88
89
    /**
90
     * Search through available triggers to find a possible match.
91
     *
92
     * @param string $trigger The trigger to find responses for.
93
     *
94
     * @return void
95
     */
96
    protected function searchTriggers(string $trigger): void
97
    {
98
        synapse()->triggers->each(
99
            function ($class) use ($trigger) {
100
                $triggerClass = "\\Axiom\\Rivescript\\Cortex\\Triggers\\$class";
101
                $triggerClass = new $triggerClass($this->input);
102
103
                $found = $triggerClass->parse($trigger, $this->input);
104
105
                if ($found === true) {
106
                    synapse()->memory->shortTerm()->put('trigger', $trigger);
107
                    $this->output = $this->getResponse($trigger);
108
                    return false;
109
                }
110
            }
111
        );
112
    }
113
114
    /**
115
     * Process the correct output response by the interpreter.
116
     *
117
     * @return string
118
     * @deprecated
119
     */
120
    public function process2(): string
121
    {
122
        $topic = synapse()->memory->shortTerm()->get('topic') ?? 'random';
123
        $triggers = synapse()->brain->topic($topic)->triggers();
124
        $triggerClasses = synapse()->triggers;
0 ignored issues
show
Unused Code introduced by
The assignment to $triggerClasses is dead and can be removed.
Loading history...
125
126
127
        synapse()->brain->say("Analyzing topic {$topic}...");
128
129
        echo "======================================================\n";
130
        echo "PROCESS TOPIC: {$topic}\n";
131
        echo "======================================================\n";
132
133
        $this->output = 'Error: Response could not be determined.';
134
135
        if ($this->recursion == 25) {
136
            $this->recursion = 0;
137
            return $this->output;
138
        }
139
140
        $source = $this->input->source();
0 ignored issues
show
Unused Code introduced by
The assignment to $source is dead and can be removed.
Loading history...
141
142
//        Checking topic random for any %Previous's
143
//No %Previous in this topic!
144
        synapse()->brain->say("Searching their topic for a match...");
145
146
147
        foreach ($triggers as $trigger => $info) {
148
            //  $isValid = $this->isValidTrigger($trigger);
149
            $this->searchTriggers($trigger);
150
        }
151
        return $this->output;
152
    }
153
154
    /**
155
     * Search through available triggers to find a possible match.
156
     *
157
     * @param string $trigger The trigger to find responses for.
158
     *
159
     * @return void
160
     * @deprecated
161
     */
162
    protected function searchTriggers2(string $trigger)
163
    {
164
        synapse()->triggers->each(
165
            function ($class) use ($trigger) {
166
                $triggerClass = "\\Axiom\\Rivescript\\Cortex\\Triggers\\$class";
167
                $triggerClass = new $triggerClass($this->input);
168
169
                $found = $triggerClass->parse($trigger, $this->input);
170
171
//                synapse()->brain->say("Try to match \"{$source}\" against {$trigger} ({$trigger})");
172
                if ($found === true) {
173
                    synapse()->memory->shortTerm()->put('trigger', $trigger);
174
                    $this->output = $this->getResponse($trigger);
175
                    return false;
176
                }
177
            }
178
        );
179
    }
180
181
    /**
182
     * Search through available triggers to find a possible match.
183
     *
184
     * @param string $trigger The trigger to find responses for.
185
     *
186
     * @return bool
187
     */
188
    protected function isValidTrigger(string $trigger): bool
189
    {
190
        /**
191
         * Get the connected trigger classes.
192
         */
193
        $classes = synapse()->triggers->all();
194
195
        foreach ($classes as $class) {
196
            $triggerClass = "\\Axiom\\Rivescript\\Cortex\\Triggers\\$class";
197
            $triggerClass = new $triggerClass($this->input);
198
199
            $found = $triggerClass->parse($trigger, $this->input);
200
201
            if ($found === true) {
202
                return true;
203
            }
204
        }
205
206
        return false;
207
    }
208
209
    /**
210
     * Fetch a response from the found trigger.
211
     *
212
     * @param string $trigger The trigger to get a response for.
213
     *
214
     * @return string
215
     */
216
    protected function getResponse(string $trigger): string
217
    {
218
        $topic = synapse()->memory->shortTerm()->get('topic') ?? 'random';
219
        $originalTrigger = synapse()->brain->topic($topic)->triggers()->get($trigger);
220
221
222
        // FIXME: Temp fix for rsts
223
        if (isset($originalTrigger['responses']) === false) {
224
            $this->output = "Error: Response could not be determined.";
225
            return $this->output;
226
        }
227
        /**
228
         * Get the best suitable response from
229
         * the ResponseQueue.
230
         */
231
        $response = $originalTrigger['responses']->process();
232
        $output = $this->parseResponse($response);
233
234
        /**
235
         * It could be possible that tags have altered the trigger.
236
         * If so evaluate possible changes.
237
         */
238
        $processedTrigger = synapse()->brain->topic()->triggers()->get($trigger);
239
240
        if (isset($processedTrigger['redirect'])) {
241
            //$output .= $this->getResponse($processedTrigger['redirect']);
242
            synapse()->input = new Input($processedTrigger['redirect'], 0);
243
            $this->process();
244
        }
245
246
// TODO:
247
//        $key = array_rand($trigger['responses']);
248
//        $this->output = $this->parseResponse($trigger['responses'][$key]);
249
        return $output;
250
251
// TODO:
252
//        $key = array_rand($trigger['responses']);
253
//        $this->output = $this->parseResponse($trigger['responses'][$key]);
254
//        return $output;
255
    }
256
257
258
    /**
259
     * Fetch a response from the found trigger.
260
     *
261
     * @param string $trigger The trigger to get a response for.
262
     *
263
     * @return string
264
     */
265
    protected function getResponse2(string $trigger): string
266
    {
267
        $topic = synapse()->memory->shortTerm()->get('topic') ?? 'random';
268
        $originalTrigger = synapse()->brain->topic($topic)->triggers()->get($trigger);
269
        echo "GETRESPONSE TOPIC: {$topic}\n";
270
        echo "GETRESPONSE TRIGGER: {$trigger}\n";
271
272
        // FIXME: Temp fix for rsts
273
        if (isset($originalTrigger['responses']) === false) {
274
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the type-hinted return string.
Loading history...
275
        }
276
277
        /**
278
         * Get the best suitable response from
279
         * the ResponseQueue.
280
         */
281
        $response = $originalTrigger['responses']->process();
282
283
        $output = $this->parseResponse($response);
284
285
        /**
286
         * It could be possible that tags have altered the trigger.
287
         * If so evaluate possible changes.
288
         */
289
        $processedTrigger = synapse()->brain->topic()->triggers()->get($trigger);
290
291
        echo "GETRESPONSE CHECKING FOR REDIRECT ON: {$trigger}\n";
292
293
        if (isset($processedTrigger['redirect'])) {
294
//            synapse()->brain->say("Pretend user said: {$processedTrigger['redirect']}");
295
            synapse()->brain->say("Redirect to Trigger : {$processedTrigger['redirect']} Topic: {$topic}");
296
            synapse()->memory->shortTerm()->put('trigger', $processedTrigger['redirect']);
297
298
            //     return false;
299
//            $output .= $this->getResponse($processedTrigger['redirect']);
300
            $this->recursion++;
301
            $output .= $this->process();
302
        }
303
304
// TODO:
305
//        $key = array_rand($trigger['responses']);
306
//        $this->output = $this->parseResponse($trigger['responses'][$key]);
307
308
        $output = $this->parseTags($output);
309
        echo "GETRESPONSE OUTPUT: {$output}\n";
310
        return $output;
311
312
// TODO:
313
//        $key = array_rand($trigger['responses']);
314
//        $this->output = $this->parseResponse($trigger['responses'][$key]);
315
//        return $output;
316
    }
317
318
    /**
319
     * Parse the response through the available tags.
320
     *
321
     * @param string $response
322
     *
323
     * @return string
324
     */
325
    protected function parseResponse(string $response): string
326
    {
327
        synapse()->tags->each(
328
            function ($tag) use (&$response) {
329
                $class = "\\Axiom\\Rivescript\\Cortex\\Tags\\$tag";
330
                $tagClass = new $class();
331
332
                $response = $tagClass->parse($response, $this->input);
333
            }
334
        );
335
336
        return $response;
337
    }
338
}
339