First full commit of plugin system

This commit is contained in:
laf
2014-02-25 12:51:07 +00:00
parent 6c64e98bdf
commit c7e421e1fd
10 changed files with 297 additions and 7 deletions

61
doc/Plugin_System.md Normal file
View File

@ -0,0 +1,61 @@
# Developing for the Plugin System
This documentation will hopefully give you a basis for how to write a plugin for LibreNMS.
A test plugin is available on GitHib: https://github.com/laf/Test
Plugins need to be installed into html/plugins
The structure of a plugin is follows:
```
html/plugins
/PluginName
/PluginName.php
/PluginName.inc.php
```
The above structure is checked before a plugin can be installed.
All files / folder names are case sensitive and must match.
PluginName - This is a directory and needs to be named as per the plugin you are creating.
PluginName.php - This file is used to process calls into the plugin from the main LibreNMS install.
Here only functions within the class for your plugin that LibreNMS calls will be executed.
For a list of currently enabled system hooks, please see further down.
The minimum code required in this file is (replace Test with the name of your plugin):
```
<?php
class Test {
}
?>
```
PluginName.inc.php - This file is the main included file when browsing to the plugin itself.
You can use this to display / edit / remove whatever you like.
The minimum code required in this file is:
```
<?php
?>
```
### System Hooks ###
System hooks are called as functions within your plugin class, so for example to create a menu entry within the PLugin dropdown you would do:
```
public function menu() {
echo('<li><a href="plugin/p='.get_class().'">'.get_class().'</a></li>');
}
```
This would then add the name and a link to your plugin.
The following system hooks are currently available:
menu()
* This is called to build the plugin menu system and you can use this to link to your plugin (you don't have to).

View File

@ -0,0 +1,68 @@
<?php
class Plugins
{
private static $plugins = array();
public static function start()
{
global $config;
if(file_exists($config['plugin_dir']))
{
//$plugin_files = scandir($config['plugin_dir']);
$plugin_files = dbFetchRows("SELECT * FROM `plugins` WHERE `plugin_active` = '1'");
foreach($plugin_files as $plugins)
{
$plugin_info = pathinfo($config['plugin_dir'].'/'.$plugins['plugin_name'].'/'.$plugins['plugin_name'].'.php');
if($plugin_info['extension'] == 'php')
{
if(is_file($config['plugin_dir'].'/'.$plugins['plugin_name'].'/'.$plugins['plugin_name'].'.php'))
{
self::load($config['plugin_dir'].'/'.$plugins['plugin_name'].'/'.$plugins['plugin_name'].'.php', $plugin_info['filename']);
}
}
}
return true;
}
else
{
return false;
}
}
public static function load($file, $pluginName)
{
include($file);
$plugin = new $pluginName;
$hooks = get_class_methods($plugin);
foreach($hooks as $hookName)
{
if($hookName{0} != '_')
{
self::$plugins[$hookName][] = $pluginName;
}
}
return $plugin;
}
public static function call($hook, $params=false)
{
if(count(self::$plugins[$hook]) != 0)
{
foreach(self::$plugins[$hook] as $name)
{
if(!is_array($params))
{
call_user_func(array($name, $hook));
}
else
{
call_user_func_array(array($name, $hook), $params);
}
}
}
}
}
?>

View File

@ -484,15 +484,19 @@ if(is_file("includes/print-menubar-custom.inc.php"))
</form>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-hover="dropdown" data-toggle="dropdown"> Plugins<b class="caret"></b></a>
<ul class="dropdown-menu">
<?php
if($_SESSION['widescreen'] === 1)
{
echo(' <a href="' . $toggle_url . 'widescreen=no" title="Switch to normal screen width layout">Normal width</a>');
} else {
echo(' <a href="' . $toggle_url . 'widescreen=yes" title="Switch to wide screen layout">Widescreen</a>');
}
Plugins::call('menu');
?>
<li role="presentation" class="divider"></li>
<?php
if ($_SESSION['userlevel'] >= '10')
{
echo(' <li><a href="plugin/view=admin">Plugin Admin</a></li>');
}
?>
</ul>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-hover="dropdown" data-toggle="dropdown"><img src="images/16/wrench.png" border="0" align="absmiddle" /> System<b class="caret"></b></a>

View File

@ -17,6 +17,8 @@ include("../config.php");
include_once("../includes/definitions.inc.php");
include("../includes/functions.php");
include("includes/functions.inc.php");
include('includes/plugins.inc.php');
Plugins::start();
// Check for install.inc.php
if (!file_exists('../config.php') && $_SERVER['PATH_INFO'] != '/install.php') {

20
html/pages/plugin.inc.php Normal file
View File

@ -0,0 +1,20 @@
<?php
$link_array = array('page' => 'plugin');
$pagetitle[] = "Plugin";
if ($vars['view'] == "admin")
{
include_once('pages/plugin/admin.inc.php');
}
else
{
$plugin = dbFetchRow("SELECT `plugin_name` FROM `plugins` WHERE `plugin_name` = '".$vars['p']."'");
if(!empty($plugin))
{
require('plugins/'.$plugin['plugin_name'].'/'.$plugin['plugin_name'].'.inc.php');
}
}
?>

View File

@ -0,0 +1,95 @@
<?php
if ($_SESSION['userlevel'] >= '10')
{
// Scan for new plugins and add to the database
$new_plugins = scan_new_plugins();
// Check if we have to toggle enabled / disable a particular module
$plugin_id = $_POST['plugin_id'];
$plugin_active = $_POST['plugin_active'];
if(is_numeric($plugin_id) && is_numeric($plugin_active))
{
if( $plugin_active == '0')
{
$plugin_active = 1;
}
elseif( $plugin_active == '1')
{
$plugin_active = 0;
}
else
{
$plugin_active = 0;
}
dbUpdate(array('plugin_active' => $plugin_active), 'plugins', '`plugin_id` = ?', array($plugin_id));
}
?>
<div class="panel panel-default panel-condensed">
<div class="panel-heading">
<strong>System plugins</strong>
</div>
<?php
if($new_plugins > 0)
{
echo('<div class="panel-body">
<div class="alert alert-warning">
We have found ' . $new_plugins . ' new plugins that need to be configured and enabled
</div>
</div>');
}
?>
<table class="table table-condensed">
<tr>
<th>Name</th>
<th>Action</th>
</tr>
<?php
foreach (dbFetchRows("SELECT * FROM plugins") as $plugins)
{
if($plugins['plugin_active'] == 1)
{
$plugin_colour = 'bg-success';
$plugin_button = 'danger';
$plugin_label = 'Disable';
}
else
{
$plugin_colour = 'bg-danger';
$plugin_button = 'success';
$plugin_label = 'Enable';
}
echo('<tr class="'. $plugin_colour .'">
<td>
'. $plugins['plugin_name'] . '
</td>
<td>
<form class="form-inline" role="form" action="" method="post" id="'.$plugins['plugin_id'].'" name=="'.$plugins['plugin_id'].'">
<input type="hidden" name="plugin_id" value="'.$plugins['plugin_id'].'">
<input type="hidden" name="plugin_active" value="'.$plugins['plugin_active'].'">
<button type="submit" class="btn btn-sm btn-'.$plugin_button.'">'.$plugin_label.'</button>
</form>
</td>
</tr>');
}
?>
</table>
</div>
<?php
}
else
{
include("includes/error-no-perm.inc.php");
}
?>

2
html/plugins/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

View File

@ -1218,5 +1218,6 @@ if (!isset($config['html_dir'])) { $config['html_dir'] = $config['install_dir']
if (!isset($config['rrd_dir'])) { $config['rrd_dir'] = $config['install_dir'] . '/rrd'; }
if (!isset($config['log_dir'])) { $config['log_dir'] = $config['install_dir'] . '/logs'; }
if (!isset($config['log_file'])) { $config['log_dir'] . "/" . $config['project_id'] . ".log"; }
if (!isset($config['plugin_dir'])) { $config['plugin_dir'] = $config['html_dir'] . '/plugins'; }
?>

View File

@ -876,4 +876,40 @@ function is_port_valid($port, $device)
return $valid;
}
function scan_new_plugins()
{
global $config, $debug;
$installed = 0; // Track how many plugins we install.
if(file_exists($config['plugin_dir']))
{
$plugin_files = scandir($config['plugin_dir']);
foreach($plugin_files as $name)
{
if(is_dir($config['plugin_dir'].'/'.$name))
{
if($name != '.' && $name != '..')
{
if(is_file($config['plugin_dir'].'/'.$name.'/'.$name.'.php') && is_file($config['plugin_dir'].'/'.$name.'/'.$name.'.inc.php'))
{
$plugin_id = dbFetchRow("SELECT `plugin_id` FROM `plugins` WHERE `plugin_name` = '$name'");
if(empty($plugin_id))
{
if(dbInsert(array('plugin_name' => $name, 'plugin_active' => '0'), 'plugins'))
{
$installed++;
}
}
}
}
}
}
}
return( $installed );
}
?>

1
sql-schema/030.sql Normal file
View File

@ -0,0 +1 @@
CREATE TABLE IF NOT EXISTS `plugins` ( `plugin_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , `plugin_name` VARCHAR( 60 ) NOT NULL , `plugin_active` INT NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1;