ajax_wrapper-1.0.1/src/Controller/AjaxWrapperController.php
src/Controller/AjaxWrapperController.php
<?php
namespace Drupal\ajax_wrapper\Controller;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\CommandInterface;
use Drupal\Core\Ajax\SettingsCommand;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Form\FormState;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteObjectInterface;
use Drupal\Core\Url;
use Drupal\ajax_wrapper\Ajax\StoreHistoryCommand;
use Drupal\ajax_wrapper\Utility\AjaxWrapperCallbackUtility;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\RouterInterface;
/**
* This class re-renders a block using ajax.
*
* Requests are altered so any filtering done is taken into account.
*
* @package Drupal\ajax_overview_block\Controller
*/
class AjaxWrapperController extends ControllerBase {
/**
* The full request stack.
*
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $requestStack;
/**
* The current request.
*
* @var \Symfony\Component\HttpFoundation\Request
*/
protected $request;
/**
* An array containing form values.
*
* @var array
*/
protected $data = [];
/**
* The form state.
*
* @var \Drupal\Core\Form\FormStateInterface
*/
protected $formState = NULL;
/**
* The router.
*
* @var \Symfony\Component\Routing\RouterInterface
*/
protected $router;
/**
* The callback utility.
*
* @var \Drupal\ajax_wrapper\Utility\AjaxWrapperCallbackUtility
*/
protected AjaxWrapperCallbackUtility $callbackUtility;
/**
* MessageCatalogueAjaxController constructor.
*
* @param \Drupal\ajax_wrapper\Utility\AjaxWrapperCallbackUtility $callbackUtility
* The callback utility.
* @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
* The request stack.
* @param \Symfony\Component\Routing\RouterInterface $router
* The router.
*/
public function __construct(
AjaxWrapperCallbackUtility $callbackUtility,
RequestStack $requestStack,
RouterInterface $router,
) {
$this->callbackUtility = $callbackUtility;
$this->requestStack = $requestStack;
$this->request = $requestStack->getCurrentRequest();
$this->router = $router;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('ajax_wrapper.utility.callback'),
$container->get('request_stack'),
$container->get('router.no_access_checks')
);
}
/**
* Refreshes a block when a form is submitted.
*/
public function refresh() {
// Fetch all data sent to us via ajax.
$this->data = $this->request->request->all();
$ajaxResponse = new AjaxResponse();
// Set the form state if applicable.
if (!empty($this->data['form_data'])) {
$params = [];
parse_str($this->data['form_data'] ?? '', $params);
// Build the form state.
$formState = new FormState();
$formState->setValues($params ?? []);
$this->formState = $formState;
}
// Build the GET URL, Request and push it to the stack.
$url = $this->buildAndPushRequest();
$requestUrl = $this->getUrlFromCurrentRequest();
$drupalSettingsCommand = new SettingsCommand([
'path' => [
'baseUrl' => '/',
'currentPath' => $requestUrl->getInternalPath(),
],
], TRUE);
$ajaxResponse->addCommand($drupalSettingsCommand);
$callbacks = $this->doCallback();
foreach ($callbacks as $command) {
if (!$command instanceof CommandInterface) {
continue;
}
$ajaxResponse->addCommand($command);
}
$storeHistoryCommand = new StoreHistoryCommand(
'body', $url
);
$ajaxResponse->addCommand($storeHistoryCommand);
return $ajaxResponse;
}
/**
* Create the URL with parameters attached.
*
* @return \Drupal\Core\GeneratedUrl|string|null
* Returns the string of the URL.
*/
protected function buildAndPushRequest(): ?string {
if (empty($this->data['url'])) {
return NULL;
}
$url = ($this->data['url']);
$parsedUrl = parse_url($url);
$path = $parsedUrl['path'] ?? NULL;
if (!$path) {
$path = $this->request->get('current_path') ?? '/';
}
if ($this->formState instanceof FormStateInterface) {
$formStateClone = clone $this->formState;
$parsedUrl['query'] = http_build_query($formStateClone->cleanValues()->getValues());
}
if (isset($parsedUrl['query'])) {
$path .= '?' . $parsedUrl['query'];
}
$request = Request::create($path, 'GET');
$attributes = $this->router->matchRequest($request);
if (!$attributes) {
return FALSE;
}
if ($this->request->hasSession()) {
$request->setSession($this->request->getSession());
}
$request->attributes->add($attributes);
$page = $request->query->get('page');
$_REQUEST['page'] = $page;
$this->requestStack->push($request);
$route_name = $attributes[RouteObjectInterface::ROUTE_NAME];
$route_parameters = $attributes['_raw_variables']->all();
$url = new Url($route_name, $route_parameters, [
'query' => $request->query->all(),
]);
return $url->toString(TRUE)
->getGeneratedUrl();
}
/**
* Returns the url from the current request.
*
* @return string
* The url in string format.
*/
protected function getUrlFromCurrentRequest(): Url {
$currentRequest = $this->requestStack->getCurrentRequest();
$parameters = $currentRequest->query->all();
$requestUrl = Url::createFromRequest(
$this->requestStack->getCurrentRequest()
);
$requestUrl->setOptions(['query' => $parameters]);
return $requestUrl;
}
/**
* Does the callback.
*
* @return mixed
* The value of the callback function.
*/
protected function doCallback() {
$callback = $this->data['ajax_wrapper_settings']['callback'] ?? [];
if (empty($callback)) {
throw new \Exception('No callback was specified...');
}
return $this->callbackUtility->doCallback(
$callback['function'], $callback['arguments'] ?? [], 'Callback was not trusted',
);
}
}
