backports murph-skeleton

This commit is contained in:
Simon Vieille 2021-05-18 11:22:26 +02:00
parent 968844222d
commit 04ac34da18
15 changed files with 247 additions and 63 deletions

View file

@ -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')

View file

@ -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,
];

View file

@ -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()
{

View file

@ -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[]
*/

View file

@ -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()
{

View file

@ -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
{

View 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([
]);
}
}

View file

@ -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,

View file

@ -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"

View file

@ -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 %}

View file

@ -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 }}">

View file

@ -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>

View file

@ -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 %}

View file

@ -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);
}

View file

@ -66,4 +66,9 @@ class SiteRequest
return null !== $menu ? $menu->getNavigation() : null;
}
public function getDomain(): string
{
return $this->requestStack->getCurrentRequest()->headers->get('host');
}
}