<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use w3des\AdminBundle\Entity\Node;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\Response;
use w3des\AdminBundle\Service\Nodes;
use Symfony\Component\Routing\Annotation\Route;
use w3des\AdminBundle\Model\NodeView;
use w3des\AdminBundle\Service\ModuleRegistry;
use w3des\AdminBundle\Service\CMS;
use w3des\AdminBundle\Service\Toolbar;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Contracts\Cache\TagAwareCacheInterface;
use Symfony\Contracts\Cache\ItemInterface;
use App\Twig\AppExtension;
use w3des\AdminBundle\Cache\AppCacheInterface;
use w3des\AdminBundle\Twig\Runtime\HelperRuntime;
/**
* @author zulus
*/
class NodeController extends AbstractController
{
private AppCacheInterface $cache;
private Nodes $nodes;
private Toolbar $toolbar;
private CMS $cms;
private array $tmp = [];
private ModuleRegistry $registry;
public function __construct(AppCacheInterface $appCache, CMS $cms, Nodes $nodes, ModuleRegistry $registry, Toolbar $toolbar)
{
$this->cache = $appCache;
$this->nodes = $nodes;
$this->toolbar = $toolbar;
$this->cms = $cms;
$this->registry = $registry;
}
public function process(Request $request, $id)
{
$node = $this->cache->get($this->cache->tags()->node($id), function(ItemInterface $item) use ($id) {
$item->tag($this->cache->tags()->node($id));
$node = $this->nodes->getById((int) $id);
$node->_fetch();
return $node;
});
if (null === $node) {
throw $this->createNotFoundException();
}
$request->attributes->set('node', $node);
$cfg = $this->nodes->getNodeCfg($node->type);
if ($this->toolbar->isAdminLogged()) {
$this->toolbar->setEditPath($this->generateUrl('admin.node.edit', [
'id' => $node->id,
'type' => $node->type
]));
} elseif ($node->vars->has('public') && !$node->vars->public) {
throw $this->createNotFoundException();
}
$modules = [];
foreach ($node->modules as $section => $list) {
$modules[$section] = [];
foreach ($list as $data) {
$result = $this->registry->getModule($data->type)->frontend($request, $data, $cfg['modules'][$section]['options'][$data->type]['options']);
if ($result instanceof Response) {
if ($result->getStatusCode() == 200) {
$modules[$section][] = $result->getBody();
} else {
return $result;
}
} elseif ($result === null) {
continue;
} else {
$modules[$section][] = $this->renderView(\str_replace('module.', 'nodes/', $data->type) . '.html.twig', $result);
}
}
}
if ($cfg['redirectEmpty'] && count($node->modules[$cfg['redirectEmpty']]) == 0) {
$redirect = $this->cache->get('node.redirect.' . $node->id, function (ItemInterface $item) use ($node) {
$item->tag([
'node.' . $node->id,
$this->cache->tags()->node('menu')
]);
foreach ($node->children as $child) {
if ($child->url) {
return $child->url;
}
}
$tmp = $this->nodes->getNodes('menu', [
'where' => [
'node' => $node->model
]
]);
if (count($tmp['list'])) {
$n = $tmp['list'][0];
foreach ($n->children as $ch) {
if ($ch->vars->node && $ch->vars->node->vars->public) {
return $ch->vars->node->url;
}
}
}
return false;
});
if ($redirect !== false) {
return $this->redirect($redirect);
}
}
// return $this->render('home/index.html.twig', ['selected' => [], 'season' => []]);
$currentService = $this->cms->getService();
if ($currentService == 0) {
return $this->render('cms/node_' . $node->type . '.html.twig', [
'node' => $node,
'modules' => $modules
]);
} else {
return $this->render('cms/node_' . $node->type . '_bip.html.twig', [
'node' => $node,
'modules' => $modules
]);
}
}
private function getNode($id): ?NodeView
{
if (isset($this->tmp[$id])) {
return $this->tmp[$id];
}
return $this->tmp[$id] = $this->nodes->getById($id);
}
private function saveNode(NodeView $item)
{
$this->tmp[$item->id] = $item;
}
private function lazyModule($info, $node)
{
if (isset($this->tmp[$info[1]])) {
return $this->tmp[$info[1]];
}
$n = new NodeView($this->nodes, $node);
$n->id = $info[1];
return $n;
}
/**
* @Route("/_download/{id}", name="download", methods={"GET"})
*/
public function download(Node $node)
{
if ($node->getType() != 'file') {
throw $this->createAccessDeniedException();
}
$response = new BinaryFileResponse($this->getParameter('upload.path') . $this->nodes->getVariable($node, 'file')['path']);
$response->setContentDisposition('attachment', $this->nodes->getVariable($node, 'name'));
return $response;
}
/**
* @Route("/{_locale}/search", name="search")
*/
public function search(AppExtension $ext, Request $request)
{
if (strlen(trim($request->query->get('query'))) < 3) {
return $this->redirectToRoute('homepage');
}
return $this->render('cms/search.html.twig', [
'query' => $request->query->get('query'),
'search' => $this->nodes->search($request->query->get('type') ? [
$request->query->get('type')
] : [
'page',
'offer',
'news',
'product'
], [
'page' => $request->query->get('page', 1),
'max' => 10,
'service' => $this->cms->getService() ===0 ? -1 : $this->cms->getService(),
'search' => trim($request->query->get('query')),
'locale' => $request->getLocale(),
'pagging' => true
])
]);
}
}