The Little Guy Posted June 27, 2012 Share Posted June 27, 2012 I am thinking of creating an application that allows for user plugins to extend the functionality of the application. I have written one before, but I am not sure if it is a good way of doing it. Any suggestions on how one could be created, and best practices for making one? Quote Link to comment https://forums.phpfreaks.com/topic/264895-plugin-system/ Share on other sites More sharing options...
scootstah Posted June 27, 2012 Share Posted June 27, 2012 I like the idea of using hooks, so that plugins don't have to modify any part of the application. To see what I mean, compare something like Wordpress to SMF or phpBB. Quote Link to comment https://forums.phpfreaks.com/topic/264895-plugin-system/#findComment-1357509 Share on other sites More sharing options...
RobertP Posted June 27, 2012 Share Posted June 27, 2012 Write it your own way. But NEVER write it the way smf does ( LOL ). Quote Link to comment https://forums.phpfreaks.com/topic/264895-plugin-system/#findComment-1357567 Share on other sites More sharing options...
The Little Guy Posted June 30, 2012 Author Share Posted June 30, 2012 here is what I did: foreach($plugins as $plugin){ $dir = $plugin["directory"]; $filename = "plugins/$dir/index.during.php"; if(is_file($filename)){ require_once $filename; } } I don't know if it is a good method or not, but in index.php this code runs in the middle of the page, it calls index.during.php and executes the script in there. That script is a procedural script that runs how ever it is programmed. Now I have come to another question... how would you make a plugin for a plugin? For example say I make a "Blog" plugin it has an entire blogging system built. Now lets say to my blog I want to add a poll system so people can vote for something. Any suggestions on an approach to do that? Quote Link to comment https://forums.phpfreaks.com/topic/264895-plugin-system/#findComment-1358213 Share on other sites More sharing options...
Adam Posted July 1, 2012 Share Posted July 1, 2012 Your method is fine to include the plugin code, but as scootstah mentioned you would need to use something like hooks to expose the core functionality. Otherwise your plug-ins are going to be incredibly limited. Hooks are essentially just kind of events that the plug-ins listen for, and can alter what happens or modify some data/objects passed in. There's a load of ways you could implement them, but here's a very rudimentary example: $hooks->register('blog.write', function($blog) { // Do something with the blog return $blog; }); $this->hooks->trigger('blog.write', array($blog)); You'd probably want to allow a callback to be passed in (optionally instead of a function) to allow the plug-ins to become more robust. You would also need to think about error/exception handling, extending core objects, core dependencies, permissions and prioritisation, etc. Think about it before you publish anything; if you dramatically change the implementation after launch you'll annoy any plug-in writers. I can't really comment on some of the challenges you'll face, because I've never actually implemented anything to this level before. Been meaning to for a while though. I would imagine there's some code out there already you could use if you don't fancy writing it yourself. Quote Link to comment https://forums.phpfreaks.com/topic/264895-plugin-system/#findComment-1358245 Share on other sites More sharing options...
The Little Guy Posted July 2, 2012 Author Share Posted July 2, 2012 I am kinda stumped or maybe even confused.... But with what you guys are saying, I have the following: /classes/Hook.php <?php class Hook extends Cleep{ public $listeners = array(); public function __construct(){ parent::__construct(); } public function register($name, $callback){ $this->listeners[$name] = $callback; } public function trigger(){ $args = func_get_args(); $argNum = count($args); if($argNum < 1) trigger_error("Insufficient arguments", E_USER_ERROR); $hook_name = array_shift($args); return call_user_func($this->listeners[$hook_name], $args); } } /includes/setup.php $hook = new Hook(); foreach($plugins as $plugin){ $plugin = $plugin["directory"]; $file = __DIR__."/register_plugins/$plugin.php"; if(is_file($file)){ require_once $file; } } /includes/register_plugins/$plugin.php $hook->register("hi", function(){ $this->add("CONTENT", "Hello! I Am A Blog"); }); The part I am stumped on, is how can I use $this->add("CONTENT", "Hello! I Am A Blog"); because I am getting this: Fatal error: Using $this when not in object context in /includes/register_plugins/blog.php on line 4 Am I doing something wrong or missing something? Quote Link to comment https://forums.phpfreaks.com/topic/264895-plugin-system/#findComment-1358491 Share on other sites More sharing options...
Adam Posted July 2, 2012 Share Posted July 2, 2012 Yeah, you're just passing in an anonymous function, not an object. Where are you expecting the add() method to come from? You'd be much better off passing in the data like in my example though, as opposed to some random method names like "add()". That would get confusing, and if there's ever say two pieces of data in question, then how would that work? Quote Link to comment https://forums.phpfreaks.com/topic/264895-plugin-system/#findComment-1358492 Share on other sites More sharing options...
The Little Guy Posted July 2, 2012 Author Share Posted July 2, 2012 actually "add" should be "assign", it is from my template class, and I can not have a second template instance so, my: Hook extends Cleep extends Template extends Base. I don't really understand your example, there isn't enough information. Quote Link to comment https://forums.phpfreaks.com/topic/264895-plugin-system/#findComment-1358493 Share on other sites More sharing options...
ignace Posted July 2, 2012 Share Posted July 2, 2012 If your template variable is called $template then pass it through use() $hook->register("hi", function() use($template, $hook) { $template->add("CONTENT", "Hello! I Am A Blog"); }); Or make sure to pass it when calling call_user_func(); $hook->register("hi", function($template) { $template->add("CONTENT", "Hello! I Am A Blog"); }); Quote Link to comment https://forums.phpfreaks.com/topic/264895-plugin-system/#findComment-1358496 Share on other sites More sharing options...
ignace Posted July 2, 2012 Share Posted July 2, 2012 Look at https://github.com/proem/proem/blob/develop/lib/Proem/Api/Signal/Event/Standard.php https://github.com/proem/proem/blob/develop/lib/Proem/Api/Signal/Manager/Standard.php For an example hook system. This has been developed by one of our members: thorpe. If you want to be able to stopPropagation aswell then take a look at https://github.com/zendframework/zf2/blob/master/library/Zend/EventManager/Event.php https://github.com/zendframework/zf2/blob/master/library/Zend/EventManager/EventManager.php Both have many similarities except for the stopPropagation. Quote Link to comment https://forums.phpfreaks.com/topic/264895-plugin-system/#findComment-1358498 Share on other sites More sharing options...
trq Posted July 2, 2012 Share Posted July 2, 2012 stopPropagation is actually a feature that I plan on implementing pretty soon. I'm working on a few plugins at the moment that will require it to be available. Quote Link to comment https://forums.phpfreaks.com/topic/264895-plugin-system/#findComment-1358512 Share on other sites More sharing options...
The Little Guy Posted July 2, 2012 Author Share Posted July 2, 2012 So I kinda changed it up, taking some of your guy ideas (Thanks for the thoughts/help). What do you think of me taking this approach. <?php /** * @var $hook Hook * @var $template Template */ $blog = new stdClass(); $blog->hi = function($name) use ($template){ $template->assign("CONTENT", "Hi $name, I am a blog!"); }; $hook->register("blog", $blog); // Registers the blog class using the name blog <?php /** * @var $hook Hook */ $hook->trigger("blog.hi", "Ryan"); Quote Link to comment https://forums.phpfreaks.com/topic/264895-plugin-system/#findComment-1358558 Share on other sites More sharing options...
Adam Posted July 2, 2012 Share Posted July 2, 2012 The code triggering a hook shouldn't define how the plug-ins work, they should just pass in some context like the blog object/array. Including "hi" within the event name, and using it like you are, forces the plug-in to define an object with a hi() method. Keep it flexible and allow the plug-ins to pass in any callback they want. The "blog.write" in my example was just an event named "write" within a "blog" event namespace by the way. Doing it that way allows you to be more flexible with what your hooks listen for. Quote Link to comment https://forums.phpfreaks.com/topic/264895-plugin-system/#findComment-1358564 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.