* * This source file is subject to the MIT license that is bundled * with this source code in the file LICENSE. */ namespace EasyWeChatComposer; use EasyWeChat\Kernel\Contracts\EventHandlerInterface; use Pimple\Container; use ReflectionClass; class Extension { /** * @var \Pimple\Container */ protected $app; /** * @var string */ protected $manifestPath; /** * @var array|null */ protected $manifest; /** * @param \Pimple\Container $app */ public function __construct(Container $app) { $this->app = $app; $this->manifestPath = __DIR__.'/../extensions.php'; } /** * Get observers. * * @return array */ public function observers(): array { if ($this->shouldIgnore()) { return []; } $observers = []; foreach ($this->getManifest() as $name => $extra) { $observers = array_merge($observers, $extra['observers'] ?? []); } return array_map([$this, 'listObserver'], array_filter($observers, [$this, 'validateObserver'])); } /** * @param mixed $observer * * @return bool */ protected function isDisable($observer): bool { return in_array($observer, $this->app->config->get('disable_observers', [])); } /** * Get the observers should be ignore. * * @return bool */ protected function shouldIgnore(): bool { return !file_exists($this->manifestPath) || $this->isDisable('*'); } /** * Validate the given observer. * * @param mixed $observer * * @return bool * * @throws \ReflectionException */ protected function validateObserver($observer): bool { return !$this->isDisable($observer) && (new ReflectionClass($observer))->implementsInterface(EventHandlerInterface::class) && $this->accessible($observer); } /** * Determine whether the given observer is accessible. * * @param string $observer * * @return bool */ protected function accessible($observer): bool { if (!method_exists($observer, 'getAccessor')) { return true; } return in_array(get_class($this->app), (array) $observer::getAccessor()); } /** * @param mixed $observer * * @return array */ protected function listObserver($observer): array { $condition = method_exists($observer, 'onCondition') ? $observer::onCondition() : '*'; return [$observer, $condition]; } /** * Get the easywechat manifest. * * @return array */ protected function getManifest(): array { if (!is_null($this->manifest)) { return $this->manifest; } return $this->manifest = file_exists($this->manifestPath) ? require $this->manifestPath : []; } }