<?php
namespace App\Controller\Abstract;
use App\Service\Abstract\Traits\BasicData;
use App\Service\Abstract\Traits\Main;
use App\Service\ModulesManager;
use App\Service\Utils\Options;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Asset\Package;
use Symfony\Component\Asset\VersionStrategy\EmptyVersionStrategy;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Security;
abstract class MainController extends AbstractController
{
use Main {
Main::__construct as private mainConstruct;
}
use BasicData;
/**
* @var ModulesManager
*/
protected ModulesManager $moduleManager;
/**
* @param EntityManagerInterface $em
* @param Security $security
* @param Options $options
* @param UrlGeneratorInterface $router
* @param ModulesManager $moduleManager
*/
public function __construct(
EntityManagerInterface $em,
Security $security,
Options $options,
UrlGeneratorInterface $router,
ModulesManager $moduleManager
) {
$this->mainConstruct($em, $security, $options, $router);
$this->moduleManager = $moduleManager;
}
/**
* @param Request $request
* @param string|null $view
* @param array $params
* @param array $globalParams
* @param int $statusCode
*
* @return Response
*/
public function response(
Request $request,
?string $view,
array $params = [],
array $globalParams = [],
int $statusCode = 200,
bool $breakComponenets = false
): Response {
if ($view === null) {
$view = $this->options->env('ERROR_404', 'errors\\404.html.twig');
$statusCode = 404;
} elseif ($statusCode == 403) {
$view = $this->options->env('ERROR_403', 'errors\\403.html.twig');
}
$globalVariables = array_merge($this->options->globalVariables(), [
'route' => $request->get('_route'),
'statusCode' => $statusCode,
], $globalParams);
if (isset($params['fetch']) && is_array($params['fetch'])) {
$globalVariables = array_merge($globalVariables, $this->loadFromFetch($params['fetch']));
} else {
$globalVariables = array_merge($globalVariables, $this->loadDefaults());
}
$globalVariables['content'] = $this->renderView($view, array_merge($globalVariables, $params));
if ($request->getRealMethod() == 'POST') {
return new JsonResponse($globalVariables);
}
if ($statusCode !== 200) {
return $this->render($view, $globalVariables)
->setStatusCode($statusCode);
} elseif ($breakComponenets) {
return $this->render($view, $globalVariables);
}
$globalVariables['components'] = [
'menu' => $this->getMenu(),
];
return $this->render($this->getBaseTwig(), $globalVariables)
->setStatusCode($statusCode);
}
/**
* @return string
*/
private function getBaseTwig(): string
{
if ($this->getUser()) {
return 'main\\user\\base.html.twig';
}
return 'main\\website\\base.html.twig';
}
/**
* @return array
*/
public function getMenu(): array
{
$links = $this->moduleManager->getAllModules(true);
$links = array_combine(array_column($links, 'id'), $links);
$child = [];
foreach ($links as $k => &$item) {
$item['classes'] = [$item['route']];
if (empty($item['parent'])) {
$item['parent'] = 0;
} else {
$links[$item['parent']]['classes'][$k] = $item['route'];
}
$child[$item['parent']][$k] = &$item;
}
unset($item);
foreach ($links as $k => &$item) {
if (isset($child[$k])) {
$item['child'] = $child[$k];
$item['classes'] = ($item['classes'] + array_column($child[$k], 'classes')[0]);
}
}
$links = $child[0] ?? [];
uasort($links, function ($a, $b) {
return $a['menu_position'] <=> $b['menu_position'];
});
return $links;
}
/**
* @param array $fetch
*
* @return array
*/
private function loadFromFetch(array $fetch): array
{
$options = [
'userRoles' => 'fetchUserRoles',
'userStatuses' => 'fetchStatuses',
'logoImage' => 'logoImage',
];
$results = [];
if (isset($fetch['loadDefaults'])) {
$results = $this->loadDefaults();
}
foreach (array_intersect_key($fetch, $options) as $key => $value) {
$results[$key] = $this->{$options[$key]}(...$value);
}
return $results;
}
/**
* @return array
*/
private function loadDefaults(): array
{
return [
'logoImage' => $this->logoImage(),
];
}
/**
* @return string
*/
private function logoImage(): string
{
$package = new Package(new EmptyVersionStrategy());
return $package->getUrl('/pentrucomenzi/public/assets/img/logo.png');
}
}