function views_dependent_filters_handler_filter_dependent::exposed_form in Views Dependent Filters 7
Make our changes to the form but don't return anything ourselves.
Overrides views_handler_filter::exposed_form
File
Class
Code
function exposed_form(&$form, &$form_state) {
$filters = $this->view->display_handler
->get_handlers('filter');
// Build an array of dependency info.
$dependency_info = array(
// An array keyed by controller filter IDs, where the values are arrays
// of their possible values.
// In practice there is only one controller filter, but technically there
// could be several. The problem is that the admin UI to set them up
// would become a nightmare, and there's the matter of whether to combine
// them with AND or OR. Hence one for later, if ever required.
'controllers' => array(),
// An array of dependent filter IDs.
'dependents' => array(),
// A lookup of filter IDs to filter URL identifiers.
'identifiers' => array(),
);
if (!empty($this->options['controller_filter'])) {
$controller_filter = $this->options['controller_filter'];
$dependency_info['controllers'][$controller_filter] = array();
if (!empty($this->options['controller_values'])) {
if (is_array($this->options['controller_values'])) {
// Filter out the crud from Form API checkboxes and get rid of the
// keys to avoid confusion: we compare on values further down.
$controller_values = array_values(array_filter($this->options['controller_values']));
}
else {
$controller_values = array(
$this->options['controller_values'],
);
}
$dependency_info['controllers'][$controller_filter] = $controller_values;
$identifier = $filters[$controller_filter]->options['expose']['identifier'];
$dependency_info['identifiers'][$controller_filter] = $identifier;
}
}
$dependency_info['dependents'] = array_values(array_filter($this->options['dependent_filters']));
// Populate the identifiers lookup with our dependent filters.
foreach ($dependency_info['dependents'] as $dependent_filter_id) {
$identifier = $filters[$dependent_filter_id]->options['expose']['identifier'];
$dependency_info['identifiers'][$dependent_filter_id] = $identifier;
}
//dsm($form_state['input'], 'input');
$filters = $this->view->display_handler
->get_handlers('filter');
foreach ($dependency_info['controllers'] as $filter_id => $controller_values) {
// Get the form identifier.
$identifier = $filters[$filter_id]->options['expose']['identifier'];
// Get the input for this filter.
$input = $form_state['input'][$identifier];
// Convert values for non-multiple filters to an array.
if (!$this->view->filter[$filter_id]->options['expose']['multiple']) {
$input = array(
$input,
);
}
$intersection = array_intersect($input, $controller_values);
if (!count($intersection)) {
$this->filters_kill = $dependency_info['dependents'];
}
}
// We can kill the dependent filters now.
// $this->filters_disable();
// ...alternatively, leave them there so their form is shown, but prevent
// them from collecting input.
// This means the form element can be subject to CTools dependent visiblity
// and means the user can refine their filtering without an interim
// submission of the form.
// @todo: Allow this as an option, ie have a 'no js' version which would
// just kill dependent filters now.
// To make the dependent filters change their visibility we need to add a
// CTools dependent property, but we can't do that here as the form
// elements for these don't exist yet.
// Only way to do this is to register an #after_build on the whole form
// which lives in module code rather than in this handler.
// Add our settings to the form state as an array, as we need to account
// for the possiblity that more than one copy of this handler may be
// playing at once!
$form_state['dependent_exposed_filters'][] = $dependency_info;
$form['#after_build'] = array(
'views_dependent_filters_exposed_form_after_build',
);
// Some clean-up for things that come later.
// Mark ourselves not being exposed now we've done our work. This isn't
// necessary for Views itself, but allows compatibility with the
// better_exposed_filters module whose exposed_form_alter() tries to work
// with all exposed filters.
$this->options['exposed'] = FALSE;
// We do nada to the form ourselves.
return;
}