@@ -7,8 +7,16 @@ use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; | |||
use EasyCorp\Bundle\EasyAdminBundle\Config\Assets; | |||
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; | |||
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController as EaAbstractCrudController; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\FormField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator; | |||
use Lc\SovBundle\Doctrine\Extension\DevAliasInterface; | |||
use Lc\SovBundle\Doctrine\Extension\SeoInterface; | |||
use Lc\SovBundle\Doctrine\Extension\TranslatableInterface; | |||
use Lc\SovBundle\Field\GalleryManagerField; | |||
use Lc\SovBundle\Field\ImageManagerField; | |||
use Lc\SovBundle\Field\StatusField; | |||
use Symfony\Component\HttpFoundation\RequestStack; | |||
use Symfony\Component\HttpFoundation\Session\SessionInterface; | |||
@@ -71,14 +79,14 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
'class' => 'btn btn-outline-danger action-delete', | |||
], | |||
Action::SAVE_AND_RETURN => $actionSaveAndReturn, | |||
Action::INDEX=>$actionIndex | |||
Action::INDEX => $actionIndex, | |||
]; | |||
$actionsArray[Crud::PAGE_NEW] = [ | |||
Action::SAVE_AND_ADD_ANOTHER => [ | |||
'class' => 'btn btn-info float-right', | |||
], | |||
Action::SAVE_AND_RETURN => $actionSaveAndReturn, | |||
Action::INDEX=>$actionIndex | |||
Action::INDEX => $actionIndex, | |||
]; | |||
$actions->add(Crud::PAGE_EDIT, Action::INDEX); | |||
@@ -144,4 +152,26 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
$crud->setPaginatorPageSize($maxResults); | |||
} | |||
public function configureFields(string $pageName): iterable | |||
{ | |||
if (in_array(SeoInterface::class, class_implements($this->getEntityFqcn()))) { | |||
$seoPanel = [ | |||
FormField::addPanel('Seo'), | |||
TextareaField::new('metaTitle')->setLabel('Meta Title')->setHelp('Affiché dans les résultats de recherche Google'), | |||
TextareaField::new('metaDescription')->setLabel('Meta description')->setHelp('Affiché dans les résultats de recherche Google'), | |||
]; | |||
} | |||
if (in_array(DevAliasInterface::class, class_implements($this->getEntityFqcn()))) { | |||
$confPanel = [ | |||
FormField::addPanel('Conf'), | |||
TextField::new('devAlias') | |||
]; | |||
} | |||
return array_merge($seoPanel, $confPanel); | |||
} | |||
} |
@@ -0,0 +1,82 @@ | |||
<?php | |||
namespace Lc\SovBundle\Form\Type; | |||
use ArrayObject; | |||
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; | |||
use EasyCorp\Bundle\EasyAdminBundle\Dto\AssetsDto; | |||
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto; | |||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\FormField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Form\EventListener\EasyAdminTabSubscriber; | |||
use EasyCorp\Bundle\EasyAdminBundle\Form\Type\EaFormPanelType; | |||
use Symfony\Bridge\Doctrine\Form\DoctrineOrmTypeGuesser; | |||
use Symfony\Component\Form\AbstractType; | |||
use Symfony\Component\Form\FormBuilderInterface; | |||
use Symfony\Component\Form\FormInterface; | |||
use Symfony\Component\Form\FormView; | |||
use Symfony\Component\OptionsResolver\Options; | |||
use Symfony\Component\OptionsResolver\OptionsResolver; | |||
/** | |||
* Custom form type that deals with some of the logic used to render the | |||
* forms used to create and edit EasyAdmin entities. | |||
* | |||
* @author Maxime Steinhausser <maxime.steinhausser@gmail.com> | |||
*/ | |||
class CrudFormType extends AbstractType | |||
{ | |||
protected $parent; | |||
protected $doctrineOrmTypeGuesser; | |||
public function __construct(DoctrineOrmTypeGuesser $doctrineOrmTypeGuesser, \EasyCorp\Bundle\EasyAdminBundle\Form\Type\CrudFormType $crudFormType) | |||
{ | |||
$this->parent = $crudFormType; | |||
$this->doctrineOrmTypeGuesser = $doctrineOrmTypeGuesser; | |||
} | |||
public function buildForm(FormBuilderInterface $builder, array $options) | |||
{ | |||
$this->parent->buildForm($builder, $options); | |||
$entityDto = $options['entityDto']; | |||
$currentFormPanel = 0; | |||
foreach ($entityDto->getFields() as $fieldDto) { | |||
if (null === $formFieldType = $fieldDto->getFormType()) { | |||
$guessType = $this->doctrineOrmTypeGuesser->guessType($entityDto->getFqcn(), $fieldDto->getProperty()); | |||
$formFieldType = $guessType->getType(); | |||
$formFieldOptions = array_merge($guessType->getOptions(), $formFieldOptions); | |||
} | |||
if (EaFormPanelType::class === $formFieldType) { | |||
++$currentFormPanel; | |||
$formPanels[$currentFormPanel] = [ | |||
'form_tab' => $currentFormTab ?? null, | |||
'label' => $fieldDto->getLabel(), | |||
'help' => $fieldDto->getHelp(), | |||
'css_class' => $fieldDto->getCssClass(), | |||
]; | |||
foreach($fieldDto->getCustomOptions()->all() as $customOptionKey=> $customOption){ | |||
$formPanels[$currentFormPanel][$customOptionKey] = $customOption; | |||
} | |||
continue; | |||
} | |||
} | |||
$builder->setAttribute('ea_form_panels', $formPanels); | |||
//$this->niche->buildForm($builder, $options); | |||
} | |||
public function finishView(FormView $view, FormInterface $form, array $options){ | |||
$this->parent->finishView($view, $form, $options); | |||
} | |||
public function configureOptions(OptionsResolver $resolver){ | |||
$this->parent->configureOptions($resolver); | |||
} | |||
public function getBlockPrefix(){ | |||
return $this->parent->getBlockPrefix(); | |||
} | |||
} |
@@ -0,0 +1,24 @@ | |||
services: | |||
_defaults: | |||
autowire: true # Automatically injects dependencies in your services. | |||
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. | |||
Lc\SovBundle\: | |||
resource: '../../' | |||
exclude: | |||
- '../../DependencyInjection/' | |||
- '../../Entity/' | |||
- '../../Kernel.php' | |||
- '../../Tests/' | |||
Lc\SovBundle\Controller\: | |||
resource: '../../Controller/' | |||
tags: [ 'controller.service_arguments' ] | |||
Lc\SovBundle\Form\Type\CrudFormType: | |||
decorates: EasyCorp\Bundle\EasyAdminBundle\Form\Type\CrudFormType | |||
arguments: ['@form.type_guesser.doctrine', '@.inner'] | |||
# EasyCorp\Bundle\EasyAdminBundle\Form\Type\CrudFormType: | |||
# class: Lc\SovBundle\Form\Type\CrudFormType |
@@ -37,23 +37,13 @@ | |||
{% block page_actions_wrapper %} | |||
{% endblock page_actions_wrapper %} | |||
{% block main %} | |||
<div class="col-8"> | |||
<div class="card"> | |||
<div class="card-status-top bg-primary"></div> | |||
<div class="card-header "> | |||
{% set default_title = ea.crud.defaultPageTitle('new')|trans(ea.i18n.translationParameters, 'EasyAdminBundle') %} | |||
<h2 class="card-title">{{ ea.crud.customPageTitle is null ? default_title|raw : ea.crud.customPageTitle('new')|trans(ea.i18n.translationParameters)|raw }}</h2> | |||
</div> | |||
<div class="card-body"> | |||
{% block form %} | |||
{{ form(form) }} | |||
{% endblock form %} | |||
</div> | |||
</div> | |||
<div class="clearfix"></div> | |||
{% block form %} | |||
{{ form(form) }} | |||
{% endblock form %} | |||
</div> | |||
{% block form_footer %} |
@@ -0,0 +1,5 @@ | |||
MON GARS c'est de la balle !!! | |||
NICHE | |||
{{form_row(form.title)}} | |||
{{form_row(form.description)}} |
@@ -79,18 +79,21 @@ | |||
<div class="input-group"> | |||
<div class="input-group-prepend"> | |||
{% if form.parent.vars['row_attr']['data-sortable'] is defined %} | |||
<button type="button" class="btn btn-success lc-btn-sortable" data-toggle="tooltip" title="Trier les images"> | |||
<button type="button" class="btn btn-success lc-btn-sortable" data-toggle="tooltip" | |||
title="Trier les images"> | |||
<i class="fa fa-arrows-alt"></i> | |||
</button> | |||
{% endif %} | |||
<button type="button" class="btn btn-primary lc-filemanager-open" data-id="{{ form.path.vars.id }}" data-toggle="tooltip" title="Sélectionner un fichier" | |||
<button type="button" class="btn btn-primary lc-filemanager-open" data-id="{{ form.path.vars.id }}" | |||
data-toggle="tooltip" title="Sélectionner un fichier" | |||
data-target="{{ path('file_manager', {module:1, conf:'default'})|raw }}"> | |||
<i class="fa fa-folder-open"></i> | |||
</button> | |||
</div> | |||
{{ form_widget(form.legend) }} | |||
<div class="input-group-append"> | |||
<button type="button" class="btn btn-danger lc-filemanager-delete" data-toggle="tooltip" title="Supprimer l'image" | |||
<button type="button" class="btn btn-danger lc-filemanager-delete" data-toggle="tooltip" | |||
title="Supprimer l'image" | |||
data-id="{{ form.path.vars.id }}"> | |||
<i class="fa fa-trash"></i> | |||
</button> | |||
@@ -104,7 +107,7 @@ | |||
{% endblock file_manager_widget %} | |||
{% block checkbox_radio_label -%} | |||
{#- Do not display the label if widget is not defined in order to prevent double label rendering -#} | |||
{#- Do not display the label if widget is not defined in order to prevent double label rendering -#} | |||
{%- if widget is defined -%} | |||
{% set is_parent_custom = parent_label_class is defined and ('checkbox-custom' in parent_label_class or 'radio-custom' in parent_label_class or 'switch-custom' in parent_label_class) %} | |||
{% set is_custom = label_attr.class is defined and ('checkbox-custom' in label_attr.class or 'radio-custom' in label_attr.class or 'switch-custom' in label_attr.class) %} | |||
@@ -138,12 +141,104 @@ | |||
{{ widget|raw }} | |||
<span class="checkmark"></span> | |||
{# {% if translation_domain == 'lcshop' %} | |||
{# {% if translation_domain == 'lcshop' %} | |||
{{ name|lc_trad(easyadmin['entity']['name'], 'field') }} | |||
{% else %}#} | |||
{% else %} #} | |||
{{- label is not same as(false) ? (translation_domain is same as(false) ? label : label|trans(label_translation_parameters, translation_domain))|raw -}} | |||
{#{% endif %}#} | |||
{# {% endif %} #} | |||
{{- form_errors(form) -}} | |||
</label> | |||
{%- endif -%} | |||
{%- endblock checkbox_radio_label %} | |||
{% use 'bootstrap_4_layout.html.twig' %} | |||
{% block form_start %} | |||
{{ parent() }} | |||
<div class="card card-outline"> | |||
<div class="card-header p-0 border-bottom-0"> | |||
<ul id="nav-params" class="nav nav-pills" role="navigation"> | |||
{% for panel_name, panel_config in ea_crud_form.form_panels|filter(panel_config => not panel_config.form_tab or panel_config.form_tab == tab_name) %} | |||
{% set panel_has_header = panel_config.label|default(false) or panel_config.icon|default(false) %} | |||
<li class="nav-item"> | |||
<a href="#panel-{{ panel_name }} " class="nav-link {{ panel_name == 1 ? 'active' }}" data-toggle="tab" role="tab" | |||
aria-controls="panel-{{ panel_name }}"> | |||
{{ panel_config.label|raw }} | |||
<i class="fa fa-exclamation-circle invalid-form"></i> | |||
</a> | |||
</li> | |||
{% endfor %} | |||
</ul> | |||
</div> | |||
</div> | |||
{% endblock form_start %} | |||
{% block ea_crud_widget_panels %} | |||
<div class="tab-content"> | |||
{% for panel_name, panel_config in ea_crud_form.form_panels|filter(panel_config => not panel_config.form_tab or panel_config.form_tab == tab_name) %} | |||
{% set panel_has_header = panel_config.label|default(false) or panel_config.icon|default(false) %} | |||
{% set collapsible = panel_config.collapsible %} | |||
{% set collapsed = panel_config.collapsed %} | |||
<div class="tab-pane {{ panel_name == 1 ? 'active' }}" id="panel-{{ panel_name }}" | |||
aria-labelledby="{{ panel_name }}-tab"> | |||
{% if panel_config.template is defined and panel_config.template is not null %} | |||
{% include panel_config.template %} | |||
{% else %} | |||
<div class="card {{ panel_config.css_class ?? '' }}"> | |||
<div class="card-status-top bg-primary"></div> | |||
<div class="card-header "> | |||
{% if panel_has_header %} | |||
{# <div class="content-panel-header {{ collapsible ? 'collapsible' }} {{ panel_config.help|default(false) is not empty ? 'with-help' }}"> #} | |||
{% if collapsible %} | |||
<a href="#content-{{ panel_name }}" data-toggle="collapse" class="content-panel-collapse {{ collapsed ? 'collapsed' }}" aria-expanded="{{ collapsed ? 'false' : 'true' }}" aria-controls="content-{{ panel_name }}"> | |||
<i class="fas fw fa-chevron-right collapse-icon"></i> | |||
{% endif %} | |||
{% if panel_config.icon|default(false) %} | |||
<i class="{{ panel_config.icon }}"></i> | |||
{% endif %} | |||
{{ panel_config.label|raw }} | |||
{% if collapsible %} | |||
</a> | |||
{% endif %} | |||
{% if panel_config.help|default(false) %} | |||
<div class="content-panel-header-help">{{ panel_config.help|raw }}</div> | |||
{% endif %} | |||
{% endif %} | |||
</div> | |||
<div class="card-body {{ collapsible ? 'collapse' }} {{ not collapsed ? 'show' }}"> | |||
{% for field in form|filter(field => 'hidden' not in field.vars.block_prefixes and field.vars.ea_crud_form.form_panel == panel_name) %} | |||
{% if not field.vars.ea_crud_form.form_tab or field.vars.ea_crud_form.form_tab == tab_name %} | |||
{{ form_row(field) }} | |||
{% endif %} | |||
{% endfor %} | |||
</div> | |||
</div> | |||
{% endif %} | |||
</div> | |||
{% else %} | |||
<div class="card"> | |||
<div class="card-status-top bg-primary"></div> | |||
<div class="card-header "></div> | |||
<div class="card-body"> | |||
{% for field in form|filter(field => 'hidden' not in field.vars.block_prefixes and (not field.vars.ea_crud_form.form_tab or field.vars.ea_crud_form.form_tab == tab_name)) %} | |||
{{ form_row(field) }} | |||
{% endfor %} | |||
</div> | |||
</div> | |||
{% endfor %} | |||
</div> | |||
{% endblock ea_crud_widget_panels %} |