Arbit - project tracking

Arbit - project tracking

Revert wiki page

A wiki page with the requested title does not exist yet.

You do not have sufficant permissions to edit or create the wiki page.

===================
Arbit module design
===================

.. warning:: This document is still at the level of the first discussions. It is currently outdated. Feel free to update its contents.

Scope of this document
======================

This document describes the design decisions made during the planning phase of
the general module structure for arbit. Its main purpose is to present you
with the needed information for module development. It will define strict
rules which must be followed, as well as guidelines which should be followed
to create a well formed module.

Scope of a module
=================

Modules are working in a project only based context. They are never used in a
cross-project like way.

Purpose of a module
===================

A module is considered to be a sub controller of the application. It should
always be used to fullfill special tasks which all belong to one group. To make
things a little bit clearer some examples are given below:

- Subversion
- Wiki
- Issue tracking
- ...

Filesystem structure
====================

Every module needs to fullfil a special set of requirements concerning its
file and directory structure. Any module which does not followthese rules is
not considered a valid module by the application core.

Module base directory
---------------------

Modules always reside in their own subfolder beyond the "modules"
directory. The name of this directory is used as identification of this
perticular module throughout the whole application. Therefore it needs to
follow strict defintion guidelines. The following regular expression defines a
valid module directory name. ::

    [A-Z][a-zA-Z0-9]*

Spaces, underscores, hyphens and anything else are prohibited due to naming
class naming issues. See `Module class name`_ for details about this.

Autoload file
-------------

.. note:: The autoload file is only used, if the autoload element in $properties is **null**

Every module needs to include an autoload file which is used by the class
autoloader mechanism to create a class to file mapping. This autoload file
must reside inside the modules folder and be called "autoload.php". Inside
this file a php array needs to be defined and returned which creates a mapping
from classnames to filenames. These filenames are specified relative to the
root directory of the module. A simple example file is given below: ::

    <?php
    return array(
        "arbitFoobarModuleController"        =>  "controller.php",
        "arbitFoobarModuleMyHelperClass"     =>  "helperclass.php",
        "arbitFoobarModuleMyClassInASubdir"  =>  "subdir/anotherClass.php",
        // ...
    );
    ?>

Definition file - $properties
-----------------------------

The Definition file contains a class extended from arbitModuleDefintion.
It contains all for the project controller necessary informations in own propertys.
Here is an example for such a `definition file <http://tracker.arbitracker.org/arbit/browse_source/view/src/modules/source/definition.php>`__ .




**Permissions**
~~~~~~~~~~~~~~~~~~~

Each module may optionally define a set of permissions, which may then be
assigned to groups of users in the system. A permission string maps to the
possibility for one user to perform some action in the module.

The permissions of a module are defined by the permissions element of $properties
of the module definition class. It consists in an array with the available
permissions and their respective description, like the example further `below <#example1>`_.

**Signal-Slot definitions**
~~~~~~~~~~~~~~~~~~~~~~~~~~~

Every communication between different modules is handled using a
signal-slot mechanism. A module can register itself to recieve any
type of signal from other modules as well as send signals to the core to
make possibly interested modules aware of the send information. Every module
needs to specify which signals it is going to send and which slots, for
recieving a forreign signal, it defines.


**Slots**

A module can register itself to recieve any type of signal. The whole
signaling process is handled using static callback methods inside arbitrary
module classes. Therefore the signal-slot core needs to know which signals
need to be passed to our module along with a function which should be called on
recieve. This definition and mapping is defined in the *slots* element of the
$properties array. It is supposed to be a array containing a mapping
between a signal-name and a valid callback inside the module.
An example is given further `below <#example1>`_.

For modules that need to react on all signals or that need to react on signals
dynamically a catch-all functionality will be provided. This still needs to to
be defined. (real? did not see this till now)

**Signals**


Every module is forced to define a list of signals it is going to emmit.

Reasons for the decission to force a signals property
`````````````````````````````````````````````````````

The definition of this data has three important goals which should be clarified
before explaining the exact definition syntax. The signals file provides a way
of consistent error checking for mistyped signals or registered signals which
may not be existent any longer. This may happen due to BC breaks in a forreign
module. In a perfekt environment this should actually never happen, but it can
never be ruled out. Nevertheless it is strongly discouraged to introduce BC
breaks inside one module generation. Only the signals to be sent by a module
can be validated and it will be checked, that a module only sends such signals
it really has registered before.

Another goal is to provide a complete and informative documentation of the
signals which may be used by a forreign module developer to interact with your
module. The third and most important goal is to provide a way of asking a
module about it signals. This is inevitable to present the needed facillities
to create some sort of notification module.


Signal definition
`````````````````

The array containing the signals is in the signals element of the $properties
array. It contains a mapping between any signal emmited by the module and
a short description of it. A short example is given further `below <#example1>`_.


**Template directory**
~~~~~~~~~~~~~~~~~~~~~~

The template directory is defined in the templateDirectory element of the
$properties array and points relative to the directory of the current
module which is defined in the path element of $properties and
uses in general the __DIR__ constant.
It contains all module specific templates in a specified manner.
See `TemplateDesign <TemplateDesign>`__ for details about templatedir structure.


**controller**
~~~~~~~~~~~~~~

The name of the controller class is defined in the controller element of
the $properties array and should follow a specified `Module class name`_ convention.
The module controller handle all requests from web or cli which point to this module.
Also the *static* mothods for slots are often in this class.

**example1**
~~~~~~~~~~~~

Now the often mentioned example for module Definitions, or rather the $properties array of it: ::

	<?php
    protected $properties = array(
        'autoload'          => null,
        'permissions'       => array(
            'source_manage'      => 'User is allowed perform source management task, like chckout, update & cache priming.',
            'source_view_source' => 'User is allowed to view the source code in the web interface.',
        ),
        'slots'             => array(
            'sourceAnnotate' => 'arbitModuleSourceController::annotateSource',
        ),
        'signals'           => array(
            'sourceAnnotate'    => 'Annotate a source file [, line [, position]] with additional information.',
            'sourceInitialized' => 'The source checkout has been initialized.',
            'sourceUpdated'     => 'The source checkout has been updated.',
        ),

        'templateDirectory' => 'templates/',
        'controller'        => 'arbitModuleSourceController',
        'path'              => __DIR__,
    );
    ?>


Definition file - other
-----------------------

There are a few more definitions in other variables of the
definition class they are needed for several tasks of the arbit framework.

**$caches**
~~~~~~~~~~~

An array of caches used and needed from the module with additional
*time to live* element for every cache, so arbit know when to clean the cache. 


**$facades**
~~~~~~~~~~~~

An array of available backends/facades for this modul. Till now most of
the modules only have couchDB as backend.

**$viewModels**
~~~~~~~~~~~~~~~

List of used view handlers associated with a list of view
models used by the module, each associated with a callback to
the concrete handler implementation to visit the view model.

What are they for? They extend the arbitViewModel class and handle
which variables are available for the templates.

**$commands**
~~~~~~~~~~~~~

The commands array is primary for the periodic component. All commands
from this array could be executed from periodic. Take a look at the src/tasks/
directory for more informations how to add tasks.


**rest**
~~~~~~~~

Now there two more variables, $couchDbDocuments and $couchDbViews.
They are used for the couchDB backend, or rather the phpillow lib for
access couchDB. No idea till now why it was placed there and not inside the
facade section of the module. Could be messy when adding other backends, because
both variables are only used for couchDB and useless for example doctrin.

What i will say with it, this part of the module could change in future.


Class naming scheme
===================

The class names of a module need to comply to a specific naming scheme. This
restriction is needed to prohibit naming collisions.

Module class name
-----------------

The "module class" represents the base controller of the module which is called
by the application core to retrieve any sort of output. Therefore it must have
a unique name which is known to the core, as well as it has to implement
certain interfaces. This name consists of two parts a strictly defined part and
the module identifier, which is explained in the `Module base directory`_
section. The enforced part always needs to be
"arbit[IDENTIFIER]ModuleController". [IDENTIFIER] represents the module
identifier in this name. A list of examples may be found below: ::

    Identifier: Wiki
    Classname:  arbitWikiModuleController

    Identifier: IssueTracker
    Classname:  arbitIssueTrackerModuleController

General class names
-------------------

To prohibit naming conflicts any class used inside a destinct module needs to
begin with "arbit[IDENTIFIER]Module". Therefore you may call your Wiki markup
parser class "arbitWikiModuleMarkupParser".