commercetools-8.x-1.2-alpha1/modules/commercetools_content/src/Service/CommercetoolsAjaxHelper.php
modules/commercetools_content/src/Service/CommercetoolsAjaxHelper.php
<?php
namespace Drupal\commercetools_content\Service;
use Drupal\Core\Controller\ControllerResolverInterface;
use Drupal\commercetools_content\CommercetoolsAjaxInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* Ajax helper service.
*/
class CommercetoolsAjaxHelper {
/**
* System content block ids.
*/
public const SYSTEM_BLOCK_PLUGIN_ID = 'system_main_block';
/**
* Block attribute name for ajax handling.
*/
public const COMMERCETOOLS_BLOCK_ID = 'data-ct-block-id';
/**
* Attribute for block product index. User to handle blocks properly.
*/
public const COMMERCETOOLS_PRODUCT_INDEX = 'data-ct-product-index';
/**
* Class for ajaxification of blocks.
*/
public const COMMERCETOOLS_SYSTEM_BLOCK_FORCE_UPDATE = 'data-ct-ajaxify-system-block';
public const COMMERCETOOLS_SYSTEM_BLOCK_FORCE_UPDATE_CONFIG = 'ajaxify_system_main_block';
public const COMMERCETOOLS_SYSTEM_BLOCK_ATTRIBUTE = 'data-ct-is-system-block';
public const COMMERCETOOLS_AJAX_ATTRIBUTE = 'data-ct-ajaxify';
/**
* Constructor of ajax helper.
*
* @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
* Request stack.
* @param \Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface $argumentResolver
* Argument resolver.
* @param \Drupal\Core\Controller\ControllerResolverInterface $controllerResolver
* Controller resolver.
* @param \Symfony\Component\HttpKernel\HttpKernel $httpKernel
* Http kernel.
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $eventDispatcher
* Event dispatcher.
*/
public function __construct(
protected RequestStack $requestStack,
protected ArgumentResolverInterface $argumentResolver,
protected ControllerResolverInterface $controllerResolver,
protected HttpKernel $httpKernel,
protected EventDispatcherInterface $eventDispatcher,
) {
}
/**
* Adjust request object in order to build correct urls.
*
* @param array $targetUrl
* Target url query param.
*
* @return array
* Render array result
*/
public function renderMainContentByPath(array $targetUrl) {
// Get the current request stack service.
$currentRequest = $this->requestStack->getCurrentRequest();
$path = $targetUrl['path'];
$query = $targetUrl['query'];
// Build the full URL as a normal page request.
$baseUrl = $currentRequest->getSchemeAndHttpHost();
$newUrl = $baseUrl . $path . '?' . http_build_query($query);
// Recreate request with correct attributes.
$request = Request::create($newUrl, "GET", [], [], [], $currentRequest->server->all());
// Propagate base path. Required to properly render links in response.
$request->server->set('REQUEST_URI', $currentRequest->getBasePath() . $path . '?' . http_build_query($query));
// Event to properly initialize query and put necessary route match objects.
// It's required to add and extract ajax controller.
$event = new RequestEvent($this->httpKernel, $request, HttpKernel::MAIN_REQUEST);
$request = $this->eventDispatcher->dispatch($event, KernelEvents::REQUEST);
$request = $request->getRequest();
// It's required to prevent - NotFoundHttpException.
$session = $currentRequest->getSession();
$request->setSession($session);
// Push the new request into the request stack.
$this->requestStack->push($request);
// Get the controller.
$controller = $this->controllerResolver->getController($request);
$arguments = $this->argumentResolver->getArguments($request, $controller);
return $controller(...$arguments);
}
/**
* Check controller from request is eligible to ajaxify.
*
* @return bool
* Whether controller is eligible to use ajax.
*/
public function isSystemBlockAjaxified(): bool {
$request = $this->requestStack->getCurrentRequest();
$controller = $this->controllerResolver->getController($request)[0];
if ($controller instanceof CommercetoolsAjaxInterface) {
return TRUE;
}
return FALSE;
}
/**
* Applies ajax attributes to given block.
*
* @param array $build
* Render array.
* @param int $index
* Block product list index.
*/
public static function applyAjaxifyAttributesToBlock(array &$build, int $index = 0): void {
$build['#attributes'][self::COMMERCETOOLS_AJAX_ATTRIBUTE] = TRUE;
$build['#attributes'][self::COMMERCETOOLS_BLOCK_ID] = $build['#id'];
$build['#attributes'][self::COMMERCETOOLS_PRODUCT_INDEX] = $index;
}
}
