1
|
|
|
<?php |
2
|
|
|
namespace Posibrain; |
3
|
|
|
|
4
|
|
|
use Monolog\Logger; |
5
|
|
|
use Monolog\Handler\StreamHandler; |
6
|
|
|
use Posibrain\OutputDecorationEnum; |
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* |
10
|
|
|
* @author Fylhan (http://fylhan.la-bnbox.fr) |
11
|
|
|
* @license LGPL-2.1+ |
12
|
|
|
*/ |
13
|
|
|
class TchatBotIdentity |
14
|
|
|
{ |
15
|
|
|
|
16
|
|
|
private static $logger = NULL; |
17
|
|
|
|
18
|
|
|
private $id; |
19
|
|
|
|
20
|
|
|
private $lang; |
21
|
|
|
|
22
|
|
|
private $name; |
23
|
|
|
|
24
|
|
|
private $pseudo; |
25
|
|
|
|
26
|
|
|
private $avatar; |
27
|
|
|
|
28
|
|
|
private $conceptorName; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* |
32
|
|
|
* @var \DateTime |
33
|
|
|
*/ |
34
|
|
|
private $birthday; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* |
38
|
|
|
* @var \DateTimeZone |
39
|
|
|
*/ |
40
|
|
|
private $timezone; |
41
|
|
|
|
42
|
|
|
private $charset; |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* |
46
|
|
|
* @see \Posibrain\OutputDecorationEnum |
47
|
|
|
*/ |
48
|
|
|
private $outputDecoration; |
49
|
|
|
|
50
|
|
|
private $triggers; |
51
|
|
|
|
52
|
|
|
private $positrons; |
53
|
|
|
|
54
|
|
|
private $instinctPath; |
55
|
|
|
private $memoryPath; |
56
|
|
|
|
57
|
|
|
public function __construct($id = '', $lang = '', $params = array()) |
58
|
|
|
{ |
59
|
|
|
// Logger |
60
|
|
View Code Duplication |
if (NULL == self::$logger) { |
|
|
|
|
61
|
|
|
self::$logger = new Logger(__CLASS__); |
62
|
|
|
if (! empty($params) && isset($params['loggerHandler'])) { |
63
|
|
|
self::$logger->pushHandler($params['loggerHandler']); |
64
|
|
|
} |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
if (key_exists('instinctPath', $params)) { |
68
|
|
|
$this->instinctPath = $params['instinctPath']; |
69
|
|
|
} |
70
|
|
|
if (key_exists('memoryPath', $params)) { |
71
|
|
|
$this->memoryPath = $params['memoryPath']; |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
// Default bot configuration |
75
|
|
|
$defaultConfig = array( |
76
|
|
|
'id' => 'sammy', |
77
|
|
|
'lang' => 'fr', |
78
|
|
|
'instinctPath' => ((! empty($params) && isset($params['instinctPath'])) ? $params['instinctPath'] : __DIR__ . '/../../app/brains/'), |
79
|
|
|
'memoryPath' => ((! empty($params) && isset($params['memoryPath'])) ? $params['memoryPath'] : __DIR__ . '/../../app/memories/'), |
80
|
|
|
'charset' => 'UTF-8' |
81
|
|
|
); |
82
|
|
|
|
83
|
|
|
// Configure the bot |
84
|
|
|
$this->id = ! empty($id) ? $id : $defaultConfig['id']; |
85
|
|
|
$this->lang = ! empty($lang) ? $lang : $defaultConfig['lang']; |
86
|
|
|
$this->instinctPath = ! empty($params['instinctPath']) ? $params['instinctPath'] : $defaultConfig['instinctPath']; |
87
|
|
|
$this->instinctPath .= ! endsWith('/', $this->instinctPath) ? '/' : ''; |
88
|
|
|
$this->memoryPath = ! empty($params['memoryPath']) ? $params['memoryPath'] : $defaultConfig['memoryPath']; |
89
|
|
|
$this->memoryPath .= ! endsWith('/', $this->memoryPath) ? '/' : ''; |
90
|
|
|
$this->setCharset(isset($params['charset']) ? $params['charset'] : $defaultConfig['charset']); |
91
|
|
|
$this->birthday = new \DateTime(); |
92
|
|
|
$this->outputDecoration = OutputDecorationEnum::Html; |
93
|
|
|
|
94
|
|
|
if (! $this->loadIdentity($this->getIdentityPath())) { |
95
|
|
|
self::$logger->addAlert('No such bot: this conversation will be very stupid...', array( |
96
|
|
|
$id, |
97
|
|
|
$lang, |
98
|
|
|
$params |
99
|
|
|
)); |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
if (key_exists('name', $params)) { |
103
|
|
|
$this->name = $params['name']; |
104
|
|
|
} |
105
|
|
|
if (key_exists('pseudo', $params)) { |
106
|
|
|
$this->pseudo = $params['pseudo']; |
107
|
|
|
} |
108
|
|
|
if (key_exists('avatar', $params)) { |
109
|
|
|
$this->avatar = $params['avatar']; |
110
|
|
|
} |
111
|
|
|
if (key_exists('conceptorName', $params)) { |
112
|
|
|
$this->conceptorName = $params['conceptorName']; |
113
|
|
|
} |
114
|
|
|
if (key_exists('birthday', $params)) { |
115
|
|
|
$this->setBirthday($params['birthday']); |
116
|
|
|
} |
117
|
|
|
if (key_exists('timezone', $params)) { |
118
|
|
|
$this->setTimezone($params['timezone']); |
119
|
|
|
} |
120
|
|
|
if (key_exists('charset', $params)) { |
121
|
|
|
$this->charset = $params['charset']; |
122
|
|
|
} |
123
|
|
|
if (key_exists('outputDecoration', $params)) { |
124
|
|
|
$this->outputDecoration = $params['outputDecoration']; |
125
|
|
|
} |
126
|
|
|
if (key_exists('triggers', $params)) { |
127
|
|
|
$this->triggers = $params['triggers']; |
128
|
|
|
} |
129
|
|
|
if (key_exists('positrons', $params)) { |
130
|
|
|
$this->positrons = $params['positrons']; |
131
|
|
|
} |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
public function getIdentityPath() |
135
|
|
|
{ |
136
|
|
|
return $this->instinctPath . $this->id . '/identity.json'; |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
private function loadIdentity($identityPath) |
140
|
|
|
{ |
141
|
|
|
if (! is_file($identityPath)) { |
142
|
|
|
return false; |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
$identity = loadJsonFile($identityPath); |
146
|
|
|
if (key_exists('name', $identity)) { |
147
|
|
|
$this->name = $identity->name; |
148
|
|
|
} |
149
|
|
|
if (key_exists('pseudo', $identity)) { |
150
|
|
|
$this->pseudo = $identity->pseudo; |
151
|
|
|
} |
152
|
|
|
if (key_exists('avatar', $identity)) { |
153
|
|
|
$this->avatar = $identity->avatar; |
154
|
|
|
} |
155
|
|
|
if (key_exists('conceptorName', $identity)) { |
156
|
|
|
$this->conceptorName = $identity->conceptorName; |
157
|
|
|
} |
158
|
|
|
if (key_exists('birthday', $identity)) { |
159
|
|
|
$this->setBirthday($identity->birthday); |
160
|
|
|
} |
161
|
|
|
if (key_exists('timezone', $identity)) { |
162
|
|
|
$this->setTimezone($identity->timezone); |
163
|
|
|
} |
164
|
|
|
if (key_exists('charset', $identity)) { |
165
|
|
|
$this->charset = $identity->charset; |
166
|
|
|
} |
167
|
|
|
if (key_exists('outputDecoration', $identity)) { |
168
|
|
|
$this->outputDecoration = $identity->outputDecoration; |
169
|
|
|
} |
170
|
|
|
if (key_exists('triggers', $identity)) { |
171
|
|
|
$this->triggers = $identity->triggers; |
172
|
|
|
} |
173
|
|
|
if (key_exists('positrons', $identity)) { |
174
|
|
|
$this->positrons = $identity->positrons; |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
return true; |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
public function getSynonymsPath() |
181
|
|
|
{ |
182
|
|
|
return $this->instinctPath . $this->id . '/' . $this->lang . '_synonyms.json'; |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
public function getKnowledgePath() |
186
|
|
|
{ |
187
|
|
|
return $this->instinctPath . $this->id . '/' . $this->lang . '_knowledge.json'; |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
public function getComputedKnowledgePath() |
191
|
|
|
{ |
192
|
|
|
return $this->memoryPath . $this->id . '/' . $this->lang . '_knowledge_computed.json'; |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
public function getNoKnowledgePath() |
196
|
|
|
{ |
197
|
|
|
return __DIR__ . '/brains/no-knowledge.json'; |
198
|
|
|
} |
199
|
|
|
|
200
|
|
|
/* Getter / Setter */ |
201
|
|
|
public function getId() |
202
|
|
|
{ |
203
|
|
|
return $this->id; |
204
|
|
|
} |
205
|
|
|
|
206
|
|
|
public function setId($id) |
207
|
|
|
{ |
208
|
|
|
$this->id = $id; |
209
|
|
|
} |
210
|
|
|
|
211
|
|
|
public function getLang() |
212
|
|
|
{ |
213
|
|
|
return $this->lang; |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
public function setLang($lang) |
217
|
|
|
{ |
218
|
|
|
$this->lang = $lang; |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
public function getInstinctPath() |
222
|
|
|
{ |
223
|
|
|
return $this->instinctPath; |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
public function setInstinctPath($instinctPath) |
227
|
|
|
{ |
228
|
|
|
$this->instinctPath = $instinctPath; |
229
|
|
|
} |
230
|
|
|
|
231
|
|
|
public function getCharset() |
232
|
|
|
{ |
233
|
|
|
return $this->charset; |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
public function setCharset($charset) |
237
|
|
|
{ |
238
|
|
|
$this->charset = $charset; |
239
|
|
|
// Manage everything internally as UTF-8 |
240
|
|
|
// Bot files, and bot output can have a different charset |
241
|
|
|
// Conversion is done when files are loaded |
242
|
|
|
// and when bot reply is returned |
243
|
|
|
mb_internal_encoding('UTF-8'); |
244
|
|
|
} |
245
|
|
|
|
246
|
|
|
public function getName() |
247
|
|
|
{ |
248
|
|
|
return $this->name; |
249
|
|
|
} |
250
|
|
|
|
251
|
|
|
public function setName($name) |
252
|
|
|
{ |
253
|
|
|
$this->name = $name; |
254
|
|
|
return $this; |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
public function getPseudo() |
258
|
|
|
{ |
259
|
|
|
return $this->pseudo; |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
public function setPseudo($pseudo) |
263
|
|
|
{ |
264
|
|
|
$this->pseudo = $pseudo; |
265
|
|
|
return $this; |
266
|
|
|
} |
267
|
|
|
|
268
|
|
|
public function getAvatar() |
269
|
|
|
{ |
270
|
|
|
return $this->avatar; |
271
|
|
|
} |
272
|
|
|
|
273
|
|
|
public function setAvatar($avatar) |
274
|
|
|
{ |
275
|
|
|
$this->avatar = $avatar; |
276
|
|
|
return $this; |
277
|
|
|
} |
278
|
|
|
|
279
|
|
|
public function getConceptorName() |
280
|
|
|
{ |
281
|
|
|
return $this->conceptorName; |
282
|
|
|
} |
283
|
|
|
|
284
|
|
|
public function setConceptorName($conceptorName) |
285
|
|
|
{ |
286
|
|
|
$this->conceptorName = $conceptorName; |
287
|
|
|
return $this; |
288
|
|
|
} |
289
|
|
|
|
290
|
|
|
/** |
291
|
|
|
* |
292
|
|
|
* @return DateTime |
293
|
|
|
*/ |
294
|
|
|
public function getBirthday() |
295
|
|
|
{ |
296
|
|
|
return $this->birthday; |
297
|
|
|
} |
298
|
|
|
|
299
|
|
|
public function setBirthday($birthday) |
300
|
|
|
{ |
301
|
|
|
if (! ($birthday instanceof \DateTime)) { |
302
|
|
|
$birthday = \DateTime::createFromFormat('Y-m-d', $birthday); |
303
|
|
|
} |
304
|
|
|
$this->birthday = $birthday; |
305
|
|
|
return $this; |
306
|
|
|
} |
307
|
|
|
|
308
|
|
|
/** |
309
|
|
|
* |
310
|
|
|
* @return DateTimeZone |
311
|
|
|
*/ |
312
|
|
|
public function getTimezone() |
313
|
|
|
{ |
314
|
|
|
return $this->timezone; |
315
|
|
|
} |
316
|
|
|
|
317
|
|
|
public function setTimezone($timezone) |
318
|
|
|
{ |
319
|
|
|
if (! ($timezone instanceof \DateTimeZone)) { |
320
|
|
|
try { |
321
|
|
|
$timezone = new \DateTimeZone($timezone); |
322
|
|
|
} catch (Exception $e) { |
|
|
|
|
323
|
|
|
$timezone = new \DateTimeZone('Europe/Paris'); |
324
|
|
|
} |
325
|
|
|
} |
326
|
|
|
$this->timezone = $timezone; |
327
|
|
|
return $this; |
328
|
|
|
} |
329
|
|
|
|
330
|
|
|
public function getOutputDecoration() |
331
|
|
|
{ |
332
|
|
|
return $this->outputDecoration; |
333
|
|
|
} |
334
|
|
|
|
335
|
|
|
public function setOutputDecoration($outputDecoration) |
336
|
|
|
{ |
337
|
|
|
$this->outputDecoration = $outputDecoration; |
338
|
|
|
return $this; |
339
|
|
|
} |
340
|
|
|
|
341
|
|
|
public function getTriggers() |
342
|
|
|
{ |
343
|
|
|
return $this->triggers; |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
public function setTriggers($triggers) |
347
|
|
|
{ |
348
|
|
|
$this->triggers = $triggers; |
349
|
|
|
return $this; |
350
|
|
|
} |
351
|
|
|
|
352
|
|
|
public function getPositrons() |
353
|
|
|
{ |
354
|
|
|
return $this->positrons; |
355
|
|
|
} |
356
|
|
|
|
357
|
|
|
public function setPositrons($positrons) |
358
|
|
|
{ |
359
|
|
|
$this->positrons = $positrons; |
360
|
|
|
return $this; |
361
|
|
|
} |
362
|
|
|
|
363
|
|
|
public function getMemoryPath() |
364
|
|
|
{ |
365
|
|
|
return $this->memoryPath; |
366
|
|
|
} |
367
|
|
|
|
368
|
|
|
public function setMemoryPath($memoryPath) |
369
|
|
|
{ |
370
|
|
|
$this->memoryPath = $memoryPath; |
371
|
|
|
return $this; |
372
|
|
|
} |
373
|
|
|
|
374
|
|
|
} |
375
|
|
|
|
376
|
|
|
|
377
|
|
|
|
378
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.