Plugin Update (#16291)

* Plugin Update
Extract interfaces for use in plugin packages

# Conflicts:
#	composer.lock

* Fix some issues
settings_view -> content_view
This commit is contained in:
Tony Murray
2024-08-15 15:26:47 -05:00
committed by GitHub
parent f6fe0cf2da
commit 70c2c543f3
19 changed files with 79 additions and 58 deletions

View File

@@ -26,11 +26,12 @@
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
use LibreNMS\Interfaces\Plugins\PluginManagerInterface;
class PluginManager extends Facade
{
protected static function getFacadeAccessor()
{
return \App\Plugins\PluginManager::class;
return PluginManagerInterface::class;
}
}

View File

@@ -3,11 +3,11 @@
namespace App\Http\Controllers;
use App\Models\Plugin;
use App\Plugins\PluginManager;
use LibreNMS\Interfaces\Plugins\PluginManagerInterface;
class PluginAdminController extends Controller
{
public function __invoke(PluginManager $manager): \Illuminate\Contracts\View\View
public function __invoke(PluginManagerInterface $manager): \Illuminate\Contracts\View\View
{
// legacy v1 plugins
\LibreNMS\Plugins::scanNew();

View File

@@ -3,13 +3,13 @@
namespace App\Http\Controllers;
use App\Models\Plugin;
use App\Plugins\Hooks\PageHook;
use App\Plugins\PluginManager;
use Illuminate\Http\Request;
use LibreNMS\Interfaces\Plugins\Hooks\SinglePageHook;
use LibreNMS\Interfaces\Plugins\PluginManagerInterface;
class PluginPageController extends Controller
{
public function __invoke(PluginManager $manager, Plugin $plugin): \Illuminate\Contracts\View\View
public function __invoke(PluginManagerInterface $manager, Plugin $plugin): \Illuminate\Contracts\View\View
{
if (! $manager->pluginEnabled($plugin->plugin_name)) {
abort(404, trans('plugins.errors.disabled', ['plugin' => $plugin->plugin_name]));
@@ -20,10 +20,10 @@ class PluginPageController extends Controller
'title' => trans('plugins.settings_page', ['plugin' => $plugin->plugin_name]),
'plugin_name' => $plugin->plugin_name,
'plugin_id' => Plugin::where('plugin_name', $plugin->plugin_name)->value('plugin_id'),
'settings_view' => 'plugins.missing',
'content_view' => 'plugins.missing',
'settings' => [],
],
(array) $manager->call(PageHook::class, [], $plugin->plugin_name)->first()
$manager->call(SinglePageHook::class, [], $plugin->plugin_name)[0] ?? []
);
return view('plugins.settings', $data);

View File

@@ -3,14 +3,14 @@
namespace App\Http\Controllers;
use App\Models\Plugin;
use App\Plugins\Hooks\SettingsHook;
use App\Plugins\PluginManager;
use Illuminate\Http\Request;
use LibreNMS\Interfaces\Plugins\Hooks\SettingsHook;
use LibreNMS\Interfaces\Plugins\PluginManagerInterface;
use LibreNMS\Util\Notifications;
class PluginSettingsController extends Controller
{
public function __invoke(PluginManager $manager, Plugin $plugin): \Illuminate\Contracts\View\View
public function __invoke(PluginManagerInterface $manager, Plugin $plugin): \Illuminate\Contracts\View\View
{
if (! $manager->pluginEnabled($plugin->plugin_name)) {
abort(404, trans('plugins.errors.disabled', ['plugin' => $plugin->plugin_name]));
@@ -21,10 +21,10 @@ class PluginSettingsController extends Controller
'title' => trans('plugins.settings_page', ['plugin' => $plugin->plugin_name]),
'plugin_name' => $plugin->plugin_name,
'plugin_id' => Plugin::where('plugin_name', $plugin->plugin_name)->value('plugin_id'),
'settings_view' => 'plugins.missing',
'content_view' => 'plugins.missing',
'settings' => [],
],
(array) $manager->call(SettingsHook::class, [], $plugin->plugin_name)->first()
$manager->call(SettingsHook::class, [], $plugin->plugin_name)[0] ?? []
);
return view('plugins.settings', $data);

View File

@@ -41,11 +41,11 @@ use App\Models\User;
use App\Models\UserPref;
use App\Models\Vminfo;
use App\Models\WirelessSensor;
use App\Plugins\Hooks\MenuEntryHook;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;
use LibreNMS\Config;
use LibreNMS\Interfaces\Plugins\Hooks\MenuEntryHook;
use LibreNMS\Plugins;
use LibreNMS\Util\ObjectCache;
use PluginManager;

View File

@@ -33,7 +33,7 @@ class Page extends PageHook
{
// point to the view for your plugin's settings
// this is the default name so you can create the blade file as in this plugin
// by ommitting the variable, or point to another one
// by omitting the variable, or point to another one
// public string $view = 'resources.views.page';

View File

@@ -1,16 +0,0 @@
<?php
namespace App\Plugins;
interface Hook
{
/**
* Will be called by the plugin manager to check if the user is authorized. Will be called with Dependency Injection.
*/
// public function authorize(): bool;
/**
* Will be called by the plugin manager to execute this plugin at the correct time. Will be called with Dependency Injection.
*/
// public function handle();
}

View File

@@ -30,7 +30,7 @@ use App\Models\User;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Str;
abstract class DeviceOverviewHook
abstract class DeviceOverviewHook implements \LibreNMS\Interfaces\Plugins\Hooks\DeviceOverviewHook
{
public string $view = 'resources.views.device-overview';

View File

@@ -29,7 +29,7 @@ use App\Models\User;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Str;
abstract class MenuEntryHook
abstract class MenuEntryHook implements \LibreNMS\Interfaces\Plugins\Hooks\MenuEntryHook
{
public string $view = 'resources.views.menu';

View File

@@ -29,7 +29,7 @@ use App\Models\User;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Str;
abstract class PageHook
abstract class PageHook implements \LibreNMS\Interfaces\Plugins\Hooks\SinglePageHook
{
public string $view = 'resources.views.page';
@@ -46,7 +46,7 @@ abstract class PageHook
final public function handle(string $pluginName, array $settings, Application $app): array
{
return array_merge([
'settings_view' => Str::start($this->view, "$pluginName::"),
'content_view' => Str::start($this->view, "$pluginName::"),
], $app->call([$this, 'data'], [
'settings' => $settings,
]));

View File

@@ -27,11 +27,10 @@ namespace App\Plugins\Hooks;
use App\Models\Port;
use App\Models\User;
use App\Plugins\Hook;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Str;
abstract class PortTabHook implements Hook
abstract class PortTabHook implements \LibreNMS\Interfaces\Plugins\Hooks\PortTabHook
{
/** @var string */
public $view = 'resources.views.port-tab';

View File

@@ -29,7 +29,7 @@ use App\Models\User;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Str;
abstract class SettingsHook
abstract class SettingsHook implements \LibreNMS\Interfaces\Plugins\Hooks\SettingsHook
{
public string $view = 'resources.views.settings';
@@ -48,7 +48,7 @@ abstract class SettingsHook
final public function handle(string $pluginName, array $settings, Application $app): array
{
return array_merge([
'settings_view' => Str::start($this->view, "$pluginName::"),
'content_view' => Str::start($this->view, "$pluginName::"),
], $this->data($app->call([$this, 'data'], [
'settings' => $settings,
])));

View File

@@ -30,10 +30,11 @@ use App\Models\Plugin;
use Exception;
use Illuminate\Database\QueryException;
use Illuminate\Support\Collection;
use LibreNMS\Interfaces\Plugins\PluginManagerInterface;
use LibreNMS\Util\Notifications;
use Log;
class PluginManager
class PluginManager implements PluginManagerInterface
{
/** @var Collection */
private $hooks;
@@ -104,9 +105,9 @@ class PluginManager
* @param string $hookType
* @param array $args
* @param string|null $plugin only for this plugin if set
* @return \Illuminate\Support\Collection
* @return array
*/
public function call(string $hookType, array $args = [], ?string $plugin = null): Collection
public function call(string $hookType, array $args = [], ?string $plugin = null): array
{
return $this->hooksFor($hookType, $args, $plugin)
->map(function ($hook) use ($args, $hookType) {
@@ -127,7 +128,7 @@ class PluginManager
}
})->filter(function ($hook) {
return $hook !== 'HOOK FAILED';
});
})->values()->all();
}
/**

View File

@@ -26,28 +26,28 @@
namespace App\Providers;
use App\Exceptions\PluginDoesNotImplementHookException;
use App\Plugins\PluginManager;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
use LibreNMS\Interfaces\Plugins\PluginManagerInterface;
class PluginProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton(PluginManager::class, function ($app) {
return new PluginManager;
$this->app->singleton(PluginManagerInterface::class, function ($app) {
return new \App\Plugins\PluginManager;
});
}
public function boot(): void
{
$this->loadLocalPlugins($this->app->make(PluginManager::class));
$this->loadLocalPlugins($this->app->make(PluginManagerInterface::class));
}
/**
* Load any local plugins these plugins must implement only one hook.
*/
protected function loadLocalPlugins(PluginManager $manager): void
protected function loadLocalPlugins(PluginManagerInterface $manager): void
{
$plugin_view_location_registered = [];
@@ -83,8 +83,8 @@ class PluginProvider extends ServiceProvider
*/
protected function hookType(string $class): string
{
foreach (class_parents($class) as $parent) {
if (Str::startsWith($parent, 'App\Plugins\Hooks\\')) {
foreach (class_implements($class) as $parent) {
if (Str::startsWith($parent, 'LibreNMS\Interfaces\Plugins\Hooks\\')) {
return $parent;
}
}

View File

@@ -42,6 +42,7 @@
"laravel/tinker": "^2.8",
"laravel/ui": "^4.2",
"librenms/laravel-vue-i18n-generator": "dev-master",
"librenms/plugin-interfaces": "^1.0",
"mews/purifier": "^3.4",
"nunomaduro/laravel-console-summary": "^1.9",
"pear/console_color2": "^0.1",

37
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "277d3c3cae41b8c97cf6e330393f124a",
"content-hash": "dabb9a7876ed5d206fc8278729d2d417",
"packages": [
{
"name": "amenadiel/jpgraph",
@@ -3180,6 +3180,41 @@
},
"time": "2024-07-26T10:48:47+00:00"
},
{
"name": "librenms/plugin-interfaces",
"version": "1.0",
"source": {
"type": "git",
"url": "https://github.com/librenms/plugin-interfaces.git",
"reference": "7a196c3e47c5c5eb140f895dde6ceac998cf7b48"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/librenms/plugin-interfaces/zipball/7a196c3e47c5c5eb140f895dde6ceac998cf7b48",
"reference": "7a196c3e47c5c5eb140f895dde6ceac998cf7b48",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"type": "library",
"autoload": {
"psr-4": {
"LibreNMS\\Interfaces\\Plugins\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"0BSD"
],
"description": "Interfaces required to create a LibreNMS Plugin",
"homepage": "https://www.librenms.org/",
"support": {
"issues": "https://github.com/librenms/plugin-interfaces/issues",
"source": "https://github.com/librenms/plugin-interfaces/tree/1.0"
},
"time": "2024-08-15T15:23:53+00:00"
},
{
"name": "mews/purifier",
"version": "3.4.2",

View File

@@ -1,6 +1,6 @@
<?php
use App\Plugins\Hooks\DeviceOverviewHook;
use LibreNMS\Interfaces\Plugins\Hooks\DeviceOverviewHook;
$overview = 1;
@@ -20,9 +20,9 @@ require 'includes/html/dev-groups-overview-data.inc.php';
require 'overview/puppet_agent.inc.php';
echo LibreNMS\Plugins::call('device_overview_container', [$device]);
PluginManager::call(DeviceOverviewHook::class, ['device' => DeviceCache::getPrimary()])->each(function ($view) {
foreach (PluginManager::call(DeviceOverviewHook::class, ['device' => DeviceCache::getPrimary()]) as $view) {
echo $view;
});
}
require 'overview/ports.inc.php';

View File

@@ -13,7 +13,7 @@
* @author PipoCanaja <pipocanaja@gmail.com>
*/
use App\Plugins\Hooks\PortTabHook;
use LibreNMS\Interfaces\Plugins\Hooks\PortTabHook;
$pagetitle[] = 'Plugins';
$no_refresh = true;
@@ -23,6 +23,6 @@ $no_refresh = true;
<hr>
<?php
echo \LibreNMS\Plugins::call('port_container', [$device, $port]);
PluginManager::call(PortTabHook::class, ['port' => $portModel])->each(function ($view) {
foreach (PluginManager::call(PortTabHook::class, ['port' => $portModel]) as $view) {
echo $view;
});
};

View File

@@ -3,5 +3,5 @@
@section('title', $title)
@section('content')
@include($settings_view, $settings)
@include($content_view, $settings)
@endsection