Passed
Push — master ( d44e36...c2d6d5 )
by Johnny
02:21
created

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

301
    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...
302
    {
303
        synapse()->memory->global()->put('debug', true);
304
    }
305
306
    /**
307
     * Make the client respond to a message.
308
     *
309
     * @param string      $msg   The message the client has to process and respond to.
310
     * @param string      $user  The user id.
311
     * @param string|null $scope Not used at this point.
312
     *
313
     * @return string
314
     */
315
    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

315
    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...
316
    {
317
318
        // FIXME: Must be $user, $message, Sscope
319
        //    $msg = $this->stripNasties($msg, "");
320
        synapse()->rivescript->say("Asked to reply to :user :msg", ['user' => $user, 'msg' => $msg]);
321
322
323
        $input = new Input($msg, $user);
324
        $output = new Output();
325
326
        synapse()->input = $input;
327
328
        $output = $output->process();
329
330
        if (empty($output)) {
331
            $output = $this->errors['replyNotMatched'];
332
        }
333
334
        synapse()->memory->inputs()->push($msg);
335
        synapse()->memory->replies()->push($output);
336
337
        return $output;
338
    }
339
}
340