View source
<?php
namespace Drupal\views_random_seed\Plugin\views\sort;
use Drupal\Core\Form\FormStateInterface;
use Drupal\views\Plugin\views\sort\SortPluginBase;
use Drupal\views\Views;
use Drupal\views_random_seed\SeedCalculator;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\search_api\Plugin\views\query\SearchApiQuery;
class ViewsRandomSeedRandom extends SortPluginBase {
public $query;
protected $seedCalculator;
public function __construct(array $configuration, $plugin_id, $plugin_definition, SeedCalculator $seedCalculator) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->seedCalculator = $seedCalculator;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('views_random_seed.seed_calculator'));
}
protected function defineOptions() {
$options = parent::defineOptions();
$options['reuse_seed'] = [
'default' => '',
];
$options['user_seed_type'] = [
'default' => 'same_per_user',
];
$options['anonymous_session'] = [
'default' => FALSE,
];
$options['reset_seed_int'] = [
'default' => '3600',
];
$options['reset_seed_custom'] = [
'default' => '300',
];
return $options;
}
public function adminSummary() {
return "";
}
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
$form['order']['#access'] = FALSE;
$reuseSeedArray = [
'' => $this
->t('None'),
];
$viewList = Views::getAllViews();
foreach ($viewList as $view) {
foreach ($view
->get('display') as $display) {
$reuseSeedArray[$view
->id() . '-' . $display['id']] = $view
->label() . ': ' . $display['display_title'];
}
}
$form['reuse_seed'] = [
'#type' => 'select',
'#title' => $this
->t('Reuse seed from another view display'),
'#options' => $reuseSeedArray,
'#description' => $this
->t('With this option enabled, you can sync results between views.'),
'#default_value' => $this->options['reuse_seed'] ?? '',
];
$form['user_seed_type'] = [
'#type' => 'radios',
'#title' => $this
->t('User seed type'),
'#options' => [
'same_per_user' => $this
->t('Use the same seed for every user'),
'diff_per_user' => $this
->t('Use a different seed per user'),
],
'#default_value' => $this->options['user_seed_type'] ?? 'same_per_user',
];
$form['anonymous_session'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Anonymous sessions'),
'#default_value' => $this->options['anonymous_session'] ?? FALSE,
'#description' => $this
->t('Start sessions for anonymous users, which impacts performance.<br />If left unchecked, the seed will be the same for all anonymous users.'),
'#states' => [
'visible' => [
':input[name="options[user_seed_type]"]' => [
'value' => 'diff_per_user',
],
],
],
];
$form['reset_seed_int'] = [
'#type' => 'radios',
'#title' => $this
->t('Reset seed'),
'#options' => [
-1 => $this
->t('Never'),
0 => $this
->t('Custom'),
3600 => $this
->t('Every hour'),
28800 => $this
->t('Every eight hours'),
86400 => $this
->t('Every day'),
],
'#default_value' => $this->options['reset_seed_int'] ?? '3600',
];
$form['reset_seed_custom'] = [
'#type' => 'number',
'#min' => 0,
'#size' => 10,
'#title' => $this
->t('Custom reset seed'),
'#required' => TRUE,
'#default_value' => $this->options['reset_seed_custom'] ?? '300',
'#description' => $this
->t('Define your own custom reset time in seconds.'),
'#states' => [
'visible' => [
':input[name="options[reset_seed_int]"]' => [
'value' => '0',
],
],
],
];
}
public function usesGroupBy() {
return FALSE;
}
public function query() {
$db_type = \Drupal::database()
->driver();
$seed = $this->seedCalculator
->calculateSeed($this->options, $this->view
->id(), $this->view->current_display, $db_type);
switch ($db_type) {
case 'mysql':
case 'mysqli':
$formula = 'RAND(' . $seed . ')';
break;
case 'pgsql':
\Drupal::database()
->query('select setseed(' . $seed . ')');
\Drupal::database()
->query("select random()");
$formula = 'RANDOM()';
break;
}
if (!empty($formula)) {
if ($this->view->query instanceof SearchApiQuery) {
$this->query
->addOrderBy('rand', NULL, NULL, '', [
'seed' => $seed,
'formula' => $formula,
]);
}
else {
$this->query
->addOrderBy(NULL, $formula, $this->options['order'], '_' . $this->field);
}
}
}
public function getCacheContexts() {
$contexts = parent::getCacheContexts();
if ($this->options['user_seed_type'] === 'diff_per_user') {
$contexts[] = 'user';
}
return $contexts;
}
}