I’d like to chime in with two cents here, if everyone doesn’t mind.
The current way that plugins are stored in the DB and then eval() has been bothering me, as has another aspect that we’ll get to in the moment. This morning during my two hour cat nap it struck me why (other than the obvious performance hit for repeatedly eval()’ing code):
We are setting ourselves up to have problems as we move more and more things into the plugins due to the fact there is no namespace. Looking at the FCKEditor plugin, for instance, we see:
if (!function_exists('getFCKEditorSettings')) {
function getFCKEditorSettings() {
...
};
};
That’s fine, but what happens if a plugin author tried to define a function with the same name as another plugin author? Or if someone accidently defined a plugin with the name of a core function and/or existing PHP function? At the moment one of two things happens: either the person didn’t call function_exists() and things just break horribly-- potentially even making it so if the person doesn’t have phpMyAdmin or similiar they can’t even access the backend to fix the problem-- OR the plugin doesn’t declare its functions and ends up calling the previously defined funcs, which would have completely unpredictable behavior.
So, in a nutshell, this is my suggestion: every plugin should be enclosed in its own class in the form of:
class plugin_fckeditor extends plugin {
function plugin_fckeditor() {
....
};
function getFCKEditorSettings() {
...
};
};
Several nice things result:
[list]
- Every plugin now has its own namespace.
- Who doesn’t like OO design?
[li]Plugins automatically have an init function, if needed
- By extending the plugin base class, we can easily add/expand functionality of plugins in the future, if needed.
- A biggie: filesystem based plugins become very, very practical, allowing us to abstract out parts of the core (*)
- And much, much more!
(*) As an example: Imagine that frontend editing, capsules/containers, placeholders, custom fields, etc. were all created as distinct plugins, located on the filesystem. Now the $modx->parseDocumentSource() function just has to see which plugins have been activated on the backend for the onParseDocument event and load those particular classes. As part of their startup, they pass in the token(s) that they work with. As parseDocumentSource examines the source, it only calls those plugins that are needed: so, for instance, if there are no [[]] tags, the capsules/containers plugin doesn’t even get called. The end result: the document parser is considerably more efficient than it is now, an admin can completely deactivate features he doesn’t use, AND we don’t take the repeated performance hits for repeatedly calling eval() on the plugin code.
Of course, DB based plugins would continue to operate exactly as they do now and current plugins would still work, but I would make a case that for perfomance reasons all plugins we distribute with the core should be filesystem based to minimize the eval() overhead (and to demonstrate the most efficient method for creating plugins).
So... what are everyone’s thoughts? I don’t mind putting this together and, in fact, already have a very solid start on another little project, if everyone sees the value that I do.
[/list]