As part of my framework's development, I wanted to be able to make core modules fixed across many sites, but equally I wanted to be able to tweak and modify certain bits easily.
What I came up with, is a simple 1 include script plugin system that can be dropped into any existing PHP site and immediately enable plugin support anywhere the developer chooses. So called Hooks are points set within the code that can be attached to to run extra code.
pluginmanager.inc
<?
{
private static $pluginManager;
private $plugins;
private $hooks;
function __construct ()
{
$this->plugins = array ();
$this->hooks = array ();
{
if ($PlugFolder != '.' && $PlugFolder != '..')
{
{
{
if ($Plug != '.' && $Plug != '..' && strtolower (substr ($Plug, strlen ($Plug) - 4)) == '.php')
{
$Code = file_get_contents ($plugin_dir . $PlugFolder . '/' . $Plug);
$Plug = strtolower ($Plug);
$Plug = substr ($Plug , 0, strlen ($Plug) - 4);
}
}
}
}
}
{
if (is_null (self::$pluginManager))
{
self::$pluginManager = new pluginManager ($config);
}
return self::$pluginManager;
}
private function addHook ($hook, $plugin, $code)
{
if (!isset ($this->hooks[$hook][$plugin]))
}
{
$hook = strtolower ($hook);
$Code = '';
if (isset ($this->hooks[$hook]))
{
foreach ($this->hooks[$hook] as $plugin => $hook)
$Code .= $hook;
}
return $Code;
}
}
?>
With this saved in your site code folder, you can include it and start it up by doing the following:
index.php
<?
Thats it then, the plugin manager is running in your site. Using the power of Eval, you can put plugins anywhere within your site setting known 'hooks' for example
index.php
<?
include ('pluginmanager.inc');
pluginManager::getPluginManager ();
eval (PluginManager::getPluginManager ()->pluginHooks ('Start'));
This creates a hook called Start, and runs any plugins that are attached to it - which at this moment we don't have any of.
Lets Create a Plugin
Relative to the pluginmanager.inc file, create a folder plugins. Within this, we can now create plugins - a single plugin is a group of text files, called by the plugin hook that they are to hook onto and filled with the PHP code to be run.
So, for example, if we create a folder, 'test' and within this 2 text files, one called Start.php and one called End.php (to match the Hooks we created earlier). We'll now create a simple plugin to monitor the time taken to load the entire page.
Start.php
function getMicroTime ()
{
list ($usec, $sec) = explode (" ",microtime ());
return ((float)$usec + (float)$sec);
}
$plugin_loadtime_startTime = getMicroTime ();
End.php
print "Page Generated in " . round (getMicroTime () - $plugin_loadtime_startTime, 2) . " seconds. ";
This simple block of code should enable you to add a Plugin System to your own sites relatively easily.
Similar Articles from the web
PHP5 Plugin System
In reply to this
Allen
said
error in pluginmanager
I know this is an older post, but the script has potential. I belive theres a couple of errors in the pluginmanager.inc file. Adding an extra closing tag for one of the "if" statements fixes this, but it still doesn't seem to execute the code from the plugin(s). Any ideas?
In reply to this
TimIgoe
said
PluginManager
I believe I've corrected the problem in the above code with the missing tag, also there was a legacy line in there from the system I actually developed it for, it was reliant on a configration file being set. This has been removed (the if check at the start of the
In reply to this
brixter
said
it's not working!
it's not working, I followed as stated above but it returns parse error i forgot the line. Please do UPDATE this because I want this^^
In reply to this
TimIgoe
said
Fix
In pasting the code into the blog, I'd managed to miss copying a } which caused the errors, this has been fixed now in the post above.
Let me know if you still need help.
In reply to this
brixter
said
fast
Your fast thank for the update^^ will post for question later. Thank you very much!
In reply to this
Brixter
said
fast
This one sure stands out from the rest of plugins tutorials out there. pretty excited to implement this one of these nights.
In reply to this
Brixter
said
Error
Hi again!
Seems like error in the pluginmanager.inc. added } in line 51 and it runs well.
It would be nice to be able to add <?PHP in the plugin directory. So I rplaced the code see below:
// Call any plugins that are hooked into this
public function pluginHooks ($hook)
{
$hook = strtolower ($hook);
$Code = '';
if (isset ($this->hooks[$hook]))
{
foreach ($this->hooks[$hook] as $plugin => $hook)
$Code .= $hook;
}
// Let's use eval instead of return
eval "PHP?>".$Code."<?";
}
}
Use echo to print the plugin.
echo (PluginManager::getPluginManager ()->pluginHooks ('Start'));
In reply to this
Brixter
said
reply
Hi again!
Hi, I noticed at your tutorial that if you are to create a plugin, you
won't be able to do so if you include php tags (<?PHP ?> ). So I
modified your code to work the way I like. Please see below if i am
correct:
<?PHP
class PSOUP_plugin
{
private static $PSOUP_plugin;
private $plugins;
private $hooks;
function __construct ()
{
$this->plugins = array ();
$this->hooks = array ();
// Get a list of hte plugins from the plugin folder
// include them, then initialise them
// Once they have been init'd
// the hooks dotted around the system can call on the plugins
$plugin_dir = 'PSOUP_plugins/';
$pluginsList = @opendir ($plugin_dir);
while ($PlugFolder = readdir ($pluginsList))
{
if ($PlugFolder != '.' && $PlugFolder != '..')
{ // Look for folders of plugins
if (is_dir ($plugin_dir . $PlugFolder))
{
// Now we look at the files in the plugin folder
$PlugList = opendir ($plugin_dir . $PlugFolder);
while ($Plug = readdir ($PlugList))
{
if ($Plug != '.' && $Plug != '..' && strtolower (substr ($Plug, strlen ($Plug) - 4)) == '.php')
{
$Code = file_get_contents ($plugin_dir . $PlugFolder . '/' . $Plug);
$Plug = strtolower ($Plug);
$Plug = substr ($Plug , 0, strlen ($Plug) - 4); // Strip the .PHP
// Save the Plugin (/plugins/PlugName/HookName.php)
$this->addHook ($Plug, $PlugFolder, $Code);
}
}
}
}
}
}
// Gets the plugin manager singleton
public static function fetch ()
{
if (is_null (self::$PSOUP_plugin))
{
self::$PSOUP_plugin = new PSOUP_plugin ($config);
}
return self::$PSOUP_plugin;
}
private function addHook ($hook, $plugin, $code)
{
if (!isset ($this->hooks[$hook][$plugin])) // Not set
$this->hooks[$hook][$plugin] = $code;
else // Already set
die ("Already Hooked into this - " . $plugin . " -> " . $hook);
}
// Call any plugins that are hooked into this
public function PSOUP_hooks ($hook)
{
$hook = strtolower ($hook);
$Code = '';
if (isset ($this->hooks[$hook]))
{
foreach ($this->hooks[$hook] as $plugin => $hook)
$Code .= $hook;
}
eval ("PHP?>".$Code."<?");
}
}
?>
I also noticed that with my current directory structure please see
below, when I try to invoke the plugin inside the directory admin, the
plugin it wont work. So with this regard, i created another plugin file
(admin.class.php) and changed the directory path from PSOUP_plugins/
into ../PSOUP_plugins/.
Please how can I fix this?
This is my directory structure as of now.
MYSCRIPT:
- Plugins
- Admin
- PSOUP_plugins
- Includes - plugin.class.php - admin.class.php
- index.php
In reply to this
TimIgoe
said
Fix
I don't think that'd work - You've modified the eval to have php?> and then <? rahter than ?> and <?php
For each plugin set, you need a folder, then you name the files with teh code the same as the 'hook' you are looking for.
in the case of the one you pasted,
PluginManager::getPluginManager ()->pluginHooks ('Start')
the file would be called Start.php within a folder, in plugins. So...
plugins\myTestPlugin\Start.php
also, you NEED to eval the code inline to get the function to run in the context of the data it has to access, if you eval in the object, your plugin code will never see the data from 'outside' that it may need to work on.
In reply to this
brixter
said
question
Thanks fixed about the ?> and <?PHP. Yes the plugin need to have the same name, but my question is that when I try to run the plugin inside a directory let say admin directory, it won't run not unless I create another plugin class and change the plugin path adding "../". So my problem right now is that I have the 2 same plugin class.
That is my only probem now. Thanks for this great plugin class youve shared. I am able to maximize by adding the ability to upload, install, uninstall and configure the activated plugin inside my admin panel. I also able to create my own "Hello Dolly" plugin with this ^^
Post a reply