mirror of
https://code.castopod.org/adaures/castopod
synced 2025-05-30 14:02:01 +00:00
test(plugins): add test suite for Plugins service
This commit is contained in:
parent
3a900bbab6
commit
91dc8c8325
@ -52,11 +52,7 @@ abstract class BasePlugin implements PluginInterface
|
|||||||
$this->manifest = new Manifest($this->key);
|
$this->manifest = new Manifest($this->key);
|
||||||
$this->manifest->loadFromFile($manifestPath);
|
$this->manifest->loadFromFile($manifestPath);
|
||||||
|
|
||||||
if ($this->getManifestErrors() !== []) {
|
$this->status = get_plugin_setting($this->key, 'active') ? PluginStatus::ACTIVE : PluginStatus::INACTIVE;
|
||||||
$this->status = PluginStatus::INVALID;
|
|
||||||
} else {
|
|
||||||
$this->status = get_plugin_option($this->key, 'active') ? PluginStatus::ACTIVE : PluginStatus::INACTIVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->iconSrc = $this->loadIcon($directory . '/icon.svg');
|
$this->iconSrc = $this->loadIcon($directory . '/icon.svg');
|
||||||
|
|
||||||
@ -98,17 +94,48 @@ abstract class BasePlugin implements PluginInterface
|
|||||||
|
|
||||||
final public function getGeneralSetting(string $key): mixed
|
final public function getGeneralSetting(string $key): mixed
|
||||||
{
|
{
|
||||||
return get_plugin_option($this->key, $key);
|
return get_plugin_setting($this->key, $key);
|
||||||
}
|
}
|
||||||
|
|
||||||
final public function getPodcastSetting(int $podcastId, string $key): mixed
|
final public function getPodcastSetting(int $podcastId, string $key): mixed
|
||||||
{
|
{
|
||||||
return get_plugin_option($this->key, $key, ['podcast', $podcastId]);
|
return get_plugin_setting($this->key, $key, ['podcast', $podcastId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
final public function getEpisodeSetting(int $episodeId, string $key): mixed
|
final public function getEpisodeSetting(int $episodeId, string $key): mixed
|
||||||
{
|
{
|
||||||
return get_plugin_option($this->key, $key, ['episode', $episodeId]);
|
return get_plugin_setting($this->key, $key, ['episode', $episodeId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool true on success, false on failure
|
||||||
|
*/
|
||||||
|
final public function activate(): bool
|
||||||
|
{
|
||||||
|
if ($this->status === PluginStatus::ACTIVE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->setStatus(PluginStatus::ACTIVE);
|
||||||
|
|
||||||
|
if ($this->status === PluginStatus::INACTIVE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_plugin_setting($this->key, 'active', true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function deactivate(): bool
|
||||||
|
{
|
||||||
|
if ($this->status !== PluginStatus::ACTIVE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->setStatus(PluginStatus::INACTIVE);
|
||||||
|
set_plugin_setting($this->key, 'active', false);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
final public function getStatus(): PluginStatus
|
final public function getStatus(): PluginStatus
|
||||||
@ -243,14 +270,30 @@ abstract class BasePlugin implements PluginInterface
|
|||||||
return $this->manifest->license ?? 'UNLICENSED';
|
return $this->manifest->license ?? 'UNLICENSED';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param PluginStatus::ACTIVE|PluginStatus::INACTIVE $value
|
||||||
|
*/
|
||||||
|
final protected function setStatus(PluginStatus $value): self
|
||||||
|
{
|
||||||
|
if ($this->getManifestErrors() !== []) {
|
||||||
|
$this->status = PluginStatus::INVALID;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->status = $value;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
final protected function getOption(string $option): mixed
|
final protected function getOption(string $option): mixed
|
||||||
{
|
{
|
||||||
return get_plugin_option($this->key, $option);
|
return get_plugin_setting($this->key, $option);
|
||||||
}
|
}
|
||||||
|
|
||||||
final protected function setOption(string $option, mixed $value = null): void
|
final protected function setOption(string $option, mixed $value = null): void
|
||||||
{
|
{
|
||||||
set_plugin_option($this->key, $option, $value);
|
set_plugin_setting($this->key, $option, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function loadIcon(string $path): string
|
private function loadIcon(string $path): string
|
||||||
|
@ -209,12 +209,16 @@ class Plugins
|
|||||||
|
|
||||||
public function activate(BasePlugin $plugin): void
|
public function activate(BasePlugin $plugin): void
|
||||||
{
|
{
|
||||||
set_plugin_option($plugin->getKey(), 'active', true);
|
if ($plugin->activate()) {
|
||||||
|
++self::$activeCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function deactivate(BasePlugin $plugin): void
|
public function deactivate(BasePlugin $plugin): void
|
||||||
{
|
{
|
||||||
set_plugin_option($plugin->getKey(), 'active', false);
|
if ($plugin->deactivate()) {
|
||||||
|
--self::$activeCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -222,7 +226,7 @@ class Plugins
|
|||||||
*/
|
*/
|
||||||
public function setOption(BasePlugin $plugin, string $name, mixed $value, array $additionalContext = null): void
|
public function setOption(BasePlugin $plugin, string $name, mixed $value, array $additionalContext = null): void
|
||||||
{
|
{
|
||||||
set_plugin_option($plugin->getKey(), $name, $value, $additionalContext);
|
set_plugin_setting($plugin->getKey(), $name, $value, $additionalContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getInstalledCount(): int
|
public function getInstalledCount(): int
|
||||||
@ -282,12 +286,23 @@ class Plugins
|
|||||||
ucwords(str_replace(['-', '_', '.'], ' ', $vendor . ' ' . $package)) . 'Plugin'
|
ucwords(str_replace(['-', '_', '.'], ' ', $vendor . ' ' . $package)) . 'Plugin'
|
||||||
);
|
);
|
||||||
|
|
||||||
spl_autoload_register(static function ($class) use (&$className, &$pluginDirectory): void {
|
$pluginFile = $pluginDirectory . DIRECTORY_SEPARATOR . 'Plugin.php';
|
||||||
if ($class === $className) {
|
spl_autoload_register(static function ($class) use (&$className, &$pluginFile): void {
|
||||||
include $pluginDirectory . DIRECTORY_SEPARATOR . 'Plugin.php';
|
if ($class !== $className) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! file_exists($pluginFile)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
include_once $pluginFile;
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
|
if (! class_exists($className)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$plugin = new $className($vendor, $package, $pluginDirectory);
|
$plugin = new $className($vendor, $package, $pluginDirectory);
|
||||||
if (! $plugin instanceof BasePlugin) {
|
if (! $plugin instanceof BasePlugin) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -11,11 +11,11 @@ if (! function_exists('plugins')) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! function_exists('get_plugin_option')) {
|
if (! function_exists('get_plugin_setting')) {
|
||||||
/**
|
/**
|
||||||
* @param ?array{'podcast'|'episode',int} $additionalContext
|
* @param ?array{'podcast'|'episode',int} $additionalContext
|
||||||
*/
|
*/
|
||||||
function get_plugin_option(string $pluginKey, string $option, array $additionalContext = null): mixed
|
function get_plugin_setting(string $pluginKey, string $option, array $additionalContext = null): mixed
|
||||||
{
|
{
|
||||||
$key = sprintf('Plugins.%s', $option);
|
$key = sprintf('Plugins.%s', $option);
|
||||||
$context = sprintf('plugin:%s', $pluginKey);
|
$context = sprintf('plugin:%s', $pluginKey);
|
||||||
@ -28,11 +28,11 @@ if (! function_exists('get_plugin_option')) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! function_exists('set_plugin_option')) {
|
if (! function_exists('set_plugin_setting')) {
|
||||||
/**
|
/**
|
||||||
* @param ?array{'podcast'|'episode',int} $additionalContext
|
* @param ?array{'podcast'|'episode',int} $additionalContext
|
||||||
*/
|
*/
|
||||||
function set_plugin_option(
|
function set_plugin_setting(
|
||||||
string $pluginKey,
|
string $pluginKey,
|
||||||
string $option,
|
string $option,
|
||||||
mixed $value = null,
|
mixed $value = null,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Tests\Modules\Api\Rest\V1;
|
namespace Tests\Modules\Plugins;
|
||||||
|
|
||||||
use CodeIgniter\Test\CIUnitTestCase;
|
use CodeIgniter\Test\CIUnitTestCase;
|
||||||
use Modules\Plugins\Manifest\Manifest;
|
use Modules\Plugins\Manifest\Manifest;
|
||||||
@ -20,7 +20,7 @@ final class ManifestTest extends CIUnitTestCase
|
|||||||
$this->assertNotEquals($manifest->name, 'acme/hello-world');
|
$this->assertNotEquals($manifest->name, 'acme/hello-world');
|
||||||
$this->assertNotEquals($manifest->version, '1.0.0');
|
$this->assertNotEquals($manifest->version, '1.0.0');
|
||||||
|
|
||||||
$manifest->loadFromFile(TESTPATH . 'modules/Plugins/Mocks/manifests/manifest-required.json');
|
$manifest->loadFromFile(TESTPATH . 'modules/Plugins/mocks/manifests/manifest-required.json');
|
||||||
|
|
||||||
// no errors
|
// no errors
|
||||||
$this->assertEmpty($manifest->getPluginErrors('acme/hello-world'));
|
$this->assertEmpty($manifest->getPluginErrors('acme/hello-world'));
|
||||||
@ -34,7 +34,7 @@ final class ManifestTest extends CIUnitTestCase
|
|||||||
{
|
{
|
||||||
$manifest = new Manifest('acme/hello-world');
|
$manifest = new Manifest('acme/hello-world');
|
||||||
|
|
||||||
$manifest->loadFromFile(TESTPATH . 'modules/Plugins/Mocks/manifests/manifest-empty.json');
|
$manifest->loadFromFile(TESTPATH . 'modules/Plugins/mocks/manifests/manifest-empty.json');
|
||||||
|
|
||||||
$errors = $manifest->getPluginErrors('acme/hello-world');
|
$errors = $manifest->getPluginErrors('acme/hello-world');
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ final class ManifestTest extends CIUnitTestCase
|
|||||||
{
|
{
|
||||||
$manifest = new Manifest('acme/hello-world');
|
$manifest = new Manifest('acme/hello-world');
|
||||||
|
|
||||||
$manifest->loadFromFile(TESTPATH . 'modules/Plugins/Mocks/manifests/manifest-full-valid.json');
|
$manifest->loadFromFile(TESTPATH . 'modules/Plugins/mocks/manifests/manifest-full-valid.json');
|
||||||
|
|
||||||
// no errors
|
// no errors
|
||||||
$this->assertEmpty($manifest->getPluginErrors('acme/hello-world'));
|
$this->assertEmpty($manifest->getPluginErrors('acme/hello-world'));
|
||||||
@ -59,7 +59,7 @@ final class ManifestTest extends CIUnitTestCase
|
|||||||
{
|
{
|
||||||
$manifest = new Manifest('acme/hello-world');
|
$manifest = new Manifest('acme/hello-world');
|
||||||
|
|
||||||
$manifest->loadFromFile(TESTPATH . 'modules/Plugins/Mocks/manifests/manifest-full-invalid.json');
|
$manifest->loadFromFile(TESTPATH . 'modules/Plugins/mocks/manifests/manifest-full-invalid.json');
|
||||||
|
|
||||||
// errors
|
// errors
|
||||||
$this->assertNotEmpty($manifest->getPluginErrors('acme/hello-world'));
|
$this->assertNotEmpty($manifest->getPluginErrors('acme/hello-world'));
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Tests\Modules\Plugins\Mocks\Plugins\AcmeHelloUniverse;
|
|
||||||
|
|
||||||
use Modules\Plugins\Core\BasePlugin;
|
|
||||||
|
|
||||||
class Plugin extends BasePlugin
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Tests\Modules\Plugins\Mocks\Plugins\AcmeHelloWorld;
|
|
||||||
|
|
||||||
use Modules\Plugins\Core\BasePlugin;
|
|
||||||
|
|
||||||
class Plugin extends BasePlugin
|
|
||||||
{
|
|
||||||
}
|
|
175
tests/modules/Plugins/PluginsTest.php
Normal file
175
tests/modules/Plugins/PluginsTest.php
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Tests\Modules\Plugins;
|
||||||
|
|
||||||
|
use App\Entities\Episode;
|
||||||
|
use App\Entities\Podcast;
|
||||||
|
use App\Libraries\SimpleRSSElement;
|
||||||
|
use CodeIgniter\Test\CIUnitTestCase;
|
||||||
|
use CodeIgniter\Test\DatabaseTestTrait;
|
||||||
|
use Modules\Plugins\Config\Plugins as PluginsConfig;
|
||||||
|
use Modules\Plugins\Core\Plugins;
|
||||||
|
use Modules\Plugins\Core\PluginStatus;
|
||||||
|
use Override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class PluginsTest extends CIUnitTestCase
|
||||||
|
{
|
||||||
|
use DatabaseTestTrait;
|
||||||
|
|
||||||
|
protected $migrate = true;
|
||||||
|
|
||||||
|
protected $migrateOnce = false;
|
||||||
|
|
||||||
|
protected $refresh = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string|null
|
||||||
|
*/
|
||||||
|
protected $namespace;
|
||||||
|
|
||||||
|
protected static Plugins $plugins;
|
||||||
|
|
||||||
|
#[Override]
|
||||||
|
public static function setUpBeforeClass(): void
|
||||||
|
{
|
||||||
|
$pluginsConfig = new PluginsConfig();
|
||||||
|
$pluginsConfig->folder = __DIR__ . '/mocks/plugins' . DIRECTORY_SEPARATOR;
|
||||||
|
|
||||||
|
self::$plugins = new Plugins($pluginsConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRegister(): void
|
||||||
|
{
|
||||||
|
$this->assertCount(7, self::$plugins->getAllPlugins());
|
||||||
|
$this->assertEquals(7, self::$plugins->getInstalledCount());
|
||||||
|
$this->assertEquals(0, self::$plugins->getActiveCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testActivateDeactivate(): void
|
||||||
|
{
|
||||||
|
$this->assertEquals(0, self::$plugins->getActiveCount());
|
||||||
|
|
||||||
|
$plugin = self::$plugins->getAllPlugins()[0];
|
||||||
|
|
||||||
|
// get first plugin and activate it
|
||||||
|
self::$plugins->activate($plugin);
|
||||||
|
|
||||||
|
$this->assertEquals(1, self::$plugins->getActiveCount());
|
||||||
|
$this->assertEquals(PluginStatus::ACTIVE, $plugin->getStatus());
|
||||||
|
$this->seeInDatabase('settings', [
|
||||||
|
'class' => PluginsConfig::class,
|
||||||
|
'key' => 'active',
|
||||||
|
'value' => '1',
|
||||||
|
'type' => 'boolean',
|
||||||
|
'context' => 'plugin:' . $plugin->getKey(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// get first plugin and deactivate it
|
||||||
|
self::$plugins->deactivate($plugin);
|
||||||
|
|
||||||
|
$this->assertEquals(0, self::$plugins->getActiveCount());
|
||||||
|
$this->assertEquals(PluginStatus::INACTIVE, $plugin->getStatus());
|
||||||
|
$this->seeInDatabase('settings', [
|
||||||
|
'class' => PluginsConfig::class,
|
||||||
|
'key' => 'active',
|
||||||
|
'value' => '0',
|
||||||
|
'type' => 'boolean',
|
||||||
|
'context' => 'plugin:' . $plugin->getKey(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRunHooksActive(): void
|
||||||
|
{
|
||||||
|
$acmeAllHooksPlugin = self::$plugins->getPlugin('acme', 'all-hooks');
|
||||||
|
|
||||||
|
self::$plugins->activate($acmeAllHooksPlugin);
|
||||||
|
|
||||||
|
$this->assertEquals(1, self::$plugins->getActiveCount());
|
||||||
|
|
||||||
|
$podcast = new Podcast();
|
||||||
|
$this->assertEquals('', $podcast->title);
|
||||||
|
self::$plugins->runHook('rssBeforeChannel', [$podcast]);
|
||||||
|
$this->assertEquals('Podcast test', $podcast->title);
|
||||||
|
|
||||||
|
$channel = new SimpleRSSElement('<channel></channel>');
|
||||||
|
$this->assertTrue(empty($channel->foo));
|
||||||
|
self::$plugins->runHook('rssAfterChannel', [$podcast, $channel]);
|
||||||
|
$this->assertFalse(empty($channel->foo));
|
||||||
|
|
||||||
|
$episode = new Episode();
|
||||||
|
$this->assertEquals('', $episode->title);
|
||||||
|
self::$plugins->runHook('rssBeforeItem', [$episode]);
|
||||||
|
$this->assertEquals('Episode test', $episode->title);
|
||||||
|
|
||||||
|
$item = new SimpleRSSElement('<item></item>');
|
||||||
|
$this->assertTrue(empty($item->efoo));
|
||||||
|
self::$plugins->runHook('rssAfterItem', [$episode, $item]);
|
||||||
|
$this->assertFalse(empty($item->efoo));
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
self::$plugins->runHook('siteHead', []);
|
||||||
|
$result = ob_get_contents();
|
||||||
|
ob_end_clean(); //Discard output buffer
|
||||||
|
$this->assertEquals('hello', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRunHooksInactive(): void
|
||||||
|
{
|
||||||
|
$acmeAllHooksPlugin = self::$plugins->getPlugin('acme', 'all-hooks');
|
||||||
|
|
||||||
|
self::$plugins->deactivate($acmeAllHooksPlugin);
|
||||||
|
|
||||||
|
$this->assertEquals(0, self::$plugins->getActiveCount());
|
||||||
|
|
||||||
|
// nothing should change when running hooks as the plugin is inactive
|
||||||
|
|
||||||
|
$podcast = new Podcast();
|
||||||
|
$this->assertEquals('', $podcast->title);
|
||||||
|
self::$plugins->runHook('rssBeforeChannel', [$podcast]);
|
||||||
|
$this->assertEquals('', $podcast->title);
|
||||||
|
|
||||||
|
$channel = new SimpleRSSElement('<channel></channel>');
|
||||||
|
$this->assertTrue(empty($channel->foo));
|
||||||
|
self::$plugins->runHook('rssAfterChannel', [$podcast, $channel]);
|
||||||
|
$this->assertTrue(empty($channel->foo));
|
||||||
|
|
||||||
|
$episode = new Episode();
|
||||||
|
$this->assertEquals('', $episode->title);
|
||||||
|
self::$plugins->runHook('rssBeforeItem', [$episode]);
|
||||||
|
$this->assertEquals('', $episode->title);
|
||||||
|
|
||||||
|
$item = new SimpleRSSElement('<item></item>');
|
||||||
|
$this->assertTrue(empty($item->efoo));
|
||||||
|
self::$plugins->runHook('rssAfterItem', [$episode, $item]);
|
||||||
|
$this->assertTrue(empty($item->efoo));
|
||||||
|
|
||||||
|
ob_start();
|
||||||
|
self::$plugins->runHook('siteHead', []);
|
||||||
|
$result = ob_get_contents();
|
||||||
|
ob_end_clean(); //Discard output buffer
|
||||||
|
$this->assertEquals('', $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRunUndeclaredHook(): void
|
||||||
|
{
|
||||||
|
$acmeUndeclaredHookPlugin = self::$plugins->getPlugin('acme', 'undeclared-hook');
|
||||||
|
|
||||||
|
self::$plugins->activate($acmeUndeclaredHookPlugin);
|
||||||
|
|
||||||
|
$podcast = new Podcast();
|
||||||
|
$this->assertEquals('', $podcast->title);
|
||||||
|
self::$plugins->runHook('rssBeforeChannel', [$podcast]);
|
||||||
|
$this->assertEquals('Podcast test undeclared', $podcast->title);
|
||||||
|
|
||||||
|
// rssAfterChannel has not been declared in plugin manifest, should not be running
|
||||||
|
$channel = new SimpleRSSElement('<channel></channel>');
|
||||||
|
$this->assertTrue(empty($channel->foo));
|
||||||
|
self::$plugins->runHook('rssAfterChannel', [$podcast, $channel]);
|
||||||
|
$this->assertTrue(empty($channel->foo));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use App\Entities\Episode;
|
||||||
|
use App\Entities\Podcast;
|
||||||
|
use App\Libraries\SimpleRSSElement;
|
||||||
|
use Modules\Plugins\Core\BasePlugin;
|
||||||
|
|
||||||
|
class AcmeAllHooksPlugin extends BasePlugin
|
||||||
|
{
|
||||||
|
#[Override]
|
||||||
|
public function rssBeforeChannel(Podcast $podcast): void
|
||||||
|
{
|
||||||
|
$podcast->title = 'Podcast test';
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Override]
|
||||||
|
public function rssAfterChannel(Podcast $podcast, SimpleRSSElement $channel): void
|
||||||
|
{
|
||||||
|
$channel->addChild('foo', 'bar');
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Override]
|
||||||
|
public function rssBeforeItem(Episode $episode): void
|
||||||
|
{
|
||||||
|
$episode->title = 'Episode test';
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Override]
|
||||||
|
public function rssAfterItem(Episode $episode, SimpleRSSElement $item): void
|
||||||
|
{
|
||||||
|
$item->addChild('efoo', 'ebar');
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Override]
|
||||||
|
public function siteHead(): void
|
||||||
|
{
|
||||||
|
echo 'hello';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "acme/all-hooks",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"hooks": [
|
||||||
|
"rssBeforeChannel",
|
||||||
|
"rssAfterChannel",
|
||||||
|
"rssBeforeItem",
|
||||||
|
"rssAfterItem",
|
||||||
|
"siteHead"
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Plugins\Core\BasePlugin;
|
||||||
|
|
||||||
|
class AcmeEmptyManifestPlugin extends BasePlugin
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
{}
|
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Plugins\Core\BasePlugin;
|
||||||
|
|
||||||
|
class AcmeHelloUniversePlugin extends BasePlugin
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Plugins\Core\BasePlugin;
|
||||||
|
|
||||||
|
class AcmeHelloWorldPlugin extends BasePlugin
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use App\Entities\Podcast;
|
||||||
|
use App\Libraries\SimpleRSSElement;
|
||||||
|
use Modules\Plugins\Core\BasePlugin;
|
||||||
|
|
||||||
|
class AcmeUndeclaredHookPlugin extends BasePlugin
|
||||||
|
{
|
||||||
|
#[Override]
|
||||||
|
public function rssBeforeChannel(Podcast $podcast): void
|
||||||
|
{
|
||||||
|
$podcast->title = 'Podcast test undeclared';
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Override]
|
||||||
|
public function rssAfterChannel(Podcast $podcast, SimpleRSSElement $channel): void
|
||||||
|
{
|
||||||
|
$channel->addChild('foo', 'bar');
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"name": "acme/all-hooks",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"hooks": ["rssBeforeChannel"]
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Plugins\Core\BasePlugin;
|
||||||
|
|
||||||
|
class AtlantisHelloBroken extends BasePlugin
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"name": "atlantis/hello-broken",
|
||||||
|
"version": "1.0.0"
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Plugins\Core\BasePlugin;
|
||||||
|
|
||||||
|
class AtlantisHelloWorldPlugin extends BasePlugin
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"name": "atlantis/hello-world",
|
||||||
|
"version": "1.0.0"
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Modules\Plugins\Core\BasePlugin;
|
||||||
|
|
||||||
|
class AtlantisNoManifestPlugin extends BasePlugin
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"name": "atlantis/no-plugin-file",
|
||||||
|
"version": "1.0.0"
|
||||||
|
}
|
@ -6,14 +6,14 @@
|
|||||||
<x-Forms.Checkbox
|
<x-Forms.Checkbox
|
||||||
name="<?= $field->key ?>"
|
name="<?= $field->key ?>"
|
||||||
hint="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.hint', $plugin->getKey(), $type, $field->key), $field->hint)) ?>"
|
hint="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.hint', $plugin->getKey(), $type, $field->key), $field->hint)) ?>"
|
||||||
isChecked="<?= get_plugin_option($plugin->getKey(), $field->key, $context) ? 'true' : 'false' ?>"
|
isChecked="<?= get_plugin_setting($plugin->getKey(), $field->key, $context) ? 'true' : 'false' ?>"
|
||||||
><?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.label', $plugin->getKey(), $type, $field->key), $field->label)) ?></x-Forms.Checkbox>
|
><?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.label', $plugin->getKey(), $type, $field->key), $field->label)) ?></x-Forms.Checkbox>
|
||||||
<?php break;
|
<?php break;
|
||||||
case 'toggler': ?>
|
case 'toggler': ?>
|
||||||
<x-Forms.Toggler
|
<x-Forms.Toggler
|
||||||
name="<?= $field->key ?>"
|
name="<?= $field->key ?>"
|
||||||
hint="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.hint', $plugin->getKey(), $type, $field->key), $field->hint)) ?>"
|
hint="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.hint', $plugin->getKey(), $type, $field->key), $field->hint)) ?>"
|
||||||
isChecked="<?= get_plugin_option($plugin->getKey(), $field->key, $context) ? 'true' : 'false' ?>"
|
isChecked="<?= get_plugin_setting($plugin->getKey(), $field->key, $context) ? 'true' : 'false' ?>"
|
||||||
><?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.label', $plugin->getKey(), $type, $field->key), $field->label)) ?></x-Forms.Toggler>
|
><?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.label', $plugin->getKey(), $type, $field->key), $field->label)) ?></x-Forms.Toggler>
|
||||||
<?php break;
|
<?php break;
|
||||||
case 'radio-group': ?>
|
case 'radio-group': ?>
|
||||||
@ -24,7 +24,7 @@
|
|||||||
helper="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.helper', $plugin->getKey(), $type, $field->key), $field->helper)) ?>"
|
helper="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.helper', $plugin->getKey(), $type, $field->key), $field->helper)) ?>"
|
||||||
options="<?= esc(json_encode($field->getOptionsArray(sprintf('%s.settings.%s.%s.options', $plugin->getKey(), $type, $field->key)))) ?>"
|
options="<?= esc(json_encode($field->getOptionsArray(sprintf('%s.settings.%s.%s.options', $plugin->getKey(), $type, $field->key)))) ?>"
|
||||||
isRequired="<?= $field->optional ? 'false' : 'true' ?>"
|
isRequired="<?= $field->optional ? 'false' : 'true' ?>"
|
||||||
value="<?= get_plugin_option($plugin->getKey(), $field->key, $context) ?>"
|
value="<?= get_plugin_setting($plugin->getKey(), $field->key, $context) ?>"
|
||||||
/>
|
/>
|
||||||
<?php break;
|
<?php break;
|
||||||
case 'select': ?>
|
case 'select': ?>
|
||||||
@ -36,7 +36,7 @@
|
|||||||
helper="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.helper', $plugin->getKey(), $type, $field->key), $field->helper)) ?>"
|
helper="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.helper', $plugin->getKey(), $type, $field->key), $field->helper)) ?>"
|
||||||
options="<?= esc(json_encode($field->getOptionsArray(sprintf('%s.settings.%s.%s.options', $plugin->getKey(), $type, $field->key)))) ?>"
|
options="<?= esc(json_encode($field->getOptionsArray(sprintf('%s.settings.%s.%s.options', $plugin->getKey(), $type, $field->key)))) ?>"
|
||||||
isRequired="<?= $field->optional ? 'false' : 'true' ?>"
|
isRequired="<?= $field->optional ? 'false' : 'true' ?>"
|
||||||
value="<?= get_plugin_option($plugin->getKey(), $field->key, $context) ?>"
|
value="<?= get_plugin_setting($plugin->getKey(), $field->key, $context) ?>"
|
||||||
/>
|
/>
|
||||||
<?php break;
|
<?php break;
|
||||||
case 'select-multiple': ?>
|
case 'select-multiple': ?>
|
||||||
@ -48,7 +48,7 @@
|
|||||||
helper="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.helper', $plugin->getKey(), $type, $field->key), $field->helper)) ?>"
|
helper="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.helper', $plugin->getKey(), $type, $field->key), $field->helper)) ?>"
|
||||||
options="<?= esc(json_encode($field->getOptionsArray(sprintf('%s.settings.%s.%s.options', $plugin->getKey(), $type, $field->key)))) ?>"
|
options="<?= esc(json_encode($field->getOptionsArray(sprintf('%s.settings.%s.%s.options', $plugin->getKey(), $type, $field->key)))) ?>"
|
||||||
isRequired="<?= $field->optional ? 'false' : 'true' ?>"
|
isRequired="<?= $field->optional ? 'false' : 'true' ?>"
|
||||||
value="<?= esc(json_encode(get_plugin_option($plugin->getKey(), $field->key, $context))) ?>"
|
value="<?= esc(json_encode(get_plugin_setting($plugin->getKey(), $field->key, $context))) ?>"
|
||||||
/>
|
/>
|
||||||
<?php break;
|
<?php break;
|
||||||
case 'email': ?>
|
case 'email': ?>
|
||||||
@ -60,7 +60,7 @@
|
|||||||
hint="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.hint', $plugin->getKey(), $type, $field->key), $field->hint)) ?>"
|
hint="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.hint', $plugin->getKey(), $type, $field->key), $field->hint)) ?>"
|
||||||
helper="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.helper', $plugin->getKey(), $type, $field->key), $field->helper)) ?>"
|
helper="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.helper', $plugin->getKey(), $type, $field->key), $field->helper)) ?>"
|
||||||
isRequired="<?= $field->optional ? 'false' : 'true' ?>"
|
isRequired="<?= $field->optional ? 'false' : 'true' ?>"
|
||||||
value="<?= get_plugin_option($plugin->getKey(), $field->key, $context) ?>"
|
value="<?= get_plugin_setting($plugin->getKey(), $field->key, $context) ?>"
|
||||||
/>
|
/>
|
||||||
<?php break;
|
<?php break;
|
||||||
case 'url': ?>
|
case 'url': ?>
|
||||||
@ -73,7 +73,7 @@
|
|||||||
hint="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.hint', $plugin->getKey(), $type, $field->key), $field->hint)) ?>"
|
hint="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.hint', $plugin->getKey(), $type, $field->key), $field->hint)) ?>"
|
||||||
helper="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.helper', $plugin->getKey(), $type, $field->key), $field->helper)) ?>"
|
helper="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.helper', $plugin->getKey(), $type, $field->key), $field->helper)) ?>"
|
||||||
isRequired="<?= $field->optional ? 'false' : 'true' ?>"
|
isRequired="<?= $field->optional ? 'false' : 'true' ?>"
|
||||||
value="<?= get_plugin_option($plugin->getKey(), $field->key, $context) ?>"
|
value="<?= get_plugin_setting($plugin->getKey(), $field->key, $context) ?>"
|
||||||
/>
|
/>
|
||||||
<?php break;
|
<?php break;
|
||||||
case 'number': ?>
|
case 'number': ?>
|
||||||
@ -85,7 +85,7 @@
|
|||||||
hint="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.hint', $plugin->getKey(), $type, $field->key), $field->hint)) ?>"
|
hint="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.hint', $plugin->getKey(), $type, $field->key), $field->hint)) ?>"
|
||||||
helper="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.helper', $plugin->getKey(), $type, $field->key), $field->helper)) ?>"
|
helper="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.helper', $plugin->getKey(), $type, $field->key), $field->helper)) ?>"
|
||||||
isRequired="<?= $field->optional ? 'false' : 'true' ?>"
|
isRequired="<?= $field->optional ? 'false' : 'true' ?>"
|
||||||
value="<?= get_plugin_option($plugin->getKey(), $field->key, $context) ?>"
|
value="<?= get_plugin_setting($plugin->getKey(), $field->key, $context) ?>"
|
||||||
/>
|
/>
|
||||||
<?php break;
|
<?php break;
|
||||||
case 'textarea': ?>
|
case 'textarea': ?>
|
||||||
@ -96,7 +96,7 @@
|
|||||||
hint="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.hint', $plugin->getKey(), $type, $field->key), $field->hint)) ?>"
|
hint="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.hint', $plugin->getKey(), $type, $field->key), $field->hint)) ?>"
|
||||||
helper="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.helper', $plugin->getKey(), $type, $field->key), $field->helper)) ?>"
|
helper="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.helper', $plugin->getKey(), $type, $field->key), $field->helper)) ?>"
|
||||||
isRequired="<?= $field->optional ? 'false' : 'true' ?>"
|
isRequired="<?= $field->optional ? 'false' : 'true' ?>"
|
||||||
value="<?= get_plugin_option($plugin->getKey(), $field->key, $context) ?>"
|
value="<?= get_plugin_setting($plugin->getKey(), $field->key, $context) ?>"
|
||||||
/>
|
/>
|
||||||
<?php break;
|
<?php break;
|
||||||
case 'markdown': ?>
|
case 'markdown': ?>
|
||||||
@ -107,7 +107,7 @@
|
|||||||
hint="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.hint', $plugin->getKey(), $type, $field->key), $field->hint)) ?>"
|
hint="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.hint', $plugin->getKey(), $type, $field->key), $field->hint)) ?>"
|
||||||
helper="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.helper', $plugin->getKey(), $type, $field->key), $field->helper)) ?>"
|
helper="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.helper', $plugin->getKey(), $type, $field->key), $field->helper)) ?>"
|
||||||
isRequired="<?= $field->optional ? 'false' : 'true' ?>"
|
isRequired="<?= $field->optional ? 'false' : 'true' ?>"
|
||||||
value="<?= get_plugin_option($plugin->getKey(), $field->key, $context) ?>"
|
value="<?= get_plugin_setting($plugin->getKey(), $field->key, $context) ?>"
|
||||||
/>
|
/>
|
||||||
<?php break;
|
<?php break;
|
||||||
case 'datetime':
|
case 'datetime':
|
||||||
@ -119,7 +119,7 @@
|
|||||||
hint="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.hint', $plugin->getKey(), $type, $field->key), $field->hint)) ?>"
|
hint="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.hint', $plugin->getKey(), $type, $field->key), $field->hint)) ?>"
|
||||||
helper="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.helper', $plugin->getKey(), $type, $field->key), $field->helper)) ?>"
|
helper="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.helper', $plugin->getKey(), $type, $field->key), $field->helper)) ?>"
|
||||||
isRequired="<?= $field->optional ? 'false' : 'true' ?>"
|
isRequired="<?= $field->optional ? 'false' : 'true' ?>"
|
||||||
value="<?= get_plugin_option($plugin->getKey(), $field->key, $context) ?>"
|
value="<?= get_plugin_setting($plugin->getKey(), $field->key, $context) ?>"
|
||||||
/>
|
/>
|
||||||
<?php break;
|
<?php break;
|
||||||
default: ?>
|
default: ?>
|
||||||
@ -130,7 +130,7 @@
|
|||||||
hint="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.hint', $plugin->getKey(), $type, $field->key), $field->hint)) ?>"
|
hint="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.hint', $plugin->getKey(), $type, $field->key), $field->hint)) ?>"
|
||||||
helper="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.helper', $plugin->getKey(), $type, $field->key), $field->helper)) ?>"
|
helper="<?= esc($field->getTranslated(sprintf('%s.settings.%s.%s.helper', $plugin->getKey(), $type, $field->key), $field->helper)) ?>"
|
||||||
isRequired="<?= $field->optional ? 'false' : 'true' ?>"
|
isRequired="<?= $field->optional ? 'false' : 'true' ?>"
|
||||||
value="<?= get_plugin_option($plugin->getKey(), $field->key, $context) ?>"
|
value="<?= get_plugin_setting($plugin->getKey(), $field->key, $context) ?>"
|
||||||
/>
|
/>
|
||||||
<?php endswitch; ?>
|
<?php endswitch; ?>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user