Skip to content

Instantly share code, notes, and snippets.

@chriscalip
Created April 28, 2017 22:41
Show Gist options
  • Save chriscalip/77d027ef2615d61465a207859b517d1d to your computer and use it in GitHub Desktop.
Save chriscalip/77d027ef2615d61465a207859b517d1d to your computer and use it in GitHub Desktop.
<?php
namespace Drupal\address\Plugin\search_api\processor;
use Drupal\Component\Utility\Html;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Core\Form\FormStateInterface;
use Drupal\search_api\Processor\FieldsProcessorPluginBase;
/**
* Makes searches case-insensitive on selected fields.
*
* @SearchApiProcessor(
* id = "address_abbreviations_to_full_form",
* label = @Translation("Address Field : Convert Abbreviations into Full Text Form."),
* description = @Translation("Converts abbreviations to its full text form. Components supported are country_code, administrative_area, locality, and dependent_locality"),
* stages = {
* "pre_index_save" = 0,
* "preprocess_index" = -20,
* "preprocess_query" = -20
* }
* )
*/
class AddressAbbreviationsToFullForm extends FieldsProcessorPluginBase {
/**
* The address format repository.
*
* @var \CommerceGuys\Addressing\AddressFormat\AddressFormatRepositoryInterface
*/
protected $addressFormatRepository;
/**
* The subdivision repository.
*
* @var \CommerceGuys\Addressing\Country\CountryRepositoryInterface
*/
protected $countryRepository;
/**
* The subdivision repository.
*
* @var \CommerceGuys\Addressing\Subdivision\SubdivisionRepositoryInterface
*/
protected $subdivisionRepository;
/**
* The address module field list of compontents supported by this processor.
*
*/
protected $supportedComponents;
/**
* {@inheritdoc}
*/
public function __construct(array $configuration, $plugin_id, array $plugin_definition) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->addressFormatRepository = \Drupal::service('address.address_format_repository');
$this->countryRepository = \Drupal::service('address.country_repository');
$this->subdivisionRepository = \Drupal::service('address.subdivision_repository');
$this->supportedComponents = ['country_code', 'administrative_area', 'locality', 'dependent_locality'];
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$fields = $this->index->getFields();
$supported_fields = [];
foreach ($fields as $name => $field) {
$is_supported = FALSE;
foreach ($this->supportedComponents as $compontent) {
if ((strpos($field->getPropertyPath(), ':' . $compontent) !== FALSE)) {
$is_supported = TRUE;
}
}
if (!$is_supported) {
continue;
}
$supported_field = $field->getPropertyPath();
$form[$supported_field] = [
'#type' => 'fieldset',
'#title' => Html::escape($field->getPrefixedLabel()),
'#collapsible' => FALSE,
'#collapsed' => FALSE,
];
$form[$supported_field]['enable'] = [
'#type' => 'checkbox',
'#title' => $this->t('Enable'),
'#default_value' => $this->configuration[$supported_field]['enable'],
];
$form[$supported_field]['concat'] = [
'#type' => 'checkbox',
'#title' => $this->t('Concat'),
'#description' => $this->t('Combine code and full text using a dash separator. eg. {abbreviation} - {full text}'),
'#default_value' => $this->configuration[$supported_field]['concat'],
];
}
return $form;
}
/**
* Parses Plugin Configuration Form Values to usable plugin configuration array.
*
* @return array
* Plugin configuration values.
*/
private function getPluginConfiguration() {
$config_form_values = $this->configuration;
$plugin_configuration = [];
foreach ($config_form_values as $field_and_component => $configuration) {
list($field, $component) = explode(':', $field_and_component);
$plugin_configuration[$field][$component] = $configuration;
}
return $plugin_configuration;
}
/**
* Retrieves full text value of an addressfield component.
*
* @return string
* Full text value of an addressfield component code value.
*/
private function triangulateCodeToFulltext($field_value, $target, $configuration) {
$addressFormat = $this->addressFormatRepository->get($field_value['country_code']);
$current = $result = $field_value[$target];
$countries = $subdivisions = [];
switch ($target) {
case 'country_code':
$countries = $this->countryRepository->getAll();
break;
case 'administrative_area':
$subdivisions = $this->subdivisionRepository->getAll([$field_value['country_code']]);
break;
case 'locality':
$subdivisions = $this->subdivisionRepository->getAll([$field_value['country_code'], $field_value['administrative_area']]);
break;
case 'dependent_locality':
$subdivisions = $this->subdivisionRepository->getAll([$field_value['country_code'], $field_value['administrative_area'], $field_value['locality']]);
break;
}
if ($target == 'country_code') {
if (empty($countries[$current])) {
return $result;
}
$code = $countries[$current]->getCountryCode();
$name = $countries[$current]->getName();
}
elseif (in_array($target, ['administrative_area', 'locality', 'dependent_locality'])) {
if (empty($subdivisions[$current])) {
return $result;
}
$code = $subdivisions[$current]->getCode();
$name = $subdivisions[$current]->getName();
}
if ($configuration['concat'] && ($current != $name)) {
$result = $code . ' - ' . $name;
}
elseif (!$configuration['concat'] && ($current != $name)) {
$result = $name;
}
return $result;
}
/**
* {@inheritdoc}
*/
public function preprocessIndexItems(array $items) {
$plugin_configuration = $this->getPluginConfiguration();
foreach ($items as $item) {
foreach ($item->getFields() as $name => $field) {
list($field_name, $component) = explode(":", $field->getPropertyPath());
if (!isset($plugin_configuration[$field_name]) ||
!isset($plugin_configuration[$field_name][$component]) ||
empty($plugin_configuration[$field_name][$component]['enable'])
) {
continue;
}
$entity_adapter = $item->getOriginalObject();
$entity = $entity_adapter->getValue();
$field_values = $entity->get($field_name)->getValue();
$new_data = [];
foreach ($field_values as $delta => $field_value) {
// override targeted component code value with full text value.
$new_data[$delta] = $this->triangulateCodeToFulltext($field_value, $component, $plugin_configuration[$field_name][$component]);
}
$field->setValues($new_data);
if ($this->testField($name, $field)) {
$this->processField($field);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment