Вход Регистрация
Файл: vendor/symfony/event-dispatcher/Debug/WrappedListener.php
Строк: 192
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace SymfonyComponentEventDispatcherDebug;

use 
PsrEventDispatcherStoppableEventInterface;
use 
SymfonyComponentEventDispatcherEventDispatcherInterface;
use 
SymfonyComponentStopwatchStopwatch;
use 
SymfonyComponentVarDumperCasterClassStub;

/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
final class WrappedListener
{
    private 
string|array|object $listener;
    private ?
Closure $optimizedListener;
    private 
string $name;
    private 
bool $called false;
    private 
bool $stoppedPropagation false;
    private 
Stopwatch $stopwatch;
    private ?
EventDispatcherInterface $dispatcher;
    private 
string $pretty;
    private 
string $callableRef;
    private 
ClassStub|string $stub;
    private ?
int $priority null;
    private static 
bool $hasClassStub;

    public function 
__construct(callable|array $listener, ?string $nameStopwatch $stopwatch, ?EventDispatcherInterface $dispatcher null, ?int $priority null)
    {
        
$this->listener $listener;
        
$this->optimizedListener $listener instanceof Closure $listener : (is_callable($listener) ? $listener(...) : null);
        
$this->stopwatch $stopwatch;
        
$this->dispatcher $dispatcher;
        
$this->priority $priority;

        if (
is_array($listener)) {
            [
$this->name$this->callableRef] = $this->parseListener($listener);
            
$this->pretty $this->name.'::'.$listener[1];
            
$this->callableRef .= '::'.$listener[1];
        } elseif (
$listener instanceof Closure) {
            
$r = new ReflectionFunction($listener);
            if (
str_contains($r->name'{closure')) {
                
$this->pretty $this->name 'closure';
            } elseif (
$class PHP_VERSION_ID >= 80111 $r->getClosureCalledClass() : $r->getClosureScopeClass()) {
                
$this->name $class->name;
                
$this->pretty $this->name.'::'.$r->name;
            } else {
                
$this->pretty $this->name $r->name;
            }
        } elseif (
is_string($listener)) {
            
$this->pretty $this->name $listener;
        } else {
            
$this->name get_debug_type($listener);
            
$this->pretty $this->name.'::__invoke';
            
$this->callableRef $listener::class.'::__invoke';
        }

        if (
null !== $name) {
            
$this->name $name;
        }

        
self::$hasClassStub ??= class_exists(ClassStub::class);
    }

    public function 
getWrappedListener(): callable|array
    {
        return 
$this->listener;
    }

    public function 
wasCalled(): bool
    
{
        return 
$this->called;
    }

    public function 
stoppedPropagation(): bool
    
{
        return 
$this->stoppedPropagation;
    }

    public function 
getPretty(): string
    
{
        return 
$this->pretty;
    }

    public function 
getInfo(string $eventName): array
    {
        
$this->stub ??= self::$hasClassStub ? new ClassStub($this->pretty.'()'$this->callableRef ?? $this->listener) : $this->pretty.'()';

        return [
            
'event' => $eventName,
            
'priority' => $this->priority ??= $this->dispatcher?->getListenerPriority($eventName$this->listener),
            
'pretty' => $this->pretty,
            
'stub' => $this->stub,
        ];
    }

    public function 
__invoke(object $eventstring $eventNameEventDispatcherInterface $dispatcher): void
    
{
        
$dispatcher $this->dispatcher ?: $dispatcher;

        
$this->called true;
        
$this->priority ??= $dispatcher->getListenerPriority($eventName$this->listener);

        
$e $this->stopwatch->start($this->name'event_listener');

        try {
            (
$this->optimizedListener ?? $this->listener)($event$eventName$dispatcher);
        } finally {
            if (
$e->isStarted()) {
                
$e->stop();
            }
        }

        if (
$event instanceof StoppableEventInterface && $event->isPropagationStopped()) {
            
$this->stoppedPropagation true;
        }
    }

    private function 
parseListener(array $listener): array
    {
        if (
$listener[0] instanceof Closure) {
            foreach ((new 
ReflectionFunction($listener[0]))->getAttributes(Closure::class) as $attribute) {
                if (
$name $attribute->getArguments()['name'] ?? false) {
                    return [
$name$attribute->getArguments()['class'] ?? $name];
                }
            }
        }

        if (
is_object($listener[0])) {
            return [
get_debug_type($listener[0]), $listener[0]::class];
        }

        return [
$listener[0], $listener[0]];
    }
}
Онлайн: 0
Реклама