<?php
namespace w3des\AdminBundle\Service;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use w3des\AdminBundle\Entity\Node;
use w3des\AdminBundle\Model\ValueDefinition;
use w3des\AdminBundle\Model\ModuleInfo;
use w3des\AdminBundle\Model\ValuesMap;
use w3des\AdminBundle\Model\NodeView;
use w3des\AdminBundle\Entity\NodeVariable;
use Symfony\Contracts\Cache\TagAwareCacheInterface;
class Nodes
{
private EntityManagerInterface $em;
private array $cfg;
private Values $vals;
private RouterInterface $router;
private CMS $cms;
private TagAwareCacheInterface $cache;
public function __construct(TagAwareCacheInterface $appCache, EntityManagerInterface $em, CMS $cms, Values $vals, RouterInterface $router, array $cfg)
{
$this->em = $em;
$this->cfg = $cfg;
$this->vals = $vals;
$this->router = $router;
$this->cms = $cms;
$this->cache = $appCache;
}
public function getCfg()
{
return $this->cfg;
}
public function getNodeCfg($type)
{
return $this->cfg[$type];
}
public function getVariables(Node $node, $locale = null): ValuesMap
{
if ($locale == null) {
$locale = $this->cms->getLocale();
}
if ($node->getVariableMap() == null) {
$cfg = $this->getNodeCfg($node->getType());
$node->setVariableMap($this->vals->createMap($node->getVariables(), $cfg['fields'], $locale));
}
return $node->getVariableMap();
}
public function getVariable(Node $node, $name, $locale = null)
{
return $this->getVariables($node, $locale)->get($name, $locale);
}
/**
* @return array[]
*/
public function getFields($type)
{
return $this->cfg[$type]['fields'];
}
public function getSectionModules(Node $node, $section, $trackParents = false)
{
$res = [];
foreach ($this->getVariable($node, $section . '_modules') as $pos => $item) {
$res[] = new ModuleInfo($item->getType(), $this->getVariables($item), $pos, $node, $section);
}
return $res;
}
public function hasUrl(Node $node, $locale = null)
{
return $node->getUrls()->containsKey($locale ?? $this->cms->getLocale());
}
public function getUrl(Node $node, $mode = UrlGeneratorInterface::ABSOLUTE_PATH, $locale = null)
{
if (! $this->hasUrl($node, $locale)) {
if ($this->getNodeCfg($node->getType())['links']) {
foreach ($node->getPositions() as $pos) {
if ($pos->getType() === 'link' && $pos->getTarget()->getLocale() == $locale) {
return $this->getUrl($pos->getTarget(), $mode, $locale);
}
}
}
return null;
}
$routeParams = [
'path' => $node->getUrls()[$locale ?? $this->cms->getLocale()]->getPath(),
'_locale' => $locale ?? $this->cms->getLocale()
];
$prefix = '';
if ($node->getService() != $this->cms->getService()) {
$ser = $this->cms->getServiceById($node->getService());
$host = $ser['domains'][0];
$prefix = $this->router->getContext()->getScheme() . '://' . $host;
$mode = UrlGeneratorInterface::ABSOLUTE_PATH;
}
return $prefix . $this->router->generate('node', $routeParams, $mode);
}
public function getNodes(string $type, array $cfg = [])
{
if (! isset($cfg['locale'])) {
if ($this->getNodeCfg($type)['locale']) {
$cfg['locale'] = $this->cms->getLocale();
} else {
$cfg['locale'] = Values::MODEL_DEFAULT_LOCALE;
}
}
$cfg['page_locale'] = $this->cms->getLocale();
$res = $this->em->getRepository(Node::class)->findByConfig($this->cms->getService(), $type, $this, $cfg);
if ($cfg['query'] ?? false) {
return $res;
}
$res['list'] = $this->wrapArray($res['list']);
return $res;
}
public function getModel(int $id): ?Node
{
return $this->em->find(Node::class, $id);
}
public function getById(int $id): ?NodeView
{
return $this->wrap($this->em->find(Node::class, $id));
}
public function getByPath(string $path, ?string $locale): ?NodeView
{
return $this->wrap($this->em->getRepository(Node::class)->findByPath($this->cms->getService(), $path, $locale ?? $this->cms->getLocale()));
}
public function inUse(Node $node, $except = null)
{
return $this->em->getRepository(Node::class)->checkInUse($node, $except);
}
/**
* @param Node $node
* @return NodeView
*/
public function wrap(?Node $node, $parent = null): ?NodeView
{
if (null === $node) {
return null;
}
return new NodeView($this, $node, $parent);
}
/**
*
* return NodeView[]
*/
public function wrapArray(iterable $it)
{
$list = [];
foreach ($it as $node) {
$list[] = $this->wrap($node);
}
return $list;
}
public function wrapVariables(ValuesMap $vars): ValuesMap
{
$values = $vars->getValues();
$definitions = $vars->getDefinitions();
foreach ($values as $name => $localized) {
if ($definitions[$name]['storeType'] == 'node') {
foreach ($localized as $loc => $v) {
if ($definitions[$name]['array']) {
$v = $this->wrapArray($v);
} else {
$v = $this->wrap($v);
}
$values[$name][$loc] = $v;
}
}
}
return new ValuesMap($definitions, $values, $vars->getLocale());
}
public function search(array $types, array $cfg = [])
{
$res = $this->em->getRepository(Node::class)->searchByConfig($cfg['service'] ?? $this->cms->getService(), $types, $cfg);
if ($cfg['query'] ?? false) {
return $res;
}
$res['list'] = $this->wrapArray($res['list']);
return $res;
}
}