private function sortListeners($eventName) { $this->sorted[$eventName] = array(); $available = array(); list($namespace, $event, $separator) = Event::parseName($eventName); $className = $namespace; do { if (empty($this->listeners[$key = ($className ? $className . $separator : '') . $event])) { continue; } $available = $available + array_fill_keys(array_keys($this->listeners[$key]), array()); foreach ($this->listeners[$key] as $priority => $listeners) { foreach ($listeners as $listener) { if ($className === $namespace && in_array($listener, $available[$priority], TRUE)) { continue; } $available[$priority][] = $listener; } } } while ($className && class_exists($className) && ($className = get_parent_class($className))); if (empty($available)) { return; } krsort($available); // [priority => [[listener, ...], ...] $sorted = call_user_func_array('array_merge', $available); $this->sorted[$eventName] = array_map(function ($callable) use($event) { if ($callable instanceof EventSubscriber) { return $callable; } if (is_object($callable) && method_exists($callable, $event)) { $callable = array($callable, $event); } return $callable; }, $sorted); // [callback, ...] }
public function registerEvent(Event $event) { $this->events[] = $event; $event->setPanel($this); }
/** * {@inheritDoc} */ public function removeEventListener($unsubscribe, $subscriber = NULL) { if ($unsubscribe instanceof Doctrine\Common\EventSubscriber) { $subscriber = $unsubscribe; $unsubscribe = []; foreach ($subscriber->getSubscribedEvents() as $eventName => $params) { if (is_array($params) && is_array($params[0]) || !is_numeric($eventName)) { // [EventName => [[method, priority], ...], ...] // [EventName => [method, priority], ...] && [EventName => method, . $unsubscribe[] = $eventName; } else { // [EventName, ...] $unsubscribe[] = $params; } } } $namespace = $this->namespace; $unsubscribe = array_map(function ($eventName) use($namespace) { list($ns, $event) = Event::parseName($eventName); return $ns === NULL ? $namespace . $event : $eventName; }, (array) $unsubscribe); $this->evm->removeEventListener($unsubscribe, $subscriber); }
/** * @param \Nette\DI\ContainerBuilder $builder */ private function optimizeListeners(Nette\DI\ContainerBuilder $builder) { $listeners = array(); foreach ($this->listeners as $serviceName => $eventNames) { foreach ($eventNames as $eventName) { list($namespace, $event) = Kdyby\Events\Event::parseName($eventName); $listeners[$eventName][] = $serviceName; if (!$namespace || !class_exists($namespace)) { continue; // it might not even be a "classname" event namespace } // find all subclasses and register the listener to all the classes dispatching them foreach ($builder->getDefinitions() as $def) { if (!($class = $def->getClass())) { continue; // ignore unresolved classes } if (is_subclass_of($class, $namespace)) { $listeners["{$class}::{$event}"][] = $serviceName; } } } } foreach ($listeners as $id => $subscribers) { $listeners[$id] = array_unique($subscribers); } $builder->getDefinition($this->prefix('manager'))->setClass('Kdyby\\Events\\LazyEventManager', array($listeners))->setup = $this->allowedManagerSetup; }