HandlerList */ private $allLists = []; /** * Unregisters all the listeners * If a Plugin or Listener is passed, all the listeners with that object will be removed * * @param Plugin|Listener|null $object */ public function unregisterAll($object = null) : void{ if($object instanceof Listener or $object instanceof Plugin){ foreach($this->allLists as $h){ $h->unregister($object); } }else{ foreach($this->allLists as $h){ $h->clear(); } } } /** * @param ReflectionClass $class * @phpstan-param \ReflectionClass $class * * @return bool */ private static function isValidClass(\ReflectionClass $class) : bool{ $tags = Utils::parseDocComment((string) $class->getDocComment()); return !$class->isAbstract() || isset($tags["allowHandle"]); } /** * @param \ReflectionClass $class * @phpstan-param \ReflectionClass $class * * @return \ReflectionClass|null * @phpstan-return \ReflectionClass|null */ private static function resolveNearestHandleableParent(\ReflectionClass $class) : ?\ReflectionClass{ for($parent = $class->getParentClass(); $parent !== false && !self::isValidClass($parent); $parent = $parent->getParentClass()){ //NOOP } return $parent ?: null; } /** * Returns the HandlerList for listeners that explicitly handle this event. * * Calling this method also lazily initializes the $classMap inheritance tree of handler lists. * * @param string $event * * @return HandlerList * @throws \ReflectionException * @throws \InvalidArgumentException */ public function getListFor(string $event) : HandlerList{ if(isset($this->allLists[$event])){ return $this->allLists[$event]; } $class = new \ReflectionClass($event); if(!self::isValidClass($class)){ throw new \InvalidArgumentException("Event must be non-abstract or have the @allowHandle annotation"); } $parent = self::resolveNearestHandleableParent($class); return $this->allLists[$event] = new HandlerList($event, $parent !== null ? $this->getListFor($parent->getName()) : null); } /** * @return HandlerList[] */ public function getAll() : array{ return $this->allLists; } }