Baseclass: Component Interface

The main purpose of the component base class is to ease a components interfacing with MidCOM. Before MidCOM 2.4 you needed around 200 lines of code to build the interface required for MidCOM to control your components. While this was cumbersome for the author, the real problem was for me as a core developer that it is almost impossible to change or enhance the component interface in an easy way. The new baseclass solves both problems.

For a start, the base class is completly documented in the MidCOM API documentation. I would greatly appreciate any feedback about the documentation there. What I'm about to write here, is about the thoughts behind this class, and its integration into the framework. Having read the base class documentation is a prerequisite for this article.

Basic design considerations

The class uses a bit of declarative programming to do its work. You simply set a number of variables during construction, and the class does the rest of the basic tasks for you completly. Further customization is done using event handlers called by the framework or the base class itself. Event handlers can be introduced for many tasks regarding handling of the entire component. The two handlers existing right now show the versatility, one is there for initialization work, the other to initiate a complete reindexing of the component.

For all tasks, the major difference between standard component code and component interface code is the fact, that it operates without a specific topic or component context.

This leads to an important consequence: You must not do anything which has to do with regular on-site component operations within this interface class. This breaks encaspulation and makes extension or modification of this interface difficult. To support this guideline, the class does almost all work for you regarding component initialization.

The MidCOM Component Interface

To further illustrate the idea behind this class, we take a look at the internals of MidCOM, how it interfaces with a component.

...

The example class

The following example code illustrates a complete component interface utilizing all features of the base class. It is taken from the net.nemein.calendar component.

Code

<?php

/**
* @package net.nemein.calendar
* @author The Midgard Project, http://www.midgard-project.org
* @version $Id: interfaces.php,v 1.3 2005/03/04 14:24:16 torben Exp $
* @copyright The Midgard Project, http://www.midgard-project.org
* @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
*/

/**
* Calendar MidCOM interface class.
*
* @package net.nemein.calendar
*/

class net_nemein_calendar_interface extends midcom_baseclasses_components_interface
{
    
/**
     * Constructor.
     *
     * Nothing fancy, loads all script files and the datamanager library.
     */
    
function net_nemein_calendar_interface()
    {
        
parent::midcom_baseclasses_components_interface();
        
        
$this->_component = 'net.nemein.calendar';
        
$this->_autoload_files = Array('viewer.php', 'admin.php', 'navigation.php', 'functions.php');
    }
    
    
/**
     * Initialize n.n.calendar library.
     *
     * @return bool inidicating success.
     */
    
function _on_initialize()
    {
        
parent::_on_initialize();
        
        
error_reporting(E_WARNING);
        global
$nncal_snippetroot;
        global
$nemein_net;

        
// Give NemeinCalendar the MidCOM locale info
        
$i18n = & $GLOBALS["midcom"]->get_service("i18n");
        
$nemein_net['language'] = $i18n->get_current_language();
        
$nemein_net['locale'] = $i18n->get_language_db();
        
$nemein_net['locale'] = $nemein_net['locale'][$nemein_net['language']]["locale"];

        
$nncal_snippetroot="/NemeinCalendar/Version 2.0";
        
$event_types=array (0 => array ('label' => 'Public','public' => 1),1 => array ('label' => 'Private','public' => 0));
        
$NNCAL_PTYPES=$event_types;
        global
$NNCAL_PTYPES;

        
mgd_include_snippet_php($nncal_snippetroot."/Core/init-loc");
        
mgd_include_snippet_php($nncal_snippetroot."/Core/Classes");
        
error_reporting(E_ALL);
        
        return
true;
    }
    
    
/**
     * Iterate over all events and create index record using the custom indexer
     * method.
     */
    
function _on_reindex($topic, $config, &$indexer)
    {
        
$root_event = $topic->parameter("net.nemein.calendar","root_event");
        if (
$root_event)
        {
            
$root_event = mgd_get_object_by_guid($root_event);
        }
        if (
$events = mgd_list_events($root_event->id))
        {
            while (
$events->fetch ())
            {
                
$document = net_nemein_calendar_event2document(new NemeinCalendar_event($events->id));
                if (
$document)
                {
                    
$indexer->index($document);
                }
            }
        }
        return
true;
    }
}

?>