isAbstract()) { // don't do anything } elseif (is_subclass_of($class, "Extension")) { /** @var Extension $extension */ $extension = new $class(); // skip extensions which don't support our current database if (!$extension->is_live()) { continue; } foreach (get_class_methods($extension) as $method) { if (substr($method, 0, 2) == "on") { $event = substr($method, 2) . "Event"; $pos = $extension->get_priority() * 100; while (isset($_shm_event_listeners[$event][$pos])) { $pos += 1; } $_shm_event_listeners[$event][$pos] = $extension; } } } } } function _dump_event_listeners(array $event_listeners, string $path): void { $p = "<"."?php\n"; foreach (get_declared_classes() as $class) { $rclass = new ReflectionClass($class); if ($rclass->isAbstract()) { } elseif (is_subclass_of($class, "Extension")) { $p .= "\$$class = new $class(); "; } } $p .= "\$_shm_event_listeners = array(\n"; foreach ($event_listeners as $event => $listeners) { $p .= "\t'$event' => array(\n"; foreach ($listeners as $id => $listener) { $p .= "\t\t$id => \$".get_class($listener).",\n"; } $p .= "\t),\n"; } $p .= ");\n"; $p .= "?".">"; file_put_contents($path, $p); } function ext_is_live(string $ext_name): bool { if (class_exists($ext_name)) { /** @var Extension $ext */ $ext = new $ext_name(); return $ext->is_live(); } return false; } /** @private */ global $_shm_event_count; $_shm_event_count = 0; /** * Send an event to all registered Extensions. */ function send_event(Event $event): void { global $_shm_event_listeners, $_shm_event_count, $_tracer; if (!isset($_shm_event_listeners[get_class($event)])) { return; } $method_name = "on".str_replace("Event", "", get_class($event)); // send_event() is performance sensitive, and with the number // of times context gets called the time starts to add up $tracer_enabled = constant('EVENT_TRACE'); if ($tracer_enabled) $_tracer->begin(get_class($event)); // SHIT: http://bugs.php.net/bug.php?id=35106 $my_event_listeners = $_shm_event_listeners[get_class($event)]; ksort($my_event_listeners); foreach ($my_event_listeners as $listener) { if ($tracer_enabled) $_tracer->begin(get_class($listener)); if (method_exists($listener, $method_name)) { $listener->$method_name($event); } if ($tracer_enabled) $_tracer->end(); if($event->stop_processing===true) { break; } } $_shm_event_count++; if ($tracer_enabled) $_tracer->end(); }