You are here

class SearchApiAlterBundleFilter in Search API 7

Represents a data alteration that restricts entity indexes to some bundles.

Hierarchy

Expanded class hierarchy of SearchApiAlterBundleFilter

1 string reference to 'SearchApiAlterBundleFilter'
search_api_search_api_alter_callback_info in ./search_api.module
Implements hook_search_api_alter_callback_info().

File

includes/callback_bundle_filter.inc, line 11
Contains SearchApiAlterBundleFilter.

View source
class SearchApiAlterBundleFilter extends SearchApiAbstractAlterCallback {

  /**
   * {@inheritdoc}
   */
  public function supportsIndex(SearchApiIndex $index) {
    if ($this
      ->isMultiEntityIndex($index)) {
      $info = entity_get_info();
      foreach ($index->options['datasource']['types'] as $type) {
        if (isset($info[$type]) && self::hasBundles($info[$type])) {
          return TRUE;
        }
      }
      return FALSE;
    }
    return $index
      ->getEntityType() && ($info = entity_get_info($index
      ->getEntityType())) && self::hasBundles($info);
  }

  /**
   * {@inheritdoc}
   */
  public function alterItems(array &$items) {
    if (!$this
      ->supportsIndex($this->index) || !isset($this->options['bundles'])) {
      return;
    }
    $multi_entity = $this
      ->isMultiEntityIndex();
    if ($multi_entity) {
      $bundle_prop = 'item_bundle';
    }
    else {
      $info = entity_get_info($this->index
        ->getEntityType());
      $bundle_prop = $info['entity keys']['bundle'];
    }
    $bundles = array_flip($this->options['bundles']);
    $default = (bool) $this->options['default'];
    foreach ($items as $id => $item) {

      // Ignore types that have no bundles.
      if ($multi_entity && !self::hasBundles(entity_get_info($item->item_type))) {
        continue;
      }
      if (isset($bundles[$item->{$bundle_prop}]) == $default) {
        unset($items[$id]);
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function configurationForm() {
    if ($this
      ->supportsIndex($this->index)) {
      $options = array();
      if ($this
        ->isMultiEntityIndex()) {
        $info = entity_get_info();
        $unsupported_types = array();
        foreach ($this->index->options['datasource']['types'] as $type) {
          if (isset($info[$type]) && self::hasBundles($info[$type])) {
            foreach ($info[$type]['bundles'] as $bundle => $bundle_info) {
              $options["{$type}:{$bundle}"] = $info[$type]['label'] . ' » ' . $bundle_info['label'];
            }
          }
          else {
            $unsupported_types[] = isset($info[$type]['label']) ? $info[$type]['label'] : $type;
          }
        }
        if ($unsupported_types) {
          $form['unsupported_types']['#markup'] = '<p>' . t('The following entity types do not contain any bundles: @types. All items of those types will therefore be included in the index.', array(
            '@types' => implode(', ', $unsupported_types),
          )) . '</p>';
        }
      }
      else {
        $info = entity_get_info($this->index
          ->getEntityType());
        foreach ($info['bundles'] as $bundle => $bundle_info) {
          $options[$bundle] = isset($bundle_info['label']) ? $bundle_info['label'] : $bundle;
        }
      }
      if (!empty($this->index->options['datasource']['bundles'])) {
        $form['message']['#markup'] = '<p>' . t("<strong>Note:</strong> This index is already restricted to certain bundles. If you use this data alteration, those will be reduced further. However, the index setting is better supported in the user interface and should therefore be prefered. For example, using this data alteration will not reduce the displayed total number of items to index (even though some of them will not be indexed). Consider creating a new index with appropriate bundle settings instead.") . '</p>';
        $included_bundles = array_flip($this->index->options['datasource']['bundles']);
        $options = array_intersect_key($options, $included_bundles);
      }
      $form['default'] = array(
        '#type' => 'radios',
        '#title' => t('Which items should be indexed?'),
        '#default_value' => isset($this->options['default']) ? $this->options['default'] : 1,
        '#options' => array(
          1 => t('All but those from one of the selected bundles'),
          0 => t('Only those from the selected bundles'),
        ),
      );
      $form['bundles'] = array(
        '#type' => 'select',
        '#title' => t('Bundles'),
        '#default_value' => isset($this->options['bundles']) ? $this->options['bundles'] : array(),
        '#options' => $options,
        '#size' => min(4, count($options)),
        '#multiple' => TRUE,
      );
    }
    else {
      $form = array(
        'forbidden' => array(
          '#markup' => '<p>' . t("Items indexed by this index don't have bundles and therefore cannot be filtered here.") . '</p>',
        ),
      );
    }
    return $form;
  }

  /**
   * Determines whether a certain entity type has any bundles.
   *
   * @param array $entity_info
   *   The entity type's entity_get_info() array.
   *
   * @return bool
   *   TRUE if the entity type has bundles, FALSE otherwise.
   */
  protected static function hasBundles(array $entity_info) {
    return !empty($entity_info['entity keys']['bundle']) && !empty($entity_info['bundles']);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
SearchApiAbstractAlterCallback::$index protected property The index whose items will be altered.
SearchApiAbstractAlterCallback::$options protected property The configuration options for this callback, if it has any.
SearchApiAbstractAlterCallback::configurationFormSubmit public function Implements SearchApiAlterCallbackInterface::configurationFormSubmit(). Overrides SearchApiAlterCallbackInterface::configurationFormSubmit 4
SearchApiAbstractAlterCallback::configurationFormValidate public function Implements SearchApiAlterCallbackInterface::configurationFormValidate(). Overrides SearchApiAlterCallbackInterface::configurationFormValidate 1
SearchApiAbstractAlterCallback::isMultiEntityIndex protected function Determines whether the given index contains multiple types of entities.
SearchApiAbstractAlterCallback::propertyInfo public function Implements SearchApiAlterCallbackInterface::propertyInfo(). Overrides SearchApiAlterCallbackInterface::propertyInfo 6
SearchApiAbstractAlterCallback::__construct public function Implements SearchApiAlterCallbackInterface::__construct(). Overrides SearchApiAlterCallbackInterface::__construct 1
SearchApiAlterBundleFilter::alterItems public function Alter items before indexing. Overrides SearchApiAlterCallbackInterface::alterItems
SearchApiAlterBundleFilter::configurationForm public function Implements SearchApiAlterCallbackInterface::configurationForm(). Overrides SearchApiAbstractAlterCallback::configurationForm
SearchApiAlterBundleFilter::hasBundles protected static function Determines whether a certain entity type has any bundles.
SearchApiAlterBundleFilter::supportsIndex public function Implements SearchApiAlterCallbackInterface::supportsIndex(). Overrides SearchApiAbstractAlterCallback::supportsIndex