arch-8.x-1.x-dev/modules/price/modules/search_api/src/Plugin/views/filter/SearchApiPriceFilter.php
modules/price/modules/search_api/src/Plugin/views/filter/SearchApiPriceFilter.php
<?php
namespace Drupal\arch_price_search_api\Plugin\views\filter;
use Drupal\arch_price\Manager\PriceTypeManagerInterface;
use Drupal\Core\Config\Entity\ConfigEntityStorageInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\search_api\Plugin\views\filter\SearchApiNumeric;
use Drupal\search_api\Query\ConditionGroupInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines a price filter to the view.
*
* @ingroup views_filter_handlers
*
* @ViewsFilter("arch_price_search_api")
*/
class SearchApiPriceFilter extends SearchApiNumeric {
/**
* Current user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $currentUser;
/**
* Price type manager.
*
* @var \Drupal\arch_price\Manager\PriceTypeManagerInterface
*/
protected $priceTypeManager;
/**
* Currency storage.
*
* @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface
*/
protected $currencyStorage;
/**
* {@inheritdoc}
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
AccountInterface $current_user,
PriceTypeManagerInterface $price_type_manager,
ConfigEntityStorageInterface $currency_storage,
) {
parent::__construct(
$configuration,
$plugin_id,
$plugin_definition
);
$this->currentUser = $current_user;
$this->priceTypeManager = $price_type_manager;
$this->currencyStorage = $currency_storage;
}
/**
* {@inheritdoc}
*/
public static function create(
ContainerInterface $container,
array $configuration,
$plugin_id,
$plugin_definition,
) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('current_user'),
$container->get('price_type.manager'),
$container->get('entity_type.manager')->getStorage('currency')
);
}
/**
* {@inheritdoc}
*/
protected function defineOptions() {
$options = parent::defineOptions();
$options['value']['contains']['base'] = ['default' => 'net'];
$options['value']['contains']['currency_expose'] = ['default' => FALSE];
$options['value']['contains']['currency'] = ['default' => ''];
return $options;
}
/**
* {@inheritdoc}
*/
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
$form['value']['base'] = [
'#type' => 'select',
'#title' => $this->t('Price base', [], ['context' => 'arch_price']),
'#options' => [
'net' => $this->t('Net', [], ['context' => 'arch_price']),
'gross' => $this->t('Gross', [], ['context' => 'arch_price']),
],
'#default_value' => $this->value['base'],
'#required' => TRUE,
'#weight' => -5,
];
$currency_options = [
'' => $this->t('- Select -'),
];
$currency_options += \Drupal::service('currency.form_helper')->getCurrencyOptions();
$form['value']['currency'] = [
'#type' => 'select',
'#options' => $currency_options,
'#default_value' => $this->value['currency'],
'#title' => $this->t('Currency'),
'#weight' => -1,
];
if ($this->options['exposed']) {
$form['value']['currency_expose'] = [
'#type' => 'checkbox',
'#title' => $this->t('Expose currency selection'),
'#default_value' => $this->value['currency_expose'],
'#weight' => -2,
];
$form['value']['currency']['#states']['required'] = [
':input[name="options[value][currency_expose]"]' => ['checked' => FALSE],
];
}
else {
$form['value']['currency_expose'] = [
'#type' => 'value',
'#value' => FALSE,
];
}
}
/**
* {@inheritdoc}
*/
public function buildExposeForm(&$form, FormStateInterface $form_state) {
parent::buildExposeForm($form, $form_state);
$form['value']['currency_expose'] = [
'#type' => 'checkbox',
'#title' => $this->t('Expose currency selection'),
'#default_value' => $this->value['currency_expose'],
'#weight' => -2,
];
}
/**
* {@inheritdoc}
*/
public function valueForm(&$form, FormStateInterface $form_state) {
parent::valueForm($form, $form_state);
$form['value']['base'] = [
'#type' => 'value',
'#value' => $this->options['expose']['currency'],
];
if ($this->options['expose']['currency_expose']) {
$currency_options = \Drupal::service('currency.form_helper')->getCurrencyOptions();
unset($currency_options['XXX']);
$form['value']['currency'] = [
'#type' => 'select',
'#title' => $this->t('Currency'),
'#default_value' => $this->value['currency'],
'#options' => $currency_options,
];
}
else {
$currency = $this->options['expose']['currency'];
$this->getModuleHandler()->alter('arch_price_search_api_filter_currency', $currency);
$form['value']['currency'] = [
'#type' => 'value',
'#value' => $currency,
];
}
}
/**
* {@inheritdoc}
*/
public function query() {
$this->ensureMyTable();
$fields = $this->getFilteringFields();
$info = $this->operators();
if (!empty($info[$this->operator]['method'])) {
$group = $this->query->createConditionGroup('or', ['arch_price']);
foreach ($fields as $field) {
$this->{$info[$this->operator]['method']}($field['property'], $group);
}
$this->query->addConditionGroup($group);
}
}
/**
* Get filtering fields.
*
* @return string[][]
* List of filtering fields.
*/
public function getFilteringFields(array $input = []) {
$fields = [];
$base = $this->options['value']['base'] ?: 'net';
if (
!empty($this->value['base'])
&& in_array($this->value['base'], ['net', 'gross'])
) {
$base = $this->value['base'];
}
$currencies = $this->currencyStorage->loadMultiple();
$selected_currency = $this->options['value']['currency'];
if ($this->options['value']['currency_expose']) {
if (
!empty($input['currency'])
&& !empty($currencies[$input['currency']])
) {
$selected_currency = $input['currency'];
}
elseif (
!empty($this->value['currency'])
&& !empty($currencies[$this->value['currency']])
) {
$selected_currency = $this->value['currency'];
}
}
foreach ($this->priceTypeManager->getAvailablePriceTypes($this->currentUser, 'view') as $price_type) {
foreach ($currencies as $currency_id => $currency) {
if ($currency_id != $selected_currency) {
continue;
}
/** @var \Drupal\currency\Entity\CurrencyInterface $currency */
foreach (['net', 'gross'] as $field) {
if ($field != $base) {
continue;
}
$field = strtolower('arch_price_' . $field . '_' . $price_type->id() . '_' . $currency->id());
$fields[$field] = [
'property' => $field,
'base' => $base,
'currency' => $currency->id(),
'price_type' => $price_type->id(),
];
}
}
}
return $fields;
}
/**
* {@inheritdoc}
*/
protected function opBetween($field, ?ConditionGroupInterface $group = NULL) {
$operator = $this->operator == 'between' ? 'BETWEEN' : 'NOT BETWEEN';
if ($group) {
$group->addCondition(
$field,
[$this->value['min'], $this->value['max']],
$operator
);
}
else {
$this->query->addWhere(
$this->options['group'],
$field,
[$this->value['min'], $this->value['max']],
$operator
);
}
}
/**
* {@inheritdoc}
*/
protected function opSimple($field = NULL, ?ConditionGroupInterface $group = NULL) {
if ($group) {
$group->addCondition($field, $this->value['value'], $this->operator);
}
else {
$this->query->addWhere($this->options['group'], $field, $this->value['value'], $this->operator);
}
}
/**
* {@inheritdoc}
*/
protected function opEmpty($field, ?ConditionGroupInterface $group = NULL) {
$operator = $this->operator == 'empty' ? 'IS NULL' : 'IS NOT NULL';
if ($group) {
$group->addCondition($field, NULL, $operator);
}
else {
$this->query->addWhere($this->options['group'], $field, NULL, $operator);
}
}
}
