Passed
Push — master ( ce9550...f62ea3 )
by Johnny
02:15
created

Rivescript::isUtf8Enabled()   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
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
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;
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
Bug introduced by
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
    public $onWarn = null;
43
    public $onDebug = null;
44
45
    /**
46
     * A recursion limit before an attempt to
47
     * fetch a reply will be abandoned.
48
     *
49
     * @var int
50
     */
51
    public int $depth = 50;
52
53
    /**
54
     * Error messages.
55
     *
56
     * @var array|string[]
57
     */
58
    public array $errors = [
59
        "replyNotMatched" => "ERR: No Reply Matched",
60
        "replyNotFound" => "ERR: No Reply Found",
61
        "objectNotFound" => "[ERR: Object Not Found]",
62
        "deepRecursion" => "ERR: Deep Recursion Detected"
63
    ];
64
65
    /**
66
     * Flag to indicating if utf8
67
     * modes is enabled.
68
     *
69
     * @var bool
70
     */
71
    protected bool $utf8 = false;
72
73
    /**
74
     * Flag to indicate debug mode
75
     * is enabled or not.
76
     *
77
     * @var bool
78
     */
79
    public bool $debug = false;
80
81
    /**
82
     * This is the user identification.
83
     *
84
     * @var string
85
     */
86
    private string $client_id = 'local-user';
87
88
    /**
89
     * Create a new Rivescript instance.
90
     *
91
     * @throws \Axiom\Rivescript\Exceptions\ContentLoadingException
92
     */
93
    public function __construct()
94
    {
95
        parent::__construct();
96
97
        include __DIR__ . '/bootstrap.php';
98
99
        synapse()->brain->setMaster($this);
100
        synapse()->rivescript = $this;
101
102
//        $this->setClientId($this->client_id);
103
        $this->registerTags();
104
    }
105
106
    /**
107
     * Initialize the Tags
108
     *
109
     * @return void
110
     */
111
    private function registerTags(): void
112
    {
113
        synapse()->tags->each(
0 ignored issues
show
Bug Best Practice introduced by
The property tags does not exist on Axiom\Rivescript\Cortex\Synapse. Since you implemented __get, consider adding a @property annotation.
Loading history...
114
            function ($tag) {
115
                $class = "\\Axiom\\Rivescript\\Cortex\\Tags\\$tag";
116
                $tagInstance = new $class();
117
118
                $tagInfo = $tagInstance->getTagName();
119
                if (is_array($tagInfo)) {
120
                    foreach ($tagInfo as $tagName) {
121
                        synapse()->memory->tags()->put($tagName, $tagInstance);
122
                    }
123
                } else {
124
                    synapse()->memory->tags()->put($tagInfo, $tagInstance);
125
                }
126
            }
127
        );
128
    }
129
130
    /**
131
     * Load Rivescript interpretable content.
132
     * Into the Interpreter.
133
     *
134
     * Please note: This supports
135
     *
136
     * - Directory path to Rivescript interpretable files.
137
     * - Array of absolute paths to Rivescript interpretable files
138
     * - Absolute string containing path to Rivescript interpretable file.
139
     * - A stream of text with Rivescript interpretable script.
140
     *
141
     * Please note 2:
142
     *
143
     * If you profile a directory with rivescript documents make sure they are
144
     * all interpretable Rivescript will throw syntax errors while trying to
145
     * parse those files.
146
     *
147
     * @param array<string>|string $info The files to read
148
     *
149
     * @return void
150
     */
151
    public function load($info): void
152
    {
153
        parent::load($info);
154
        $this->processInformation();
155
    }
156
157
    /**
158
     * Stream new information into the brain.
159
     *
160
     * @param string $string The string of information to feed the brain.
161
     *
162
     * @return void
163
     */
164
    public function stream(string $string): void
165
    {
166
        fseek($this->getStream(), 0, SEEK_SET);
167
        rewind($this->getStream());
168
169
        $this->writeToMemory($string);
170
        $this->processInformation();
171
    }
172
173
    /**
174
     * Process new information in the
175
     * stream.
176
     *
177
     * @return void
178
     */
179
    private function processInformation(): void
180
    {
181
        synapse()->memory->local()->put('concat', 'none');
182
        synapse()->brain->teach($this->getStream());
183
    }
184
185
    /**
186
     * Set the client id.
187
     *
188
     * @param string $client_id The client id for this user.
189
     *
190
     * @return void
191
     */
192
    public function setClientId(string $client_id = 'local-user'): void
193
    {
194
        $this->client_id = $client_id;
195
    }
196
197
    /**
198
     * Return the client id.
199
     *
200
     * @return string
201
     */
202
    public function getClientId(): string
203
    {
204
        return $this->client_id;
205
    }
206
207
    /**
208
     * Set user variables.
209
     *
210
     * @param string $name  The name of the variable.
211
     * @param string $value The value of the variable.
212
     *
213
     * @return void
214
     */
215
    public function set_uservar(string $name, string $value): void
216
    {
217
        synapse()->memory->user($this->client_id)->put($name, $value);
218
    }
219
220
    /**
221
     * Get user variable.
222
     *
223
     * @param string $name The name of the variable.
224
     *
225
     * @return mixed
226
     */
227
    public function get_uservar(string $name)
228
    {
229
        return synapse()->memory->user($this->client_id)->get($name) ?? "undefined";
230
    }
231
232
    /**
233
     * Log a message to say.
234
     *
235
     * @param string $message   The message to print out.
236
     * @param array  $args      (format) arguments for the message.
237
     * @param int    $verbosity The verbosity level of the message.
238
     *
239
     * @return void
240
     */
241
    public function say(string $message, array $args = [], int $verbosity = Rivescript::VERBOSITY_NORMAL): void
242
    {
243
244
        $message = $this->formatString($message, $args);
245
246
        if ($this->onSay) {
247
            call_user_func($this->onSay, $message, $verbosity);
248
        }
249
    }
250
251
    /**
252
     * Write a debug message.
253
     *
254
     * @param string $message   The message to print out.
255
     * @param array  $args      (format) arguments for the message.
256
     * @param int    $verbosity The verbosity level of the message.
257
     *
258
     * @return void
259
     */
260
    public function warn(string $message, array $args = [], int $verbosity = Rivescript::VERBOSITY_DEBUG): void
261
    {
262
        $message = "[WARNING]: " . $this->formatString($message, $args);
263
264
        if ($this->onWarn) {
265
            call_user_func($this->onWarn, $message, $verbosity);
266
        }
267
    }
268
269
    /**
270
     * Write a warning.
271
     *
272
     * @param string $message   The message to print out.
273
     * @param array  $args      (format) arguments for the message.
274
     * @param int    $verbosity The verbosity level of the message.
275
     *
276
     * @return void
277
     */
278
    public function debug(string $message, array $args = [], int $verbosity = Rivescript::VERBOSITY_NORMAL): void
279
    {
280
        $message = "[DEBUG]: " . $this->formatString($message, $args);
281
282
        if ($this->onDebug) {
283
            call_user_func($this->onDebug, $message, $verbosity);
284
        }
285
    }
286
287
288
    /**
289
     * Create a string PDO style/
290
     *
291
     * @param string $msg  The message to write.
292
     * @param array  $args The arguments for the message.
293
     *
294
     * @return string
295
     */
296
    private function formatString(string $msg, array $args = []): string
297
    {
298
        $search = [];
299
        $replace = [];
300
301
        if (is_array($args) === true && count($args) > 0) {
302
            foreach ($args as $key => $value) {
303
                $search [] = ":{$key}";
304
                $replace [] = $value;
305
            }
306
307
            $msg = str_replace($search, $replace, $msg);
308
        }
309
310
        return $msg;
311
    }
312
313
    /**
314
     * Enable debug mode.
315
     *
316
     * @param bool $enabled Enable true/false.
317
     *
318
     * @return void
319
     */
320
    public function enableDebugMode(bool $enabled = true): void
0 ignored issues
show
Unused Code introduced by
The parameter $enabled 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

320
    public function enableDebugMode(/** @scrutinizer ignore-unused */ bool $enabled = true): void

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...
321
    {
322
        synapse()->memory->global()->put('debug', true);
323
    }
324
325
    public function utf8(bool $status = false)
326
    {
327
        $this->utf8 = $status;
328
    }
329
330
    public function isUtf8Enabled(): bool
331
    {
332
        return ($this->utf8 === true);
333
    }
334
335
    /**
336
     * Make the client respond to a message.
337
     *
338
     * @param string      $msg   The message the client has to process and respond to.
339
     * @param string      $user  The user id.
340
     * @param string|null $scope Not used at this point.
341
     *
342
     * @return string
343
     */
344
    public function reply(string $msg, string $user = 'local-user', string $scope = null): string
0 ignored issues
show
Unused Code introduced by
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

344
    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...
345
    {
346
347
        // FIXME: Must be $user, $message, Sscope
348
        //    $msg = $this->stripNasties($msg, "");
349
        synapse()->rivescript->say("Asked to reply to :user :msg", ['user' => $user, 'msg' => $msg]);
350
351
352
        $input = new Input($msg, $user);
353
        $output = new Output();
354
355
        synapse()->input = $input;
356
357
        $output = $output->process();
358
359
        if (empty($output)) {
360
            $output = $this->errors['replyNotMatched'];
361
        }
362
363
        synapse()->memory->inputs()->push($msg);
364
        synapse()->memory->replies()->push($output);
365
366
        return $output;
367
    }
368
}
369