View source
<?php
namespace Drupal\webform_views\Plugin\views\filter;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\ElementInfoManagerInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\views\Plugin\views\filter\StringFilter;
use Symfony\Component\DependencyInjection\ContainerInterface;
class WebformSubmissionFieldFilter extends StringFilter {
const ELEMENT_TYPE = 'element';
protected $entityTypeManager;
protected $elementInfoManager;
protected $routeMatch;
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
$instance
->setEntityTypeManager($container
->get('entity_type.manager'));
$instance
->setElementInfoManager($container
->get('plugin.manager.element_info'));
$instance
->setRouteMatch($container
->get('current_route_match'));
return $instance;
}
public function operatorForm(&$form, FormStateInterface $form_state) {
parent::operatorForm($form, $form_state);
if (isset($form['operator'])) {
$do_ajax = TRUE;
if (!$this
->isExposed()) {
$parents = [
'options',
'operator',
];
}
elseif (!$this
->isAGroup()) {
$do_ajax = FALSE;
$parents = [];
}
elseif ($this->options['expose']['use_operator']) {
$do_ajax = FALSE;
$parents = [
$this->options['expose']['operator_id'],
];
}
else {
$do_ajax = FALSE;
$parents = [];
}
$operator = NestedArray::getValue($form_state
->getUserInput(), $parents);
if (!$operator || is_array($operator) || !isset($this
->operators()[$operator])) {
$operator = $this->operator;
}
if ($do_ajax) {
$process = $this
->getFormElementProperty($form['operator'], '#process', []);
array_unshift($process, [
self::class,
'processOperatorForm',
]);
$form['operator']['#ajax'] = [
'callback' => [
self::class,
'ajaxValueForm',
],
'wrapper' => 'this-will-be-set-up-in-process',
];
if ($this->routeMatch
->getRouteName() == 'views_ui.form_add_handler') {
$ajax_url = Url::fromRoute('views_ui.form_handler', [
'js' => $this->routeMatch
->getRawParameter('js'),
'view' => $this->routeMatch
->getRawParameter('view'),
'display_id' => $this->routeMatch
->getRawParameter('display_id'),
'type' => $this->routeMatch
->getRawParameter('type'),
'id' => $this->options['id'],
]);
$form['operator']['#ajax']['url'] = $ajax_url;
}
$form['operator']['#process'] = $process;
}
else {
$operator = 'contains';
}
$form_state
->set([
'webform_views',
'filter_operator',
], $operator);
}
}
public function valueForm(&$form, FormStateInterface $form_state) {
$element = $this
->getWebformElement();
$element['#default_value'] = $this->value;
$element['#required'] = FALSE;
$operator = $form_state
->get([
'webform_views',
'filter_operator',
]) ?: $this->operator;
$operator_definition = $this
->operators()[$operator];
if (isset($operator_definition['webform_views_element_type']) && $operator_definition['webform_views_element_type'] != self::ELEMENT_TYPE) {
$element['#type'] = $operator_definition['webform_views_element_type'];
unset($element['#options']);
}
$html_id = Html::getUniqueId($this->pluginId);
$form_state
->set([
'webform_views',
'filter_value_form_wrapper_id',
], $html_id);
$theme_wrappers = $this
->getFormElementProperty($element, '#theme_wrappers', []);
$theme_wrappers['container'] = [
'#attributes' => [
'id' => $html_id,
],
];
$element['#theme_wrappers'] = $theme_wrappers;
$process = $this
->getFormElementProperty($element, '#process', []);
array_unshift($process, [
self::class,
'processValueForm',
]);
$element['#process'] = $process;
$element['#webform_views_filter']['operators'] = $this
->operators();
$form['value'] = $element;
}
public function acceptExposedInput($input) {
if (parent::acceptExposedInput($input)) {
if (empty($this->options['exposed'])) {
return TRUE;
}
if (!empty($this->options['expose']['identifier'])) {
$value = $input[$this->options['expose']['identifier']];
return (bool) $value;
}
}
return FALSE;
}
function operators() {
$operators = parent::operators();
$operator_map = [
'=' => self::ELEMENT_TYPE,
'!=' => self::ELEMENT_TYPE,
'contains' => 'textfield',
'word' => 'textfield',
'allwords' => 'textfield',
'starts' => 'textfield',
'not_starts' => 'textfield',
'ends' => 'textfield',
'not_ends' => 'textfield',
'not' => 'textfield',
'shorterthan' => 'number',
'longerthan' => 'number',
'regular_expression' => 'textfield',
];
foreach ($operators as $k => $v) {
if (isset($operator_map[$k])) {
$operators[$k]['webform_views_element_type'] = $operator_map[$k];
}
}
return $operators;
}
public static function processOperatorForm($element, FormStateInterface $form_state, $form) {
$element['#ajax']['wrapper'] = $form_state
->get([
'webform_views',
'filter_value_form_wrapper_id',
]);
return $element;
}
public static function processValueForm($element, FormStateInterface $form_state, $form) {
$form_state
->set([
'webform_views',
'filter_value_form_array_parents',
], $element['#array_parents']);
return $element;
}
public static function ajaxValueForm($form, FormStateInterface $form_state) {
$value_form = NestedArray::getValue($form, $form_state
->get([
'webform_views',
'filter_value_form_array_parents',
]));
unset($value_form['#prefix'], $value_form['#suffix']);
return $value_form;
}
public function setEntityTypeManager(EntityTypeManagerInterface $entity_type_manager) {
$this->entityTypeManager = $entity_type_manager;
}
public function setElementInfoManager(ElementInfoManagerInterface $element_info_manager) {
$this->elementInfoManager = $element_info_manager;
}
public function setRouteMatch(RouteMatchInterface $route_match) {
$this->routeMatch = $route_match;
}
protected function getFormElementProperty($element, $property, $default) {
if (isset($element[$property])) {
return $element[$property];
}
return $this->elementInfoManager
->getInfoProperty($element['#type'], $property, $default);
}
protected function getWebformElement() {
$webform = $this->entityTypeManager
->getStorage('webform')
->load($this->definition['webform_id']);
return $webform
->getElementInitialized($this->definition['webform_submission_field']);
}
}