You are viewing an old version of this wiki page. You can also read the most recent version of this page. Last version
Arbit module design
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
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 .
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.
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.
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.
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 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".