protected function Selective::getOids in Views Selective Filters 8
Returns a list of options for current view, only at runtime.
1 call to Selective::getOids()
- Selective::getValueOptions in src/
Plugin/ views/ filter/ Selective.php - Child classes should be used to override this function and set the 'value options', unless 'options callback' is defined as a valid function or static public method to generate these values.
File
- src/
Plugin/ views/ filter/ Selective.php, line 258
Class
- Selective
- Views filter handler for selective values.
Namespace
Drupal\views_selective_filters\Plugin\views\filterCode
protected function getOids() {
// Parameters that we will be using during the process.
$base_field = $this->definition['field_base'];
$ui_name = $this
->adminLabel();
$signature = $this
->getSignature();
// Prevent same filters from being recalculated.
if (empty(static::$results[$signature])) {
// We don't want a badly configured selective filter
// to return thousands of possible values.
$max_items = (int) $this->options['selective_items_limit'];
// Clone the view (so it works while editting) and get all results.
$view_copy = Views::executableFactory()
->get($this->view->storage);
if (!$view_copy) {
return NULL;
}
// Store a flag so that we can know from other places
// that this view is being used to obtain selective data.
$view_copy->selective_oids = TRUE;
// Store information about what filter is this view being used for.
$view_copy->selective_handler_signature = $signature;
// Transfer contextual information to cloned view.
$view_copy
->setExposedInput($this->view
->getExposedInput());
$view_copy
->setArguments($this->view->args);
// Mess up with the field used for distinct have thousands of elements.
// Limit result set to 100: anything above is not user friendly at all.
$view_copy
->setItemsPerPage($max_items);
$view_copy
->setDisplay($this->view->current_display);
$display = $view_copy
->getDisplay();
// Remove any exposed form configuration. This showed up with BEF module!
unset($display->display['display_options']['exposed_form']);
$fields =& $display
->getHandlers('field');
$fields = array_intersect_key($fields, [
$this->options['selective_display_field'] => TRUE,
]);
// Check to see if the user remembered to add the field.
if (empty($fields)) {
drupal_set_message(t('Selective query filter must have corresponding field added to view with Administrative Name set to "@name" and Base Type "@type"', [
'@name' => $ui_name,
'@type' => $base_field,
]), 'error');
return [];
}
// Get ID of field that will be used for rendering.
$field = reset($fields);
$field_options = $field->options;
// Get field Id.
$field_id = $field_options['id'];
// Check that relationships are coherent between Field and Filter.
$no_display_field_relationship = empty($field_options['relationship']) || $field_options['relationship'] === 'none';
$no_filter_relationship = empty($this->options['relationship']) || $this->options['relationship'] === 'none';
$equal = $no_display_field_relationship === TRUE && $no_filter_relationship === TRUE || $field_options['relationship'] === $this->options['relationship'];
if (!$equal) {
drupal_set_message(t('Selective filter "@name": relationship of field and filter must match.', [
'@name' => $ui_name,
'@type' => $base_field,
]), 'error');
return [];
}
// If main field is excluded from presentation, bring it back.
// Set group type for handler to populate database relationships in query.
$field_options['exclude'] = 0;
$field_options['group_type'] = 'group';
// Remove all sorting: sorts must be added to aggregate fields.
// $sorts =& $display->getHandlers('sort');
// $sorts = [];.
// Turn this into an aggregate query.
$display
->setOption('group_by', 1);
// Aggregate is incompatible with distinct and pure distinct.
// At least it does not make sense as it is implemented now.
$query_options = $display
->getOption('query');
$query_options['options']['distinct'] = TRUE;
$display
->setOption('query', $query_options);
// Some style plugins can affect the built query, make sure we use a
// reliable field based style plugin.
$display
->setOption('pager', [
'type' => 'none',
'options' => [],
]);
$display
->setOption('style', [
'type' => 'default',
'options' => [],
]);
$display
->setOption('row', [
'type' => 'fields',
'options' => [],
]);
$display
->setOption('cache', [
'type' => 'none',
'options' => [],
]);
// Run View.
$view_copy
->execute($this->view->current_display);
// We show human-readable values when case.
if (method_exists($field, 'getValueOptions')) {
$field
->getValueOptions();
}
$style = $display
->getPlugin('style');
// Create array of objects for selector.
$oids = [];
foreach ($view_copy->result as $row) {
$key = $field
->getValue($row);
$key = is_array($key) ? reset($key) : $key;
// @todo This double escapes markup.
$value = $style
->getField($row->index, $field_id);
$oids[$key] = SafeMarkup::checkPlain($value);
}
// Sort values.
$sort_option = $this->options['selective_display_sort'];
switch ($sort_option) {
case 'ASC':
asort($oids);
break;
case 'DESC':
arsort($oids);
break;
case 'KASC':
ksort($oids);
break;
case 'KDESC':
krsort($oids);
break;
case 'ORIG':
$oids = static::filterOriginalOptions($this
->getOriginalOptions(), array_keys($oids));
break;
case 'NONE':
break;
default:
asort($oids);
}
// If limit exceeded this field is not good for being "selective".
if (!empty($max_items) && count($oids) == $max_items) {
drupal_set_message(t('Selective filter "@field" has limited the amount of total results. Please, review you query configuration.', [
'@field' => $ui_name,
]), 'warning');
}
static::$results[$signature] = $oids;
$view_copy
->destroy();
}
return static::$results[$signature];
}