/**
  * Update custom data.
  *
  *  - custom data is modified as follows
  *    - if custom data is changed it's updated.
  *    - if custom data is newly entered in field, it's inserted into db, finally
  *    - if existing custom data is cleared, it is deleted from the table.
  *
  * @param  array  &$groupTree - array of all custom groups, fields and values.
  * @param  string $entityType - type of entity being extended
  * @param  int    $entityId   - id of the contact whose custom data is to be updated
  * @return void
  *
  * @access public
  * @static
  *
  */
 function updateCustomData(&$groupTree, $entityType, $entityId)
 {
     $tableName = CRM_Core_BAO_CustomGroup::_getTableName($entityType);
     // traverse the group tree
     foreach ($groupTree as $group) {
         $groupId = $group['id'];
         // traverse fields
         foreach ($group['fields'] as $field) {
             $fieldId = $field['id'];
             /**
              * $field['customValue'] is set in the tree in the following cases
              *     - data existed in db for that field
              *     - new data was entered in the "form" for that field
              */
             if (isset($field['customValue'])) {
                 // customValue exists hence we need a DAO.
                 $customValueDAO =& new CRM_Core_DAO_CustomValue();
                 $customValueDAO->entity_table = $tableName;
                 $customValueDAO->custom_field_id = $fieldId;
                 $customValueDAO->entity_id = $entityId;
                 // check if it's an update or new one
                 if (isset($field['customValue']['id'])) {
                     // get the id of row in civicrm_custom_value
                     $customValueDAO->id = $field['customValue']['id'];
                 }
                 $data = $field['customValue']['data'];
                 // since custom data is empty, delete it from db.
                 // note we cannot use a plain if($data) since data could have a value "0"
                 // which will result in a !false expression
                 // and accidental deletion of data.
                 // especially true in the case of radio buttons where we are using the values
                 // 1 - true and 0 for false.
                 if (!strlen(trim($data))) {
                     $customValueDAO->delete();
                     continue;
                 }
                 // data is not empty
                 switch ($field['data_type']) {
                     case 'String':
                         $customValueDAO->char_data = $data;
                         break;
                     case 'Int':
                     case 'Boolean':
                     case 'StateProvince':
                     case 'Country':
                         $customValueDAO->int_data = $data;
                         break;
                     case 'Float':
                         $customValueDAO->float_data = $data;
                         break;
                     case 'Money':
                         $customValueDAO->decimal_data = number_format($data, 2, '.', '');
                         break;
                     case 'Memo':
                         $customValueDAO->memo_data = $data;
                         break;
                     case 'Date':
                         $customValueDAO->date_data = $data;
                         break;
                 }
                 // insert/update of custom value
                 $customValueDAO->save();
             }
         }
     }
 }