If SearchApiEtDatasourceController::getItemId() returns NULL, when search api hook_node_access_records_alter implementation is fired search_api_et tries to load all related nodes because an array([0] =>NULL) is given

More details:

  1. function search_api_node_access_records_alter is fired.

    In this fucntion we have:

    $item_id = $index->datasource()->getItemId($node);
    $item_ids =  array($item_id);
    

    So first getItemId() is called and its result pushed to an array and assigneid to $item_ids.

  2. getItem() code in SearchApiEtDatasourceController is:
      public function getItemId($item) {
        return isset($item->search_api_et_id) ? $item->search_api_et_id : NULL;
      }
    

    So, if node has not the property search_api_et_id this function returns NULL. This is the case in my installation. This return value is legal, as stated in SearchApiDataSourceControllerInterface::getItemId:

    * @return mixed
    * Either the unique ID of the item, or NULL if none is available.

  3. Back search_api_node_access_records_alter we have a $item_ids that's is just array() with one element that is null. A little after trackItemChange() is called. If you follow the code path from SearchApiEtDatasourceController::trackItemChange() you pass through:
    • SearchApiEtDatasourceController::getTrackableItemIdsFromMixedSource
    • SearchApiEtDatasourceController::getTrackableItemIds
    • SearchApiEtDatasourceController::getTrackableEntityIds

    Unfortunately getTrackableEntityIds receives NULL as $entity_ids, so no condition is added to the query and all ids form index's entity type are returned.

  4. All of those ids are received in getTrackableItemIds that makes a call to entity_load with all of them, trying to load all entities.

In my case I have about 5000 nodes, that are loaded, making the system unresponsive.

I'm posting this as a bug because as stated on SearchApiDataSourceControllerInterface::getItemId documentation a NULL is a legal return value, but search_api_et tries to load any given nodes, even a large number of them. May be saerch api shouldn't allow such return value, may be it should check it before passing it to data sources trackItemChange implementations. I'm not sure so I start here.

Not sure why my node has NULL in search_api_et_id property. In my workflow a node is being created programatically and saved: in the node_save process is when search_api_et tries make the described process.

Comments

tunic created an issue. See original summary.

tunic’s picture

search_api_node_access_records_alter, implementation of the hook_node_access_records_alter, was introduced in the search api current last release (1.18), commit 91df7107.

tunic’s picture

FInally I think at least part of the problem is search api. Filed a new issue: #2742053: Node access records change implementation could pass wrong parameters to trackItemChange.

That patch fixes this one too, but it may be is worth to check how search api et manages this case.

thepanz’s picture

idebr’s picture

Status: Active » Closed (duplicate)