/common/components/telegram/Parser.php
https://gitlab.com/jafari/resana · PHP · 299 lines · 184 code · 34 blank · 81 comment · 16 complexity · 73c696c1fbff2b1165dc509cf92dc7eb MD5 · raw file
- <?php
- /**
- * @link http://www.noghteh.ir/
- * @copyright Copyright (c) 2015 Noghteh
- * @license http://www.noghteh.ir/license/
- */
- namespace common\components\telegram;
- use Yii;
- use yii\base\Model;
- use airani\telegram\TelegramBot;
- use common\models\ChannelMember;
- use common\models\Chat as ChatModel;
- use common\components\telegram\types\Chat;
- use common\components\telegram\types\Update;
- /**
- * TelegramParser
- * Parse telegram requests
- *
- * @property array $commandPatterns
- * @property array $commands
- * @property \common\models\Bot $bot
- * @property Update $update
- * @property ChannelMember $channelMember
- * @property ChatModel $chatModel
- *
- * @author Ali Irani <ali@irani.im>
- */
- class Parser extends Model
- {
- public $bot;
- private $_update;
- private $_commands;
- /**
- * Set data cache
- * @param $key
- * @param $value
- * @param int $duration
- * @param null $dependency
- * @return bool
- */
- public function cacheSet($key, $value, $duration = 60, $dependency = null)
- {
- return Yii::$app->cache->set('telegram:' . $key, $value, $duration, $dependency);
- }
- /**
- * Returns data cache by key
- * @param $key
- * @return mixed
- */
- public function cacheGet($key)
- {
- return Yii::$app->cache->get('telegram:' . $key);
- }
- /**
- * Delete Cache
- * @param $key
- * @return mixed
- */
- public function cacheDelete($key)
- {
- return Yii::$app->cache->delete('telegram:' . $key);
- }
- public function getUpdate()
- {
- return $this->_update;
- }
- public function setUpdate($params)
- {
- $this->_update = new Update($params);
- }
- /**
- * Parse telegram request
- */
- public function parse()
- {
- $this->saveChat();
- if ($this->update->baseMessage->isLeftChat()) {
- $this->leftGroup();
- } elseif ($this->update->baseMessage->isNewChat()) {
- $this->activateChat();
- }
- $this->parseCommands();
- }
- /**
- * Returns chat model object
- * @return null|static
- */
- public function getChatModel()
- {
- $message = $this->update->baseMessage;
- $chatId = $message->migrate_to_chat_id ?: $message->chat->id;
- /** @var ChatModel $chat */
- if ($chatAttr = $this->cacheGet("chat:$chatId")) {
- $chat = new ChatModel($chatAttr);
- $chat->setOldAttributes($chatAttr);
- return $chat;
- }
- if ($chat = ChatModel::findOne(['chat_id' => $chatId])) {
- $this->cacheSet("chat:$chatId", $chat->attributes);
- }
- return $chat;
- }
- /**
- * Returns Channel Member model object
- * @return ChannelMember
- */
- public function getChannelMember()
- {
- $chatId = $this->update->baseMessage->chat->id;
- /** @var ChannelMember $channelMember */
- if ($channelMemberAttr = $this->cacheGet("channelMember:$chatId")) {
- $channelMember = new ChannelMember($channelMemberAttr);
- $channelMember->setOldAttributes($channelMemberAttr);
- return $channelMember;
- }
- $channelMember = ChannelMember::findOne([
- 'channel_id' => $this->bot->channel_id,
- 'member_id' => $this->chatModel->member_id
- ]);
- if ($channelMember) {
- $this->cacheSet("channelMember:$chatId", $channelMember->attributes);
- }
- return $channelMember;
- }
- /**
- * Save chat
- * @return bool
- */
- public function saveChat()
- {
- if (($chat = $this->chatModel) === null) {
- $message = $this->update->baseMessage;
- $chatId = $message->migrate_to_chat_id ?: $message->chat->id;
- $chat = new ChatModel([
- 'chat_id' => $chatId,
- 'name' => $message->chat->name,
- 'username' => $message->chat->username ?: '',
- 'type' => self::getChatTypesId()[$message->chat->type],
- ]);
- if ($chat->save() === false) {
- Yii::error(['message' => 'Save new chat failed.', 'errors' => $chat->errors], __METHOD__);
- return false;
- }
- }
- if (($this->channelMember) === null) {
- $channelMember = new ChannelMember([
- 'channel_id' => $this->bot->channel_id,
- 'member_id' => $chat->member_id,
- ]);
- if ($channelMember->save() === false) {
- Yii::error(['message' => 'Save new channel member failed.', 'errors' => $channelMember->errors], __METHOD__);
- return false;
- }
- }
- return true;
- }
- /**
- * Check message with available commands and execute appropriate command
- * @return bool
- */
- public function parseCommands()
- {
- $textWords = explode(' ', $this->update->baseMessage->text);
- if (empty($textWords)) {
- return false;
- }
- $text = $this->getResponseCommand() ?: strtolower($textWords[0]);
- $patterns = $this->commandPatterns;
- foreach ([$text, $this->update->baseMessage->text] as $pattern) {
- $commandIndex = array_search($pattern, $patterns, false);
- if ($commandIndex !== false) {
- $command = $this->getCommands()[$commandIndex];
- $command->run();
- return true;
- }
- }
- return false;
- }
- /**
- * Returns all available commands
- * @return array
- */
- public function getCommands()
- {
- if ($this->_commands) {
- return $this->_commands;
- }
- $path = Yii::getAlias('@common/components/telegram/commands');
- $namespace = '\common\components\telegram\commands';
- $files = glob($path.'/*.php');
- $commands = [];
- foreach ($files as $file) {
- if (preg_match('/.*\/([\w]+Command).php/', $file, $matches)) {
- $className = $namespace . '\\' . $matches[1];
- $commands[] = new $className(['bot' => $this->bot, 'update' => $this->update]);
- }
- }
-
- $this->_commands = $commands;
- return $commands;
- }
- /**
- * Returns patterns of available commands
- * @return array
- */
- public function getCommandPatterns()
- {
- $commands = $this->getCommands();
- if (count($commands) === 0) {
- return [];
- }
- $patterns = [];
- foreach ($commands as $command) {
- $patterns[] = $command->getPattern();
- }
-
- return $patterns;
- }
- /**
- * Returns response command if is set
- * @return mixed | null
- */
- public function getResponseCommand()
- {
- $response = Yii::$app->cache->get('reply:' . $this->update->baseMessage->chat->id);
- return isset($response['command']) ? $response['command'] : null;
- }
- /**
- * Change channel member status to the left group
- * @return bool
- */
- public function leftGroup()
- {
- if ($this->channelMember) {
- $chatId = $this->update->baseMessage->chat->id;
- $this->cacheDelete("channelMember:$chatId");
- return $this->channelMember->leftGroup() ? true : false;
- }
- return false;
- }
- /**
- * Change channel member status to active
- * @return bool
- */
- public function activateChat()
- {
- if ($this->channelMember) {
- $chatId = $this->update->baseMessage->chat->id;
- $this->cacheDelete("channelMember:$chatId");
- return $this->channelMember->activate() ? true : false;
- }
- return false;
- }
- /**
- * Returns types id of chat model
- * @return array
- */
- public static function getChatTypesId()
- {
- return [
- Chat::TYPE_CHANNEL => ChatModel::TYPE_CHANNEL,
- Chat::TYPE_PRIVATE => ChatModel::TYPE_USER,
- Chat::TYPE_GROUP => ChatModel::TYPE_GROUP,
- Chat::TYPE_SUPER_GROUP => ChatModel::TYPE_SUPER_GROUP,
- ];
- }
- }