Skip to content

Commit

Permalink
Merge pull request #26 from SergiX44/develop
Browse files Browse the repository at this point in the history
Fallback fixes
  • Loading branch information
cheeghi committed Jan 1, 2021
2 parents f41b309 + 8518bf1 commit 56845bd
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 52 deletions.
7 changes: 7 additions & 0 deletions src/Zanzara/Context.php
Expand Up @@ -488,4 +488,11 @@ public function getLoop(): LoopInterface
return $this->container->get(LoopInterface::class);
}

/**
* @return bool
*/
public function isCallbackQuery(): bool
{
return $this->getCallbackQuery() !== null;
}
}
7 changes: 1 addition & 6 deletions src/Zanzara/Listener/ListenerCollector.php
Expand Up @@ -56,11 +56,6 @@ abstract class ListenerCollector
*/
protected $listeners = [];

/**
* @var Listener
*/
protected $fallbackListener;

/**
* @var ContainerInterface
*/
Expand Down Expand Up @@ -437,7 +432,7 @@ public function onUpdate($callback): MiddlewareCollector
public function fallback($callback): MiddlewareCollector
{
$listener = new Listener($callback, $this->container);
$this->fallbackListener = $listener;
$this->listeners['fallback'] = $listener;
return $listener;
}

Expand Down
85 changes: 40 additions & 45 deletions src/Zanzara/Listener/ListenerResolver.php
Expand Up @@ -37,59 +37,51 @@ public function resolveListeners(Update $update): PromiseInterface
switch ($updateType) {

case CallbackQuery::class:
$chatId = $update->getEffectiveChat() ? $update->getEffectiveChat()->getId() : null;
$callbackQuery = $update->getCallbackQuery();
$text = $callbackQuery->getMessage() ? $callbackQuery->getMessage()->getText() : null;
if ($text) {
$this->findListenerAndPush($listeners, 'cb_query_texts', $text);
}
if ($callbackQuery->getData()) {
$this->findListenerAndPush($listeners, 'cb_query_data', $callbackQuery->getData());
}
$chatId = $update->getEffectiveChat() ? $update->getEffectiveChat()->getId() : null;
if ($chatId) {
$this->conversationManager->getConversationHandler($chatId)
->then(function ($handlerInfo) use ($deferred, &$listeners) {
if ($handlerInfo) {
$listeners[] = new Listener($handlerInfo[0], $this->container);
$this->conversationManager->getConversationHandler($chatId)
->then(function ($handlerInfo) use ($deferred, $callbackQuery, $text, &$listeners) {
if (!$handlerInfo) { // if we are not in a conversation, call the listeners as usual
if ($text) {
$this->findListenerAndPush($listeners, 'cb_query_texts', $text);
}
$deferred->resolve($listeners);
})->otherwise(function ($e) use ($deferred) {
// if something goes wrong, reject the promise
$deferred->reject($e);
});
} else {
$deferred->resolve($listeners);
}
if ($callbackQuery->getData()) {
$this->findListenerAndPush($listeners, 'cb_query_data', $callbackQuery->getData());
}
} else { // if we are in a conversation, redirect it only to the conversation step
$listeners[] = new Listener($handlerInfo[0], $this->container);
}
$deferred->resolve($listeners);
})->otherwise(function ($e) use ($deferred) {
// if something goes wrong, reject the promise
$deferred->reject($e);
});
break;

case Message::class:
$text = $update->getMessage()->getText();
$chatId = $update->getEffectiveChat()->getId();
$this->conversationManager->getConversationHandler($chatId)
->then(function ($handlerInfo) use ($chatId, $text, $deferred, &$listeners) {
if (!$handlerInfo) {
if ($text) {
$this->findListenerAndPush($listeners, 'messages', $text);
} elseif ($this->fallbackListener) {
$listeners[] = $this->fallbackListener;
}
$deferred->resolve($listeners);
return;
}

$skipListeners = $handlerInfo[1];

if (!$skipListeners && $text) {
$listener = $this->findListenerAndPush($listeners, 'messages', $text);
if (!$handlerInfo) { // if we are not in a conversation, call the listeners as usual
$this->findListenerAndPush($listeners, 'messages', $text);
} elseif (!$handlerInfo[1] && $text) {
// if we are in a conversation, and listeners are not skipped by the step call,
// try to call the matching listeners
$listener = $this->findListenerAndPush($listeners, 'messages', $text, true);
if (!$listener) {
// if no listeners are found, call the next conversation step
$listeners[] = new Listener($handlerInfo[0], $this->container);
} else {
// if listener is found, escape the conversation
$this->conversationManager->deleteConversationCache($chatId);
}
} else {
// if the coversation is forcing only the conversation handlers,
// skip the other listeners
$listeners[] = new Listener($handlerInfo[0], $this->container);
}

$deferred->resolve($listeners);
})->otherwise(function ($e) use ($deferred) {
// if something goes wrong, reject the promise
Expand All @@ -107,22 +99,25 @@ public function resolveListeners(Update $update): PromiseInterface
/**
* @param Listener[] $listeners
* @param string $listenerType
* @param string $listenerId
* @param string|null $listenerId
* @param bool $skipFallback
* @return Listener|null
*/
private function findListenerAndPush(array &$listeners, string $listenerType, string $listenerId): ?Listener
private function findListenerAndPush(array &$listeners, string $listenerType, ?string $listenerId = null, bool $skipFallback = false): ?Listener
{
$typedListeners = $this->listeners[$listenerType] ?? [];
foreach ($typedListeners as $regex => $listener) {
if (preg_match($regex, $listenerId)) {
$listeners[] = $listener;
return $listener;
if ($listenerId !== null) {
$typedListeners = $this->listeners[$listenerType] ?? [];
foreach ($typedListeners as $regex => $listener) {
if (preg_match($regex, $listenerId)) {
$listeners[] = $listener;
return $listener;
}
}
}

if ($this->fallbackListener !== null) {
$listeners[] = $this->fallbackListener;
return $this->fallbackListener;
if (isset($this->listeners['fallback']) && !$skipFallback) {
$listeners[] = $this->listeners['fallback'];
return $this->listeners['fallback'];
}

return null;
Expand Down
2 changes: 1 addition & 1 deletion tests/Listener/CallbackQueryTest.php
Expand Up @@ -99,9 +99,9 @@ public function testCbQueryByInlineQuery()
$this->assertSame('BAAAAHbYAAA4skAJl8HevRCfRb8', $cbQuery->getInlineMessageId());
$this->assertSame('777777777777777777', $cbQuery->getChatInstance());
$this->assertSame('ok', $cbQuery->getData());
$this->assertTrue($ctx->isCallbackQuery());
});

$bot->run();
}

}
19 changes: 19 additions & 0 deletions tests/Middleware/MiddlewareTest.php
Expand Up @@ -44,4 +44,23 @@ public function testMiddleware()
$bot->run();
}

public function testMiddlewareOnFallback()
{
$config = new Config();
$config->setUpdateMode(Config::WEBHOOK_MODE);
$config->setUpdateStream(__DIR__ . '/../update_types/command.json');
$bot = new Zanzara("test", $config);

$bot->middleware(function (Context $ctx, $next) {
$ctx->set('exec', true);
$next($ctx);
});

$bot->fallback(function (Context $ctx) {
$this->assertNotNull($ctx->get('exec'));
});

$bot->run();
}

}

0 comments on commit 56845bd

Please sign in to comment.