Skip to content

Commit

Permalink
feat: enhance middleware to accept parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
Mateodioev committed Nov 10, 2024
1 parent 91df935 commit f77ed3f
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 6 deletions.
19 changes: 17 additions & 2 deletions examples/ButtonCallback.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class ButtonCallback extends CallbackCommand
protected string $name = 'button1';
protected string $description = 'Button 1 callback';
protected array $middlewares = [
EchoPayload::class,
EchoPayload::class . ':This is the example param',
];

public function execute(array $args = [])
Expand All @@ -38,14 +38,29 @@ public function execute(array $args = [])
}
}

/**
* This payload format the params sent in the callback query as
* Received new payload: "payload"
*/
class EchoPayload extends Middleware
{
public function __construct(private string $exampleParam = '')
{
}

/**
* @throws StopCommand Stop execution command if payload is empty
*/
public function __invoke(Context $ctx, Api $api, array $args = [])
{
var_dump('Old results: ', $args);
$ctx->logger?->debug(
message: 'Old results: {args}',
context: ['args' => json_encode($args)]
);
$ctx->logger?->debug(
message: 'Param passed to the middleware: {param}',
context: ['param' => $this->exampleParam]
);
$message = 'Received new payload: "%s"';

if (empty($ctx->getPayload())) {
Expand Down
37 changes: 34 additions & 3 deletions src/Events/abstractEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Closure;
use Mateodioev\Bots\Telegram\Api;
use Mateodioev\TgHandler\BotException;
use Mateodioev\TgHandler\Db\{DbInterface, PrefixDb};
use Mateodioev\TgHandler\Filters\{Filter, FilterCollection};
use Mateodioev\TgHandler\{Bot, Context, Middleware\ClosureMiddleware, Middleware\Middleware};
Expand All @@ -14,7 +15,12 @@
use ReflectionException;
use Revolt\EventLoop;

use Throwable;

use function Amp\delay;
use function class_exists;
use function explode;
use function is_callable;

abstract class abstractEvent implements EventInterface
{
Expand Down Expand Up @@ -171,12 +177,11 @@ public function middlewares(): array
$middlewares = [];
foreach ($this->middlewares as $i => $middleware) {
if ($middleware instanceof Closure) {
$middlewares[(string) $i] = ClosureMiddleware::create($middleware)
->withId($i);
$middlewares[(string) $i] = ClosureMiddleware::create($middleware)->withId($i);
continue;
}
if (is_string($middleware)) {
$middleware = new $middleware();
$middleware = $this->createMiddlewareFromString($middleware);
$middlewares[$middleware->name()] = $middleware;
continue;
}
Expand All @@ -192,6 +197,32 @@ public function middlewares(): array
return $this->middlewares;
}

private function createMiddlewareFromString(string $strMiddleware): Middleware
{
[$className, $parts] = explode(':', "$strMiddleware:"); // add ":" to avoid errors

$existsClass = class_exists($className);
if (!$existsClass && is_callable($className)) {
// Parts are not needed for closures
return ClosureMiddleware::create($className);
}
if ($existsClass === false) {
throw new BotException("Middleware class $className not found");
}

$parts = explode(',', $parts);

if (empty($parts)) {
return new $className();
}

try {
return new $className(...$parts);
} catch (Throwable $th) {
throw new BotException("Error creating middleware $className: " . $th->getMessage());
}
}

/**
* @throws ReflectionException
*/
Expand Down
38 changes: 37 additions & 1 deletion tests/Events/MiddlewareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use Mateodioev\Bots\Telegram\Api;
use Mateodioev\TgHandler\Context;
use Mateodioev\TgHandler\Events\Types\AllEvent;

use Mateodioev\TgHandler\Middleware\{ClosureMiddleware, Middleware};
use Monolog\Test\TestCase;

Expand Down Expand Up @@ -72,6 +71,23 @@ public function testGetEventMiddleware()
}
}

public function testMiddlewareWithParams()
{
$middleware = $this->createMiddlewareWithParams('param');
$this->assertIsString($middleware->name());
$this->assertEquals('param', $middleware->name());

$event = $this->createEvent();
$event->addMiddleware($middleware);

$this->assertNotEmpty($event->middlewares());
$this->assertEquals(1, count($event->middlewares()));
$this->assertIsArray($event->middlewares());

$this->assertIsString($event->middlewares()['param']->name());
$this->assertEquals('param', $event->middlewares()['param']->name());
}

private function createMiddleware()
{
return new class () extends Middleware {
Expand All @@ -96,4 +112,24 @@ public function execute(array $args = [])
}
};
}

private function createMiddlewareWithParams(string $param)
{
return new class ($param) extends Middleware {
public function __construct(
private string $param
) {
}

public function __invoke(Context $ctx, Api $api, array $args = [])
{
return $this->param;
}

public function name(): string
{
return $this->param; // Use the param passed
}
};
}
}

0 comments on commit f77ed3f

Please sign in to comment.