I needed to do something similar. There were two things to work on: getting the Contact ID in the search suggestion in the quick search and getting CiviCRM to search the Contact Id by default when placing a number in the quick/regular search and hitting enter.
Note: I just adapted my code to work with contact ID, didn't test it.
I used a CiviCRM extension with the queryObjects hook:
[myext]/myext.php
// Get the Contact ID to display in the suggestions
function extname_civicrm_apiWrappers(&$wrappers, $apiRequest) {
if ($apiRequest['entity'] == 'Contact') {
if ($apiRequest['action'] == 'getquick') {
$wrappers[] = new CRM_Extname_APIWrapper_GetQuick();
}
}
}
function emulate_civicrm_api3_contact_getList($params) {
$res = civicrm_api3('Contact','get', $params);
// reformat the output to look like getquick
foreach ($res['values'] as $idx => &$value) {
$value['data'] = $value['id'].' :: '.$value['sort_name'] . ( empty($value['nick_name']) ? '' : ' ('.$value['nick_name'].')' );
foreach (['street_address','city','state_province_name','postal_code','phone','email'] as $col) {
if (!empty($value[$col])) $value['data'] .= ' :: '.$value[$col];
}
}
return $res;
}
// Get the id to be part of the default search
function extname_civicrm_queryObjects (&$queryObjects, $type = 'Contact') {
if ($type == 'Contact') {
$queryObjects[] = new CRM_Extname_BAO_Query();
}
}
[myext]/CRM/Extname/APIWrapper/GetQuick.php
clas
s CRM_Extname_APIWrapper_GetQuick implements API_Wrapper {
public function fromApiInput($apiRequest) {
if (!empty($apiRequest['params']['field_name'])) return $apiRequest;
$apiRequest['entity'] = 'Contact';
$apiRequest['action'] = 'getlist';
$apiRequest['function'] = 'emulate_civicrm_api3_contact_getList';
$apiRequest['params']['sequential'] = '1';
$apiRequest['params']['nick_name'] = $apiRequest['params']['id'] = $apiRequest['params']['name'];
unset($apiRequest['params']['name']);
unset($apiRequest['params']['option']);
unset($apiRequest['params']['task']);
unset($apiRequest['params']['field_name']);
unset($apiRequest['params']['table_name']);
return $apiRequest;
}
// this never seems called
public function toApiOutput($apiRequest, $result) {
return $result;
}
}
[myext]/CRM/Extname/BAO/Query.php
class CRM_Extname_BAO_Query extends CRM_Contact_BAO_Query_Interface {
function &getFields() {
return ['id'];
}
function from($name, $mode, $side) {
return '';
}
function where(&$query) {
$grouping = NULL;
foreach (array_keys($query->_params) as $id) {
if (empty($query->_params[$id][0])) {
continue;
}
$this->whereClauseSingle($query->_params[$id], $query);
}
}
function whereClauseSingle(&$values, &$query) {
list($name, $op, $value, $grouping, $wildcard) = $values;
$fields = $this->getFields();
if (!empty($value) && !is_array($value)) {
$quoteValue = "\"$value\"";
}
// Look in CRM_Contact_BAO_Query:2025 for how this is all gatherered into or's and ands
switch ($name) {
case 'sort_name':
// the default search is grouping=0; this is pretty hard coded into CRM_Contact_BAO_Query
if ($grouping==0) {
foreach ($query->_where[$grouping] as $key => $val) {
if (strpos($query->_where[$grouping][$key],'sort_name')===false) continue;
// search id if numeric
if (is_numeric($value)) {
$query->_qill[$grouping][$key] .= ' Or '.($value ? ts('Contact ID is '.$quoteValue) : ts('Contact ID is not '.$quoteValue));
$query->_where[$grouping][$key] .= ' OR '.CRM_Contact_BAO_Query::buildClause("contact_a.id", "=", (int)$value, "Int");
}
break;
}
}
return;
}
}
public function getPanesMapper(&$panes) {
return $panes;
}
}