View source
<?php
namespace Drupal\search_api_grouping\Plugin\search_api\processor;
use Drupal\Core\Form\FormStateInterface;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\search_api\Item\Item;
use Drupal\search_api\Processor\FieldsProcessorPluginBase;
class Denormalize extends FieldsProcessorPluginBase {
public function defaultConfiguration() {
$configuration = parent::defaultConfiguration();
$configuration += [
'permutation_limit' => NULL,
'denormalization_field' => '',
];
return $configuration;
}
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
$denormalization_field =& $form_state
->getValue('denormalization_field');
$denormalization_field = array_keys(array_filter($denormalization_field));
$this
->setConfiguration($form_state
->getValues());
}
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form = parent::buildConfigurationForm($form, $form_state);
$form['permutation_limit'] = [
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#title' => t('Permutation limit'),
'#description' => t('Defines how permutations should be processed. Can become handy if you just want to have one item of a multi-value field. Leave empty for no limit.'),
'#weight' => 1,
];
$options = [];
foreach ($this
->getIndex()
->getFields() as $field_name => $field) {
$label = $field
->getLabel();
if (stristr($field_name, ':')) {
list($field_name, $property) = explode(':', $field_name, 2);
}
if (stristr($label, "»")) {
list($type, $label) = explode('»', $label, 2);
}
if ($field_info = FieldStorageConfig::loadByName('node', $field_name)) {
if (!empty($field_info
->getCardinality()) && ($field_info
->getCardinality() == -1 || $field_info
->getCardinality() > 1)) {
\Drupal::service('entity_field.manager')
->getBaseFieldDefinitions('node');
$options[$field_name] = $label . ' (' . $field_name . ')';
$form['permutation_limit'][$field_name] = [
'#type' => 'textfield',
'#title' => $label,
'#size' => 4,
'#maxlength' => 10,
'#states' => [
'visible' => [
':input[name$="[denormalization_field][' . $field_name . ']"]' => [
'checked' => TRUE,
],
],
],
'#default_value' => !empty($this->configuration['permutation_limit'][$field_name]) ? $this->configuration['permutation_limit'][$field_name] : NULL,
];
}
}
}
$form['fields']['#options'] = $options;
$form['fields']['#type'] = 'checkboxes';
unset($form['fields']['#attributes']);
$form['denormalization_field'] = $form['fields'];
$form['fields']['#access'] = FALSE;
$form['denormalization_field'] = [
'#title' => t('The field to use to denormalize the items to index.'),
'#description' => t('The field hast to be selected for indexing to use it for denormalization.'),
'#default_value' => isset($this->configuration['denormalization_field']) ? $this->configuration['denormalization_field'] : NULL,
] + $form['denormalization_field'];
return $form;
}
public function alterIndexedItems(array &$items) {
$all_nodes = [];
foreach ($items as $item_id => $item) {
$node = $this
->getDenormalizationFields();
foreach ($node as $field_name => $permutation_limit) {
$values = $item
->getField($field_name)
->getValues();
if (!empty($item
->getField($field_name)
->getValues())) {
$all_nodes[$item_id][$field_name] = $values;
}
}
}
$denormalized_items = [];
foreach ($items as $original_item_id => $original_item) {
$part_denormalized_items[$original_item_id] = $original_item;
$original_fields = $all_nodes[$original_item_id];
foreach ($original_fields as $field_name => $field) {
foreach ($part_denormalized_items as $part_denormalized_item_name => $part_denormalized_item) {
foreach ($field as $field_value) {
$part_denormalized_items[$part_denormalized_item_name . $field_name . $field_value] = $this
->createDocument($part_denormalized_item, $field_name, $field_value);
}
unset($part_denormalized_items[$part_denormalized_item_name]);
}
unset($part_denormalized_items[$original_item_id]);
}
$denormalized_items += $part_denormalized_items;
$part_denormalized_items = [];
}
$items = $denormalized_items;
}
public function getDenormalizationFields() {
$fields =& drupal_static(__FUNCTION__, []);
if (empty($fields)) {
$fields = array_filter($this->configuration['denormalization_field']);
foreach ($fields as $field_name => $field) {
$fields[$field_name] = 0;
if (!empty($this->configuration['permutation_limit'][$field]) && is_numeric($this->configuration['permutation_limit'][$field])) {
$fields[$field_name] = (int) $this->configuration['permutation_limit'][$field];
}
}
}
return $fields;
}
protected function createDocument(Item $item, $field_name, $value) {
$item = clone $item;
$item
->getField($field_name)
->setValues([
$value,
]);
return $item;
}
protected function testType($type) {
return $this
->getDataTypeHelper()
->isTextType($type, [
'text',
'string',
'integer',
]);
}
}