View source
<?php
namespace Drupal\views_arg_order_sort\Plugin\views\sort;
use Drupal\Core\Form\FormStateInterface;
use Drupal\views\Plugin\views\sort\SortPluginBase;
use Drupal\views\Views;
class ArgOrderSort extends SortPluginBase {
protected function defineOptions() {
$options = parent::defineOptions();
$options['inherit_type'] = [
'default' => 1,
];
$options['null_below'] = [
'default' => 1,
];
$options['argument_number'] = [
'default' => 0,
];
$options['field_type'] = [
'default' => 'node::nid',
];
return $options;
}
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
$options = [];
$base_tables = Views::viewsData()
->fetchBaseTables();
$table_data = Views::viewsData()
->getAll();
foreach ($base_tables as $table => $values) {
$data = $table_data[$table];
$group = (string) render($data['table']['group']);
foreach ($data as $field => $f) {
if (isset($f['entity field'])) {
$options[$group][$table . '::' . $field] = render($f['title']);
}
}
}
$form['argument_number'] = [
'#title' => $this
->t('Argument'),
'#type' => 'select',
'#options' => [
1,
2,
3,
4,
5,
6,
7,
8,
9,
],
'#default_value' => $this->options['argument_number'],
];
$form['null_below'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Non arguments at End'),
'#description' => $this
->t('Place items not in the argument at the end.'),
'#default_value' => $this->options['null_below'],
'#options' => [
0,
'Null values below',
],
];
$form['inherit_type'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Inherit type of Field from Argument'),
'#description' => $this
->t('If the argument is the NULL argument or you want to choose a different type for linking the uncheck, otherwise it is safe to leave it checked.'),
'#default_value' => $this->options['inherit_type'],
'#options' => [
0,
'Inherit type of Field from Argument',
],
'#ajax' => [
'callback' => 'views_boxes_arg_order_type_callback',
'wrapper' => 'arg-order-type',
'method' => 'replace',
'effect' => 'fade',
],
];
$form['field_type'] = [
'#title' => $this
->t('Type of Argument Field'),
'#type' => 'select',
'#options' => $options,
'#default_value' => $this->options['field_type'],
];
}
public function query() {
$arg_to_use = $this->options['argument_number'];
$inherit_type = $this->options['inherit_type'];
$order = $this->options['order'];
$null_below = $this->options['null_below'];
if ($inherit_type) {
$arg_handlers = array_values($this->view->argument);
$arg_handler = $arg_handlers[$arg_to_use];
$left_table = $arg_handler->tableAlias;
$left_field = $arg_handler->realField;
}
else {
[
$left_table,
$left_field,
] = explode('::', $this->options['field_type']);
}
$args = $this->view->args;
$items = isset($args[$arg_to_use]) ? preg_split("/(\\+|\\,)/", $args[$arg_to_use]) : [];
$invert_order = $order == 'DESC';
$items = $invert_order ? array_reverse($items) : $items;
$max_o = 0;
$case_items = [];
$placeholder_suffix = str_replace(':' . $left_table . '_' . $left_field, '', $this->query
->placeholder($left_table . '_' . $left_field));
if (!empty($placeholder_suffix) && intval($placeholder_suffix) > 1) {
$placeholder_suffix = intval($placeholder_suffix) - 1;
}
else {
$placeholder_suffix = '';
}
$value_query_type = ':' . $left_table . '_' . $left_field . $placeholder_suffix;
if (count($items) == 1) {
$this->sort_values[0] = 0;
$case_items[] = "WHEN " . $value_query_type . " THEN 0 ";
}
else {
foreach ($items as $o => $value) {
$this->sort_values[$value] = $o;
if ($value) {
$case_items[] = "WHEN " . $value_query_type . "__{$o} THEN {$o} ";
$max_o = $max_o > $o ? $max_o : $o;
}
}
}
if (!empty($case_items)) {
$is_desc = $order == 'DESC';
$null_o = $is_desc == $null_below ? -1 : $max_o + 1;
$order_by = "CASE {$left_table}.{$left_field} " . implode("", $case_items) . " ELSE {$null_o} END";
$alias = "arg_order" . rand(0, 10000);
$this->query
->addOrderBy(NULL, $order_by, $order, $alias);
}
}
}