+ if (!empty($request['input']) && !empty($defaults['search_field_fallback']) && $result['count'] < $request['params']['options']['limit']) {
+ // We support a field fallback. Note we don't do this as an OR query because that could easily
+ // bypass an index & kill the server. We just 'pad' the results if needed with the second
+ // query - this is effectively the same as what the old Ajax::getContactEmail function did.
+ // Since these queries should be quick & often only one should be needed this is a simpler alternative
+ // to constructing a UNION via the api.
+ $request['params'][$defaults['search_field_fallback']] = $request['params'][$defaults['search_field']];
+ if ($request['params']['options']['sort'] === $defaults['search_field']) {
+ // The way indexing works here is that the order by field will be chosen in preference to the
+ // filter field. This can result in really bad performance so use the filter field for the sort.
+ // See https://github.com/civicrm/civicrm-core/pull/16993 for performance test results.
+ $request['params']['options']['sort'] = $defaults['search_field_fallback'];
+ }
+ // Exclude anything returned from the previous query since we are looking for additional rows in this
+ // second query.
+ $request['params'][$defaults['search_field']] = ['NOT LIKE' => $request['params'][$defaults['search_field_fallback']]['LIKE']];
+ $request['params']['options']['limit'] -= $result['count'];
+ $result2 = civicrm_api3($entity, 'get', $request['params']);
+ $result['values'] = array_merge($result['values'], $result2['values']);
+ $result['count'] = count($result['values']);
+ }
+ else {
+ // Re-index to sequential = 0.
+ $result['values'] = array_merge($result['values']);
+ }