refreshless-8.x-1.x-dev/modules/refreshless_turbo/src/PathProcessor/AjaxPageStatePathProcessor.php
modules/refreshless_turbo/src/PathProcessor/AjaxPageStatePathProcessor.php
<?php
declare(strict_types=1);
namespace Drupal\refreshless_turbo\PathProcessor;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\PathProcessor\OutboundPathProcessorInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Symfony\Component\HttpFoundation\Request;
/**
* Path processor to remove the 'ajax_page_state' query parameter.
*
* Under normal conditions, Drupal does not set this query parameter on GET
* requests, but we do to use core's already loaded libraries functionality.
* This has the unexpected result of certain links with a query string being
* rendered with 'ajax_page_state' present, including the subset of 'libraries'.
* This not only makes links look messy, but also instructs Drupal to load a
* broken (incomplete) set of libraries if reloading the page or navigating via
* the browser history.
*
* @todo Should we add checks to only remove 'ajax_page_state' if this was a
* RefreshLess request?
*
* @see \Drupal\refreshless_turbo\StackMiddleware\AdditiveLibraries
* Reads RefreshLess page state and sets it as 'ajax_page_state' on incoming
* requests, both POST and GET.
*
* @see \Drupal\refreshless_turbo\Pager\PagerManager
* Decorated pager manager to remove the 'ajax_page_state' query parameter
* from pager links.
*/
class AjaxPageStatePathProcessor implements OutboundPathProcessorInterface {
/**
* {@inheritdoc}
*/
public function processOutbound(
$path,
&$options = [],
?Request $request = null,
?BubbleableMetadata $bubbleable_metadata = null,
) {
if (isset($options['query']['destination'])) {
$options['query']['destination'] = $this->processDestination(
$options['query']['destination'],
);
}
// Note that this doesn't seem to affect pager links. We have to decorate
// the pager manager to fix those.
if (isset($options['query']['ajax_page_state'])) {
unset($options['query']['ajax_page_state']);
}
return $path;
}
/**
* Remove 'ajax_page_state' from a 'destination' parameter.
*
* @param string $destination
* An unparsed 'destination' parameter.
*
* @return string
* The $destination parameter with 'ajax_page_state' removed if it was
* found.
*
* @see \Drupal\Core\Routing\RedirectDestination::get()
* This builds the redirect destination if 'destination' is found in the
* query parameters.
*/
protected function processDestination(string $destination): string {
$parsed = UrlHelper::parse($destination);
if (!isset($parsed['query']['ajax_page_state'])) {
return $destination;
}
unset($parsed['query']['ajax_page_state']);
$modified = $parsed['path'];
if (!empty($parsed['query'])) {
$modified .= '?' . UrlHelper::buildQuery($parsed['query']);
}
if (!empty($parsed['fragment'])) {
$modified .= '#' . $parsed['fragment'];
}
return $modified;
}
}
