backports murph-skeleton

This commit is contained in:
Simon Vieille 2021-05-13 17:33:06 +02:00
parent 61f0324e2d
commit 1e542c185c
14 changed files with 151 additions and 15 deletions

View file

@ -46,6 +46,9 @@ abstract class CrudController extends AdminController
protected function doNew(EntityInterface $entity, EntityManager $entityManager, Request $request, callable $beforeCreate = null): Response
{
$configuration = $this->getConfiguration();
$this->prepareEntity($entity);
$form = $this->createForm($configuration->getForm('new'), $entity);
if ($request->isMethod('POST')) {
@ -86,6 +89,9 @@ abstract class CrudController extends AdminController
protected function doEdit(EntityInterface $entity, EntityManager $entityManager, Request $request, callable $beforeUpdate = null): Response
{
$configuration = $this->getConfiguration();
$this->prepareEntity($entity);
$form = $this->createForm($configuration->getForm('edit'), $entity);
if ($request->isMethod('POST')) {
@ -181,4 +187,15 @@ abstract class CrudController extends AdminController
$session->set($form->getName(), $filters);
}
}
protected function prepareEntity(EntityInterface $entity)
{
$configuration = $this->getConfiguration();
if ($configuration->isI18n()) {
foreach ($configuration->getLocales() as $locale) {
$entity->addTranslation($entity->translate($locale, false));
}
}
}
}

View file

@ -19,6 +19,8 @@ class CrudConfiguration
protected array $viewDatas = [];
protected array $fields = [];
protected array $maxPerPage = [];
protected array $locales = [];
protected ?string $defaultLocale = null;
protected static $self;
@ -198,4 +200,29 @@ class CrudConfiguration
{
return $this->maxPerPage[$page] ?? $default;
}
/* -- */
public function setI18n(array $locales, string $defaultLocale): self
{
$this->locales = $locales;
$this->defaultLocale = $defaultLocale;
return $this;
}
public function getLocales(): array
{
return $this->locales;
}
public function getDefaultLocale(): ?string
{
return $this->defaultLocale;
}
public function isI18n(): bool
{
return !empty($this->locales);
}
}

View file

@ -2,8 +2,8 @@
namespace App\Core\Crud\Field;
use App\Core\Crud\Exception\CrudConfigurationException;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException;
use Symfony\Component\PropertyAccess\PropertyAccess;
use Twig\Environment;
@ -14,11 +14,11 @@ use Twig\Environment;
*/
abstract class Field
{
public function buildView(Environment $twig, $entity, array $options)
public function buildView(Environment $twig, $entity, array $options, ?string $locale = null)
{
return $twig->render($this->getView($options), [
'entity' => $entity,
'value' => $this->getValue($entity, $options),
'value' => $this->getValue($entity, $options, $locale),
'options' => $options,
]);
}
@ -43,12 +43,20 @@ abstract class Field
return $resolver;
}
protected function getValue($entity, array $options)
protected function getValue($entity, array $options, ?string $locale = null)
{
if (null !== $options['property']) {
$propertyAccessor = PropertyAccess::createPropertyAccessorBuilder()->getPropertyAccessor();
$value = $propertyAccessor->getValue($entity, $options['property']);
try {
$value = $propertyAccessor->getValue($entity, $options['property']);
} catch (NoSuchPropertyException $e) {
if (null !== $locale) {
$value = $propertyAccessor->getValue($entity->translate($locale), $options['property']);
} else {
throw $e;
}
}
} elseif (null !== $options['property_builder']) {
$value = call_user_func($options['property_builder'], $entity, $options);
} else {

View file

@ -0,0 +1,27 @@
<?php
namespace App\Core\Crud\Field;
use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* class ImageField.
*
* @author Simon Vieille <simon@deblan.fr>
*/
class ImageField extends Field
{
public function configureOptions(OptionsResolver $resolver): OptionsResolver
{
parent::configureOptions($resolver);
$resolver->setDefaults([
'view' => '@Core/admin/crud/field/image.html.twig',
'image_attr' => [],
]);
$resolver->setAllowedTypes('image_attr', ['array']);
return $resolver;
}
}

View file

@ -0,0 +1,20 @@
<?php
namespace App\Core\Manager;
use App\Core\Entity\EntityInterface;
/**
* class TranslatableEntityManager.
*
* @author Simon Vieille <simon@deblan.fr>
*/
class TranslatableEntityManager extends EntityManager
{
protected function persist(EntityInterface $entity)
{
$this->entityManager->persist($entity);
$entity->mergeNewTranslations();
$this->flush();
}
}

View file

@ -1,6 +1,12 @@
<div class="row">
<div class="col-md-12">
{{ form_widget(form) }}
{% for item in form %}
{% if configuration.isI18n and item.vars.name == 'translations' %}
{{ include(configuration.view('form_translations', '@Core/admin/crud/_form_translations.html.twig')) }}
{% else %}
{{ include(configuration.view('form_widget', '@Core/admin/crud/_form_widget.html.twig')) }}
{% endif %}
{% endfor %}
</div>
</div>

View file

@ -0,0 +1,21 @@
<ul class="nav nav-pills mt-3 mb-3 p-0">
{% for locale in configuration.locales %}
<li class="nav-item">
<a class="nav-link {% if loop.first %}active{% endif %}" data-toggle="tab" href="#form-locale-{{ loop.index }}">
<span class="flag-icon flag-icon-{{ locale }}"></span>
{{ locale|upper|trans }}
</a>
</li>
{% endfor %}
</ul>
<div class="tab-content">
{% for locale in configuration.locales %}
<div class="tab-pane {% if loop.first %}show active{% endif %}" id="form-locale-{{ loop.index }}">
{% for item in item.children[locale] %}
{{ include(configuration.view('form_widget', '@Core/admin/crud/_form_widget.html.twig')) }}
{% endfor %}
</div>
{% endfor %}
</div>

View file

@ -0,0 +1 @@
{{ form_row(item) }}

View file

@ -70,7 +70,7 @@
<div class="tab-content">
<div class="tab-pane active">
<div class="tab-form">
{{ include(configuration.view('editForm', '@Core/admin/crud/_form.html.twig')) }}
{{ include(configuration.view('form', '@Core/admin/crud/_form.html.twig')) }}
</div>
</div>
</div>

View file

@ -0,0 +1 @@
<img {% for k, v in options.image_attr %}{{ k }}="{{ v }}"{% endfor %} src="{{ asset(value) }}">

View file

@ -65,7 +65,15 @@
<tbody>
{% for item in pager %}
{% block list_item %}
<tr data-dblclick="">
{%- set dbClick %}
{% if configuration.action('index', 'show', true) %}
{{ path(configuration.pageRoute('show'), {entity: item.id}) }}
{% elseif configuration.action('index', 'edit', true) %}
{{ path(configuration.pageRoute('edit'), {entity: item.id}) }}
{% endif %}
{% endset -%}
<tr data-dblclick="{{ dbClick }}">
{% for config in configuration.fields('index') %}
{% set attr = config.options.attr is defined ? config.options.attr : [] %}
{% set action = config.options.action is defined ? config.options.action : null %}
@ -73,14 +81,14 @@
<td {% for key, value in attr %}{{ key }}="{{ value }}"{% endfor %}>
{% if action == 'show' %}
<a href="{{ path(configuration.pageRoute('show'), {entity: item.id}) }}">
{{ render_field(item, config) }}
{{ render_field(item, config, configuration.defaultLocale) }}
</a>
{% elseif action == 'edit' %}
<a href="{{ path(configuration.pageRoute('edit'), {entity: item.id}) }}">
{{ render_field(item, config) }}
{{ render_field(item, config, configuration.defaultLocale) }}
</a>
{% else %}
{{ render_field(item, config) }}
{{ render_field(item, config, configuration.defaultLocale) }}
{% endif %}
</td>
{% endfor %}

View file

@ -36,7 +36,7 @@
<div class="tab-content">
<div class="tab-pane active">
<div class="tab-form">
{{ include(configuration.view('newForm', '@Core/admin/crud/_form.html.twig')) }}
{{ include(configuration.view('form', '@Core/admin/crud/_form.html.twig')) }}
</div>
</div>
</div>

View file

@ -37,7 +37,7 @@
{% block show %}
<div class="row">
<div class="col-md-12">
{{ include(configuration.view('showEntity', '@Core/admin/crud/_show.html.twig')) }}
{{ include(configuration.view('show_entity', '@Core/admin/crud/_show.html.twig')) }}
</div>
</div>
{% endblock %}

View file

@ -33,12 +33,12 @@ class CrudExtension extends AbstractExtension
];
}
public function renderField($entity, array $config): string
public function renderField($entity, array $config, ?string $locale = null): string
{
$field = $config['field'];
$instance = new $field();
$resolver = $instance->configureOptions(new OptionsResolver());
return $instance->buildView($this->twig, $entity, $resolver->resolve($config['options']));
return $instance->buildView($this->twig, $entity, $resolver->resolve($config['options']), $locale);
}
}