<?php
declare(strict_types=1);
namespace App\Service\Content;
use App\Entity\Content\PageTranslation;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Controller\ControllerReference;
use Symfony\Component\HttpKernel\Fragment\InlineFragmentRenderer;
class Widgetizer
{
protected array $widgets = [
'google_map' => 'App\\Controller\\App\\App\\PublicController::googleMapAction',
'contact_form' => 'App\\Controller\\App\\App\\PublicController::contactFormAction',
'blog' => 'App\\Controller\\Content\\App\\BlogController::byTypeAction',
'documents' => 'App\\Controller\\Content\\App\\DocumentController::widgetAction',
];
private InlineFragmentRenderer $fragmentRenderer;
private RequestStack $requestStack;
public function __construct(InlineFragmentRenderer $fragmentRenderer, RequestStack $requestStack)
{
$this->fragmentRenderer = $fragmentRenderer;
$this->requestStack = $requestStack;
}
public function compile(string $content = null): ?string
{
if (empty($content)) {
return '';
}
return preg_replace_callback('/%%(.*)%%/', [$this, 'replaceWithWidget'], $content);
}
private function replaceWithWidget($matches): string
{
$parameters = explode(' ', $matches[1]);
$widget = array_shift($parameters);
$controller = $this->widgets[$widget] ?? null;
if (!$controller) {
return '';
}
$parameters = $this->mapParams($parameters);
$response = $this->getWidget($controller, $parameters);
if (!$response instanceof Response) {
return '';
}
return $response->getContent();
}
private function mapParams($params = array()): array
{
$newParams = array();
foreach ($params as $param) {
preg_match('/([a-zA-Z0-9_]+)\=\"([^"]+)\"/', $param, $matches);
$value = array_pop($matches);
$key = array_pop($matches);
$newParams[$key] = $value;
}
return $newParams;
}
private function getWidget($controller, array $attributes = array(), array $query = array()): ?Response
{
$request = $this->requestStack->getCurrentRequest();
$attributes['_locale'] = $request->getLocale();
return $this->fragmentRenderer->render(new ControllerReference($controller, $attributes, $query), $request);
}
public function widgetize(PageTranslation $translation): PageTranslation
{
return $translation
->setContent(
$this->compile(
$translation->getContent()
)
)
/*->setPageTop(
$this->compile(
$translation->getPageTop()
)
)
->setPageBottom(
$this->compile(
$translation->getPageBottom()
)
)*/;
}
}