Skip to content

Commit

Permalink
Merge pull request #451 from nutgram/4.x_new_group_syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
sergix44 committed May 7, 2023
2 parents dec2336 + ceb9c05 commit 24667c4
Show file tree
Hide file tree
Showing 12 changed files with 343 additions and 130 deletions.
14 changes: 0 additions & 14 deletions src/Exception/CannotSerializeException.php

This file was deleted.

17 changes: 17 additions & 0 deletions src/Exception/StatusFinalizedException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace SergiX44\Nutgram\Exception;

use Exception;
use Throwable;

class StatusFinalizedException extends Exception
{
public function __construct(
string $message = 'No further handlers can be registered after finalisation.',
int $code = 0,
?Throwable $previous = null
) {
parent::__construct($message, $code, $previous);
}
}
90 changes: 35 additions & 55 deletions src/Handlers/CollectHandlers.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@

namespace SergiX44\Nutgram\Handlers;

use SergiX44\Nutgram\Exception\StatusFinalizedException;
use SergiX44\Nutgram\Handlers\Listeners\MessageListeners;
use SergiX44\Nutgram\Handlers\Listeners\UpdateListeners;
use SergiX44\Nutgram\Telegram\Properties\UpdateType;

abstract class CollectHandlers
{
use UpdateHandlers, MessageHandlers;
use UpdateListeners, MessageListeners;

protected const FALLBACK = 'FALLBACK';
protected const EXCEPTION = 'EXCEPTION';
Expand All @@ -28,109 +31,83 @@ abstract class CollectHandlers
/**
* @var array
*/
protected array $groupHandlers = [];
protected array $handlers = [];

/**
* @var array
* @var HandlerGroup[]
*/
protected array $groupMiddlewares = [];
protected array $groups = [];

/**
* @var array
*/
protected array $handlers = [];
protected array $groupHandlers = [];

/**
* @var bool
*/
protected bool $finalized = false;

/**
* @param callable|callable-string|array $callable
* @param callable|callable-string|array $callable
*/
public function middleware($callable): void
{
!$this->finalized ?: throw new StatusFinalizedException();
array_unshift($this->globalMiddlewares, $callable);
}

/**
* @param Array<callable|callable-string|array> $callable
* @param Array<callable|callable-string|array> $callable
*/
public function middlewares($callable): void
{
!$this->finalized ?: throw new StatusFinalizedException();
$middlewares = is_array($callable) ? $callable : [$callable];

foreach ($middlewares as $middleware) {
$this->middleware($middleware);
}
}

/**
* @param callable|callable-string|array $middlewares
* @param callable $closure
* @return void
*/
public function group($middlewares, callable $closure): void
public function group(callable $closure)
{
$middlewares = is_array($middlewares) ? array_reverse($middlewares) : [$middlewares];

// get the current group status
$beforeMyMiddlewares = $this->groupMiddlewares;
$beforeMyHandlers = $this->groupHandlers;

// reset the current group status
$this->groupHandlers = [];

// push new middlewares to the stack
$this->groupMiddlewares = [...$middlewares, ...$this->groupMiddlewares];

// get the current target
$previousTarget = $this->target;
$this->target = 'groupHandlers';
$closure($this);
// restore the parent target
$this->target = $previousTarget;

// apply the middleware stack to the current registered group handlers
array_walk_recursive($this->groupHandlers, function ($leaf) {
if ($leaf instanceof Handler) {
foreach ($this->groupMiddlewares as $middleware) {
$leaf->middleware($middleware);
}
}
});

// commit the handlers
$this->handlers = array_merge_recursive($this->handlers, $this->groupHandlers);

// restore the status of the parent group, if any
$this->groupMiddlewares = $beforeMyMiddlewares;
$this->groupHandlers = $beforeMyHandlers;
!$this->finalized ?: throw new StatusFinalizedException();
return $this->groups[] = new HandlerGroup($closure);
}

/**
* @param callable|string $callableOrException
* @param callable|null $callable
* @param callable|string $callableOrException
* @param callable|null $callable
* @return Handler
*/
public function onException($callableOrException, $callable = null): Handler
{
!$this->finalized ?: throw new StatusFinalizedException();
return $this->registerErrorHandlerFor(self::EXCEPTION, $callableOrException, $callable);
}

/**
* @param callable|string $callableOrPattern
* @param callable|null $callable
* @param callable|string $callableOrPattern
* @param callable|null $callable
* @return Handler
*/
public function onApiError($callableOrPattern, $callable = null): Handler
{
!$this->finalized ?: throw new StatusFinalizedException();
return $this->registerErrorHandlerFor(self::API_ERROR, $callableOrPattern, $callable);
}

/**
* @param string $type
* @param string $type
* @param $callableOrPattern
* @param $callable
* @return Handler
*/
private function registerErrorHandlerFor(string $type, $callableOrPattern, $callable = null): Handler
{
!$this->finalized ?: throw new StatusFinalizedException();

if ($callable !== null) {
return $this->{$this->target}[$type][$callableOrPattern] = new Handler($callable, $callableOrPattern);
}
Expand All @@ -148,18 +125,19 @@ public function fallback($callable): Handler
}

/**
* @param UpdateType $type
* @param UpdateType $type
* @param $callable
* @return Handler
*/
public function fallbackOn(UpdateType $type, $callable): Handler
{
!$this->finalized ?: throw new StatusFinalizedException();
return $this->{$this->target}[self::FALLBACK][$type->value] = new Handler($callable, $type->value);
}

/**
* @param bool $exception
* @param bool $apiError
* @param bool $exception
* @param bool $apiError
* @return void
*/
public function clearErrorHandlers(bool $exception = true, bool $apiError = true): void
Expand All @@ -179,6 +157,7 @@ public function clearErrorHandlers(bool $exception = true, bool $apiError = true
*/
public function beforeApiRequest($callable): Handler
{
!$this->finalized ?: throw new StatusFinalizedException();
return $this->{$this->target}[self::BEFORE_API_REQUEST] = (new Handler($callable))->skipGlobalMiddlewares();
}

Expand All @@ -188,6 +167,7 @@ public function beforeApiRequest($callable): Handler
*/
public function afterApiRequest($callable): Handler
{
!$this->finalized ?: throw new StatusFinalizedException();
return $this->{$this->target}[self::AFTER_API_REQUEST] = (new Handler($callable))->skipGlobalMiddlewares();
}
}
43 changes: 43 additions & 0 deletions src/Handlers/HandlerGroup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace SergiX44\Nutgram\Handlers;

use Closure;
use SergiX44\Nutgram\Telegram\Types\Command\BotCommandScope;

class HandlerGroup
{
protected array $middlewares = [];

protected array $scopes = [];

public function __construct(public Closure $groupCallable)
{
}

public function middleware(string|array|callable|object $callable): self
{
array_unshift($this->middlewares, $callable);
return $this;
}

public function scope(BotCommandScope|array $scope): self
{
if (!is_array($scope)) {
$scope = [$scope];
}

$this->scopes = array_merge($this->scopes, $scope);
return $this;
}

public function getMiddlewares(): array
{
return $this->middlewares;
}

public function getScopes(): array
{
return $this->scopes;
}
}
Loading

0 comments on commit 24667c4

Please sign in to comment.