The application gets and sends information from/to two sources:
thus, it expects to get information coming from these sources in their native format and sends information to them in their native format. So if we get a date from the database, it will be in the ISO standard database format but if we get a date from the browser it will be in the current user's format.
Since the application expects the information to be in these formats it does all the work necessary to get the information correctly into the right format when moving it around. For example, if it reads a date from the database and sends it to the browser it will first change it to the current user's format, and when that date comes from the browser it will format it into ISO standard to be saved in the database.
To accomplish this transforming of formats, which must happen for all types of fields, the application has a set of functions that do the work and that we can use freely:
The functionality described in the previous section works well in general but produces a significant problem when we are programming new features inside the application.
The issue is when we launch a $crmentity->retrieve_entity_info() to get the information of a record and we want to change the value in one or more fields and save the record back. The information that comes out of the $crmentity->retrieve_entity_info() call is in database format (it is coming in from the database), but the information we are sending into the $crmentity->save() is expected to be in the user/browser format so we have to transform the fields into their display format just to have them transformed again to be saved correctly.
This issue can appear in various parts of the application. Mainly it will appear in the workflow custom functions and in special process functionality added.
There are two ways to do this transformation, manually or using the DataTransform class.
The DataTransform was introduced with the Web Service interface where the problem of making sure the information being sent in was consistent and in the correct format.
The idea is that you give the class methods a meta information object that contains all the information of each field and it will apply the correct formatting to each one. So to use this class we need to first get an instantiation of the meta information class:
$handler = vtws_getModuleHandlerFromName('Events', $adminUser);
$meta = $handler->getMeta();
Now we call the DataTransform method using this $meta object.
$focus->column_fields = DataTransform::sanitizeForInsert($focus->column_fields,$meta);
Let's see a real example. Imagine a function to re-open a closed ticket. This action which appears as a link in the detail view action panel will first execute a series of tests to make sure the ticket can be re-opened and, if so, will change the state of the ticket. We want to do a full save so all programmed workflows and events take place.
At some point in the execution of the action the status change is authorized and this code is executed:
$ticket = CRMEntity::getInstance('HelpDesk');
$ticket->retrieve_entity_info($recordid, 'HelpDesk');
$ticket->id = $recordid;
$ticket->column_fields['ticketstatus'] = $newStatus;
$ticket->mode = 'edit';
$ticket->save('HelpDesk');
The previous code is wrong and will lose date, currency and special characters. The correct way to do this would be like this:
$ticket = CRMEntity::getInstance('HelpDesk');
$ticket->retrieve_entity_info($recordid, 'HelpDesk');
$ticket->id = $recordid;
$ticket->column_fields['ticketstatus'] = $newStatus;
$ticket->mode = 'edit';
$handler = vtws_getModuleHandlerFromName('HelpDesk', $adminUser);
$meta = $handler->getMeta();
$ticket->column_fields = DataTransform::sanitizeForInsert($ticket->column_fields,$meta);
$ticket->column_fields = DataTransform::sanitizeTextFieldsForInsert($ticket->column_fields,$meta);
$ticket->save('HelpDesk');
In our Timecontrol module we have this situation and we resolved it with a manual transformation basically because we didn't know of the existence of the DataTransform class then.
This is the situation: a timecontrol record is started, on the detail view of the record there is a stop watch and a button to stop the time counting. This save button launches an action in the application to update the total time on the record and close the timecontrol. This save action retrieves the whole record, updates the end time fields and saves the record. If we don't transform the fields to the expected user/browser formatting the values are lost.
Let's look at the code and comment it:
$focus->retrieve_entity_info($_REQUEST['record'], $currentModule);
foreach($focus->column_fields as $fieldname => $val) {
$focus->column_fields[$fieldname] = decode_html($focus->column_fields[$fieldname]);
}
$date = new DateTimeField(null);
$focus->column_fields['date_end'] = $date->getDisplayDate($current_user);
$focus->column_fields['time_end'] = $date->getDisplayTime($current_user);
First we transform all fields with the decode_html(). This is overkill as it transform even the date and numeric fields, not only the text fields, but since that function will not affect the date and numeric fields we can take this approach and make sure the we encode any additional text custom fields that may be added. Then we take care of the end date field setting it to "NOW" and putting it into the user format