* @link https://getkirby.com * @copyright Bastian Allgeier * @license https://getkirby.com/license */ class Plugin extends Model { protected $extends; protected $info; protected $name; protected $root; /** * @param string $key * @param array|null $arguments * @return mixed|null */ public function __call(string $key, array $arguments = null) { return $this->info()[$key] ?? null; } /** * Plugin constructor * * @param string $name * @param array $extends */ public function __construct(string $name, array $extends = []) { $this->setName($name); $this->extends = $extends; $this->root = $extends['root'] ?? dirname(debug_backtrace()[0]['file']); $this->info = empty($extends['info']) === false && is_array($extends['info']) ? $extends['info'] : null; unset($this->extends['root'], $this->extends['info']); } /** * Returns the array with author information * from the composer file * * @return array */ public function authors(): array { return $this->info()['authors'] ?? []; } /** * Returns a comma-separated list with all author names * * @return string */ public function authorsNames(): string { $names = []; foreach ($this->authors() as $author) { $names[] = $author['name'] ?? null; } return implode(', ', array_filter($names)); } /** * @return array */ public function extends(): array { return $this->extends; } /** * Returns the unique id for the plugin * * @return string */ public function id(): string { return $this->name(); } /** * @return array */ public function info(): array { if (is_array($this->info) === true) { return $this->info; } try { $info = Data::read($this->manifest()); } catch (Exception $e) { // there is no manifest file or it is invalid $info = []; } return $this->info = $info; } /** * Returns the link to the plugin homepage * * @return string|null */ public function link(): ?string { $homepage = $this->info['homepage'] ?? null; $docs = $this->info['support']['docs'] ?? null; $source = $this->info['support']['source'] ?? null; $link = $homepage ?? $docs ?? $source; return V::url($link) ? $link : null; } /** * @return string */ public function manifest(): string { return $this->root() . '/composer.json'; } /** * @return string */ public function mediaRoot(): string { return App::instance()->root('media') . '/plugins/' . $this->name(); } /** * @return string */ public function mediaUrl(): string { return App::instance()->url('media') . '/plugins/' . $this->name(); } /** * @return string */ public function name(): string { return $this->name; } /** * @param string $key * @return mixed */ public function option(string $key) { return $this->kirby()->option($this->prefix() . '.' . $key); } /** * @return string */ public function prefix(): string { return str_replace('/', '.', $this->name()); } /** * @return string */ public function root(): string { return $this->root; } /** * @param string $name * @return $this * @throws \Kirby\Exception\InvalidArgumentException */ protected function setName(string $name) { if (preg_match('!^[a-z0-9-]+\/[a-z0-9-]+$!i', $name) !== 1) { throw new InvalidArgumentException('The plugin name must follow the format "a-z0-9-/a-z0-9-"'); } $this->name = $name; return $this; } /** * @return array */ public function toArray(): array { return [ 'authors' => $this->authors(), 'description' => $this->description(), 'name' => $this->name(), 'license' => $this->license(), 'link' => $this->link(), 'root' => $this->root(), 'version' => $this->version() ]; } }