15
15
defined ('TB_BASE_COMMANDS_PATH ' ) || define ('TB_BASE_COMMANDS_PATH ' , TB_BASE_PATH . '/Commands ' );
16
16
17
17
use Exception ;
18
+ use InvalidArgumentException ;
18
19
use Longman \TelegramBot \Commands \AdminCommand ;
19
20
use Longman \TelegramBot \Commands \Command ;
20
21
use Longman \TelegramBot \Commands \SystemCommand ;
29
30
30
31
class Telegram
31
32
{
33
+ /**
34
+ * Auth name for user commands
35
+ */
36
+ const AUTH_USER = 'User ' ;
37
+ /**
38
+ * Auth name tof system commands
39
+ */
40
+ const AUTH_SYSTEM = 'System ' ;
41
+ /**
42
+ * Auth name for admin commands
43
+ */
44
+ const AUTH_ADMIN = 'Admin ' ;
45
+
32
46
/**
33
47
* Version
34
48
*
@@ -71,6 +85,25 @@ class Telegram
71
85
*/
72
86
protected $ commands_paths = [];
73
87
88
+ /**
89
+ * Custom commands class names
90
+ * ```
91
+ * [
92
+ * 'User' => [
93
+ * //commandName => className
94
+ * 'start' => 'name\space\to\StartCommand',
95
+ * ],
96
+ * 'Admin' => [], //etc
97
+ * ]
98
+ * ```
99
+ * @var array
100
+ */
101
+ protected $ commandsClasses = [
102
+ self ::AUTH_USER => [],
103
+ self ::AUTH_ADMIN => [],
104
+ self ::AUTH_SYSTEM => [],
105
+ ];
106
+
74
107
/**
75
108
* Custom commands objects
76
109
*
@@ -283,6 +316,29 @@ public function getCommandsList(): array
283
316
return $ commands ;
284
317
}
285
318
319
+ /**
320
+ * Get classname of predefined commands
321
+ * @see commandsClasses
322
+ * @param string $auth Auth of command
323
+ * @param string $command Command name
324
+ *
325
+ * @return string|null
326
+ */
327
+ public function getCommandClassName (string $ auth , string $ command ): ?string
328
+ {
329
+ $ command = mb_strtolower ($ command );
330
+ $ auth = $ this ->ucFirstUnicode ($ auth );
331
+
332
+ if (!empty ($ this ->commandsClasses [$ auth ][$ command ])) {
333
+ $ className = $ this ->commandsClasses [$ auth ][$ command ];
334
+ if (class_exists ($ className )){
335
+ return $ className ;
336
+ }
337
+ }
338
+
339
+ return null ;
340
+ }
341
+
286
342
/**
287
343
* Get an object instance of the passed command
288
344
*
@@ -297,35 +353,39 @@ public function getCommandObject(string $command, string $filepath = ''): ?Comma
297
353
return $ this ->commands_objects [$ command ];
298
354
}
299
355
300
- $ which = ['System ' ];
301
- $ this ->isAdmin () && $ which [] = 'Admin ' ;
302
- $ which [] = 'User ' ;
303
-
304
- foreach ($ which as $ auth ) {
305
- if ($ filepath ) {
306
- $ command_namespace = $ this ->getFileNamespace ($ filepath );
307
- } else {
308
- $ command_namespace = __NAMESPACE__ . '\\Commands \\' . $ auth . 'Commands ' ;
356
+ $ which = [self ::AUTH_SYSTEM ];
357
+ $ this ->isAdmin () && $ which [] = self ::AUTH_ADMIN ;
358
+ $ which [] = self ::AUTH_USER ;
359
+
360
+ foreach ($ which as $ auth )
361
+ {
362
+ if (!($ command_class = $ this ->getCommandClassName ($ auth , $ command )))
363
+ {
364
+ if ($ filepath ) {
365
+ $ command_namespace = $ this ->getFileNamespace ($ filepath );
366
+ } else {
367
+ $ command_namespace = __NAMESPACE__ . '\\Commands \\' . $ auth . 'Commands ' ;
368
+ }
369
+ $ command_class = $ command_namespace . '\\' . $ this ->ucFirstUnicode ($ command ) . 'Command ' ;
309
370
}
310
- $ command_class = $ command_namespace . '\\' . $ this ->ucFirstUnicode ($ command ) . 'Command ' ;
311
371
312
372
if (class_exists ($ command_class )) {
313
373
$ command_obj = new $ command_class ($ this , $ this ->update );
314
374
315
375
switch ($ auth ) {
316
- case ' System ' :
376
+ case self :: AUTH_SYSTEM :
317
377
if ($ command_obj instanceof SystemCommand) {
318
378
return $ command_obj ;
319
379
}
320
380
break ;
321
381
322
- case ' Admin ' :
382
+ case self :: AUTH_ADMIN :
323
383
if ($ command_obj instanceof AdminCommand) {
324
384
return $ command_obj ;
325
385
}
326
386
break ;
327
387
328
- case ' User ' :
388
+ case self :: AUTH_USER :
329
389
if ($ command_obj instanceof UserCommand) {
330
390
return $ command_obj ;
331
391
}
@@ -347,7 +407,7 @@ public function getCommandObject(string $command, string $filepath = ''): ?Comma
347
407
protected function getFileNamespace (string $ src ): ?string
348
408
{
349
409
$ content = file_get_contents ($ src );
350
- if (preg_match ('#^namespace\s+(.+?);#m ' , $ content , $ m )) {
410
+ if (preg_match ('#^\s+ namespace\s+(.+?);#m ' , $ content , $ m )) {
351
411
return $ m [1 ];
352
412
}
353
413
@@ -732,6 +792,55 @@ public function isDbEnabled(): bool
732
792
return $ this ->mysql_enabled ;
733
793
}
734
794
795
+ /**
796
+ * Add a single custom commands class
797
+ *
798
+ * @param string $className Set full classname
799
+ * @return Telegram
800
+ */
801
+ public function addCommandsClass (string $ className ): Telegram
802
+ {
803
+ if (!$ className || !class_exists ($ className ))
804
+ {
805
+ $ error = 'Command class name: " ' . $ className . '" does not exist. ' ;
806
+ TelegramLog::error ($ error );
807
+ throw new InvalidArgumentException ($ error );
808
+ }
809
+
810
+ if (!is_array ($ this ->commandsClasses ))
811
+ {
812
+ $ this ->commandsClasses = [];
813
+ }
814
+
815
+ if (!is_a ($ className , Command::class, true )) {
816
+ $ error = 'Command class is not a base command class ' ;
817
+ TelegramLog::error ($ error );
818
+ throw new InvalidArgumentException ($ error );
819
+ }
820
+
821
+ $ commandObject = new $ className ($ this );
822
+
823
+ $ command = $ commandObject ->getName ();
824
+ $ auth = null ;
825
+ switch (true ) {
826
+ case $ commandObject ->isSystemCommand ():
827
+ $ auth = self ::AUTH_SYSTEM ;
828
+ break ;
829
+ case $ commandObject ->isAdminCommand ():
830
+ $ auth = self ::AUTH_ADMIN ;
831
+ break ;
832
+ case $ commandObject ->isUserCommand ():
833
+ $ auth = self ::AUTH_USER ;
834
+ break ;
835
+ }
836
+
837
+ if ($ auth ) {
838
+ $ this ->commandsClasses [$ auth ][$ command ] = $ className ;
839
+ }
840
+
841
+ return $ this ;
842
+ }
843
+
735
844
/**
736
845
* Add a single custom commands path
737
846
*
@@ -782,6 +891,16 @@ public function getCommandsPaths(): array
782
891
return $ this ->commands_paths ;
783
892
}
784
893
894
+ /**
895
+ * Return the list of commands classes
896
+ *
897
+ * @return array
898
+ */
899
+ public function getCommandsClasses (): array
900
+ {
901
+ return $ this ->commandsClasses ;
902
+ }
903
+
785
904
/**
786
905
* Set custom upload path
787
906
*
0 commit comments