{{TOC}}
= Introduction =
Modules are the main way of extending and/or modifying functionality in The Bug Genie. Modules can be used for anything from providing alternative authentication backend, to altering the way pages looks and works - and much of the functionality that is part of the main package is actually provided by modules.

With modules, you can add new sections to the site, add account settings and much more. Here's a quick howto on how to set up your first module.

= A quick overview =
Any installed module is automatically loaded and set up when the core engine initializes on each request. The module functionality is always enabled and available before any main functions are invoked. This lets you hook into pretty much any part of the core system without manipulating the base files. Modules can add routes (URLs) dynamically and on demand, and can also hook into and provide additional functionality from the command line interface (cli). You can set up modules that communicate with eachother directly or via the [[TheBugGenie:Development:Events|event system]], or your module can operate almost on its own.

= Module loading and initialization =
Modules are loaded after the core classes are added to the autoloader, and the context initialized (including the request), but before user authentication happens. All modules are loaded and added to the context before they are initialized, and no module functionality is provided before a module has been initialized.

= Structure =
To create a new module, create a new directory under the "modules" directory in the top level. The module name must be unique (clearly), and should only contain lowercase letters (convenience only - remember, some filesystem are case insensitive, which can easily lead to bugs). Inside the new module directory, create two files - one called ''class'' and another one called ''module'', a folder called ''classes'', and a module classfile inside the ''classes'' directory.

The end result should look like this:
 modules
   - mymodule
       - classes
           MyModule.class.php
       class
       module

Inside the ''module'' file, put the description of the module, which will be used when the module is shown for installation:
 My Module - a fantastic module

Inside the ''class'' file, put the name of the class that is the main module class, as well as the version number, separated by a pipe. (More information about how the main module class needs to be structured follows). In this case, the content of the file "class" would be
 MyModule|1.0

The class specified in the ''class'' file will be autoloaded when the module is instantiated. The module key will be the folder name (keep in mind the difference between the module key and the module class), and used to reference the module later. For instance, retrieving this module from elsewhere in the code is done by passing the module key to the static '''getModule()''' function in '''TBGContext'''.

Example:
<source lang="php">
// Retrieve the "mymodule" module
$module = TBGContext::getModule('mymodule');

echo get_class($module);
// outputs "MyModule"
</source>

= Module contents =
A basic module needs to extend the core '''TBGModule''' class, which implements a few final methods such as '''_construct()''', '''install()''' and '''uninstall()'''. These methods cannot be overridden, but the module loading flow in The Bug Genie gives some alternative methods of initializing your module. When a module is loaded in the core, it is instantiated, all its settings are cached (if it is installed), and the '''_initialize()''' method is called, followed by three more calls that allows you to set up your modules permissions ('''_addAvailablePermissions()'''), routes ('''_addAvailableRoutes()''') and listeners ('''_addAvailableListeners()''').

The only function that is required for your module to operate, is the '''_initialize()''' function, where you'd usually set up the name, description, etc. To help with translation, the I18n object is passed to the initialization function.

Here's an example of a basic module:

'''modules/mymodule/module:'''
 My Module - a fantastic module

'''modules/mymodule/class:'''
 MyModule|1.0

'''modules/mymodule/classes/MyModule.class.php:'''
<source lang="php">
class MyModule extends TBGModule 
{
	
	protected $_module_version = '1.0';

	/**
	 * Return an instance of this module
	 * (including this function helps with code completion,
	 * so you can call MyModule::getModule() instead of going
	 * via the TBGContext class
	 *
	 * @return MyModule
	 */
	public static function getModule()
	{
		return TBGContext::getModule('mymodule');
	}

	protected function _initialize(TBGI18n $i18n)
	{
		$this->setLongName($i18n->__('My Module'));
		$this->setDescription($i18n->__('My fantastic module'));
	}
}
</source>

= Installing a module =
To be able to use a module, it needs to be installed. This can be done either via the cli task '''manage_modules install ''' '''''module_name''''', or via the [[TBG:configure_modules|module configuration interface]]. After you have installed it, it will be added to the autoloader and loaded on each request, as well as via the cli.

When a module is installed, some functions in your module are executed (if the exists) - '''_install()''' and '''_loadFixtures()'''. If your module has database table classes in the ''classes/B2DB'' folder, they will be created after the '''_install()''' function has been called but before the '''_loadFixtures()''' function is called. This means you cannot add data to any custom tables in the '''_install()''' function, but you can do it in the '''_loadFixtures()''' function.

= Using the cli to setup an empty module =
The Bug Genie CLI has a convenience command to create an empty module skeleton, called via
 ./tbg_cli create_module MyModule

This command will create all the necessary folders and files to get your module up and running. You can continue from there, adding pages and more.

= Your first module page =
So, unless you just want to linger in the background and do tasks invisible to the user, you probably want to have a page or something where user can interact with. External modules are treated in a similar way to internal modules - that means they follow the same rules and conventions as the internal modules does when it comes to [[TheBugGenie:Development:Actions|Actions]] and [[TheBugGenie:Development:Actions|Templates]]. However - it differs for external modules in that to be able to access the page, it needs to be added to the routing stack - it needs to have a URL which the user can access.

You set this up in the '''_addAvailableRoutes()''' function, where routes are added after the module has been initialized. Keep in mind that routes are being processed first-come, first-served, so you should make a conscious effort to avoid having routes where the URL overwrites previous URLs. (See the [[TheBugGenie:Development:Routing|Routing documentation]] for more information about routes in general.) To dynamically add a route to the list, use the built-in '''addRoute()''' function from the module object:

'''TBGModule::addRoute():'''
<source lang="php">
$this->addRoute($route_key, $url, $action);
</source>

'''modules/mymodule/classes/MyModule.class.php:'''
<source lang="php">
// Add a route available via : http://<thebuggenie.location>/mymodule
// which will trigger the runFrontpage() method in the mymodules
// actions class
$this->addRoute('mymodule_frontpage', '/mymodule', 'frontpage');
</source>

The parameters in this call are similar to the normal routing parameters - except that the module will default to the current module, so that parameter is excluded. Actions and templates are then set up according to the documentation as specified in the [[TheBugGenie:Development:Actions|Actions]] and [[TheBugGenie:Development:Actions|Templates]] sections.

[[Category:TheBugGenie:Development]]