Zurmo – How the Source Code is Organized – Part 4

In previous posts on this topic we revealed the basic file structure underlying Zurmo CRM. Today we’ll continue our exploration of the Zurmo file structure and focus on the anatomy of a module. We will learn how modules fit in to the Zurmo eco-system, different “types” of modules, mandatory and optional module characteristics, and some of the limits of Zurmo’s modular architecture (as of version. 2.7.4).

Modules are the primary mechanism through which Zurmo CRM can be extended and customized. Zurmo itself, uses modules to manage major bits of functionality like security and the api. Zurmo also provides out-of-the box capability for email processing, marketing campaigns, and the designer behavior through modules. Additionally, modules are used to segregate code for objects like “Account”, “Contact”, etc. You can also use modules to extend Zurmo with your own custom classes through a fairly well defined process of “custom configuration” or “custom management” (a great topic for a future post).

Modules are not, at least as of v. 2.7.4, self-contained plug and play, zero configuration thing-a-ma-bobs that just work magically. There is no “installer” in Zurmo, and Zurmo does not yet have a “Marketplace” from which 3rd party modules can be obtained. There has been a solid support from the user community for these features, and hopefully, some of you more gifted readers may even feel compelled to contribute this capability in the near future. For now, we need to muck around in the configuration files a bit. As noted above, we’ll cover that topic in a future post.

As mentioned previously, when using the default Softaculous Zurmo installer on Arvixe Hosting personal plan, the shell command…

tree -L 1 -d ~/www/zurmo/app/protected/modules

Will yield a graphical listing of all the currently present modules. Modules in Zurmo can be “present”, i.e.: present in this directory, without being “activated” or “installed”. For the purposes of our discussion we are going to be concerned only with whether or not a module is present, and which module sub-directories are required and which are optional.

Let’s start by examining the familiar ‘accounts’ module located here:


The first thing you should notice, is the module naming convention. With some special exceptions, module directory names should be declared in camelCase. My recommendation is to go one step farther and restrict the name of your custom module directory to a single lowercase word. As of this writing the version of Yii shipped with Zurmo does not support PHP namespaces very well. Therefore, I advise that you prefix your custom module name with a somewhat unique character string. A three character string followed by the small letter ‘x’ can serve both to prevent namespace collisions, as well as provide a delimiter for code refactoring operations. In the future, the module name of ‘abcxoffices’ , for example, will be less likely to be chosen by Zurmo as a module name than say, ‘offices’.

Another important convention that you should try to follow, even though Zurmo itself is inconsistent, is to always pluralize your module names. E.g: “accounts” not “account”.

Here is the breakdown of the file structure under protected/modules/accounts:

|-- adapters                  # Data Xformation instructions
| |
| |-- columns                 # How to render special fields
| |                             such as a link in a grid view.
| |
|-- controllers               # Mandatory. control program flow
|                               typically separate php files for 
|                               API, Default, and Portal behavior.
|-- data                      # Default Data and Mock data.
|-- elements                  # GUI display controls
| |-- actions                   used by controllers for rendering.
| |                             used directly from functions
| |                             within a controller.
| |                             E.g: actionLink() menu selection.
| |
| |-- derived                   used by other models for rendering
|                               called indirectly, not via user
|                               action like clicking a menu item.
|-- forms                     # temporary non-Database storage
| |                             used for searching and selecting
| |                             use instead of model when not
| |                             requiring object persistance.
| |
| |-- attributes              # extends and overrides framework
| |                             classes. provides a way to access
| |                             attribute type info. Reflection.
| |
|-- messages                  # Language translation directories
| |-- de                         German
| |-- es                         Spanish
| |-- fr                         French
| |-- it                         Italian
|-- models                    # Mandatory. Data model(s). must
|                               conform to conventions.
|-- observers                 # Attaches event handlers for module
|-- rules                     # Special logic E.g.: gamification
| |                             or Import. 
| |
| |-- attributes              # Specifies how to handle derived
| |                              attributes in special logic.
| |                             E.g: account is not explicitly
| |                             an attribute on a an observer like| |                             a task, so how to get the account
| |                             when we import the task?         
| |
| |-- badges                  # Points for certain activities
|-- tests                     # for automated testing. TDD. 
| |-- functional              # Selenium browser based tests.
| |
| |-- unit                    # PHPUnit Unit tests.               | | 
|-- utils                     # Helpers. E.g. for merging models
| |
| |-- sanitizers              # Validation helpers. for example fo|                               typesafe operations on derived
|                                classes.
|-- views                     # Mandatory. for GUI rendering.
| |-- related                 # For DetailsAndRelations views

Some specialized modules like the zurmo module might have a different structure, however for the majority of use cases, you will want to mimic the structure of the accounts module when you create your own custom modules in Zurmo.

(c) 2104 Windsor Wallaby. All rights reserved.

Tags: , , , , , , , , , , , , , , , | Posted under Zurmo | RSS 2.0

Author Spotlight

Windsor Wallaby

Windsor Wallaby is an independent and enthusiastic Zurmo CRM supporter and Open Source contributor. Active on the Zurmo user forums and a regular personality on the weekly Zurmo developer's conference call, Windsor is committed to building helping relationships by Listening, Learning, Doing, and Sharing. Windsor works with Zurmo CRM daily to track business opportunities and contacts. Windsor also integrates Zurmo as a core platform component for in-house and bespoke IT development projects.

Leave a Reply

Your email address will not be published. Required fields are marked *