123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- <?php
- declare(strict_types=1);
- namespace App\Libs\TikTok\Kernel\Traits;
- use function array_reverse;
- use function array_unshift;
- use function call_user_func;
- use Closure;
- use App\Libs\TikTok\Kernel\Exceptions\InvalidArgumentException;
- use function func_get_args;
- use function gettype;
- use function is_array;
- use function is_callable;
- use function is_string;
- use function method_exists;
- use function spl_object_hash;
- trait InteractWithHandlers
- {
- /**
- * @var array<int, array{hash: string, handler: callable}>
- */
- protected array $handlers = [];
- /**
- * @return array<int, array{hash: string, handler: callable}>
- */
- public function getHandlers(): array
- {
- return $this->handlers;
- }
- /**
- * @param callable|string $handler
- * @return InteractWithHandlers
- * @throws InvalidArgumentException
- */
- public function with(callable|string $handler): static
- {
- return $this->withHandler($handler);
- }
- /**
- * @param callable|string $handler
- * @return InteractWithHandlers
- * @throws InvalidArgumentException
- */
- public function withHandler(callable|string $handler): static
- {
- $this->handlers[] = $this->createHandlerItem($handler);
- return $this;
- }
- /**
- * @param callable|string $handler
- * @return array{hash: string, handler: callable}
- *
- * @throws InvalidArgumentException
- */
- public function createHandlerItem(callable|string $handler): array
- {
- return [
- 'hash' => $this->getHandlerHash($handler),
- 'handler' => $this->makeClosure($handler),
- ];
- }
- /**
- * @param callable|string $handler
- * @return string
- * @throws InvalidArgumentException
- */
- protected function getHandlerHash(callable|string $handler): string
- {
- switch (true) {
- case is_string($handler):
- return $handler;
- case is_array($handler):
- return is_string($handler[0]) ? $handler[0].'::'.$handler[1] : get_class($handler[0]).$handler[1];
- case $handler instanceof Closure:
- return spl_object_hash($handler);
- default:
- throw new InvalidArgumentException('Invalid handler: '.gettype($handler));
- }
- }
- /**
- * @param callable|string $handler
- * @return callable
- * @throws InvalidArgumentException
- */
- protected function makeClosure(callable|string $handler): callable
- {
- if (is_callable($handler)) {
- return $handler;
- }
- if (class_exists($handler) && method_exists($handler, '__invoke')) {
- /**
- * @psalm-suppress InvalidFunctionCall
- * @phpstan-ignore-next-line https://github.com/phpstan/phpstan/issues/5867
- */
- return fn () => (new $handler())(...func_get_args());
- }
- throw new InvalidArgumentException(sprintf('Invalid handler: %s.', $handler));
- }
- /**
- * @param callable|string $handler
- * @return InteractWithHandlers
- * @throws InvalidArgumentException
- */
- public function prepend(callable|string $handler): static
- {
- return $this->prependHandler($handler);
- }
- /**
- * @param callable|string $handler
- * @return InteractWithHandlers
- * @throws InvalidArgumentException
- */
- public function prependHandler(callable|string $handler): static
- {
- array_unshift($this->handlers, $this->createHandlerItem($handler));
- return $this;
- }
- /**
- * @param callable|string $handler
- * @return InteractWithHandlers
- * @throws InvalidArgumentException
- */
- public function without(callable|string $handler): static
- {
- return $this->withoutHandler($handler);
- }
- /**
- * @param callable|string $handler
- * @return InteractWithHandlers
- * @throws InvalidArgumentException
- */
- public function withoutHandler(callable|string $handler): static
- {
- $index = $this->indexOf($handler);
- if ($index > -1) {
- unset($this->handlers[$index]);
- }
- return $this;
- }
- /**
- * @param callable|string $handler
- * @return int
- * @throws InvalidArgumentException
- */
- public function indexOf(callable|string $handler): int
- {
- foreach ($this->handlers as $index => $item) {
- if ($item['hash'] === $this->getHandlerHash($handler)) {
- return $index;
- }
- }
- return -1;
- }
- /**
- * @param $value
- * @param callable|string $handler
- * @return InteractWithHandlers
- * @throws InvalidArgumentException
- */
- public function when($value, callable|string $handler): static
- {
- if (is_callable($value)) {
- $value = call_user_func($value, $this);
- }
- if ($value) {
- return $this->withHandler($handler);
- }
- return $this;
- }
- public function handle($result, $payload = null)
- {
- $next = $result = is_callable($result) ? $result : fn ($p) => $result;
- foreach (array_reverse($this->handlers) as $item) {
- $next = fn ($p) => $item['handler']($p, $next) ?? $result($p);
- }
- return $next($payload);
- }
- /**
- * @param callable|string $handler
- * @return bool
- * @throws InvalidArgumentException
- */
- public function has(callable|string $handler): bool
- {
- return $this->indexOf($handler) > -1;
- }
- }
|