SuiteCRM Super Logger

posted in: SuiteCRM | 0

I’ve previously created a very simple module for SuiteCRM which adds coloured logging (SuiteCRM Colour Logger). I’ve now expanded it somewhat to add extra features.


It’s now called SuiteSuperLogger and allows specifying the log format in the config.


Enabling coloured logging can be done by adding

$sugar_config['suitesuperlogger']['colour'] = true;

To the config.

Altering the log format can be done by adding the following to config_override.php:

$sugar_config['suitesuperlogger']['format'] = ':date:[:pid:][:userId:][:level:][:remoteAddr:][:forwardedAddr:][:requestMethod:]:msg:';

The following placeholders are accepted and will be replaced with an appropriate value:

The date the message was logged
The process id
The logged in user id
The log level
The remote address as found in the PHP $_SERVER superglobal.
The request method (i.e. GET, POST, e.t.c.)
The actual log message


SuiteCRM Creating an Alert

posted in: SuiteCRM | 0

With the release of SuiteCRM 7.3 comes Alerts. These are displayed within SuiteCRM as a small badge in the menu bar. I.e:


Since these are just stored as beans we can add notifications by simply creating a new record with the appropriate values and saving it. For example:


Calling this can be used to create an alert for a specific user like so:



PHP Syntax Checking

posted in: General Programming | 0

The CLI to php allows checking for syntax errors using php -l I’ve created a very basic script which will recursively check folders for php files with syntax errors. It’s intended to quickly show syntax errors in a large application. It’s available here:

Simply run it and pass the path to your app:

php phpsyntaxcheck.php /path/to/php/files

Adding custom module to related to field in SuiteCRM

posted in: SuiteCRM | 0

Sometimes when you create a new module you want it to appear in the “Related To” dropdowns around SuiteCRM. This post will cover the simple method of adding modules to these dropdowns.


In this post we’ll add a fictional “Sport” module to the dropdown. We’ll end up with this:



The related to dropdown, like most in SuiteCRM can be changed by using the dropdown editor within SuiteCRM. We’re going to use the dropdown editor to add our custom module.


If you want to target the Related To module in Notes then edit the record_type_display_notes dropdown. For other related to dropdowns edit the parent_type_display.

We start by adding a new entry to the dropdown with the modules name as the “Item Name” and the display label we wish to use as the “Display Label”. I.e. in our example we’ll have

“ABC_Sport” as the “Item Name” and “Sport” as the “Display Label” as in this image:




And that’s it! SuiteCRM will use the module name to load the correct popup when searching for the module and will store this when saving the record. Your custom module can now be added to notes and the like.


Make a custom module importable

posted in: SuiteCRM | 0

If you’ve created a custom module but are getting the message “Imports aren’t set up for this module type” then it’s very easy to add this functionality to your custom module.


In the bean file modules/ABC_Your_Module/ABC_Your_Module.php simply add the line

var $importable = true;


After the class definition and you’ll be able to import this module.

SuiteCRM Missing Field Definitions

posted in: SuiteCRM | 0

If you move instances of SuiteCRM around it’s possible to have a copy of the SuiteCRM files that reference a custom field that doesn’t exist in the fields_meta_data table.

This can cause broken SQL queries since SuiteCRM will try to reference a field but won’t have it’s name. A broken query may look something like:

UPDATE my_custom_module SET name='Foo', =NULL,=NULL WHERE id='1234';

This can be fixed in one of two ways.

The first, preferred way is to get the info from the fields_meta_data table. This mysqldump command will create a file with the fields meta data:

mysqldump -uYourDBUser --insert-ignore --no-create-info -p YourDB fields_meta_data > fields_meta_data.sql

This can then be used to populate the new DB:

mysql -uYourDBUser -p YourNewDB < fields_meta_data.sql

The second is to find and remove the fields which are causing the issue. The following script will list any entries in the vardefs without a name which causes the original broken queries. Simply change the $base variable to be the path to the SuiteCRM instance you want to check and run php -f fieldcheck.php:

Once you have found the offending fields you can remove the definitions for them.


Add row buttons to the List View in SuiteCRM

posted in: SuiteCRM | 0

A previous post covered adding a button to the List View. However this was adding an action button to the list as a whole. This post will cover adding buttons for each row.

By the end of this post you will be able to add buttons such as this one:


Our example will look at the calls module. We’ll add a simple button to view the call on the calendar.

First off we will create a new non-db field in the calls module. We add the following file to custom/Extension/modules/Calls/Ext/Vardefs/ViewOnCalButton.php (we use the filename ‘ViewOnCalButton.php’ but this can be whatever you wish).


Next we add the language string for our new field. We place this file in custom/Extension/modules/Calls/Ext/Language/en_us.ViewOnCalButton.php:


In order to actually have the field display as a button we set up a logic hook to fill in the value. First we must define the logic hook in custom/Extension/modules/Calls/Ext/LogicHooks/ViewOnCal.php:

And then implement the hook itself and add it to custom/modules/Calls/ViewOnCalHook.php:

Note that we are creating a button which links to the calendar but this can do whatever actions you require. We must do a quick repair and rebuild from the admin menu in order for our changes above to take effect.


Finally we add the button to the list view. This can either be done in studio or by editing the list view defs. Let’s do this through studio:

ViewCalButton Studio


And there we have it. We now have the following:



Upon clicking we should be taken to the calendar.


Note that the above button is just an example and has a few issues that could be improved upon. If we click “View on calendar” for a call that isn’t ours we will be taken to a calendar page without the call on it. Can you see any other improvements? Let me know in the comments,

Car Reg Plate Game in Python

posted in: Games | 0

Me and my wife occasionally play a simple game when on longer car journeys. In the UK the last 3 characters in a car registration plate are letters.

by Cnbrb - Own work. Licensed under Public Domain via Wikimedia Commons.
by CnbrbOwn work. Licensed under Public Domain via Wikimedia Commons.

The aim of the game is to come up with words which start with the first letter, end with the last letter and contain the middle letter. So for the example plate in the image above we’d use SMR, a word that we could choose would be ‘speedometer (since it starts with s, ends with r and contains m’). Computers, unsurprisingly, are very good at this. Here’s an example of a super simple python script which prints matching words (this assumes you are on a Linux system, or at least a system with /usr/share/dict/words.

It can be called using python "BD51 SMR". This example outputs the following:


Adding a button to the List View in SuiteCRM

posted in: SuiteCRM | 0

It’s possible to add your own action menu items to the List view. By the end of this post you’ll be able to add your own menu items like this one:

Custom List View Button

In our case we’ll be adding this to the “Calls” list view.

First off we add the string for the menu item text. In this case “New action”. We place this into `custom/Extension/modules/Calls/Ext/Language/en_us.CustomMenuAction.php` (the `CustomMenuAction` part can be anything you like.



Next we create a new custom list view for the calls module and place this in `custom/modules/Calls/views/view.list.php` (customising views can be found in my SuiteCRM book).

This does the actual work of adding the button. This adds a new bit of HTML to the array `$this->lv->actionsMenuExtraItems`. SuiteCRM will then pick this up and add this to the list of action buttons.

In this case the button just points to a new entry point `myNewEntryPoint`. Adding entry points will be covered in a future post (if you are impatient you can always checkout my SuiteCRM book).

Chase the ace – The curse of the dealer

posted in: Games | 0


Chase the ace is a simple card game that I was taught when I was younger from my dad. Recently on holiday I was playing with some friends and for a few games it was always the dealer that was put out of the game first. We’d noticed this before and has dubbed it “The curse of the dealer”. I was curious to see if the curse had any basis or if it was just chance.

The rules

For those of you not familiar with Chase the Ace it is the simplest card game I know. Each player is dealt a card (the more players the better!). Play starts to the left of the dealer with each player deciding whether to keep his current card or to force the player on their left to swap with them. When play reaches the dealer they can choose to swap with the deck. After every player has had their turn the person (or persons) with the lowest card (Aces are low) is knocked out of the game. The next round starts again without the losing players until a player remains (or all players are knocked out).

Testing the curse

I created a simple python script to play a bunch of hands with 10 players and keep track of which player or players were knocked out first (the source of which can be found on GitHub.


The strategy played is pretty simple (so it may affect the outcome) and uses the following rules:

  • If a player swaps with us and we end up with a higher card then we always keep that card (since we are guaranteed to stay in).
  • If we have a card higher than a 7 keep it.
  • Otherwise swap.

Using 10 players for 10,000,000 hands gave the following results:

Position 0 1 2 3 4 5 6 7 8 9 Total
Loses 791547 1037209 1146774 1206951 1252666 1280194 1305464 1322220 1328504 1325231 11996760
% Loses 6.60 8.65 9.56 10.06 10.44 10.67 10.88 11.02 11.07 11.04



We can see that the dealer is indeed at a disadvantage and, in fact your odds of losing decreases as you get closer to early positions. I suspect that this is due to bad cards “bubbling up” through the positions. If you have a high card and are in later position you have a higher chance of losing it. I may revisit this code at some point and see if this code can be reused to generate an optional strategy.

Edit: Someone has pointed out that, in fact, it’s the second to last player that loses slightly more. I’m rerunning this with more games to see if this is chance or not – there may be a point where all players are equally disadvantaged.