/**
 * Contact.Normalize API: Normalizes one or more contacts
 *
 * @param  array $params  an associative array of contacts.
 * @return array API result descriptor
 * @see civicrm_api3_create_success
 * @see civicrm_api3_create_error
 * @throws API_Exception
 */
function civicrm_api3_contact_normalize($params)
{
    $normalize = CRM_Utils_Normalize::singleton();
    $contacts = CRM_Utils_Array::value('values', $params);
    if (sizeof($contacts)) {
        foreach ($contacts as &$contact) {
            $normalize->normalize_contact($contact);
        }
    }
    return civicrm_api3_create_success($contacts);
}
/**
 * Implementation of hook_civicrm_pre
 */
function normalize_civicrm_pre($op, $objectName, $objectId, &$objectRef)
{
    $normalize = CRM_Utils_Normalize::singleton();
    if (in_array($objectName, array('Individual', 'Organization', 'Household'))) {
        $normalize->normalize_contact($objectRef);
        // for CiviCRM 4.2.2 & lower only
        if (array_key_exists('phone', $objectRef) && is_array($objectRef['phone'])) {
            foreach ($objectRef['phone'] as &$phone) {
                $normalize->normalize_phone($phone);
            }
        }
        if (array_key_exists('address', $objectRef) && is_array($objectRef['address'])) {
            foreach ($objectRef['address'] as &$address) {
                $normalize->normalize_address($address);
            }
        }
    } elseif ($objectName == 'Phone') {
        $normalize->normalize_phone($objectRef);
    } elseif ($objectName == 'Address') {
        $normalize->normalize_address($objectRef);
    }
}
 /**
  * Update the push stats setting.
  */
 static function updatePushStats($updates)
 {
     $stats = CRM_Utils_Normalize::getSettings('normalization_stats');
     foreach ($updates as $name => $value) {
         $stats[$name] += $value;
     }
     CRM_Utils_Normalize::setSetting($stats, 'normalization_stats');
 }
 static function processNormalization($fromContactId, $toContactId)
 {
     $processInfo = array('name' => 0, 'phone' => 0, 'address' => 0);
     if (empty($fromContactId) || empty($toContactId)) {
         return $processInfo;
     }
     $contactIds = range($fromContactId, $toContactId);
     $normalization = CRM_Utils_Normalize::singleton();
     $formattedContactIds = $formattedPhoneIds = $formattedAddressIds = array();
     foreach ($contactIds as $contactId) {
         $contact = new CRM_Contact_DAO_Contact();
         $contact->id = $contactId;
         if ($contact->find()) {
             $params = array('id' => $contactId, 'contact_id' => $contactId);
             $orgContactValues = array();
             CRM_Contact_BAO_Contact::retrieve($params, $orgContactValues);
             //update contacts name fields.
             $formatNameValues = array();
             foreach ($normalization->getNameFields() as $field) {
                 $nameValue = CRM_Utils_Array::value($field, $orgContactValues);
                 if (empty($nameValue)) {
                     continue;
                 }
                 $formatNameValues[$field] = $nameValue;
             }
             if (!empty($formatNameValues)) {
                 $formatNameValues['contact_type'] = $orgContactValues['contact_type'];
                 $formattedNameValues = $formatNameValues;
                 //format name values
                 $normalization->normalize_contact($formattedNameValues);
                 //check formatted diff, only update if there is difference.
                 $formatDiff = array_diff($formatNameValues, $formattedNameValues);
                 if (!empty($formatDiff)) {
                     $formattedNameValues['id'] = $formattedNameValues['contact_id'] = $orgContactValues['id'];
                     $formattedNameValues['contact_type'] = $orgContactValues['contact_type'];
                     $contactUpdated = CRM_Contact_BAO_Contact::add($formattedNameValues);
                     if ($contactUpdated->id) {
                         $formattedContactIds[$contactUpdated->id] = $contactUpdated->id;
                     }
                     $contactUpdated->free();
                 }
             }
             //update phone fields.
             if (isset($orgContactValues['phone']) && is_array($orgContactValues['phone'])) {
                 foreach ($orgContactValues['phone'] as $cnt => $orgPhoneValues) {
                     if (!isset($orgPhoneValues['id']) || empty($orgPhoneValues['id']) || empty($orgPhoneValues['phone'])) {
                         continue;
                     }
                     $formattedPhoneValues = $orgPhoneValues;
                     //format phone fields
                     $normalization->normalize_phone($formattedPhoneValues);
                     //do check for formatted difference, than only update.
                     $formattedDiff = array_diff_assoc($orgPhoneValues, $formattedPhoneValues);
                     if (!empty($formattedDiff)) {
                         $phoneUpdated = CRM_Core_BAO_Phone::add($formattedPhoneValues);
                         if ($phoneUpdated->id) {
                             $formattedPhoneIds[$phoneUpdated->id] = $phoneUpdated->id;
                         }
                         $phoneUpdated->free();
                     }
                 }
             }
             //update address.
             if (isset($orgContactValues['address']) && is_array($orgContactValues['address'])) {
                 foreach ($orgContactValues['address'] as $cnt => $orgAddressValues) {
                     if (!isset($orgAddressValues['id']) || empty($orgAddressValues['id'])) {
                         continue;
                     }
                     $formattedAddressValues = $orgAddressValues;
                     //format addrees fields
                     $normalization->normalize_address($formattedAddressValues);
                     //do check for formatted difference, than only update.
                     $formattedDiff = array_diff($orgAddressValues, $formattedAddressValues);
                     if (!empty($formattedDiff)) {
                         $addressUpdated = CRM_Core_BAO_Address::add($formattedAddressValues, FALSE);
                         if ($addressUpdated->id) {
                             $formattedAddressIds[$addressUpdated->id] = $addressUpdated->id;
                         }
                         $addressUpdated->free();
                     }
                 }
             }
         }
         $contact->free();
     }
     $processInfo = array('name' => $formattedContactIds, 'phone' => $formattedPhoneIds, 'address' => $formattedAddressIds);
     return $processInfo;
 }