For some reason, the Drupal User association I added to the CiviCRM Contact Search API index was missing. When I started debugging the index process, the $item->civicrm_user
was always null
.
I decided to try manually populating the civicrm_user
property on the civicrm_contact
entity in a custom Search API index filter. That worked!
In sample_module.module
:
/** * Implements hook_search_api_alter_callback_info(). */ function sample_module_search_api_alter_callback_info() { 'name' => t('Sample index filter process'), 'description' => t('My entry into the index process so I can customize the items being indexed.'), 'class' => 'SampleSearchApiIndexFilter', // We need this thing to run before others. Set it to a very low weight. 'weight' => -50, ); return $callbacks; }
Create our index filter class in a file called: SampleSearchApiIndexFilter.inc
.
class SampleSearchApiIndexFilter extends SearchApiAbstractAlterCallback { /** * {@inheritdoc} */ public function supportsIndex(SearchApiIndex $index) { return $this->isCiviContactIndex($index); } /** * {@inheritdoc} */ // Make sure we're running on the supported type of indexes. if (!$this->supportsIndex($this->index)) { return; } // $index_fields = $this->index->getFields(); /* Not needed in example. */ foreach ($items as $id => $item) { // Super important! We need to index data on teh $item->civicrm_user // object but for some reason, it never gets populated $item->civicrm_user = self::getUserAccount($item->contact_id); } } /** * {@inheritdoc} */ public function configurationForm() { return parent::configurationForm(); } /** * {@inheritdoc} */ return parent::configurationFormSubmit($form, $values, $form_state); } /** * Detects whether the $index is based on a CiviCRM Contact entity. * * @param \SearchApiIndex|NULL $index * @return bool */ protected function isCiviContactIndex(SearchApiIndex $index = null) { $data_source = $index->datasource(); return $data_source->getEntityType() == 'civicrm_contact'; } static function getUserAccount($contact_id) { $uid = db_select('civicrm_uf_match', 'm') ->condition('m.contact_id', $contact_id) ->execute()->fetchCol(); } return null; } }
Add our class to sample_module.info
so Drupal's autoloader knows about it.
files[] = SampleSearchApiIndexFilter.inc
drush cc all
I'm assuming you already have a index, you'll need to add your filter to it.
Go to your index, click on FILTERS
, then look for your custom filter under the "DATA ALTERATIONS" group. Tick the box next to it, save, then re-index your content.
Software engineer by profession, embedded systems tinkerer, husband, father, fantasy novel devourer, wine lush, beer and cheese connoisseur