Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plugin registration: named arguments #6337

Merged
merged 13 commits into from
May 23, 2024
21 changes: 15 additions & 6 deletions src/Cms/AppPlugins.php
Original file line number Diff line number Diff line change
Expand Up @@ -713,17 +713,22 @@ public function nativeComponent(string $component): Closure|false
*/
public static function plugin(
string $name,
array $extends = null
array $extends = null,
array $info = [],
string|null $root = null
distantnative marked this conversation as resolved.
Show resolved Hide resolved
): PLugin|null {
if ($extends === null) {
return static::$plugins[$name] ?? null;
}

// get the correct root for the plugin
$extends['root'] ??= dirname(debug_backtrace()[0]['file']);
$plugin = new Plugin(
name: $name,
extends: $extends,
info: $info,
root: $root ?? dirname(debug_backtrace()[0]['file']),
distantnative marked this conversation as resolved.
Show resolved Hide resolved
);

$plugin = new Plugin($name, $extends);
$name = $plugin->name();
$name = $plugin->name();

if (isset(static::$plugins[$name]) === true) {
throw new DuplicateException('The plugin "' . $name . '" has already been registered');
Expand Down Expand Up @@ -792,7 +797,11 @@ protected function pluginsLoader(): array
// register as anonymous plugin (without actual extensions)
// to be picked up by the Panel\Document class when
// rendering the Panel view
static::plugin('plugins/' . $dirname, ['root' => $dir]);
static::plugin(
name: 'plugins/' . $dirname,
extends: [],
root: $dir
);
} else {
continue;
}
Expand Down
10 changes: 7 additions & 3 deletions src/Cms/Helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,18 @@ class Helpers
* ```
*/
public static $deprecations = [
// The internal `$model->contentFile*()` methods have been deprecated
'model-content-file' => true,

// Passing an `info` array inside the `extends` array has been deprecated.
// Pass the individual entries directly as named arguments.
'plugin-extends-root' => false,

// Passing a single space as value to `Xml::attr()` has been
// deprecated. In a future version, passing a single space won't
// render an empty value anymore but a single space.
// To render an empty value, please pass an empty string.
'xml-attr-single-space' => true,

// The internal `$model->contentFile*()` methods have been deprecated
'model-content-file' => true,
];

/**
Expand Down
78 changes: 46 additions & 32 deletions src/Cms/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,6 @@
class Plugin
{
protected PluginAssets $assets;
protected array $extends;
protected string $name;
protected string $root;

// caches
protected array|null $info = null;
protected UpdateStatus|null $updateStatus = null;

/**
Expand All @@ -40,16 +34,44 @@ class Plugin
*
* @throws \Kirby\Exception\InvalidArgumentException If the plugin name has an invalid format
*/
public function __construct(string $name, array $extends = [])
{
public function __construct(
protected string $name,
protected array $extends = [],
protected array $info = [],
protected string|null $root = null,
protected string|null $version = null,
) {
static::validateName($name);

$this->name = $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;
// TODO: Remove in v5
if ($root = $extends['root'] ?? null) {
Helpers::deprecated('Plugin "' . $name . '": Passing the `root` inside the `extends` array has been deprecated. Pass it directly as named argument `root`.', 'plugin-extends-root');
$this->root ??= $root;
unset($this->extends['root']);
}

$this->root ??= dirname(debug_backtrace()[0]['file']);

// TODO: Remove info property in v5
distantnative marked this conversation as resolved.
Show resolved Hide resolved
if ($info = $extends['info'] ?? null) {
Helpers::deprecated('Plugin "' . $name . '": Passing an `info` array inside the `extends` array has been deprecated. Pass the individual entries directly as named `info` argument.', 'plugin-extends-root');

if (empty($info) === false && is_array($info) === true) {
$this->info = [...$info, ...$this->info];
}

unset($this->extends['info']);
}

unset($this->extends['root'], $this->extends['info']);
// read composer.json and use as info fallback
try {
$info = Data::read($this->manifest());
} catch (Exception) {
// there is no manifest file or it is invalid
$info = [];
}

$this->info = [...$info, ...$this->info];
}

/**
Expand Down Expand Up @@ -117,22 +139,11 @@ public function id(): string
}

/**
* Returns the raw data from composer.json
* Returns the info data (from composer.json)
*/
public function info(): array
{
if (is_array($this->info) === true) {
return $this->info;
}

try {
$info = Data::read($this->manifest());
} catch (Exception) {
// there is no manifest file or it is invalid
$info = [];
}

return $this->info = $info;
return $this->info;
}

/**
Expand Down Expand Up @@ -295,17 +306,20 @@ public static function validateName(string $name): void
*/
public function version(): string|null
{
$composerName = $this->info()['name'] ?? null;
$version = $this->info()['version'] ?? null;
$name = $this->info()['name'] ?? null;

try {
// if plugin doesn't have version key in composer.json file
// try to get version from "vendor/composer/installed.php"
$version ??= InstalledVersions::getPrettyVersion($composerName);
// try to get version from "vendor/composer/installed.php",
// this is the most reliable source for the version
$version = InstalledVersions::getPrettyVersion($name);
} catch (Throwable) {
return null;
$version = null;
}

// fallback to the version provided in the plugin's index.php: as named
// argument, entry in the info array or from the composer.json file
$version ??= $this->version ?? $this->info()['version'] ?? null;

if (
is_string($version) !== true ||
$version === '' ||
Expand Down
Loading
Loading