Files
max-bot-api-client-php/src/UpdateDispatcher.php
T
2025-08-08 22:51:35 +03:00

232 lines
6.5 KiB
PHP

<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot;
use BushlanovDev\MaxMessengerBot\Enums\UpdateType;
use BushlanovDev\MaxMessengerBot\Models\Updates\AbstractUpdate;
use BushlanovDev\MaxMessengerBot\Models\Updates\MessageCreatedUpdate;
/**
* Dispatches updates to registered handlers. Supports handling specific update types and text commands.
*/
final class UpdateDispatcher
{
/**
* @var array<string, callable>
*/
private array $handlers = [];
/**
* @var array<string, callable>
*/
private array $commandHandlers = [];
/**
* @param Api $api
*/
public function __construct(private readonly Api $api)
{
}
/**
* Registers a handler for a specific update type.
*
* @param UpdateType $type The type of update to handle.
* @param callable $handler The function to execute when the update is received.
*
* @return $this
*/
public function addHandler(UpdateType $type, callable $handler): self
{
$this->handlers[$type->value] = $handler;
return $this;
}
/**
* Registers a handler for a text command without a command prefix "/" (e.g., "start").
* The command must be the first word in a message.
*
* @param string $command The command string (e.g., "start").
* @param callable(MessageCreatedUpdate, Api): void $handler The handler to execute.
*
* @return $this
*/
public function onCommand(string $command, callable $handler): self
{
$this->commandHandlers[$command] = $handler;
return $this;
}
/**
* Dispatches a parsed Update object to its registered handler.
* Command handlers are prioritized over generic message handlers.
*
* @param AbstractUpdate $update The update object to dispatch.
*/
public function dispatch(AbstractUpdate $update): void
{
if ($update instanceof MessageCreatedUpdate && $update->message->body?->text) {
$text = $update->message->body->text;
$parts = explode(' ', trim($text));
$command = $parts[0];
if (isset($this->commandHandlers[$command])) {
$this->commandHandlers[$command]($update, $this->api);
return;
}
}
$handler = $this->handlers[$update->updateType->value] ?? null;
if ($handler) {
$handler($update, $this->api);
}
}
/**
* A convenient alias for addHandler(UpdateType::MessageCreated, $handler).
*
* @param callable(Models\Updates\MessageCreatedUpdate, Api): void $handler
*
* @return $this
* @codeCoverageIgnore
*/
public function onMessageCreated(callable $handler): self
{
return $this->addHandler(UpdateType::MessageCreated, $handler);
}
/**
* A convenient alias for addHandler(UpdateType::MessageCallback, $handler).
*
* @param callable(Models\Updates\MessageCallbackUpdate, Api): void $handler
*
* @return $this
* @codeCoverageIgnore
*/
public function onMessageCallback(callable $handler): self
{
return $this->addHandler(UpdateType::MessageCallback, $handler);
}
/**
* A convenient alias for addHandler(UpdateType::MessageEdited, $handler).
*
* @param callable(Models\Updates\MessageEditedUpdate, Api): void $handler
*
* @return $this
* @codeCoverageIgnore
*/
public function onMessageEdited(callable $handler): self
{
return $this->addHandler(UpdateType::MessageEdited, $handler);
}
/**
* A convenient alias for addHandler(UpdateType::MessageRemoved, $handler).
*
* @param callable(Models\Updates\MessageRemovedUpdate, Api): void $handler
*
* @return $this
* @codeCoverageIgnore
*/
public function onMessageRemoved(callable $handler): self
{
return $this->addHandler(UpdateType::MessageRemoved, $handler);
}
/**
* A convenient alias for addHandler(UpdateType::BotAdded, $handler).
*
* @param callable(Models\Updates\BotAddedToChatUpdate, Api): void $handler
*
* @return $this
* @codeCoverageIgnore
*/
public function onBotAdded(callable $handler): self
{
return $this->addHandler(UpdateType::BotAdded, $handler);
}
/**
* A convenient alias for addHandler(UpdateType::BotRemoved, $handler).
*
* @param callable(Models\Updates\BotRemovedFromChatUpdate, Api): void $handler
*
* @return $this
* @codeCoverageIgnore
*/
public function onBotRemoved(callable $handler): self
{
return $this->addHandler(UpdateType::BotRemoved, $handler);
}
/**
* A convenient alias for addHandler(UpdateType::UserAdded, $handler).
*
* @param callable(Models\Updates\UserAddedToChatUpdate, Api): void $handler
*
* @return $this
* @codeCoverageIgnore
*/
public function onUserAdded(callable $handler): self
{
return $this->addHandler(UpdateType::UserAdded, $handler);
}
/**
* A convenient alias for addHandler(UpdateType::UserRemoved, $handler).
*
* @param callable(Models\Updates\UserRemovedFromChatUpdate, Api): void $handler
*
* @return $this
* @codeCoverageIgnore
*/
public function onUserRemoved(callable $handler): self
{
return $this->addHandler(UpdateType::UserRemoved, $handler);
}
/**
* A convenient alias for addHandler(UpdateType::BotStarted, $handler).
*
* @param callable(Models\Updates\BotStartedUpdate, Api): void $handler
*
* @return $this
* @codeCoverageIgnore
*/
public function onBotStarted(callable $handler): self
{
return $this->addHandler(UpdateType::BotStarted, $handler);
}
/**
* A convenient alias for addHandler(UpdateType::ChatTitleChanged, $handler).
*
* @param callable(Models\Updates\ChatTitleChangedUpdate, Api): void $handler
*
* @return $this
* @codeCoverageIgnore
*/
public function onChatTitleChanged(callable $handler): self
{
return $this->addHandler(UpdateType::ChatTitleChanged, $handler);
}
/**
* A convenient alias for addHandler(UpdateType::MessageChatCreated, $handler).
*
* @param callable(Models\Updates\MessageChatCreatedUpdate, Api): void $handler
*
* @return $this
* @codeCoverageIgnore
*/
public function onMessageChatCreated(callable $handler): self
{
return $this->addHandler(UpdateType::MessageChatCreated, $handler);
}
}