backports murph-skeleton
This commit is contained in:
parent
968844222d
commit
04ac34da18
|
@ -83,6 +83,7 @@ class NavigationAdminController extends CrudController
|
|||
->setForm('edit', Type::class, [])
|
||||
->setForm('new', Type::class)
|
||||
|
||||
->setView('index', '@Core/site/navigation_admin/index.html.twig')
|
||||
->setView('show_entity', '@Core/site/navigation_admin/_show.html.twig')
|
||||
->setView('form', '@Core/site/navigation_admin/_form.html.twig')
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ class PageController extends AbstractController
|
|||
'_page' => $this->siteRequest->getPage(),
|
||||
'_menu' => $this->siteRequest->getMenu(),
|
||||
'_navigation' => $this->siteRequest->getNavigation(),
|
||||
'_domain' => $this->siteRequest->getDomain(),
|
||||
'_locale' => $this->siteRequest->getNavigation()->getLocale(),
|
||||
'_store' => $this->siteStore,
|
||||
];
|
||||
|
|
|
@ -22,34 +22,34 @@ class Menu implements EntityInterface
|
|||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $id;
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255)
|
||||
*/
|
||||
private $label;
|
||||
protected $label;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255)
|
||||
*/
|
||||
private $code;
|
||||
protected $code;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=Navigation::class, inversedBy="menus")
|
||||
* @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
|
||||
*/
|
||||
private $navigation;
|
||||
protected $navigation;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity=Node::class, mappedBy="menu", orphanRemoval=true, cascade={"remove", "persist"})
|
||||
*/
|
||||
private $nodes;
|
||||
protected $nodes;
|
||||
|
||||
/**
|
||||
* @ORM\OneToOne(targetEntity=Node::class, cascade={"persist"})
|
||||
* @ORM\JoinColumn(onDelete="CASCADE")
|
||||
*/
|
||||
private $rootNode;
|
||||
protected $rootNode;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
|
|
@ -22,32 +22,37 @@ class Navigation implements EntityInterface
|
|||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $id;
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255)
|
||||
*/
|
||||
private $label;
|
||||
protected $label;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255)
|
||||
*/
|
||||
private $code;
|
||||
protected $code;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255)
|
||||
*/
|
||||
private $domain;
|
||||
protected $domain;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="text", nullable=true)
|
||||
*/
|
||||
protected $additionalDomains = [];
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity=Menu::class, mappedBy="navigation")
|
||||
*/
|
||||
private $menus;
|
||||
protected $menus;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=10)
|
||||
*/
|
||||
private $locale = 'en';
|
||||
protected $locale = 'en';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -95,6 +100,18 @@ class Navigation implements EntityInterface
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getAdditionalDomains(): array
|
||||
{
|
||||
return (array) json_decode($this->additionalDomains, true);
|
||||
}
|
||||
|
||||
public function setAdditionalDomains(array $additionalDomains): self
|
||||
{
|
||||
$this->additionalDomains = json_encode($additionalDomains);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection|Menu[]
|
||||
*/
|
||||
|
|
|
@ -26,112 +26,112 @@ class Node implements EntityInterface
|
|||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $id;
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=Menu::class, inversedBy="nodes", cascade={"persist", "remove"})
|
||||
* @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
|
||||
*/
|
||||
private $menu;
|
||||
protected $menu;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
*/
|
||||
private $label;
|
||||
protected $label;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
*/
|
||||
private $url;
|
||||
protected $url;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="boolean", options={"default"=0})
|
||||
*/
|
||||
private $disableUrl = false;
|
||||
protected $disableUrl = false;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="boolean", options={"default"=0})
|
||||
*/
|
||||
private $isVisible = false;
|
||||
protected $isVisible = false;
|
||||
|
||||
/**
|
||||
* @Gedmo\TreeLeft
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $treeLeft;
|
||||
protected $treeLeft;
|
||||
|
||||
/**
|
||||
* @Gedmo\TreeLevel
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $treeLevel;
|
||||
protected $treeLevel;
|
||||
|
||||
/**
|
||||
* @Gedmo\TreeRight
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $treeRight;
|
||||
protected $treeRight;
|
||||
|
||||
/**
|
||||
* @Gedmo\TreeRoot
|
||||
* @ORM\ManyToOne(targetEntity="Node")
|
||||
* @ORM\JoinColumn(referencedColumnName="id", onDelete="CASCADE")
|
||||
*/
|
||||
private $treeRoot;
|
||||
protected $treeRoot;
|
||||
|
||||
/**
|
||||
* @Gedmo\TreeParent
|
||||
* @ORM\ManyToOne(targetEntity="Node", inversedBy="children")
|
||||
* @ORM\JoinColumn(referencedColumnName="id", onDelete="CASCADE")
|
||||
*/
|
||||
private $parent;
|
||||
protected $parent;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity="Node", mappedBy="parent")
|
||||
* @ORM\OrderBy({"treeLeft"="ASC"})
|
||||
*/
|
||||
private $children;
|
||||
protected $children;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=Page::class, inversedBy="nodes", cascade={"persist"})
|
||||
* @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
|
||||
*/
|
||||
private $page;
|
||||
protected $page;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
*/
|
||||
private $code;
|
||||
protected $code;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="array", nullable=true)
|
||||
*/
|
||||
private $parameters = [];
|
||||
protected $parameters = [];
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="array", nullable=true)
|
||||
*/
|
||||
private $attributes = [];
|
||||
protected $attributes = [];
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
*/
|
||||
private $controller;
|
||||
protected $controller;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="array", nullable=true)
|
||||
*/
|
||||
private $sitemapParameters = [];
|
||||
protected $sitemapParameters = [];
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=Node::class, inversedBy="aliasNodes")
|
||||
*/
|
||||
private $aliasNode;
|
||||
protected $aliasNode;
|
||||
|
||||
/**
|
||||
* @ORM\OneToMany(targetEntity=Node::class, mappedBy="aliasNode")
|
||||
*/
|
||||
private $aliasNodes;
|
||||
protected $aliasNodes;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
|
|
@ -21,23 +21,23 @@ class Block
|
|||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $id;
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255)
|
||||
*/
|
||||
private $name;
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="text", nullable=true)
|
||||
*/
|
||||
private $value;
|
||||
protected $value;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity=Page::class, inversedBy="blocks")
|
||||
* @ORM\JoinColumn(onDelete="CASCADE")
|
||||
*/
|
||||
private $page;
|
||||
protected $page;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
|
|
55
core/Form/Site/NavigationAdditionalDomainType.php
Normal file
55
core/Form/Site/NavigationAdditionalDomainType.php
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
namespace App\Core\Form\Site;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
|
||||
class NavigationAdditionalDomainType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder->add(
|
||||
'domain',
|
||||
TextType::class,
|
||||
[
|
||||
'label' => 'Domain',
|
||||
'required' => true,
|
||||
'help' => 'Regular expression: do not add the delimiter',
|
||||
'attr' => [
|
||||
],
|
||||
'constraints' => [
|
||||
new NotBlank(),
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$builder->add(
|
||||
'type',
|
||||
ChoiceType::class,
|
||||
[
|
||||
'label' => 'Type',
|
||||
'required' => true,
|
||||
'choices' => [
|
||||
'Domain' => 'domain',
|
||||
'Regular expression' => 'regexp',
|
||||
],
|
||||
'attr' => [
|
||||
],
|
||||
'constraints' => [
|
||||
new NotBlank(),
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -9,6 +9,8 @@ use Symfony\Component\Form\FormBuilderInterface;
|
|||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Component\Validator\Constraints\Length;
|
||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||
use App\Core\Form\Site\NavigationAdditionalDomainType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
|
||||
|
||||
class NavigationType extends AbstractType
|
||||
{
|
||||
|
@ -56,6 +58,19 @@ class NavigationType extends AbstractType
|
|||
]
|
||||
);
|
||||
|
||||
$builder->add(
|
||||
'additionalDomains',
|
||||
CollectionType::class,
|
||||
[
|
||||
'entry_type' => NavigationAdditionalDomainType::class,
|
||||
'label' => 'Additional domains',
|
||||
'by_reference' => false,
|
||||
'allow_add' => true,
|
||||
'allow_delete' => true,
|
||||
'prototype' => true,
|
||||
]
|
||||
);
|
||||
|
||||
$builder->add(
|
||||
'locale',
|
||||
TextType::class,
|
||||
|
|
|
@ -94,6 +94,7 @@
|
|||
"Elements": "Élements"
|
||||
"Show all node URLs": "Afficher toutes les URLs du nœud"
|
||||
"Add a menu": "Ajouter un menu"
|
||||
"Add": "Ajouter"
|
||||
"Actions": "Actions"
|
||||
"Remove": "Supprimer"
|
||||
"Delete": "Supprimer"
|
||||
|
@ -147,3 +148,5 @@
|
|||
"Setting": "Paramètre"
|
||||
"Section": "Section"
|
||||
"Filter": "Filtrer"
|
||||
"Additional domains": "Domaines additionnels"
|
||||
"Regular expression: do not add the delimiter": "Expréssion régulière : ne pas ajouter de délimiteur"
|
||||
|
|
|
@ -150,32 +150,34 @@
|
|||
</td>
|
||||
{% endfor %}
|
||||
|
||||
{% if configuration.action('index', 'show', true) or configuration.action('index', 'edit', true) or configuration.action('index', 'delete', true) %}
|
||||
<td class="col-2 miw-200 text-right">
|
||||
{% if configuration.action('index', 'show', true) %}
|
||||
<a href="{{ path(configuration.pageRoute('show'), {entity: item.id}) }}" class="btn btn-sm btn-secondary mr-1">
|
||||
<span class="fa fa-eye"></span>
|
||||
</a>
|
||||
{% endif %}
|
||||
<td class="col-2 miw-200 text-right">
|
||||
{% block list_item_actions_before %}{% endblock %}
|
||||
|
||||
{% if configuration.action('index', 'edit', true) %}
|
||||
<a href="{{ path(configuration.pageRoute('edit'), {entity: item.id}) }}" class="btn btn-sm btn-primary mr-1">
|
||||
<span class="fa fa-edit"></span>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if configuration.action('index', 'show', true) %}
|
||||
<a href="{{ path(configuration.pageRoute('show'), {entity: item.id}) }}" class="btn btn-sm btn-secondary mr-1">
|
||||
<span class="fa fa-eye"></span>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if configuration.action('index', 'delete', true) %}
|
||||
<button type="submit" form="form-delete-{{ item.id }}" class="btn btn-sm btn-danger">
|
||||
<span class="fa fa-trash"></span>
|
||||
</button>
|
||||
{% if configuration.action('index', 'edit', true) %}
|
||||
<a href="{{ path(configuration.pageRoute('edit'), {entity: item.id}) }}" class="btn btn-sm btn-primary mr-1">
|
||||
<span class="fa fa-edit"></span>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
<form method="post" action="{{ path(configuration.pageRoute('delete'), {entity: item.id}) }}" id="form-delete-{{ item.id }}" data-form-confirm>
|
||||
<input type="hidden" name="_method" value="DELETE">
|
||||
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ item.id) }}">
|
||||
</form>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endif %}
|
||||
{% if configuration.action('index', 'delete', true) %}
|
||||
<button type="submit" form="form-delete-{{ item.id }}" class="btn btn-sm btn-danger">
|
||||
<span class="fa fa-trash"></span>
|
||||
</button>
|
||||
|
||||
<form method="post" action="{{ path(configuration.pageRoute('delete'), {entity: item.id}) }}" id="form-delete-{{ item.id }}" data-form-confirm>
|
||||
<input type="hidden" name="_method" value="DELETE">
|
||||
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ item.id) }}">
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
{% block list_item_actions_after %}{% endblock %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endblock %}
|
||||
{% else %}
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block collection_block_widget %}
|
||||
|
||||
<div data-collection="collection-{{ collection_name }}">
|
||||
{% for item in form.value %}
|
||||
<div data-collection-item="{{ loop.index }}">
|
||||
|
|
|
@ -1,12 +1,69 @@
|
|||
<div class="row">
|
||||
<div class="col-12 p-3">
|
||||
<div class="row">
|
||||
{% for item in ['label', 'domain', 'locale', 'code'] %}
|
||||
{% for item in ['label', 'locale', 'code'] %}
|
||||
<div class="col-12">
|
||||
{{ form_row(form[item]) }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<div class="col-12">
|
||||
{{ form_row(form.domain) }}
|
||||
</div>
|
||||
|
||||
{% set collection_name = 'additional-domains' %}
|
||||
{% set label_add = 'Add' %}
|
||||
{% set label_delete = 'Delete' %}
|
||||
|
||||
<div data-collection="collection-{{ collection_name }}" class="col-12">
|
||||
{{ form_label(form.additionalDomains) }}
|
||||
|
||||
{% for item in form.additionalDomains %}
|
||||
<div data-collection-item="{{ loop.index }}">
|
||||
<div class="row">
|
||||
{% for child in item %}
|
||||
<div class="col-12 col-md-3 pr-3">
|
||||
{{ form_row(child) }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<div class="col-12 col-md-3">
|
||||
<span data-collection-delete-container class="btn btn-sm btn-danger" style="margin-top: 2.1rem">
|
||||
<span data-collection-delete="{{ loop.index }}">
|
||||
{{ label_delete|trans }}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div data-collection-add="collection-{{ collection_name }}" class="collection-add col-12">
|
||||
<span class="btn btn-sm btn-primary" data-collection-add="collection-{{ collection_name }}">
|
||||
{{ label_add|trans }}
|
||||
</span>
|
||||
</div>
|
||||
<template type="text/template" id="collection-{{ collection_name }}">
|
||||
<div data-collection-item="__name__">
|
||||
<div class="row">
|
||||
{% for child in form.additionalDomains.vars.prototype %}
|
||||
<div class="col-12 col-md-3 pr-3">
|
||||
{{ form_row(child) }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<div class="col-12 col-md-3">
|
||||
<span data-collection-delete-container class="btn btn-sm btn-danger" style="margin-top: 2.1rem">
|
||||
{{ label_delete|trans }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-none">
|
||||
{{ form_rest(form) }}
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
{% extends '@Core/admin/crud/index.html.twig' %}
|
||||
|
||||
{% block list_item_actions_before %}
|
||||
<a href="{{ path('admin_site_tree_navigation', {navigation: item.id}) }}" class="btn btn-sm btn-success mr-1">
|
||||
<span class="fa fa-sitemap"></span>
|
||||
</a>
|
||||
{% endblock %}
|
|
@ -70,6 +70,7 @@ class SiteRouteLoader extends Loader
|
|||
'_menu' => $menu->getId(),
|
||||
'_page' => $node->getPage() ? $node->getPage()->getId() : null,
|
||||
'_navigation' => $navigation->getId(),
|
||||
'_domain' => $navigation->getDomain(),
|
||||
];
|
||||
|
||||
foreach ($node->getParameters() as $parameter) {
|
||||
|
@ -86,14 +87,35 @@ class SiteRouteLoader extends Loader
|
|||
|
||||
$requirements['_locale'] = $navigation->getLocale();
|
||||
|
||||
$additionalDomains = $navigation->getAdditionalDomains();
|
||||
|
||||
if (count($additionalDomains)) {
|
||||
$host = '{_domain}';
|
||||
$domains = [
|
||||
preg_quote($navigation->getDomain()),
|
||||
];
|
||||
|
||||
foreach ($additionalDomains as $additionalDomain) {
|
||||
if ('domain' === $additionalDomain['type']) {
|
||||
$domains[] = preg_quote($additionalDomain['domain']);
|
||||
} elseif ('regexp' === $additionalDomain['type']) {
|
||||
$domains[] = $additionalDomain['domain'];
|
||||
}
|
||||
}
|
||||
|
||||
$requirements['_domain'] = sprintf('(%s)', implode('|', $domains));
|
||||
} else {
|
||||
$host = $navigation->getDomain();
|
||||
}
|
||||
|
||||
$url = $node->getUrl();
|
||||
|
||||
if (!$uniqueness[$navigation->getDomain()]) {
|
||||
$url = sprintf('/%s%s', $navigation->getLocale(), $url);
|
||||
}
|
||||
|
||||
$route = new Route($url, $defaults, $requirements);
|
||||
$route->setHost($navigation->getDomain());
|
||||
$route = new Route($url, $defaults, $requirements, [], $host);
|
||||
//$route->setHost($navigation->getDomain());
|
||||
|
||||
$routes->add($node->getRouteName(), $route);
|
||||
}
|
||||
|
|
|
@ -66,4 +66,9 @@ class SiteRequest
|
|||
|
||||
return null !== $menu ? $menu->getNavigation() : null;
|
||||
}
|
||||
|
||||
public function getDomain(): string
|
||||
{
|
||||
return $this->requestStack->getCurrentRequest()->headers->get('host');
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue