_events[$name])) { $this->_events[$name] = []; } if ($callback instanceof \Closure) { $callback = \Closure::bind($callback, Snowflake::app()); } else if (is_array($callback) && is_string($callback[0])) { if (!class_exists($callback[0])) { throw new Exception('Undefined callback class.'); } $callback[0] = Snowflake::createObject($callback[0]); } if ($this->exists($name, $callback)) { return; } if (!empty($this->_events[$name]) && $isAppend === true) { array_unshift($this->_events[$name], [$callback, $parameter]); } else { $this->_events[$name][] = [$callback, $parameter]; } } /** * @param $name * @param $callback */ public function of($name, $callback): void { if (!isset($this->_events[$name])) { return; } foreach ($this->_events[$name] as $index => $event) { [$handler, $parameter] = $event; if ($handler !== $callback) { continue; } unset($this->_events[$name][$index]); } } /** * @param $name * @return bool */ public function offName($name): bool { if (!$this->exists($name)) { return true; } unset($this->_events[$name]); return $this->exists($name); } /** * @param $name * @param null $callback * @return bool */ public function exists($name, $callback = null): bool { if (!isset($this->_events[$name])) { return false; } if ($callback === null) { return true; } foreach ($this->_events[$name] as $event) { [$handler, $parameter] = $event; if ($handler === $callback) { return true; } } return false; } /** * @param $name * @param $handler * @return mixed */ public function get($name, $handler): mixed { if (!$this->exists($name, $handler)) { return null; } if (empty($handler)) { return $this->_events[$name]; } foreach ($this->_events[$name] as $event) { [$callback, $parameter] = $event; if ($callback === $handler) { return [$event]; } } return null; } public function clean() { $this->_events = []; } /** * @param $name * @param array $params * @param null $scope * @return bool * @throws Exception */ public function dispatch($name, $params = [], $scope = null): bool { return $this->trigger($name, $params, $scope); } /** * @param $name * @param null $parameter * @param null $handler * @param false $is_remove * @return bool * @throws Exception */ public function trigger($name, $parameter = null, $handler = null, $is_remove = false): bool { $events = $this->get($name, $handler); if (empty($events)) { return true; } foreach ($events as $index => $event) { $this->execute($event, $parameter); } if ($is_remove) { $this->offName($name); } return true; } /** * @param $event * @param $parameter * @return bool * @throws Exception */ private function execute($event, $parameter): bool { try { $meta = $this->mergeParams($event[1], $parameter); if (call_user_func($event[0], ...$meta) === false) { return false; } return true; } catch (\Throwable $throwable) { return $this->addError($throwable,'throwable'); } } /** * @param $defaultParameter * @param $parameter * @return array */ private function mergeParams($defaultParameter, $parameter = []): array { if (empty($defaultParameter)) { $defaultParameter = $parameter; } else { if (!is_array($parameter)) { $parameter = []; } foreach ($parameter as $key => $value) { $defaultParameter[] = $value; } } if (!is_array($defaultParameter)) { $defaultParameter = [$defaultParameter]; } return $defaultParameter; } }