2014-02-25 12:51:07 +00:00
< ? php
2016-08-21 13:07:14 +00:00
/**
* Plugins . php
*
* - Description -
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2021-02-08 23:29:04 +00:00
* along with this program . If not , see < https :// www . gnu . org / licenses />
2016-08-21 13:07:14 +00:00
*
2018-07-17 12:46:49 +00:00
* @ author LibreNMS Group
2021-09-10 18:09:53 +00:00
*
2021-02-08 23:29:04 +00:00
* @ link https :// www . librenms . org
2021-09-10 18:09:53 +00:00
*
2016-08-21 13:07:14 +00:00
* @ copyright 2016
*/
2014-02-25 12:51:07 +00:00
2016-08-18 01:24:27 +00:00
namespace LibreNMS ;
2018-05-09 13:05:17 +00:00
use App\Models\Plugin ;
2022-09-26 03:47:58 +00:00
use LibreNMS\Util\Notifications ;
2018-12-08 13:16:49 +00:00
use Log ;
2018-05-09 13:05:17 +00:00
2018-07-17 12:46:49 +00:00
/**
* Handles loading of plugins
*
* @ author LibreNMS Group
2021-09-10 18:09:53 +00:00
*
2021-02-08 23:29:04 +00:00
* @ link https :// www . librenms . org
2021-09-10 18:09:53 +00:00
*
2018-07-17 12:46:49 +00:00
* @ copyright 2016
*
* Supported hooks
* < ul >
* < li > menu </ li >
* < li > device_overview_container </ li >
* < li > port_container </ li >
* </ ul >
*/
2016-08-19 01:28:22 +00:00
class Plugins
{
2018-07-17 12:46:49 +00:00
/**
* Array of plugin hooks
*
2021-04-08 13:14:49 +00:00
* @ var array | null
2018-07-17 12:46:49 +00:00
*/
private static $plugins = null ;
/**
* Start loading active plugins
*
* @ return bool
*/
public static function start ()
{
if ( ! is_null ( self :: $plugins )) {
return false ;
}
2014-02-25 12:51:07 +00:00
2018-07-17 12:46:49 +00:00
self :: $plugins = [];
$plugin_dir = Config :: get ( 'plugin_dir' );
2015-07-13 18:10:26 +00:00
2018-07-17 12:46:49 +00:00
if ( ! file_exists ( $plugin_dir )) {
return false ;
}
2015-07-13 18:10:26 +00:00
2018-07-17 12:46:49 +00:00
$plugin_files = Plugin :: isActive () -> get () -> toArray ();
foreach ( $plugin_files as $plugins ) {
$plugin_file = $plugin_dir . '/' . $plugins [ 'plugin_name' ] . '/' . $plugins [ 'plugin_name' ] . '.php' ;
$plugin_info = pathinfo ( $plugin_file );
if ( $plugin_info [ 'extension' ] !== 'php' ) {
continue ;
2018-05-09 13:05:17 +00:00
}
2018-07-17 12:46:49 +00:00
if ( ! is_file ( $plugin_file )) {
continue ;
}
2014-02-25 12:51:07 +00:00
2018-07-17 12:46:49 +00:00
self :: load ( $plugin_file , $plugin_info [ 'filename' ]);
}
2015-07-13 18:10:26 +00:00
2018-07-17 12:46:49 +00:00
return true ;
}
/**
* Load plugin
*
2021-09-08 21:35:56 +00:00
* @ param string $file Full path and filename of plugin
* @ param string $pluginName Plugin name without any namespace
2018-07-17 12:46:49 +00:00
* @ return object | null
*/
2014-02-25 12:51:07 +00:00
public static function load ( $file , $pluginName )
{
2019-04-12 04:26:42 +00:00
chdir ( Config :: get ( 'install_dir' ) . '/html' );
2018-07-17 18:55:23 +00:00
$plugin = self :: getInstance ( $file , $pluginName );
2018-07-17 12:46:49 +00:00
2019-10-16 21:18:17 +00:00
if ( ! is_null ( $plugin )) {
$class = get_class ( $plugin );
$hooks = get_class_methods ( $class );
foreach (( array ) $hooks as $hookName ) {
if ( $hookName [ 0 ] != '_' ) {
2022-08-30 14:00:12 +00:00
self :: $plugins [ $hookName ][] = $plugin ;
2019-10-16 21:18:17 +00:00
}
2018-07-17 18:55:23 +00:00
}
}
2019-04-12 04:26:42 +00:00
chdir ( Config :: get ( 'install_dir' ));
2018-07-17 18:55:23 +00:00
return $plugin ;
}
/**
* Get an instance of this plugin
* Search various namespaces and include files if needed .
*
2021-09-08 21:35:56 +00:00
* @ param string $file
* @ param string $pluginName
2018-07-17 18:55:23 +00:00
* @ return object | null
*/
private static function getInstance ( $file , $pluginName )
{
2018-07-17 12:46:49 +00:00
$ns_prefix = 'LibreNMS\\Plugins\\' ;
$ns_psr4 = $ns_prefix . $pluginName . '\\' . $pluginName ;
$ns_plugin = $ns_prefix . $pluginName ;
$ns_global = $pluginName ;
2018-07-17 18:55:23 +00:00
if ( class_exists ( $ns_psr4 )) {
return new $ns_psr4 ;
2018-07-17 12:46:49 +00:00
}
2018-07-17 18:55:23 +00:00
if ( class_exists ( $ns_plugin )) {
return new $ns_plugin ;
2018-07-17 12:46:49 +00:00
}
2018-07-17 18:55:23 +00:00
// Include file because it's not psr4 (may have been included by previous class_exists calls
include_once $file ;
2018-07-17 12:46:49 +00:00
2018-07-17 18:55:23 +00:00
if ( class_exists ( $ns_global )) {
return new $ns_global ;
2018-07-17 12:46:49 +00:00
}
2018-07-17 18:55:23 +00:00
return null ;
2018-07-17 12:46:49 +00:00
}
2015-07-13 18:10:26 +00:00
2018-07-17 12:46:49 +00:00
/**
* Get all plugins implementing a specific hook .
*
2021-09-08 21:35:56 +00:00
* @ param string $hook Name of the hook to get count for
2018-07-17 12:46:49 +00:00
* @ return int | bool
*/
2018-05-22 07:11:27 +00:00
public static function countHooks ( $hook )
{
// count all plugins implementing a specific hook
self :: start ();
if ( ! empty ( self :: $plugins [ $hook ])) {
return count ( self :: $plugins [ $hook ]);
} else {
return false ;
}
}
2015-07-13 18:10:26 +00:00
2018-07-17 12:46:49 +00:00
/**
* Call hook for plugin .
*
2021-09-08 21:35:56 +00:00
* @ param string $hook Name of hook to call
* @ param array | false $params Optional array of parameters for hook
2019-05-13 19:53:29 +00:00
* @ return string
2018-07-17 12:46:49 +00:00
*/
2016-08-19 01:28:22 +00:00
public static function call ( $hook , $params = false )
{
2019-04-12 04:26:42 +00:00
chdir ( Config :: get ( 'install_dir' ) . '/html' );
2018-05-09 13:05:17 +00:00
self :: start ();
2019-05-13 19:53:29 +00:00
ob_start ();
2019-04-12 04:26:42 +00:00
if ( ! empty ( self :: $plugins [ $hook ])) {
2022-08-30 14:00:12 +00:00
foreach ( self :: $plugins [ $hook ] as $plugin ) {
2019-04-12 04:26:42 +00:00
try {
if ( ! is_array ( $params )) {
2022-08-30 14:00:12 +00:00
@ call_user_func ([ $plugin , $hook ]);
2019-04-12 04:26:42 +00:00
} else {
2022-08-30 14:00:12 +00:00
@ call_user_func_array ([ $plugin , $hook ], $params );
2019-04-12 04:26:42 +00:00
}
2022-09-26 03:47:58 +00:00
} catch ( \Exception | \Error $e ) {
2019-04-12 04:26:42 +00:00
Log :: error ( $e );
2022-09-26 03:47:58 +00:00
$class = ( string ) get_class ( $plugin );
$name = property_exists ( $class , 'name' ) ? $class :: $name : basename ( str_replace ( '\\' , '/' , $class ));
Notifications :: create ( " Plugin $name disabled " , " $name caused an error and was disabled, please check with the plugin creator to fix the error. The error can be found in logs/librenms.log " , 'plugins' , 2 );
Plugin :: where ( 'plugin_name' , $name ) -> update ([ 'plugin_active' => 0 ]);
2018-12-08 13:16:49 +00:00
}
2015-07-13 18:10:26 +00:00
}
2014-02-25 12:51:07 +00:00
}
2019-05-13 19:53:29 +00:00
$output = ob_get_contents ();
ob_end_clean ();
2019-04-12 04:26:42 +00:00
chdir ( Config :: get ( 'install_dir' ));
2020-09-21 12:54:51 +00:00
2019-05-13 19:53:29 +00:00
return $output ;
2018-07-17 12:46:49 +00:00
}
2018-05-09 13:05:17 +00:00
2018-07-17 12:46:49 +00:00
/**
* Get count of hooks .
*
* @ return int
*/
2018-05-09 13:05:17 +00:00
public static function count ()
{
self :: start ();
2020-09-21 12:54:51 +00:00
2018-05-09 13:05:17 +00:00
return count ( self :: $plugins );
}
2021-10-19 11:53:28 +00:00
public static function scanNew ()
{
$countInstalled = 0 ;
if ( file_exists ( \LibreNMS\Config :: get ( 'plugin_dir' ))) {
$plugin_files = array_diff ( scandir ( \LibreNMS\Config :: get ( 'plugin_dir' )), [ '..' , '.' ]);
$plugin_files = array_diff ( $plugin_files , Plugin :: versionOne () -> pluck ( 'plugin_name' ) -> toArray ());
foreach ( $plugin_files as $name ) {
if ( is_dir ( \LibreNMS\Config :: get ( 'plugin_dir' ) . '/' . $name )
&& is_file ( \LibreNMS\Config :: get ( 'plugin_dir' ) . '/' . $name . '/' . $name . '.php' )) {
Plugin :: create ([ 'plugin_name' => $name , 'plugin_active' => false , 'version' => 1 ]);
$countInstalled ++ ;
}
}
}
return $countInstalled ;
}
public static function scanRemoved ()
{
$countRemoved = 0 ;
if ( file_exists ( \LibreNMS\Config :: get ( 'plugin_dir' ))) {
$plugin_files = array_diff ( scandir ( \LibreNMS\Config :: get ( 'plugin_dir' )), [ '.' , '..' , '.gitignore' ]);
$plugins = Plugin :: versionOne () -> whereNotIn ( 'plugin_name' , $plugin_files ) -> select ( 'plugin_id' ) -> get ();
foreach ( $plugins as $plugin ) {
if ( $plugin -> delete ()) {
$countRemoved ++ ;
}
}
}
return $countRemoved ;
}
2018-07-17 12:46:49 +00:00
}