New plugin architecture patch

Project:ProjectPier
Version:0.8.5.0-Beta1
Component:Code
Category:feature request
Priority:normal
Assigned:TheWalrus
Status:closed - fixed
Description

This patch adds an extensible plugin architecture to PP.

It includes:
1) Plugin manager to allow actions and filters to be added/removed by plugins
2) Plugin manager to execute actions and apply filters
3) Administration interface to allow plugins to be activated/de-activated
4) A few hooks
5) A demonstration plugin

Patch made on SVN trunk rev.147

AttachmentSize
plugin-arch.patch88.19 KB
#1

This looks great!!
I'm trying it out now.
First thing I noticed though, is that your patch contains your database password and username

#2

Ok,
First off there is a comma in your sql, which is causing an error at installation:

CREATE TABLE `<?php echo $table_prefix ?>plugins` (
  `plugin_id` int(10) unsigned NOT NULL default '0',
  `title` varchar(100) <?php echo $default_collation ?> NOT NULL default '',
) ENGINE=InnoDB <?php echo $default_charset ?>;

When I removed the comma after default '' (Line 147) it installed ok.

Next, for some reason there were two copied of the same code in each of your files, which was causing 'class already been declared' errors.
At first I thought this was me accidentally patching it too many times (I'm new to patching), but when I look in the patch file I see:

===================================================================
--- application/models/plugins/base/BasePlugin.class.php (revision 0)
+++ application/models/plugins/base/BasePlugin.class.php (revision 0)
.......
.....
===================================================================
--- application/models/plugins/base/BasePlugins.class.php (revision 0)
+++ application/models/plugins/base/BasePlugins.class.php (revision 0)
.......
.....
===================================================================
--- application/models/plugins/base/BasePlugin.class.php (revision 0)
+++ application/models/plugins/base/BasePlugin.class.php (revision 0)
.......
.....
===================================================================
--- application/models/plugins/base/BasePlugins.class.php (revision 0)
+++ application/models/plugins/base/BasePlugins.class.php (revision 0)
.......
......

Again, I don't know much about patches, so this might be normal....

I went through most of the files, and deleted the duplicate code.
I went to the admin tab and tried to enable the links plugin, and get this error:

Plugins failed to activate: Project Links (Query failed with message 'Unknown column 'name' in 'field list'')

Apart from the above, it looks promising :)

EDIT:
Ok, I changed the table column name from title to name - That solved the plugins' failed to activate error

Now it says plugins' activated, but with an error flash, and the radio button for Project links is set at deactivated.
However, it has created the db table pp_project_links but the project tabs (forms etc.) are not hidden.

#3

Ok, for some reason my patches are giving exactly the same results as yours(the files you made have duplicated code).
I found an error in the your table structure though. It should be:

CREATE TABLE `<?php echo $table_prefix ?>plugins` (
  `plugin_id` int(10) unsigned NOT NULL auto_increment,
  `title` varchar(100) <?php echo $default_collation ?> NOT NULL default '',
  PRIMARY KEY  (`plugin_id`)
) ENGINE=InnoDB <?php echo $default_charset ?>;

It needs a primary key in order to work, else no plugins can be enabled.

#4

Thanks for the feedback Alex. Fixes from above have been applied and new FULL patch uploaded. For some reason TortoiseSVN insists on creating doubles of some files.

AttachmentSize
plugin-arch.ver2.patch 77.68 KB
#5

Nice patch. ProjectPier was in dire need of a plugin system, and i think this pretty much fills in that gap. It's also simple and to the point, which i imagine will encourage third party development.

One criticism i have about this patch however is it does not appear to handle new permissions in the UI. For example if i had a plugin "Cake" i might want to add a permission "Can eat cake" so i could restrict cake eating in a project to those who deserve it.

(I'd imagine one would have to play about with the ProjectUsers class to make it more extendable)

Still, great work! :)

#6

Thanks. The supplied patch is meant as a starting point to get the discussion moving on where to place hooks throughout the code. So far, as a proof of concept, I have only placed hooks in the menu areas of PP. Hooks could very well be placed in the permissions config area of PP etc.

The sample plugin does have user protection to make sure that only members of the owner company or an administrator can create, update or delete while all project members can view links associated with the project.

I found from writing the sample that it was more involved than writing for something like Wordpress and probably more like writing for Mambo/Joomla, in that the plugin files were spread across multiple existing folders (i.e. controllers, models, views). In presenting this plugin framework as a starting point, maybe we can move toward an easier structure for plugin writers to write for. This could be an uploader and unpacker that distributes files to their correct locations or maybe some mods that would allow each plugin to maintain all files in their plugin folder and allow PP to pick up whats needed in each folder.

Not sure what the way to go is and I am sure I know much less about the framework than others here but lets get talking.

#7

New FULL patch version to include auto_increment on the plugins table.

AttachmentSize
plugin-arch.ver3.patch 77.68 KB
#8

Just curious if you're part of the development mailing list or might come chat in the IRC channel.

#9
Version:<none>» 0.8.5.0-Beta1

Great start! I have some ideas to toss in...

I vote for finding a way to combine all the related plugin files into one folder. I also think that folder should be entirely separate from the application tree. Something like this:

[pp-root]/plugins/
+- Project_Links/
. . +- index.php <-- "plugin.project_links.php"
. . +- controllers/
. . | . +- LinkController.class.php
. . +- models/
. . | . +- base/
. . | . | . +- BaseProjectLinks.class.php
. . | . | . +- BaseProjectLink.class.php
. . | . +- ProjectLink.class.php
. . | . +- ProjectLinks.class.php
. . +- views/
. . | . +- link/
. . | . +- index.php
. . | . +- edit_link.php
. . +- language/
. . . . +- en_us/
. . . . . . +- project_links.php

This way all the plugin files are grouped together. This makes it easy for users to remove plugins cleanly. Thoughts?

All the source files for deactivated plugins should be excluded from the AutoLoader.

The Plugin system should gracefully deactivate (perhaps only temporarily) any missing plugins.

I really like the WP plugin mechanism that identifies plugins by a description section. Maybe this system could include an "identity.xml" or "identity.txt" to help describe the plugin to the user. Fields would include Plugin Name, Version, Homepage, Description, Author, etc. It could also include an Upgrade URL in preparation for future automated plugin installation/upgrades. (Define the tag now, so authors will include it for the future.)

Anyone have ideas on how to handle errant plugins? If a plugin causes problems, the user should have simple problem resolution options. One idea comes to mind: A "PP safe mode" URL (administrators only) where all plugins are disabled and the admin can disable plugins. It could be linked from the login screen (which might be designated a "plugin free zone").

#10

Moved this to the list thread.

#11

cgonzalez submitted an update of the plugin system in Issue 985. That patch should have been submitted here. We (Ryan and me) asked him to remove some unrelated changes (to the plugins system) in the patch and resubmit the patch here, but he never did. This has been lingering in my to-do list for a while, so I decided to knock it out this morning.

Here is cgonzalez's patch with only the minimal changes necessary to apply cleanly to the current SVN (revision 162, at the moment). This patch does not include the "Project Links" plugin as part of the patch. Alex Mayhew's "Wiki" patch as a plugin (again, courtesy of cgonzalez) is also attached to this message as a .tar.gz file even though I had to add the .txt extension onto the end of the file to get this issue tracker system to accept it. <sigh>. Just rename it to wiki_plugin.tar.gz and un-tar it directly in the /application/plugins/ directory.

The main difference between activeingredient's patch and cgonzalez's patch is that the cgonzalez patch splits the plugins into a separate directory: /application/plugins, which I feel is a cleaner solution.

AttachmentSize
cgonzalez_plugin_system.patch 40.79 KB
PluginManager Documentation.txt 1.12 KB
wiki_plugin.tar_.gz_.txt 23.71 KB
#12

Just to give credit where credit is due, most of the work in this patch is still activeingredient's work. I prefixed the name of the patch above with cgonzlaez to indicate that the patch is his update to activeingredient's patch.

So, activeingredient, a gigantic thank you to you for getting the ball rolling on this.

#13

I've tried cgonzlaez patch + wiki.tar against trunk. Everything works.

Here same patch but \t replaced by spaces (code style & cleanup)

AttachmentSize
cgonzalez_plugin_system.patch 40.88 KB
#14
Assigned to:Visitor» TheWalrus

Another update to the plugin system. Unfortunately, I'll bet that this patch still has tabs ('\t') in it instead of spaces. My apologies to andypost. I'll have to figure out Emacs...

This patch further refines the plugin system, moving all plugin files under a single directory. This patch also supersedes the permissions patch in Issue 1183. Permissions are integral to a full-featured plugin system, and this patch includes a working permissions system. As such, this is a large patch with many new files and many one and two line changes in existing files.

This patch also includes all necessary code to install a fresh PP database, and upgrade an existing PP database through the http://pp_server/install and http://pp_server/upgrade URLs. For the purposes of this patch, it calls the "new" version of ProjectPier 0.8.1. If this patch is approved, I'm assuming it will be integrated into 0.8.5. The upgrade script class implementing these changes is "QuinceUpgradeScript", following in alphabetical order (and nomenclature) from the two existing upgrade scripts.

I've updated my initial documentation regarding the changes and attached it to this message. I've also attached the updated Wiki plugin, which uses the new directory structure and implements basic per-project permissions.

As before, the Wiki plugin is really a .tar.gz file. Rename it and then untar it into the pp_root/applications/plugins/ directory.

AttachmentSize
pp_plugins_permissions.patch 112.49 KB
PluginManager Documentation.txt 2.93 KB
#15

This patch applied successfully on svn trunk

I test with clean install

1) Install failed - you forget about php echo near $default_collation

+CREATE TABLE `<?php echo $table_prefix ?>permissions` (
+  `id` int(10) unsigned NOT NULL auto_increment,
-  `source` varchar(50) $default_collation NOT NULL default '',
+  `source` varchar(50) <?php echo $default_collation ?> NOT NULL default '',
+  `permission` varchar(100) NOT NULL default '',
+  PRIMARY KEY  (`id`)
+) ENGINE=InnoDB <?php echo $default_charset ?>;

2) Next I try to activate wiki plugin - thats ok

3) Creation of first project failed - because of ProjectController.class.php line 285

<?php
$user
->setProjectPermission(active_project(),$permission,true);
?>

active_project() - returns NULL, should be replaced by $project

4) \t replaced by spaces and some cleanup

new patch attached

AttachmentSize
pp_plugins_permissions.patch 113.57 KB
#16

In #14 WikiController.class.php

line 231 //$page->setTagsFromCSV();
line 312 //$page->setTagsFromCSV($data['tags']);

In form there's not tags - notice-exception

#17

My latest patch has those lines commented out, looks like someone's used an old version of the wiki.
If you just comment the lines out it should work ok

#18

Perhaps we need to re-think this whole plugin system. I've so far discovered the following two issues:

1) The ApplicationLogs filters logs from uninstalled plugins by getting the object manager class name as a lower-case string and then checking to see if a plugin by that name exists.

I discovered this while trying to create a "Time" plugin incorporating all the TimeTracker code. However, the object manager for application logs from that plugin is called ProjectTimes. Now, I've worked around this relatively easily by adding a column to the plugins table called 'log_providers' and asking the plugin's init.php script for a list of those.

2) Public files and images. This is a major deficiency in the current plugin architecture. The plugin can't provide any static content without writing outside the /application/plugins/ directory structure. Allowing a plugin to do so would violate the principle of isolating plugins from each other. It would also make plugins harder to add and remove completely.

I discovered this because the "Wiki" plugin creates application logs, which when displayed on the dashboard tries to show an image in the left-hand column of the log entry. The wiki plugin can't distribute an image for every possible theme, though, and it would have to install that image outside of its plugin directory. Both of these situations are unacceptable. I can't solve this problem because the sequence of functions called (image_url() -> get_image_url() -> get_public_url()) makes it hard to check if a file exists and provide another default location if it doesn't. And that is not even mentioning the configuration headache installing PP would incur in getting Apache to serve public files out of another directory in addition to /public/.

So does anyone have any thoughts on how to solve these two issues? Can anyone think of any further issues like this that we may encounter? I'm sure as we create more plugins we are going to run into more issues like this. We may not be able to anticipate all of them until we encounter them, which means we need a lot more people contributing test plugins.

Plugins are making me very sad today.

#19

I'm moving this to the projectpier-development mailing list (projectpier-development@lists.sourceforge.net) because that is a much better place for this discussion than the issue tracker. Please subscribe a post there.

#20

Attached is a more complete plugin and permissions patch. I've verified that it applies cleanly to SVN revision 177 and that a new install can proceed from there. In addition, there is an upgrade script (QuinceUpgradeScript.php) to take things from a flavor of 0.8.0 to what I call 0.8.1.

Obviously this patch needs review, comments, and updates before it would be ready to commit. That said, we are using in production with a plugin specific to a segment of our business.

AttachmentSize
plugins-and-permissions.patch 130.04 KB
#21

With the last patch I was having problems accessing the install or upgrade url's at http//www.example.com/pp/public/install/ (or upgrade).

Apache error was: "The requested URL /index.php was not found on this server."

It seems the new .htaccess file in this patch requires a full path to the install/upgrade "index.php" in order for it to load the page.

This was not obvious at first since the 0.8.5 BETA 1 or svn177 does not require the full path.

I also could not find the sample plugin that was included in the original. I will try to extract it from the original to see how this works.

#22

I installed the wiki plugin from post #14 and it seems to be working fine with the patch from post #20.

Thanks TheWalrus.

It would be nice to know where this patch, as well as all of these various patches, stand in relation to upcoming releases of PP.

It is rather frustrating to have to download 5-7 different patches of which there are various incarnations from the forums to cobble together a non-standard install.

#23

Thanks TheWalrus. I've ran this patch in (from comment #20) and everything works well. Although, I did have problems with the upgrade script (QuinceUpgradeScript.php) on line 212 where the query to migrate permissions was doing a select on the project_users table (without the table prefix). I made this modification on my local copy and it seemed to go through fine.

#24
Status:patch - code needs review» closed - fixed

Accepted into 0.8.6 including wiki plugin. Superb work!