Associating PHP Code with a custom data group ..

Publicat
2008-06-02 01:36
Written by
lobo - member of the CiviCRM community - view blog guidelines
With the new custom data model in 2.0, it seemed a good time to allow developers to add columns to a custom group that are computed rather than entered. Some examples of this is computing the GPA of a student given the student's individual grades, computing the age of a contact given his/her birthday. This has been an outstanding issue, CRM-1594, for quite some time. We went down the path of describing an interface and making the admin implement the interface, similar to what we do with custom search. The admin would need to add the class implementing the interface to the group settings file. After implementing this, i could not articulate when we use an interface vs using a hook. I decided to implement it as a new "civicrm_custom" hook and it seemed a lot easier and also more inline with some of our other hooks. I did not introduce a specific "php code" data type. I chose to give the custom field a new property called "is_view". Setting this property disallows this custom field from being shown on a CiviCRM form. I suspect most "code" custom fields might want this enabled, however it is not a requirement. The code could decide to include the user entered value in the calculation of a new value. The new "civicrm_custom" hook is called whenever any field in a custom group is edited or created. The hook is called after civicrm stores the values in the custom table. The hook function receives the ID of the custom group and the ID of the object that "owns" this record. It is the responsibility of the hook to determine what has changed and what needs to be recomputed. The hook could retrieve information from one or more CiviCRM tables and then update one or more columns in the custom value table (or any other table). A sample hook implementation is:
function civitest_civicrm_custom( $op, $groupID, $entityID, &$params ) {
    if ( $op != 'create' && $op != 'edit' ) {
        return;
    }
    $tableName = CRM_Core_DAO::getFieldValue( 'CRM_Core_DAO_CustomGroup',
                                              $groupID,
                                              'table_name' );
    $randomValue = myFunctionToComputeRandomValue( );
    $sql = "
UPDATE $tableName
SET    random_code_data_3 = $randomValue
WHERE  entity_id = $entityID
";  
    CRM_Core_DAO::executeQuery( $sql,
                                CRM_Core_DAO::$_nullArray );
}
Note that the hook implementation also writes to the table record. It seemed much easier and cleaner to do it this way (for now). This code is currently checked into trunk for any developers on the cutting edge.
Filed under

Comments