Is there a recommended way to customise the quicksearch?
I found it quite hard to replace the customization done with hook_civicrm_contactListQuery (CiviCRM &lt;= 4.4) with the new hook_civicrm_apiWrappers (CiviCRM >= 4.5).

So I am sharing my results here.

My goal is to have a way to search quickly either by contact name, or by a custom field that stores a member identifier (different from internal identifier and external identifier).

My old code looked like this :

function myext_civicrm_contactListQuery( &amp;$query, $name, $context, $id ) {
  if ($context == 'navigation') {
    // if not name / email search, just keep the standard behavior
    if (!isset($_GET['tableName']) || $_GET['tableName'] != 'cc') return;

    // if the search is a number, try to look for the custom member id
    if (is_numeric($name)) {
      $query = "SELECT cc.id as id, CONCAT_WS( ' :: ', CONCAT(sort_name, ' (', im.num_ro_de_membre_37, ')') ) as data, sort_name
                FROM civicrm_contact cc
                LEFT JOIN civicrm_value_r_sum_de_membre_6 im ON ( cc.id = im.entity_id ) 
                WHERE im.num_ro_de_membre_37 = '$name'
                AND cc.is_deleted = 0
                LIMIT 5";

    } elseif (strlen($name) &lt; 2) {
      $query = "";
    }
  }

}


And now :

function myext_civicrm_apiWrappers(&amp;$wrappers, $apiRequest) {
  if ($apiRequest['entity'] == 'Contact' &amp;&amp; $apiRequest['action'] == 'getquick') {

    // search by member id if the search is a numeric value
    if (is_numeric($apiRequest['params']['name'])) {
      $wrappers[] = new CRM_Myext_APIWrapper();
    }   
  }
}

// i need to do this because there is no function civicrm_api3_contact_getlist
function emulate_civicrm_api3_contact_getList($params) {

  // not loaded by default
  include_once "api/v3/Generic/Getlist.php";
  include_once "api/v3/utils.php";

  $apiRequest = array(
    'entity' =&gt; 'Contact',
    'action' =&gt; 'getlist',
    'params' =&gt; $params,
  );  
  $res = civicrm_api3_generic_getList($apiRequest);

  // reformat the output to look like getquick
  foreach ($res['values'] as $idx =&gt; $value) {
    $res['values'][$idx]['data'] = $value['extra']['sort_name'] . " ({$value['extra']['custom_37']})";
  }

  return $res;
}


And a new APIWrapper class in a dir CRM/Myext/APIWrapper.php :

class CRM_Myext_APIWrapper implements API_Wrapper {

  public function fromApiInput($apiRequest) {

    // change api call - getquick is deprecated and doesn't work with custom field
    $apiRequest['entity'] = 'Contact';
    $apiRequest['action'] = 'getlist';
    $apiRequest['function'] = 'emulate_civicrm_api3_contact_getList';

    // change name param to field custom_37 and remove useless params
    $apiRequest['params']['params']['custom_37'] = $apiRequest['params']['name'];
    unset($apiRequest['params']['name']);
    unset($apiRequest['params']['field_name']);
    unset($apiRequest['params']['table_name']);

    // restrict return data (getlist doesn't use return param)
    $apiRequest['params']['extra'] = array('sort_name','custom_37');

    return $apiRequest;
  }

}