New Module

From Cloudrexx Development Wiki
Jump to: navigation, search

NOTE: Work in progress!
For module development in Contrexx 3.1 or newer see article New Component (draft)


This article describes the development of a module for Contrexx until (and including) version 3 ServicePack 4 (3.0.4). For newer versions, please refer to New Component (draft)

This tutorial will guide you through creating a new module in just a few steps.

If you are interested in selling your module, please see Contribute.

Get ready

In order to successfully create a module for Contrexx, you should know about these things:

Determining component type

CoreModule.svg

Contrexx consists of core components, core modules, modules and libraries. Core components are required for Contrexx to operate. Core modules are needed for Contrexx to work in a reasonable way. Modules are additional applications and libraries are code parts, that can be used outside of Contrexx. To determine to which of these component types your code belongs, see the graphic on the right.

Choose a component name

Now choose a name for your component, respecting these thoughts:

Design your module

This might be the most important step. Before you write any line of code, define for record what your module should do. Create a class diagram and an entity relationship diagram and maybe further sketches!

Where to write your code

Since your code isn't part of a standard installation of Contrexx, you best place it in the /customizing folder (see Contribute). Remember to activate customizings in global settings.

Depending on your chosen component type, your working directory will be one of these (create all non-existing folders):

  • /customizing/core/{your component's name}
  • /customizing/core_modules/{your component's name}
  • /customizing/modules/{your component's name}
  • /customizing/lib/{your company's name}/{your component's name}

You must not write any code outside your module directory! Since this is not always possible with current versions of Contrexx, there are some exceptions for this rule:

For libraries (/customizing/lib) you may start writing your code now and leave out the rest of this article. For core, core_modules and modules, please read on:

Create module structure

Now we create the basic structure for your module. The simplest way to do this is by downloading our "Demo module" This file will be updated soon and does not match the text of this article yet! and uncompress its contents into your module folder. You can of course also create the structure yourself. Here are the explained structure and sample files of the demo module:

File/Folder Description Purpose
Model Model folder See MVC
Model/Data Model data folder Contains fixtures and sample data (currently unused)
Model/Entity Model entity folder Contains entities
Model/Event Model event folder Contains model events
Model/Repository Model repository folder Contains repositories
Model/Yaml Model yaml folder Contains yaml-files used to define entities and their behavior (currently Doctrine only)
View View folder See MVC
View/Media View media folder Contains images, videos, pdf's used by this component
View/Script View script folder Contains client-side scripts such as JavaScript
View/Script/Main.js A sample JavaScript file Demo file replacing some text
View/Style View style folder Contains style definitions (CSS-files)
View/Style/Main.css A sample CSS file Demo file making text red
View/Template View template folder Contains this component's template files
View/Template/Main.css A sample template file Demo template showing some text with a tooltip
Controller Controller folder See MVC
Controller/ComponentController.class.php An example controller Main controller for this component
Controller/FrontendController.class.php An example controller Frontend controller for this component
Controller/BackendController.class.php An example controller Backend controller for this component
lang Language folder Contains language files (see Interface_Text)
lang/en/backend.php Backend language file Default backend language file
lang/en/frontend.php Frontend language file Default frontend language file
lang/de/backend.php Backend language file German backend language file
lang/de/frontend.php Frontend language file German frontend language file
Testing Testing folder Contains test cases (currently unused)

Module activation

In order to successfully load your module, Contrexx needs some data:

Global language data

To display the correct (display-)name for your module, copy /lang/{lang}/backend.php to /customizing/lang/{lang} and add the following entries (replace DEMO_MODULE with the name of your core component/module/core_module):

$_CORELANG['TXT_DEMO_MODULE'] = 'Demonstration';

$_CORELANG['TXT_DEMO_MODULE_DESCRIPTION'] = 'Sample code for a new module';

Activation

Add a row to the database Table DBPREFIXmodules:

id name distributor description_variable status is_required is_core is_active
{next free ID} {Name of your module} {your (company's) name} {$_CORELANG array index for description of your module} y {'1' for core_module, '0' otherwise} {'1' for core, '0' otherwise} 1

For {next free ID} enter the next free number that is higher than 900 (non standard IDs are defined to be higher than 900).

Modules need an existing page (frontend) in order to be activated.

Module initialization for frontend

If your module does something in frontend, copy the file /core/initFrontend.php to the customizing folder, then search for a long switch/case statement (starting somewhere after row 1055). Add your module as a case (again, replace demo with the name of your module):

    case 'Demo':
        $component = new \Cx\Modules\Demo\Controller\ComponentController();
        $componentCx = null;
        $componentRequest = null;
        $em = \Env::get('em');
        $component->getPage(true, $_ARRAYLANG, $objTemplate, $em, $objDatabase, $componentCx, $componentRequest, $page_content);
        break;

For a core module, just change ASCMS_MODULE_PATH to ASCMS_CORE_MODULE_PATH and replace 'Modules' by 'Core_Modules' in namespace. This code should deliver all dependencies to the constructor of your controller (--> Dependency Injection). The last two parameters are objects which do not exist yet.

If you use the session, you must initialize it here! See Session handling for more information.

Module initialization for backend

If your module does something in backend, copy the file /core/initBackend.php to the customizing folder, then search for a long switch/case statement (starting somewhere after row 315). Add your module as a case:

    case 'Demo':
        $component = new \Cx\Modules\Demo\Controller\ComponentController();
        $componentCx = null;
        $componentRequest = null;
        $em = \Env::get('em');
        $component->getPage(false, $_ARRAYLANG, $objTemplate, $em, $objDatabase, $componentCx, $componentRequest);
        break;

For a core module, just change ASCMS_MODULE_PATH to ASCMS_CORE_MODULE_PATH and replace 'Modules' by 'Core_Modules' in namespace. This code should deliver all dependencies to the constructor of your controller (--> Dependency Injection). The last two parameters are objects which do not exist yet.

You might want to check, if the user is allowed to access this module here. See Development_Permissions for more information.

Backend navigation entry

In order for your module to be displayed in backend, you may add a backend navigation entry. Add a row to DBPREFIXbackend_areas:

area_id parent_area_id type scope area_name is_active uri target module_id order_id access_id
{next free ID} {parent ID} navigation backend {$_CORELANG array index for module name} 1 index.php?cmd={module name} _self {module ID} {order ID} {access ID}

parent_area_id

Choose where your (core) module should be displayed:

parent_area_id Area
1 Content Management
15 Media
8 E-Commerce
29 Mail Marketing
2 Applications
28 Stats
3 Administration

module_id

Enter the ID you used in DBPREFIXmodules.

order_id

The order ID tells Contrexx in which order the entries of this parent_id should be displayed. If you want to append your module to the end of the list, simply enter the next free number with the same parent_id.

access_id

Enter the next free number that is higher than 900 (non standard IDs are defined to be higher than 900). This number is the link between user permissions and your module. After you added the DBPREFIXbackend_areas entry, you may navigate to user management in backend, edit a group and find this ID there. Be sure your user is in a group which has this permission.

Protect functions

You may protect functions (of Contrexx) using DBPREFIXbackend_areas table. For each function you want to protect, add a new row to the table:

area_id parent_area_id type scope area_name is_active uri target module_id order_id access_id
{next free ID} 0 function {backend, frontend or global} {$_CORELANG array index for function name} 1 (empty) _self {module ID} {order ID} {access ID}

These entries will be shown in group permissions too. See Development_Permissions for more info.

Workaround for customizing bug

Until Contrexx 3.0 SP4 (3.0.4), there was a bug causing your module not to be loaded. In order to work around this bug, just create an empty module folder outside the customizing. Let's say your working folder is /customizing/modules/Demo then you may create the directory /modules/Demo.

Easy activation of the demo module

The following code is not tested yet!

Here's the ready-to-use code to perform the steps described in this section for the demo module.

Insert the core language variables, perform the steps described in Module initialization for frontend and Module initialization for backend and execute the following queries in the database of your Contrexx installation:

INSERT INTO `contrexx_modules` (`id`, `name`, `distributor`, `description_variable`, `status`, `is_required`, `is_core`, `is_active`) VALUES
(9000, 'Demo', 'yournamehere', 'TXT_DEMO_MODULE', 'y', 0, 0, 1);
INSERT INTO `contrexx_backend_areas` (`area_id`, `parent_area_id`, `type`, `scope`, `area_name`, `is_active`, `uri`, `target`, `module_id`, `order_id`, `access_id`) VALUES
(NULL, 2, 'navigation', 'backend', 'TXT_DEMO_MODULE', 1, 'index.php?cmd=Demo', '_self', 9000, 0, 0)

After this, navigate to the content manager and create a new page of type application and choose the application named 'Demo'.

Backend templates

Contrexx uses the PEAR HTML Sigma Template templating system. DO NOT USE HTML_Template_Sigma CLASS DIRECTLY use \Cx\Core\Html\Sigma instead (it's a wrapper class for HTML_Template_Sigma in order to allow template customizings).

Place your HTML templates in /customizing/modules/yourmodule/template. Assuming you have a template file named overview.html you could use the following code to include it:

$template = new \Cx\Core\Html\Sigma(ASCMS_MODULE_PATH.'/yourmodule/template/overview.html');

Start writing your code

Now you can start adding your code. Here are some links that might help you finding your way: