Problem/Motivation

I've created a Data Source Controller based off SearchApiExternalDataSourceController which needs to create an adhoc Entity Wrapper for arbitrary datasets. I can't seem to get fields (properties) specified in the controller to show up, however.

The following function adds a 'properties' index to the $info array passed to entity_metadata_wrapper() but entity_metadata_wrapper() doesn't seem to support 'properties'.

protected function getPropertyInfo() {
    $info['properties']['id'] = array(
      'label' => t('ID'),
      'type' => 'string',
    );

    return $info;
  }

If I add the fields using the 'property info' index instead this works except that the propertyInfoAlter() callback wipes them out by reseting 'properties'.

public function propertyInfoAlter(EntityMetadataWrapper $wrapper, array $property_info) {
  // Overwrite the existing properties with the list of properties including
  // all fields regardless of the used bundle.
  $property_info['properties'] = entity_get_all_property_info($wrapper->type());

  if (!isset($this->added_properties)) {
    $this->added_properties = array(
      'search_api_language' => array(
        'label' => t('Item language'), 
        'description' => t("A field added by the search framework to let components determine an item's language. Is always indexed."), 
        'type' => 'string',
      ),
    );

...

}

I can remove the propertyInfoAlter() callback but then I'd have to hardcode the 'search_api_language' field back in.

Any thoughts?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

drunken monkey’s picture

Status: Active » Needs review
FileSize
937 bytes

$property_info['properties'] = entity_get_all_property_info($wrapper->type());

Oooh, this is evil! Thanks a bunch for spotting this, I seem to have missed this in #1064884: Add support for indexing non-entities—this is still hard-coded to entities and will really mess things up with any other data sources.
The attached patch hopefully fixes this.

Akaoni’s picture

Yep, that seems to have solved the problem. Thanks, dm!!
Will this patch be committed to 7.x-1.x-dev?

Akaoni’s picture

Here's another:

SearchApiAlterBundleFilter::supportsIndex() throws an error:

Recoverable fatal error: Argument 1 passed to SearchApiAlterBundleFilter::hasBundles() must be an array, null given, called in D:\Web_Public\Public\sites\all\modules\search_api\includes\callback_bundle_filter.inc on line 10 and defined in SearchApiAlterBundleFilter::hasBundles() (line 68 of D:\Web_Public\Public\sites\all\modules\search_api\includes\callback_bundle_filter.inc).

This is because of this line assuming it can find info for the non-entity:

return self::hasBundles(entity_get_info($index->item_type));

This solves the issue in the short term:

return entity_get_info($index->item_type)?self::hasBundles(entity_get_info($index->item_type)):FALSE;

Long term problem is non-entities may want to have bundles and support bundle filtering.

drunken monkey’s picture

Title: Adhoc Entity Wrapper for Data Source Controller » Fix overlooked entity type assumptions
Status: Needs review » Fixed

Will this patch be committed to 7.x-1.x-dev?

Yes, now that I know it works. Thanks for testing!

Here's another:

SearchApiAlterBundleFilter::supportsIndex() throws an error:

Ah, thanks! Would be nice to have some tests for data sources, it appears. :-/

Anyways, fixes to both bugs committed. Please re-open if anything else should pop up.

drunken monkey’s picture

Long term problem is non-entities may want to have bundles and support bundle filtering.

I don't think the Entity API allows that for non-entities. And I also can't see any use case for that in the Search API, as bundles are ignored anyways. Only thing would be the „Bundle filter“ data alteration, but you can just write your own custom DA for that. Or use #939430: Integrate Rules conditions to filter indexed entities, if fago implements it at some point.

Akaoni’s picture

Thanks again. ;)

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.