arch-8.x-1.x-dev/modules/price/src/Plugin/search_api/processor/Price.php
modules/price/src/Plugin/search_api/processor/Price.php
<?php
namespace Drupal\arch_price\Plugin\search_api\processor;
use Drupal\arch_price\Entity\PriceTypeInterface;
use Drupal\arch_product\Entity\ProductInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\search_api\Datasource\DatasourceInterface;
use Drupal\search_api\Item\ItemInterface;
use Drupal\search_api\Plugin\search_api\data_type\value\TextValue;
use Drupal\search_api\Processor\ProcessorPluginBase;
use Drupal\search_api\Processor\ProcessorProperty;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Adds the item's URL to the indexed data.
*
* @SearchApiProcessor(
* id = "search_api_arch_price_value",
* label = @Translation("Price value"),
* stages = {
* "add_properties" = 0,
* },
* locked = true,
* hidden = true,
* )
*/
class Price extends ProcessorPluginBase {
/**
* Entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Price type storage.
*
* @var \Drupal\arch_price\Entity\Storage\PriceTypeStorageInterface
*/
protected $priceTypeStorage;
/**
* Currency storage.
*
* @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface
*/
protected $currencyStorage;
/**
* Currency list.
*
* @var \Drupal\currency\Entity\Currency[]
*/
protected $currencyList;
/**
* {@inheritdoc}
*/
public static function create(
ContainerInterface $container,
array $configuration,
$plugin_id,
$plugin_definition,
) {
/** @var static $processor */
$processor = parent::create($container, $configuration, $plugin_id, $plugin_definition);
$processor->setEntityTypeManager($container->get('entity_type.manager'));
return $processor;
}
/**
* Sets entity type manager.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* Entity type manager.
*
* @return $this
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function setEntityTypeManager(EntityTypeManagerInterface $entity_type_manager) {
$this->entityTypeManager = $entity_type_manager;
$this->priceTypeStorage = $entity_type_manager->getStorage('price_type');
$this->currencyStorage = $entity_type_manager->getStorage('currency');
return $this;
}
/**
* {@inheritdoc}
*/
public function getPropertyDefinitions(?DatasourceInterface $datasource = NULL) {
$properties = [];
if ($datasource) {
/** @var \Drupal\Core\Entity\ContentEntityType $entity_type */
$entity_type = $this->entityTypeManager->getDefinition($datasource->getEntityTypeId());
if ($entity_type->entityClassImplements(ProductInterface::class)) {
foreach ($this->getDefinitions($datasource) as $property => $definition) {
$properties[$property] = new ProcessorProperty($definition);
}
}
}
return $properties;
}
/**
* Get property definition arrays.
*
* @param \Drupal\search_api\Datasource\DatasourceInterface $datasource
* The datasource this set of properties belongs to.
*
* @return array
* Property definition array.
*/
protected function getDefinitions(DatasourceInterface $datasource) {
$properties = [];
foreach ($this->priceTypeStorage->loadMultiple() as $price_type) {
/** @var \Drupal\arch_price\Entity\PriceTypeInterface $price_type */
$properties += $this->priceTypePropertyDefinitions($price_type, $datasource);
}
$properties['arch_price_value'] = [
'label' => $this->t('Price value', [], ['context' => 'arch_price']),
'type' => 'string',
'computed' => TRUE,
'processor_id' => $this->getPluginId(),
'datasource' => $datasource,
'is_list' => TRUE,
'fields' => '_custom_serialize',
];
return $properties;
}
/**
* Get property definition arrays for given price type.
*
* @param \Drupal\arch_price\Entity\PriceTypeInterface $price_type
* Price type.
* @param \Drupal\search_api\Datasource\DatasourceInterface $datasource
* The datasource this set of properties belongs to.
*
* @return array
* Property definitions.
*/
protected function priceTypePropertyDefinitions(PriceTypeInterface $price_type, DatasourceInterface $datasource) {
$definition = [
'computed' => TRUE,
'processor_id' => $this->getPluginId(),
'datasource' => $datasource,
'is_list' => TRUE,
];
$definitions = [];
$definitions['arch_price_net_' . $price_type->id()] = [
'label' => $this->t('Price: @price_type net value', ['@price_type' => $price_type->label()], ['context' => 'arch_price']),
'type' => 'decimal',
'fields' => ['net'],
] + $definition;
$definitions['arch_price_gross_' . $price_type->id()] = [
'label' => $this->t('Price: @price_type gross value', ['@price_type' => $price_type->label()], ['context' => 'arch_price']),
'type' => 'decimal',
'fields' => ['gross'],
] + $definition;
foreach ($this->getCurrencyList() as $currency) {
foreach (['net', 'gross'] as $field) {
$label = $this->t('Price: @price_type @currency net value', [
'@price_type' => $price_type->label(),
'@currency' => $currency->id(),
], ['context' => 'arch_price']);
$property = strtolower('arch_price_' . $field . '_' . $price_type->id() . '_' . $currency->id());
$definitions[$property] = [
'label' => $label,
'type' => 'decimal',
'price_type' => $price_type->id(),
'currency' => $currency->id(),
'fields' => [$field],
] + $definition;
}
}
return $definitions;
}
/**
* Get currency list.
*
* @return \Drupal\currency\Entity\Currency[]
* Currenct list.
*/
protected function getCurrencyList() {
if (!isset($this->currencyList)) {
$this->currencyList = $this->currencyStorage->loadMultiple();
}
return $this->currencyList;
}
/**
* Get price type properties.
*
* @param \Drupal\arch_price\Entity\PriceTypeInterface $price_type
* Price type.
* @param \Drupal\search_api\Datasource\DatasourceInterface $datasource
* The datasource this set of properties belongs to.
*
* @return \Drupal\search_api\Processor\ProcessorPropertyInterface[]
* Property list.
*/
protected function priceTypeProperties(PriceTypeInterface $price_type, DatasourceInterface $datasource) {
$properties = [];
foreach ($this->priceTypePropertyDefinitions($price_type, $datasource) as $property => $definition) {
unset($definition['fields']);
$properties[$property] = new ProcessorProperty($definition);
}
return $properties;
}
/**
* {@inheritdoc}
*/
public function addFieldValues(ItemInterface $item) {
/** @var \Drupal\arch_product\Entity\ProductInterface $product */
$product = $item->getOriginalObject()->getValue();
foreach ($product->getPrices() as $price) {
/** @var \Drupal\arch_price\Plugin\Field\FieldType\PriceItemInterface $price */
foreach ($this->getDefinitions($item->getDatasource()) as $property => $definition) {
/** @var \Drupal\search_api\Item\Field[] $fields */
$fields = $this->getFieldsHelper()
->filterForPropertyPath($item->getFields(), $item->getDatasourceId(), $property);
if (empty($fields)) {
continue;
}
$value = $this->getValue($price->toArray(), $definition);
if (empty($value)) {
continue;
}
foreach ($fields as $field) {
$field->addValue($value);
}
}
}
}
/**
* Get value to store.
*
* @param array $price_value
* Price value array.
* @param array $definition
* Property definition.
*
* @return mixed
* Value to store.
*/
protected function getValue(array $price_value, array $definition) {
if (empty($definition['fields'])) {
return NULL;
}
if (
!empty($definition['currency'])
&& $price_value['currency'] != $definition['currency']
) {
return NULL;
}
if (
!empty($definition['price_type'])
&& $price_value['price_type'] != $definition['price_type']
) {
return NULL;
}
if ($definition['fields'] === '_custom_serialize') {
foreach (['date_from', 'date_to'] as $key) {
if (!isset($price_value[$key])) {
unset($price_value[$key]);
}
}
ksort($price_value);
$values = [];
foreach ($price_value as $key => $value) {
$values[] = "{$key}:{$value}";
}
return new TextValue('||' . implode('||', $values) . '||');
}
if (is_array($definition['fields'])) {
$value = [];
foreach ($definition['fields'] as $field) {
$value[] = $price_value[$field];
}
if ($definition['type'] === 'string') {
return new TextValue(implode('', $value));
}
if (count($value) === 1) {
return $value[0];
}
return $value;
}
return NULL;
}
}
