diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..fd4c8b8 --- /dev/null +++ b/composer.json @@ -0,0 +1,45 @@ +{ + "name": "mirzaev/vk-chat", + "description": "Module for mirzaev/vk framework to build a chat robot", + "readme": "README.md", + "keywords": [ + "chat", + "vk", + "module" + ], + "type": "vk-module", + "license": "WTFPL", + "homepage": "https://git.mirzaev.sexy/mirzaev/vk-chat", + "authors": [ + { + "name": "Arsen Mirzaev Tatyano-Muradovich", + "email": "arsen@mirzaev.sexy", + "homepage": "https://mirzaev.sexy", + "role": "Programmer" + } + ], + "support": { + "email": "arsen@mirzaev.sexy", + "wiki": "https://git.mirzaev.sexy/mirzaev/vk-chat/wiki", + "issues": "https://git.mirzaev.sexy/mirzaev/vk-chat/issues" + }, + "funding": [ + { + "type": "funding", + "url": "https://fund.mirzaev.sexy" + } + ], + "require": { + "php": "^8.1" + }, + "autoload": { + "psr-4": { + "mirzaev\\vk\\chat\\": "mirzaev/vk/chat/system" + } + }, + "autoload-dev": { + "psr-4": { + "mirzaev\\vk\\chat\\tests\\": "mirzaev/vk/chat/tests" + } + } +} diff --git a/mirzaev/vk/chat/system/command.php b/mirzaev/vk/chat/system/command.php new file mode 100644 index 0000000..4bf4316 --- /dev/null +++ b/mirzaev/vk/chat/system/command.php @@ -0,0 +1,56 @@ + + */ +class command +{ + /** + * Конструктор + * + * @param callable $program Программа выполняемая командой + * @param array $accounts Реестр аккаунтов которым разрешено выполнять команду + */ + public function __construct( + public Closure $program, + public array $accounts + ) { + } + + /** + * Проверить наличие доступа к команде + * + * @param int $id Идентификатор аккаунта + * + * @return bool Имеет ли аккаунт доступ к команде? + */ + public function access(int $id): bool + { + // Перебор реестра аккаунтов + foreach ($this->accounts as $account) if ($account === $id) return true; + + return false; + } + + /** + * Выполнить команду + * + * @param string ...$parameters Параметры команды + * + * @return bool + */ + public function execute(string ...$parameters): bool + { + return ($this->program)(...$parameters); + } +} diff --git a/mirzaev/vk/chat/system/core.php b/mirzaev/vk/chat/system/core.php new file mode 100644 index 0000000..8ddf0e1 --- /dev/null +++ b/mirzaev/vk/chat/system/core.php @@ -0,0 +1,91 @@ + + */ +class core +{ + /** + * @var string|null $prefix Префикс + */ + protected ?string $prefix; + + /** + * @var array $patterns Реестр шаблонов + */ + protected array $patterns = []; + + /** + * Записать шаблон в реестр + * + * @param string|pattern $pattern Текст или инстанция шаблона + * @param command ...$commands Команды + * + * @return pattern Инстанция шаблона + */ + public function pattern(string|pattern $pattern, command ...$commands): pattern + { + // Инициализация шаблона + if (is_string($pattern)) $pattern = new pattern($pattern); + + foreach ($commands as $command) { + // Перебор команд + + // Подключение команд к шаблону + $pattern->command($command); + } + + // Запись в реестр + $this->patterns .= [$pattern]; + + return $pattern; + } + + /** + * Обработать сообщение + * + * Проверяет наличие совпадений с шаблонами, после чего проверяет + * все связанные с шаблоном команды и выполняет при совпадении + * + * @param array $update Событие + * + * @return bool Статус сохранения + */ + public function handle(array $update): bool + { + // Инициализация текста + $text = $update['object']['message']['text']; + + // Проверка на наличие текста и на использование префикса + if (empty($text) or isset($this->prefix) && !str_starts_with($text, $this->prefix)) return false; + + foreach ($this->patterns as $pattern) { + // Перебор шаблонов + + // Инициализация буфера параметров + $parameters = []; + + if($pattern->check($text, $parameters)) { + // Пройдена проверка на совпадение с шаблоном + + // Выполнение команд связанных с шаблоном + $pattern->handle($update['object']['message']['from_id'], $parameters); + + return true; + } + } + + return false; + } +} diff --git a/mirzaev/vk/chat/system/pattern.php b/mirzaev/vk/chat/system/pattern.php new file mode 100644 index 0000000..cd2ef3e --- /dev/null +++ b/mirzaev/vk/chat/system/pattern.php @@ -0,0 +1,89 @@ + + */ +class pattern +{ + /** + * @var array $commands Команды + */ + protected array $commands = []; + + /** + * Конструктор + * + * @param string $text Текст + */ + public function __construct(public string $text) + { + } + + /** + * Записать команду в реестр + * + * @param command $command Инстанция команды + * + * @return static + */ + public function command(command $command): static + { + // Запись в реестр + $this->commands .= [$command]; + + return $this; + } + + /** + * Проверить текст на совпадение с шаблоном + * + * @param string $text Текст + * @param array &$parameters Буфер параметров для команды + * + * @return bool Текст совпадает с шаблоном? + */ + public function check(string $text, array &$parameters = []): bool + { + // Проверка на совпадение с шаблоном + preg_match_all($this->text, $text, $matches); + + // Простой шаблон + if (count($matches) === 1) return !empty($matches[0]); + + // Удаление первого значения (текст для проверки) + unset($matches[0]); + + // Сложный шаблон + foreach ($matches as $match) if (!empty($match[0])) $parameters []= $match[0]; else return false; + + return true; + } + + /** + * Обработать подключенные команды + * + * @param int $id Идентификатор аккаунта вызывающего выполнение + * @param string ...$parameters Параметры команды + * + * @return void + */ + public function handle(int $id, string ...$parameters): void + { + foreach ($this->commands as $command) { + // Перебор команд + + // Выполнение команды + if (!empty($command->accounts) && $command->access($id)) $command->execute(...$parameters); + } + } +}