New phpPgAdmin Plugin Architecture

Student name: Leonardo Augusto Sapiras

E-mail: l.sapiras@gmail.com


Synopsis

This project will create a new plugin architecture for the phpPgAdmin, using the Hook Pattern.

Benefits to the PostgreSQL Community

The current phpPgAdmin plugin architecture is deprecated, having only one plugin, the Slony. Today, to create a plugin, the developer will need to write intrusive codes inside the phpPgAdmin core, as Slony do today, and it is not good. With a new architecture, more ideas could be developed inside the phpPgAdmin with no intrusive code.

With a good plugin architecture, new plugins will be easier created and maintaned, the phPgAdmin will have more users, and possibly more developers and collaborators as well.

There are some ideas that are waiting for a new architecture to be developed as plugins. Like:

This project has been discussed in the phpPgAdmin e-mail list some time ago, and between me and Mr. Jehan-Guillaume de Rorthais some months ago. Last year Jehan-Guillaume was my mentor, so I would like to have him as my mentor again.

Quatifiable results

  1. Refactor the current plugin architecture, creating a plugin manager to deal with the plugins;
  2. Create a new plugin, to give the users a live example of how to create and integrate a plugin with the PPA core;
  3. Tests;
  4. Documentation: how to create a plugin for phpPgAdmin and integrate it with its components (action buttons, browser tree, trail, tabs, navigation links, top links);
  5. If I have time enough, I will refactor the current Slony plugin, for this feature works with the new architecture.

Project Details

Refactor the current plugin architecture

In my participation in the Google Summer of Code 2011, I have the goal to refactor the current plugin architecture.

The news plugins will have the following structure: 


  -plugin
  |--conf/
  |  |--config.inc.php
  |--lang/
  |  |--recoded
  |  |  |--english.php
  |  |--english.php
  |  |--Makefile
  |--js/
  |--classes/
  |--images/
  |--help/
  |--tests/ (optional)
  |--themes/ (optional)
  |--ppa_plugin.php

 

As it could be saw above, the plugins will have their own pages, translation and configuration files.

The new plugin architecture will be developed using the Hooks Pattern. These way, the plugins will register their functions to the events they want to hook to. There are a lot of applications that use this concept, like the Drupal Open Source CMS do.

 

How the plugin will work on this architecture

The plugins on this architecture will be able to:


PPA screen

 

Plugin activation

To activate new plugins in the phpPgAdmin, will be added in the PPA configuration file (config.inc.php) a new variable (array) $conf['plugins']. So, to activate a plugin, the user just need to add the plugin's name in this array. Example:

/* config.inc.php */
...
$conf['plugins'][] = 'ppa_slony';
$conf['plugins'][] = 'ppa_x';
$conf['plugins'][] = 'ppa_another';
...

Plugin execution

The phpPgAdmin will have a plugin manager, that its own name says, will manager the activated plugins. Bellow is an example of how the plugin_manager.php could be:

<?php
class PluginManager {
  ...
  function add_plugin($obj_plugin) {
    $this->plugins_list[$obj_plugin->get_name()] = $obj_plugin;
  }
 
  function get_plugin($plugin_name) {
    return $this->plugins_list[$plugin_name];
  }
 
  function add_plugins_functions($plugin_name, $when, $function_name) {
    $this->plugins_functions[$when][] = array('plugin_name' => $plugin_name, 'function_name'=> $function_name);
  }
  function execute_plugins_funtions($when) {
     foreach ($this->plugins_functions[$when] as $node) {
       $plugin_name   = $node['plugin_name'];
       $function_name = $node['function_name'];
       $obj_plugin    = $this->get_plugin($plugin_name); 
 
       if (method_exists($obj_plugin, $function_name)) {
         call_user_func(array($obj_plugin, $function_name));
       }
    }
  }
  ...
}
?>

 

This plugin manager will be used in the lib.inc.php file, instantiating and registering the plugins and their functions, like the bellow example:

 

<?php
/* lib.inc.php */
...
$obj_plugin_manager = new PluginManager();
//register the plugins and their functions
foreach ($activated_plugins as $plugin) {
  include_once('./plugins/'.$plugin.'/plugin.php');
  $obj_plugin = new $plugin($obj_plugin_manager);
  $obj_plugin_manager->add_plugin($obj_plugin);
}
...
?>

In the plugin, their functions will be registered with an attribute saying where they will be used by the phpPgAdmin core. Below an example of a simple plugin that shows it:

<?php
...
class Plugin1 {
  ...
  function __construct($obj_plugin_manager) {
    $obj_plugin_manager->add_plugins_functions($this->name,
                                               'before_trail_creation',
                                               'create_trail_links');
    $obj_plugin_manager->add_plugins_functions($this->name,
                                               'after_show_tabs',
                                               'show_tab_links');
    }
 
    function create_trail_links() {
      /* show the plugin's trail links */
    }
 
    function show_tab_links() {
      /* show the plugin's tab links */
    }
}
?>

 

So, in determinated places of phpPgAdmin, like the functions that create the browser tree, trail or tabs, the plugins' function will be called as bellow:

<?php
...
$obj_plugin_manager->execute_plugins_funtions('before_trail_creation');
...
$obj_plugin_manager->execute_plugins_funtions('after_show_tabs');
...
?>

This way, the plugin will 'say' to phpPgAdmin core, what are its elements that will be showed in the PPA components.

To demonstrate it, I created a basic functional example.

Documentation

The final documentation will contain:

References

During the development of this proposal, I found some other projects that use the concept of 'Hook'. Below some of these projects:

Zend plugin's

Wordpress API Plugin

Dikini's Hook Example

Drupal modules

Inch-stones

Project Schedule

During the Google Summer of Code 2011, I will be on-line on IRC (irc.freenode.net) channels #phppgadmin, #postgresql and #gsoc available to talk. And, at least once a week, I will contact my mentor reporting what was done, what I will do in the next week, and what is preventing me from carrying out a certain activity. I will also write my activities in my blog, and a copy of this proposal will be found at the phpPgAdmin wiki page.

If there are other projects ideas being developed at the same time, it is important that developers of these applications need to be contacted to provide their versions to run tests. But that will be defined together with my mentor and phpPgAdmin developers.

Once it's released the results of students accepted, I will provide a copy of the timeline in Google Calendar.

April 25 until May 22 (Community Bonding Period): During that period, I will be in contact to my mentor and phpPgAdmin developers, explaining more detail about the accepted proposal. I will also review my project with them to see if is not missing anything before start coding;

May 23: I start coding, creating the new basic plugin structure that will be used as example for other developers;

May 27: Meeting with the mentor, when I will show him the basic plugin architecture, and start developing the Plugin Manager;

June 3: Meeting with the mentor.  Start developing the integration among the basic plugin example and the tabs and top links;

June 10: Meeting with the mentor;

June 17: Meeting with the mentor. At this date, I will start developing the integration between plugins and the trail;

June 24: Meeting with the mentor. At this date, I will start working in the integration between plugins and the navigation links;

July 1: Meeting with the mentor;

July 8: Meeting with the mentor. Finish the integration with navigation links. Start developing the integration with the action buttons;

July 11 until 15: Creation and submission of the mid-term evaluation;

July 15: Meeting with the mentor;

July 22: Meeting with the mentor. Start integrating the plugins with the browser tree;

July 29: Meeting with the mentor;

August 5: Meeting with the mentor. Finish the integration with the browser tree. Start testing and making final modifications;

August 12: Meeting with the mentor. On this day, I will stop coding, and start creating the final documentation;

August 19: Meeting with the mentor. Review of the documentation;

August 22: Finish the documentation;

August 22 until 26: Submission of the final evaluation;

Completeness Criteria

This project will be accomplished if the new Architecture Plugin: