Duplicate Check
Overview
The duplicate-check framework provides the capability to alter how the system searches for duplicate records in the database when creating records. For information on duplicate checking during imports, please refer to the index documentation.
Default Strategy
The default duplicate-check strategy, located in ./data/duplicatecheck/FilterDuplicateCheck.php
, is referred to as FilterDuplicateCheck. This strategy utilizes the Filter API and a defined filter in the vardefs of the module to search for duplicates and rank them based on matching data.
Custom Filter
To alter a defined filter for a stock a module, you only need to update the Vardefs using the Extensions framework. If you are working with a custom module, you can modify the vardefs in ./modules/<module>/vardefs.php
directly. The FilterDuplicateCheck Strategy accepts two properties in its metadata:
Name | Type | Description |
filter_template | array | An array containing the Filter Definition for which fields to search for duplicates on. Please consult the Filter API for further information on the filter syntax |
ranking_fields | array |
A list of arrays with the following properties. The order in which you list the fields for ranking will determine the ranking score. The first ranks higher, than those after it. in_field_name: Name of field in vardefs dupe_field_name: Name of field returned by filter |
Example
The following example will demonstrate how to manipulate the stock Accounts duplicate check to not filter on the shipping address city. The default Account duplicate_check
defintion, located in ./modules/Accounts/vardefs.php
, is shown below.
...
'duplicate_check' => array(
'enabled' => true,
'FilterDuplicateCheck' => array(
'filter_template' => array(
array(
'$or' => array(
array('name' => array('$equals' => '$name')),
array('duns_num' => array('$equals' => '$duns_num')),
array(
'$and' => array(
array('name' => array('$starts' => '$name')),
array(
'$or' => array(
array('billing_address_city' => array('$starts' => '$billing_address_city')),
array('shipping_address_city' => array('$starts' => '$shipping_address_city')),
)
),
)
),
)
),
),
'ranking_fields' => array(
array('in_field_name' => 'name', 'dupe_field_name' => 'name'),
array('in_field_name' => 'billing_address_city', 'dupe_field_name' => 'billing_address_city'),
array('in_field_name' => 'shipping_address_city', 'dupe_field_name' => 'shipping_address_city'),
)
)
),
...
To add or remove fields from the check, you will need to manipulate $dictionary['<module>']['duplicate_check']['FilterDuplicateCheck']['filter_template']
and $dictionary['<module>']['duplicate_check']['FilterDuplicateCheck']['ranking_fields']
. For our example, we will simply remove the references to shipping_address_city
. It is important to familiarize yourself with filter operators before making any changes.
./custom/Extension/modules/Accounts/Ext/Vardefs/newFilterDuplicateCheck.php
<?php
$dictionary['Account']['duplicate_check']['FilterDuplicateCheck'] = array(
'filter_template' => array(
array(
'$or' => array(
array('name' => array('$equals' => '$name')),
array('duns_num' => array('$equals' => '$duns_num')),
array(
'$and' => array(
array('name' => array('$starts' => '$name')),
array(
'$or' => array(
array('billing_address_city' => array('$starts' => '$billing_address_city')),
)
),
)
),
)
),
),
'ranking_fields' => array(
array('in_field_name' => 'name', 'dupe_field_name' => 'name'),
array('in_field_name' => 'billing_address_city', 'dupe_field_name' => 'billing_address_city'),
)
);
Finally, navigate to Admin > Repair > Quick Repair and Rebuild. The system will then enable the custom duplicate-check class.
If you want to disable the duplicate check entirely, you can set $dictionary['<module>']['duplicate_check']['enabled']
to false in your vardefs and run a Quick Repair and Rebuild.
$dictionary['Account']['duplicate_check']['enabled'] = false;
Custom Strategies
Custom duplicate-check class files are stored under ./custom/data/duplicatecheck/
. The files in this directory can be enabled on a module's duplicate_check property located in ./custom/Extension/modules/<module>/Ext/Vardefs/
. Only one duplicate-check class can be enabled on a module at a given time.
Duplicate Check Class
To create a custom duplicate-check strategy, you need to create a custom duplicate-check class that extends the base DuplicateCheckStrategy, ./data/duplicatecheck/DuplicateCheckStrategy.php
. To work, this custom class requires the implementation of two methods:
Method Name | Description |
setMetadata | Sets up properties for duplicate-check logic based on the passed-in metadata |
findDuplicates | Finds possible duplicate records for a given set of field data |
Example
The following example will create a new duplicate-check class called "OneFieldDuplicateCheck" that will query the database based on the configured field for records that contain data similar to that one field:
./custom/data/duplicatecheck/OneFieldDuplicateCheck.php
<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
class OneFieldDuplicateCheck extends DuplicateCheckStrategy
{
protected $field;
public function setMetadata($metadata)
{
if (isset($metadata['field'])) {
$this->field = $metadata['field'];
}
}
public function findDuplicates()
{
if (empty($this->field)){
return null;
}
$Query = new SugarQuery();
$Query->from($this->bean);
$Query->where()->ends($this->field,$this->bean->{$this->field});
$Query->limit(10);
//Filter out the same Bean during Edits
if (!empty($this->bean->id)) {
$Query->where()->notEquals('id',$this->bean->id);
}
$results = $Query->execute();
return array(
'records' => $results
);
}
}
Vardef Settings
The duplicate-check vardef settings are configured on each module and can be altered using the Extension framework.
Name | Type | Description |
enabled | boolean | Whether or not duplicate-check framework is enabled on the module |
<class_name> | array | The class name that will provide duplicate checking, set to an array of metadata that gets passed to the duplicate-check class |
If you want to enable the OneFieldDuplicateCheck strategy (shown above) for the Accounts module, you must create the following file:
./custom/Extension/modules/Accounts/Ext/Vardefs/newDuplicateCheck.php
<?php
$dictionary['Account']['duplicate_check'] = array(
'enabled' => true,
'OneFieldDuplicateCheck' => array(
'field' => 'name'
)
);
Finally, navigate to Admin > Repair > Quick Repair and Rebuild. The system will then enable the custom duplicate-check class.
Programmatic Usage
You can also use the duplicate-check framework in code such as in a logic hook or a scheduler. The following example shows how to use the module's defined duplicate-check strategy when utilizing a bean object by simply calling the findDuplicates
method on the bean object:
$account = BeanFactory::newBean('Accounts');
$account->name = 'Test';
$duplicates = $account->findDuplicates();
if (count($duplicates['records'])>0){
$GLOBALS['log']->fatal("Duplicate records found for Account");
}