Sunday, November 29, 2009

Engineering At Its Finest - Adding Accessibility Options



Reactions 

Every machine capable of enriching our lives is work of someone's ingenuity. Everything from a simple pencil to a plane. But before any new product becomes acceptable by masses, it has to be refined. Made so simple that an end user can use it. That's exactly when an idea becomes an innovation. I was always of the view that a new technology reaches its potential when it starts contributing to entertainment of the masses. But a step further would be to make technology and machines accessible to people with disabilities. That's the perfection.

Social infrastructure should specially be build; keeping disabled in mind. Why all the extra cost and effort someone may ask. My answer would be, what if all this results in some disabled reaching to even 10% of Mr. Hawking's stature. That will repay all the extra cost and effort.

Following are some examples I would like to share with all.

The Beeps in Buses

Right. We all hate that loud sound of a bus horn but these are buttons inside the buses which produces a beep sound. It can be helpful for someone who has speaking disabilities.

a modern bus with beep buttons for mute
Metro Walk

Delhi Metro gets full marks when I evaluate it on these grounds. They have lifts for disabled. But what is worth noticing is the yellow strip which is layered on top of the floor. These are the blind lines. Notice the pattern over it. A blind person with a stick can easily follow them.

delhi metro has paths for blinds
Let's build products which are accessible to all and start asking for accessibility options in ones which are already build. These features can also be of use to normal people. For e.g the beep buttons can make people act more civilized. Children can be asked to follow yellow strips, so they can stay away from crowded areas. Similarly, every new accessibility feature added may also benefit normal users in some way..

Sunday, November 22, 2009

Hacking Mantis - Adding a New Status



Reactions 

{rant} I hate nothing more than a half baked blog posts. If anyone reading this also happen to write a blog, it is my humble request to write detailed posts for tech issues. Most of the articles I am finding only goes half way, many of them never explain reason. It results into lots of wasted effort. This post is not only the solution but the process by which solution can be found. {/rant}

Mantis is a my favorite bug tracker. Alright, Bugzilla is more famous and everyone from "you know who" to "I never heard of them" uses it. But Mantis is simple and does perfectly what it is supposed to do. It also has lots of deployments and is renowned.

There can be many reasons to add a custom status to a bug tracker. Truthfully, I was surprised to not find the option for this in admin panel. For my need, I had to add a status tested to it. Which according to work flow will be like a stamp of approval from testing team. After that reporter/manager can choose to close the bug.

So where should we start from?
Let's see. When we login, first page is my_view_page.php. It be a good idea to see its code. As you can quickly see, this page gives first impression about Mantis' code structure. I see a promise that development team has put in lots of thought. We don't see anything about the statuses but they are visible at the bottom bar of the page. So they are definitely being referenced from somewhere.

First line says include core.php. By its very name, this file sounds something important. Let's open this up. As you can see, there are lots of inclusions in this file. This file is basically library/app loader. Start reading this file. Following snippet is of interest.


# Load constants and configuration files
require_once( dirname( __FILE__ ).DIRECTORY_SEPARATOR.'core'.DIRECTORY_SEPARATOR.'constant_inc.php' );
if ( file_exists( dirname( __FILE__ ).DIRECTORY_SEPARATOR.'custom_constant_inc.php' ) ) {
require_once( dirname( __FILE__ ).DIRECTORY_SEPARATOR.'custom_constant_inc.php' );



What it is saying is to include constant_inc.php in folder core and overwrite its settings by custom_constant_inc.php if it exists in root directory.

Let's open core/constant_inc.php. As expected, this file has lots of constants. And there's a comment #status and below it existent statuses are defined. Each status definition is with a number as value with numbers ascending as work flow. Fair enough. Let's introduce our custom status here. Or if you are not lazy like me ;), you can create the overwrite file and define it there.


# status
define( 'NEW_', 10 ); # NEW seems to be a reserved keyword
define( 'FEEDBACK', 20 );
define( 'ACKNOWLEDGED', 30 );
define( 'CONFIRMED', 40 );
define( 'ASSIGNED', 50 );
define( 'RESOLVED', 80 );
define( 'TESTED', 85 );
define( 'CLOSED', 90 );


So here we have tested status. After resolved and before closed.

But this change alone will not make any difference to Mantis. I truly hope it was smart enough to have picked up this new status just by someone defining it in above file.

So what to do next?
We are on the right path as we found other statuses being defined in the code. constant_inc.php has nothing further to say about statuses. Let's go back to core.php. Following block which is just next to above snippet is of interest.


require_once( dirname( __FILE__ ).DIRECTORY_SEPARATOR.'config_defaults_inc.php' );
# config_inc may not be present if this is a new install
if ( file_exists( dirname( __FILE__ ).DIRECTORY_SEPARATOR.'config_inc.php' ) ) {
require_once( dirname( __FILE__ ).DIRECTORY_SEPARATOR.'config_inc.php' );


Same meaning as code discussed above but with different files. Let's open config_defaults_inc.php. Noticed the file size? Phew, it is a huge file. To save you sometime. Following two variables are of interest

$g_status_enum_string and $g_status_colors

What they hold are the status field's possible values and color coding for that value in legend. After introducing our new tested status, these variables look as follows.


$g_status_colors = array( 'new' => '#ffa0a0', # red,
'feedback' => '#ff50a8', # purple
'acknowledged' => '#ffd850', # orange
'confirmed' => '#ffffb0', # yellow
'assigned' => '#c8c8ff', # blue
'resolved' => '#cceedd', # buish-green
'tested' => '#3399FF', # cool blue :)
'closed' => '#e8e8e8'); # light gray

$g_status_enum_string = '10:new,20:feedback,30:acknowledged,40:confirmed,50:assigned,80:resolved,85:tested,90:closed';

Well it does the trick. Now we have a new status but wait it is not called tested.

What is missing?
If you had followed this far, you must now be getting a new status option which is called @85@. Clearly we still have not defined correct name value for this status. Let's get back to core.php. Line of interest



# Load internationalization functions (needed before database_api, in case database connection fails)
require_once( $t_core_path.'lang_api.php' );


All we need to do next is to find the file from where language values are being loaded. After some echos and dies ;). It can be figured out from following snippet at the top


$t_lang_dir = dirname ( dirname ( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR;

require_once( $t_lang_dir . 'strings_' . $p_lang . '.txt' );

# Allow overriding strings declared in the language file.
# custom_strings_inc.php can use $g_active_language
$t_custom_strings = dirname ( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'custom_strings_inc.php';
if ( file_exists( $t_custom_strings ) ) {
require( $t_custom_strings ); # this may be loaded multiple times, once per language
}


$p_lang holds the language name; in our case english. That file is being loaded from the lang directory. Let's open up strings_english.txt. And voila! We hit the jackpot. Seach for keyword resolved to see all available options available for a status. As you see Mantis uses some variable names which contains the statuses to refer to their language options. This is really smart. Legend variable should be edited and following lines are what I added. Self explanatory with comments.


$s_status_enum_string = '10:new,20:feedback,30:acknowledged,40:confirmed,50:assigned,80:resolved,85:tested,90:closed';
$s_legend_tested = 'Tested';
$s_tested_bug_button = "Tested";
$s_tested_bug_title = "Set Issue to Tested";
$s_email_notification_title_for_status_bug_tested = "The following issue is Tested.";
$s_email_notification_title_for_action_relationship_child_tested = "The RELATED issue %s has been TESTED.";
$s_email_on_tested = 'Email on Tested';
$s_bug_tested_msg = 'Issue has been resolved. Enter note below...';
$s_desc_bug_tested_status_threshold = 'Status where an issue is considered tested';
$s_tested_status = 'Status where an issue is considered tested';
$s_my_view_title_tested = 'Tested';

//summary page - mantis code is smartly structured..
$s_orct = '(open/resolved/tested/closed/total)';

//custom fields
$s_custom_field_display_tested = 'Display When Testing Issues';
$s_custom_field_require_tested = 'Required On Test';

//filters :)
$s_filter_tested = "Tested";
$s_hide_tested = "Hide Tested"; //why would anyone hide the cool blue color ;)

/* required mantis flow is too simplistic to touch these
$s_relationship_warning_blocking_bugs_not_resolved = "Not all the children of this issue are yet resolved or closed.";
$s_relationship_warning_blocking_bugs_not_resolved_2 = "ATTENTION. Not all the children of this issue are yet resolved or closed.
Before resolving/closing a parent issue, all the issues related as child with this one
*/


We got more than what we wanted :)
If you notice your Mantis installation. You will also have tested status reports in summary section. It will be very helpful and it happened because of the change in $s_orct above.

Your Mantis installation will now have tested status in cool blue color with all the relevant options :).