function filter_harmonizer_page_attachments in Views Filter Harmonizer 8
Same name and namespace in other branches
- 1.0.x filter_harmonizer.module \filter_harmonizer_page_attachments()
Implements hook_page_attachments().
This is here to implement the feature that reflects the regular filter choice on the browser address bar, using contextual filters, rather than the "?FIELD_NAME1=VALUE1&FIELD_NAME2=VALUE2" format.
File
- ./
filter_harmonizer.module, line 268 - filter_harmonizer.module
Code
function filter_harmonizer_page_attachments(array &$attachments) {
global $filter_harmonizer_filter_pairs;
// This is only set if there is a View active on the current page.
if (empty($filter_harmonizer_filter_pairs)) {
return;
}
if (!Drupal::config('filter_harmonizer.settings')
->get('filter_harmonizer_regular_filter_values_in_address_bar')) {
return;
}
// If an (exposed) regular filter was submitted, visually reflect that in the
// browser address bar.
$request = Drupal::request();
$route_path = RouteMatch::createFromRequest($request)
->getRouteObject()
->getPath();
$qs = urldecode($request
->getQueryString());
foreach ($filter_harmonizer_filter_pairs as $displays) {
foreach ($displays as $filters) {
$arg_values = [];
$regular_filter_count = 0;
foreach ($filters as $field_name => $filter_pair) {
if (isset($filter_pair['regular'])) {
$regular_filter_count++;
}
// If regular filter is empty, take the contextual value (or 'all').
$arg_values[$field_name] = isset($filter_pair['regular']['value']) ? isset($filter_pair['regular']['stringified']) ? $filter_pair['regular']['stringified'] : $filter_pair['contextual']['exception'] : (isset($filter_pair['contextual']['argument']) ? $filter_pair['contextual']['argument'] : $filter_pair['contextual']['exception']);
}
if (!$regular_filter_count) {
// If we have no active regular filters on this display, then we
// don't have to update the URL path.
continue;
}
// If the number of /{arg} occurrences in $route_path is not equal to the
// number of $arg_values we can move to the next display.
if ($match_count = preg_match_all('/\\/{[^\\/.]+}/', $route_path, $matches)) {
$matches = reset($matches);
// used below
}
if ($match_count != count($arg_values)) {
continue;
}
$path = $route_path;
// Now substitute URL, but don't add superfluous trailing "/all"'s.
// It is assumed that contextual arguments appear in order on the URL.
// Start at the rear.
$i = count($arg_values) - 1;
foreach (array_reverse($arg_values) as $field_name => $value) {
if (empty($done_exc) && $value == $filters[$field_name]['contextual']['exception']) {
// Avoid trailing "/all". Wipe the arg.
$path = str_replace($matches[$i], '', $path);
}
else {
// A non-trailing /all or "normal" value: replace it. Keep the '/'.
$done_exc = TRUE;
$path = str_replace($matches[$i], "/{$value}", $path);
}
// The Views module appends the regular filter values as rather ugly
// query-parameters. Example: ?field_size_value[]=XL
// These query parameters are no longer required because we've just
// put the equivalent values in the URL as contextual arguments.
if (isset($filters[$field_name]['regular'])) {
$field_alias = $filters[$field_name]['regular']['alias'];
$pattern = '/' . $field_alias . '\\[.*\\]=.+[&]?/';
// Remove the query parameter(s) from the query string.
$qs = preg_replace($pattern, '', $qs);
}
$i--;
}
}
}
if (isset($path) && $path !== $route_path) {
$path_plus_qs = empty($qs) ? $path : $path . '?' . $qs;
$attachments['#attached']['drupalSettings']['browser_url'] = $request
->getBasePath() . $path_plus_qs;
// Let's not forget to include the few lines of JS that make this happen!
$attachments['#attached']['library'][] = 'filter_harmonizer/filter_harmonizer';
}
}