Issues (24)

src/Rivescript.php (4 issues)

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;
12
13
use Axiom\Rivescript\Cortex\ContentLoader\ContentLoader;
14
use Axiom\Rivescript\Cortex\Input;
15
use Axiom\Rivescript\Cortex\Output;
16
use Axiom\Rivescript\Traits\Tags;
17
18
/**
19
 * Rivescript class
20
 *
21
 * The entry point for using the interpreter.
22
 *
23
 * PHP version 7.4 and higher.
24
 *
25
 * @category Core
26
 * @package  Cortext
27
 * @author   Shea Lewis <[email protected]>
28
 * @license  https://opensource.org/licenses/MIT MIT
29
 * @link     https://github.com/axiom-labs/rivescript-php
30
 * @since    0.3.0
31
 */
32
class Rivescript extends ContentLoader
33
{
34
    use Tags;
0 ignored issues
show
The trait Axiom\Rivescript\Traits\Tags requires the property $memory which is not provided by Axiom\Rivescript\Rivescript.
Loading history...
35
36
    public const VERBOSITY_NORMAL = 0;
37
    public const VERBOSITY_VERBOSE = 1;
38
    public const VERBOSITY_VERY_VERBOSE = 2;
39
    public const VERBOSITY_DEBUG = 3;
40
41
    public $onSay = null;
42
43
    /**
44
     * A recursion limit before an attempt to
45
     * fetch a reply will be abandoned.
46
     *
47
     * @var int
48
     */
49
    public int $depth = 50;
50
51
    /**
52
     * Error messages.
53
     *
54
     * @var array|string[]
55
     */
56
    public array $errors = [
57
        "replyNotMatched" => "ERR: No Reply Matched",
58
        "replyNotFound" => "ERR: No Reply Found",
59
        "objectNotFound" => "[ERR: Object Not Found]",
60
        "deepRecursion" => "ERR: Deep Recursion Detected"
61
    ];
62
63
    /**
64
     * Flag to indicating if utf8
65
     * modes is enabled.
66
     *
67
     * @var bool
68
     */
69
    protected bool $utf8 = false;
70
71
    /**
72
     * Create a new Rivescript instance.
73
     *
74
     * @throws \Axiom\Rivescript\Exceptions\ContentLoadingException
75
     */
76
    public function __construct()
77
    {
78
        parent::__construct();
79
80
        include __DIR__ . '/bootstrap.php';
81
82
        synapse()->brain->setMaster($this);
83
        synapse()->rivescript = $this;
84
85
        $this->registerTags();
86
    }
87
88
    /**
89
     * Initialize the tags
90
     *
91
     * @return void
92
     */
93
    private function registerTags(): void
94
    {
95
        synapse()->tags->each(
96
            function ($tag) {
97
                $class = "\\Axiom\\Rivescript\\Cortex\\Tags\\$tag";
98
                $tagInstance = new $class();
99
100
                $tagInfo = $tagInstance->getTagName();
101
                if (is_array($tagInfo)) {
102
                    foreach ($tagInfo as $tagName) {
103
                        synapse()->memory->tags()->put($tagName, $tagInstance);
104
                    }
105
                } else {
106
                    synapse()->memory->tags()->put($tagInfo, $tagInstance);
107
                }
108
            }
109
        );
110
    }
111
112
    /**
113
     * Load Rivescript interpretable content.
114
     * Into the Interpreter.
115
     *
116
     * Please note: This supports
117
     *
118
     * - Directory path to Rivescript interpretable files.
119
     * - Array of absolute paths to Rivescript interpretable files
120
     * - Absolute string containing path to Rivescript interpretable file.
121
     * - A stream of text with Rivescript interpretable script.
122
     *
123
     * Please note 2:
124
     *
125
     * If you profile a directory with rivescript documents make sure they are
126
     * all interpretable rivescript will throw syntax errors while trying to
127
     * parse those files.
128
     *
129
     * @param array<string>|string $info The files to read
130
     *
131
     * @return void
132
     */
133
    public function load($info): void
134
    {
135
        parent::load($info);
136
        $this->processInformation();
137
    }
138
139
    /**
140
     * Stream new information into the brain.
141
     *
142
     * @param string $string The string of information to feed the brain.
143
     *
144
     * @return void
145
     */
146
    public function stream(string $string): void
147
    {
148
        fseek($this->getStream(), 0, SEEK_SET);
149
        rewind($this->getStream());
150
151
        $this->writeToMemory($string);
152
        $this->processInformation();
153
    }
154
155
    /**
156
     * Process new information in the
157
     * stream.
158
     *
159
     * @return void
160
     */
161
    private function processInformation(): void
162
    {
163
        synapse()->memory->local()->put('concat', 'none');
164
        synapse()->brain->teach($this->getStream());
165
    }
166
167
    /**
168
     * Set user variables.
169
     *
170
     * @param string $user  The user for this variable.
171
     * @param string $name  The name of the variable.
172
     * @param string $value The value of the variable.
173
     *
174
     * @return void
175
     */
176
    public function setUservar(string $user, string $name, string $value): void
177
    {
178
        synapse()->memory->user($user)->put($name, $value);
179
    }
180
181
    /**
182
     * Get user variable.
183
     *
184
     * @param string $user The user for this variable.
185
     * @param string $name The name of the variable.
186
     *
187
     * @return mixed
188
     */
189
    public function getUservar(string $user, string $name)
190
    {
191
        return synapse()->memory->user($user)->get($name);
192
    }
193
194
    /**
195
     * @param string $string
196
     * @param bool   $utf8
197
     *
198
     * @return string
199
     */
200
    private function stripNasties(string $string, bool $utf8): string
0 ignored issues
show
The parameter $utf8 is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

200
    private function stripNasties(string $string, /** @scrutinizer ignore-unused */ bool $utf8): string

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
201
    {
202
        return preg_replace("/[^A-Za-z0-9 ]/m", "", $string);
203
    }
204
205
    /**
206
     * Log a message to say.
207
     *
208
     * @param string $message   The message to print out
209
     * @param int    $verbosity The verbosity level of the message
210
     *
211
     * @return void
212
     */
213
    public function say(string $message, int $verbosity = Rivescript::VERBOSITY_NORMAL): void
214
    {
215
        if ($this->onSay) {
216
            call_user_func($this->onSay, $message, $verbosity);
217
        }
218
    }
219
220
    /**
221
     * Make the client respond to a message.
222
     *
223
     * @param string      $msg   The message the client has to process and respond to.
224
     * @param string      $user  The user id.
225
     * @param string|null $scope Not used at this point.
226
     *
227
     * @return string
228
     */
229
    public function reply(string $msg, string $user = 'local-user', string $scope = null): string
0 ignored issues
show
The parameter $scope is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

229
    public function reply(string $msg, string $user = 'local-user', /** @scrutinizer ignore-unused */ string $scope = null): string

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
230
    {
231
232
        // FIXME: Must be $user, $message, Sscope
233
        $msg = $this->stripNasties($msg, "");
0 ignored issues
show
'' of type string is incompatible with the type boolean expected by parameter $utf8 of Axiom\Rivescript\Rivescript::stripNasties(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

233
        $msg = $this->stripNasties($msg, /** @scrutinizer ignore-type */ "");
Loading history...
234
        synapse()->rivescript->say("Asked to reply to [{$user}] {$msg}");
235
236
237
        $input = new Input($msg, $user);
238
        $output = new Output();
239
240
        synapse()->input = $input;
241
242
        $output = $output->process();
243
244
        synapse()->memory->inputs()->push($msg);
245
        synapse()->memory->replies()->push($output);
246
247
        return $output;
248
    }
249
}
250