Page 1 of 1
Blog w/ Plugin Support
Posted: Thu Jun 15, 2006 3:16 pm
by LiveFree
d11 has inspired me!
In the blog project I am working on currently, I have consulted with the team leader and he likes the idea of introducing plugins into the code. Being completly new to the plugin game, I would not know how to design a backend to accept them.
I have been studying Swift, but it's useage of the plugins is too high-up for me to understand as my target system is very simple.
So does anyone has any psuedo code that can help me with designing a script to accept plugins?
Thanks
Posted: Thu Jun 15, 2006 3:29 pm
by feyd
come up with the list of classes you wish to allow plugins with and how those plugins interact with other things (i.e. do they hook into something, or replace a class, etc). Now you will need to build an interface for each of those to implement to conform to your system. After that, it's a matter of knowing how to hook them in, which can easily be done via a configuration class and servicelocator pattern.
Posted: Thu Jun 15, 2006 4:00 pm
by LiveFree
Thanks for the insight!
Well, say I wish the plugin to be able to modify any part of the site. For example a plugin to add mailing list functionality would have to create or modify classes.
is there a way to do this using includes() and storing the plugin file in that included file
Posted: Thu Jun 15, 2006 4:09 pm
by feyd
yeah, it can be done via include() if it's an output-only plugin.. although it depends on how you do output and its own output. Personally, I'm almost all object oriented with this sort of stuff as OOP lends itself far more to doing the sort of plugins I generally work with (funtionality extension)
Re: Blog w/ Plugin Support
Posted: Thu Jun 15, 2006 4:33 pm
by Chris Corbyn
Tucker wrote:I have been studying Swift, but it's useage of the plugins is too high-up for me to understand as my target system is very simple.
Either I'm getting cleverer (*cough* as if) or I haven't made clear how Swift plugins work.
The concept is simple. The "pluggable" object contains an array. The "pluggable" then allows new objects (plugins) to be loaded into this array. Each of these plugins is given a reference back to the "pluggable" in pretty much the same fashion as the plugin was loaded into the pluggable.
(I'm starting to confuse myself here

).
Ok so far we've passed a "plugin" passed to a "pluggable" and the "pluggable" passed right back into the "plguin". That creates a cyclic link between the two objects so they both have access to *anything* public in each other.
I'll try to demonstrate this on it's most basic level using PHP4 standards which most OOPers follow
Code: Select all
class pluggable
{
var pluginCollection = array();
function loadPlugin(&$pluginObject)
{
$pluginObject->loadPluggable($this);
$this->pluginCollection[] =& $pluginObject;
}
}
class plugin
{
var $pluggable;
function loadPluggable(&$pluggableObject)
{
$this->pluggable =& $pluggableObject;
}
}
$pluggable =& new pluggable;
$pluggable->loadPlugin(new plugin());
Now, it's handy to be able to identify this plugin by a name rather than arbitrarily giving it an array index. In Swift this name is defined in the plugin but I'm planning on allowing a manual oberride in loadPlugin() in future so we'll do that here for simplicity.
Code: Select all
function loadPlugin(&$pluginObject, $name)
{
$pluginObject->loadPluggable($this);
$this->pluginCollection[$name] =& $pluginObject;
}
The only other real magic is how you get the plugins to respond to things that happen in the pluggable. I can see how it may be confusing at first sight but all that really happens is that the pluggable looks for methods of certain names in all of the loaded plugins and runs them blindly if it finds them.
That method to run them looks something like:
Code: Select all
function triggerEvent($event)
{
foreach ($this->pluginCollection as $id => $obj)
{
if (method_exists($obj, $event))
{
//Run it if it exists
$this->pluginCollection[$id]->$event();
}
}
}
So to make any loaded plugins run for example a method called "onConnect()" we'd like hard-code a call to triggerEvent() at the relevant point in the pluggable.
Code: Select all
function connect()
{
//Do something that connects to a server?
$this->triggerEvent('onConnect');
}
So a plugin that was intended to do something when the pluggable connects would quite simply include an onConnect() method.
Code: Select all
class plugin
{
var $pluggable;
function loadPluggable(&$pluggableObject)
{
$this->pluggable =& $pluggableObject;
}
function onConnect()
{
echo 'Connected!';
}
}
That's it. You can add as many events as you like and they'll always just loop over all plugins and execute them where possible. Because both the plugin and the pluggable have access to each other you can make changes to any properties or run methods in the pluggable from inside the plugin at relevant times. Hint hint, put things in properties if you want plugins to have access to them.
Posted: Thu Jun 15, 2006 5:47 pm
by LiveFree
wow!
Thanks for the long time I imagine you spent on that d11!
Ill try that out, Thanks again!
Posted: Thu Jun 15, 2006 7:42 pm
by LiveFree
Ok I have been thinking of ways to implement this all day based on what d11 says and I just have 2 questions:
a) Would the example you provided allow a plugin to create a new working class that the plugin would operate out of
b) What is with the &'s everywhere? =& and the & in front of parameters
Thanks again
Posted: Fri Jun 16, 2006 4:51 am
by Chris Corbyn
Tucker wrote:Ok I have been thinking of ways to implement this all day based on what d11 says and I just have 2 questions:
a) Would the example you provided allow a plugin to create a new working class that the plugin would operate out of
b) What is with the &'s everywhere? =& and the & in front of parameters
Thanks again
a) I'm not sure how you mean? If you mean can it replace the reference to the pluggable then yes it technically could but then it would not be able to write back to the pluggable. The pluggable could still write to/control the plugin however. If you're asking if you can make the pluggable actually morph into a different object then no, that's not possible (read, not ideal). In PHP4 it's possible to replace $this with a completely different object... this rings bells and sounds sirens in my head but yes that's doable. To make the ahppen to the pluggable from within the plugin you'd need to provide a method in the pluggable which acts as a setter on the object itself. i.e.
Code: Select all
class pluggable
{
//Usual plugin support stuff here
function morphObject(&$object)
{
$this = $object;
}
}
b) Reference operators. Not needed in PHP5. In PHP4 however, without those ampersands you'd be copying the object into the other object and thus, any changes to the object are only reflected in the copy, while the original object just sits there. Using references is how most languages (JavaScript included) handle object passing. An instance of an object should be the same wherever it goes. If you need it NOT to be the same and actually make a copy of the object then you need to look at something like the
Value Object Pattern (which incidentally in PHP4 is almost a case of not using the reference operator).
Posted: Tue Jun 20, 2006 9:09 pm
by blacksnday
I just wanted to thank d11wtq
for all the explanation's and examples into plugins.
This is something I have been wanting to create for my cms
and I am thinking now that after reading this, I am ready
to tackle it!