backports murph-skeleton
This commit is contained in:
parent
61f0324e2d
commit
1e542c185c
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
27
core/Crud/Field/ImageField.php
Normal file
27
core/Crud/Field/ImageField.php
Normal 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;
|
||||
}
|
||||
}
|
20
core/Manager/TranslatableEntityManager.php
Normal file
20
core/Manager/TranslatableEntityManager.php
Normal 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();
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
|
||||
|
|
21
core/Resources/views/admin/crud/_form_translations.html.twig
Normal file
21
core/Resources/views/admin/crud/_form_translations.html.twig
Normal 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>
|
1
core/Resources/views/admin/crud/_form_widget.html.twig
Normal file
1
core/Resources/views/admin/crud/_form_widget.html.twig
Normal file
|
@ -0,0 +1 @@
|
|||
{{ form_row(item) }}
|
|
@ -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>
|
||||
|
|
1
core/Resources/views/admin/crud/field/image.html.twig
Normal file
1
core/Resources/views/admin/crud/field/image.html.twig
Normal file
|
@ -0,0 +1 @@
|
|||
<img {% for k, v in options.image_attr %}{{ k }}="{{ v }}"{% endfor %} src="{{ asset(value) }}">
|
|
@ -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 %}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 %}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue