Browse Source

Merge branch 'develop' of https://forge.laclic.fr/Laclic/SovBundle into develop

develop
Fabien Normand 3 years ago
parent
commit
1bba18aa27
21 changed files with 300 additions and 215 deletions
  1. +42
    -78
      Authenticator/LoginFormAuthenticator.php
  2. +32
    -2
      Controller/AbstractAdminController.php
  3. +13
    -1
      Controller/AbstractController.php
  4. +2
    -2
      Controller/Reminder/ReminderAdminController.php
  5. +41
    -36
      Controller/Security/SecurityAdminController.php
  6. +2
    -2
      Controller/Setting/SettingAdminController.php
  7. +2
    -2
      Controller/User/AccountAdminController.php
  8. +0
    -50
      EventSubscriber/FlashMessageAdminEventSubscriber.php
  9. +1
    -1
      Field/Filter/CheckboxFilter.php
  10. +11
    -3
      Form/Common/CrudFormType.php
  11. +1
    -1
      Notification/MailMailjetNotification.php
  12. +1
    -3
      Resources/config/services.yaml
  13. +1
    -1
      Resources/views/adminlte/crud/detail.html.twig
  14. +6
    -6
      Resources/views/adminlte/crud/form.html.twig
  15. +15
    -4
      Resources/views/adminlte/crud/form_theme.html.twig
  16. +12
    -3
      Resources/views/adminlte/crud/index.html.twig
  17. +22
    -0
      Session/Flash/FlashBag.php
  18. +44
    -0
      Translation/FlashBagTranslator.php
  19. +45
    -19
      Translation/TranslatorAdmin.php
  20. +6
    -0
      Twig/TranslatorTwigExtension.php
  21. +1
    -1
      Twig/TwigExtension.php

+ 42
- 78
Authenticator/LoginFormAuthenticator.php View File



namespace Lc\SovBundle\Authenticator; namespace Lc\SovBundle\Authenticator;


use Lc\SovBundle\Model\User\UserInterface;
use Lc\SovBundle\Doctrine\EntityManager;
use Lc\SovBundle\Repository\User\UserStore;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\User\UserInterface as SfUserInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
use Symfony\Component\Security\Guard\PasswordAuthenticatedInterface;
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface;
use Symfony\Component\Security\Http\Util\TargetPathTrait; use Symfony\Component\Security\Http\Util\TargetPathTrait;


class LoginFormAuthenticator extends AbstractFormLoginAuthenticator implements PasswordAuthenticatedInterface
class LoginFormAuthenticator extends AbstractLoginFormAuthenticator
{ {
use TargetPathTrait; use TargetPathTrait;


public const LOGIN_ROUTE = 'sov_login'; public const LOGIN_ROUTE = 'sov_login';


private $entityManager;
private $urlGenerator;
private $csrfTokenManager;
private $passwordEncoder;
protected $parameterBag;
protected UrlGeneratorInterface $urlGenerator;
protected UserStore $userStore;
protected FormFactoryInterface $formFactory;
protected ParameterBagInterface $parameterBag;


public function __construct( public function __construct(
EntityManager $entityManager,
UrlGeneratorInterface $urlGenerator,
CsrfTokenManagerInterface $csrfTokenManager,
UserPasswordEncoderInterface $passwordEncoder,
ParameterBagInterface $parameterBag
)
{
$this->entityManager = $entityManager;
UrlGeneratorInterface $urlGenerator,
UserStore $userStore,
FormFactoryInterface $formFactory,
ParameterBagInterface $parameterBag
) {
$this->urlGenerator = $urlGenerator; $this->urlGenerator = $urlGenerator;
$this->csrfTokenManager = $csrfTokenManager;
$this->passwordEncoder = $passwordEncoder;
$this->userStore = $userStore;
$this->formFactory = $formFactory;
$this->parameterBag = $parameterBag; $this->parameterBag = $parameterBag;
} }


public function supports(Request $request)
public function supports(Request $request): bool
{ {
return self::LOGIN_ROUTE === $request->attributes->get('_route')
&& $request->isMethod('POST');
return $request->isMethod('POST') && $this->getLoginUrl($request) === $request->getPathInfo();
} }


public function getCredentials(Request $request)
public function authenticate(Request $request): PassportInterface
{ {
$credentials = [
'email' => $request->request->get('email'),
'password' => $request->request->get('password'),
'csrf_token' => $request->request->get('_csrf_token'),
];
$request->getSession()->set(
Security::LAST_USERNAME,
$credentials['email']
$email = $request->request->get('email');
$password = $request->request->get('password');
$csrfToken = $request->request->get('_csrf_token');

return new Passport(
new UserBadge($email, function ($userIdentifier) {
return $this->userStore->getOneByEmail($userIdentifier);
}),
new PasswordCredentials($password),
[new CsrfTokenBadge('authenticate', $csrfToken)]
); );

return $credentials;
} }


public function getUser($credentials, UserProviderInterface $userProvider)
{
$token = new CsrfToken('authenticate', $credentials['csrf_token']);
if (!$this->csrfTokenManager->isTokenValid($token)) {
throw new InvalidCsrfTokenException();
}

$user = $this->entityManager->getRepository(UserInterface::class)->findOneBy(
['email' => $credentials['email']]
);

if (!$user) {
// fail authentication with a custom error
throw new CustomUserMessageAuthenticationException('Email could not be found.');
}

return $user;
}

public function checkCredentials($credentials, SfUserInterface $user)
{
return $this->passwordEncoder->isPasswordValid($user, $credentials['password']);
}

/**
* Used to upgrade (rehash) the user's password automatically over time.
*/
public function getPassword($credentials): ?string
{
return $credentials['password'];
}

public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey)
{
public function onAuthenticationSuccess(
Request $request,
TokenInterface $token,
string $providerKey
): RedirectResponse {
$routeName = 'home'; $routeName = 'home';
$email = $request->request->get('email'); $email = $request->request->get('email');
$loginRedirection = $this->parameterBag->get('lc_sov.login_redirection'); $loginRedirection = $this->parameterBag->get('lc_sov.login_redirection');
if (isset($useReferer) && $useReferer == true) { if (isset($useReferer) && $useReferer == true) {
$url = $request->request->get('_target_path'); $url = $request->request->get('_target_path');
} else { } else {
$user = $this->entityManager->getRepository(UserInterface::class)->findOneBy(['email' => $email]);
$user = $this->userStore->getOneByEmail($email);


if (!empty($user)) { if (!empty($user)) {
$roles = $user->getRoles(); $roles = $user->getRoles();
} }
} }


protected function getLoginUrl()
protected function getLoginUrl(Request $request): string
{ {
return $this->urlGenerator->generate(self::LOGIN_ROUTE); return $this->urlGenerator->generate(self::LOGIN_ROUTE);
} }
}
}

+ 32
- 2
Controller/AbstractAdminController.php View File

use Lc\SovBundle\Form\Common\FiltersFormType; use Lc\SovBundle\Form\Common\FiltersFormType;
use Lc\SovBundle\Form\Common\PositionType; use Lc\SovBundle\Form\Common\PositionType;
use Lc\SovBundle\Notification\MailMailjetNotification; use Lc\SovBundle\Notification\MailMailjetNotification;
use Lc\SovBundle\Translation\FlashBagTranslator;
use Lc\SovBundle\Translation\TranslatorAdmin; use Lc\SovBundle\Translation\TranslatorAdmin;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType; use Symfony\Component\Form\Extension\Core\Type\CollectionType;
parent::getSubscribedServices(), parent::getSubscribedServices(),
[ [
TranslatorAdmin::class => TranslatorAdmin::class, TranslatorAdmin::class => TranslatorAdmin::class,
FlashBagTranslator::class => FlashBagTranslator::class,
SessionInterface::class => SessionInterface::class, SessionInterface::class => SessionInterface::class,
RequestStack::class => RequestStack::class, RequestStack::class => RequestStack::class,
EntityManagerInterface::class => EntityManagerInterface::class, EntityManagerInterface::class => EntityManagerInterface::class,
$responseParameters->set('filters_form', $this->filtersForm); $responseParameters->set('filters_form', $this->filtersForm);
} }


$responseParameters->set('translation_entity_name', $this->getTranslationEntityName());

return $responseParameters; return $responseParameters;
} }


public function getTranslationEntityName()
{
return $this->getEntityFqcn();
}

public function overrideEntitiesActions(?EntityCollection $entities): void public function overrideEntitiesActions(?EntityCollection $entities): void
{ {
} }


$this->setMaxResults($crud); $this->setMaxResults($crud);


$crud->setFormOptions(['translation_entity_name' => $this->getTranslationEntityName()]);

if ($this->isInstanceOf(SortableInterface::class)) { if ($this->isInstanceOf(SortableInterface::class)) {
$crud->setDefaultSort(['position' => 'ASC']); $crud->setDefaultSort(['position' => 'ASC']);
} }
return $crud; return $crud;
} }


public function addFlashTranslator(string $type, $translationKeyName, $translationEntityName = null, $translationParam = array()):void
{
if ($translationEntityName === null && method_exists($this, 'getTranslationEntityName')) {
$translationEntityName = $this->getTranslationEntityName();
}
$this->get(FlashBagTranslator::class)->add($type, $translationKeyName, $translationEntityName, $translationParam);
}

public function setMaxResults(Crud $crud): void public function setMaxResults(Crud $crud): void
{ {
$entityClass = $this->getEntityFqcn(); $entityClass = $this->getEntityFqcn();
$url = $this->get(AdminUrlGenerator::class) $url = $this->get(AdminUrlGenerator::class)
->setAction(Action::INDEX) ->setAction(Action::INDEX)
->generateUrl(); ->generateUrl();
$this->addFlash('success', $this->get(TranslatorAdmin::class)->transFlashMessage('sort'), array());
$this->addFlashTranslator('success', 'sorted');


return $this->redirect($url); return $this->redirect($url);
} }
->setEntityId($newEntity->getId()) ->setEntityId($newEntity->getId())
->generateUrl(); ->generateUrl();


$this->addFlash('success', $translatorAdmin->transFlashMessage('duplicate'), array());
$this->addFlashTranslator('success', 'duplicated');


return $this->redirect($url); return $this->redirect($url);
} }
{ {
$entityManager->update($entityInstance); $entityManager->update($entityInstance);
$entityManager->flush(); $entityManager->flush();
$this->get(FlashBagTranslator::class)->add('success', 'updated', $this->getTranslationEntityName());
} }


public function persistEntity(EntityManagerInterface $entityManager, $entityInstance): void public function persistEntity(EntityManagerInterface $entityManager, $entityInstance): void
{ {
$entityManager->create($entityInstance); $entityManager->create($entityInstance);
$entityManager->flush(); $entityManager->flush();
$this->get(FlashBagTranslator::class)->add('success', 'created', $this->getTranslationEntityName());
} }


public function deleteEntity(EntityManagerInterface $entityManager, $entityInstance): void
{
$entityManager->delete($entityInstance);
$entityManager->flush();
$this->get(FlashBagTranslator::class)->add('success', 'deleted', $this->getTranslationEntityName());

}




public function configureActions(Actions $actions): Actions public function configureActions(Actions $actions): Actions
{ {

+ 13
- 1
Controller/AbstractController.php View File

use Lc\SovBundle\Container\User\GroupUserContainer; use Lc\SovBundle\Container\User\GroupUserContainer;
use Lc\SovBundle\Container\User\UserContainer; use Lc\SovBundle\Container\User\UserContainer;
use Lc\SovBundle\Solver\Setting\SettingSolver; use Lc\SovBundle\Solver\Setting\SettingSolver;
use Lc\SovBundle\Translation\FlashBagTranslator;
use Lc\SovBundle\Translation\TranslatorAdmin; use Lc\SovBundle\Translation\TranslatorAdmin;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController as SfAbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController as SfAbstractController;
LoggerInterface::class => LoggerInterface::class, LoggerInterface::class => LoggerInterface::class,
TranslatorInterface::class => TranslatorInterface::class, TranslatorInterface::class => TranslatorInterface::class,
TranslatorAdmin::class => TranslatorAdmin::class, TranslatorAdmin::class => TranslatorAdmin::class,
FlashBagTranslator::class => FlashBagTranslator::class,
SettingSolver::class => SettingSolver::class, SettingSolver::class => SettingSolver::class,
ComponentContainer::class => ComponentContainer::class, ComponentContainer::class => ComponentContainer::class,
FileContainer::class => FileContainer::class, FileContainer::class => FileContainer::class,
); );
} }



public function addFlashTranslator(string $type, $translationKeyName, $translationEntityName = null, $translationParam = array()):void
{
if ($translationEntityName === null && method_exists($this, 'getTranslationEntityName')) {
$translationEntityName = $this->getTranslationEntityName();
}
$this->get(FlashBagTranslator::class)->add($type, $translationKeyName, $translationEntityName, $translationParam);
}


public function getReferer(Request $request): ?string public function getReferer(Request $request): ?string
{ {
return $request->headers->get('referer'); return $request->headers->get('referer');
{ {
return $this->get(SiteSettingContainer::class); return $this->get(SiteSettingContainer::class);
} }
}
}

+ 2
- 2
Controller/Reminder/ReminderAdminController.php View File

$this->entityManager->persist($reminder); $this->entityManager->persist($reminder);
$this->entityManager->flush(); $this->entityManager->flush();


$this->addFlash('success', 'Le pense-bête a bien été ajouté');
$this->addFlashTranslator('success', 'added');
} }


return $this->redirect($request->headers->get('referer')); return $this->redirect($request->headers->get('referer'));
$this->entityManager->update($reminder); $this->entityManager->update($reminder);
$this->entityManager->flush(); $this->entityManager->flush();


$this->addFlash('success', 'Le pense-bête a bien été mis à jour');
$this->addFlashTranslator('success', 'updated');
} }


return $this->redirect($request->headers->get('referer')); return $this->redirect($request->headers->get('referer'));

+ 41
- 36
Controller/Security/SecurityAdminController.php View File

namespace Lc\SovBundle\Controller\Security; namespace Lc\SovBundle\Controller\Security;


use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils; use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class SecurityAdminController extends AbstractController class SecurityAdminController extends AbstractController
{ {
/** /**
* @Route("/user/login", name="sov_login")
* @Route("/login", name="sov_login")
*/ */
public function login(AuthenticationUtils $authenticationUtils): Response
public function login(AuthenticationUtils $authenticationUtils, Request $request): Response
{ {
if ($this->getUser()) {
return $this->redirectToRoute('app_admin_dashboard');
}
dump($request);

if ($this->getUser()) {
return $this->redirectToRoute('app_admin_dashboard');
}


// get the login error if there is one // get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError(); $error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user // last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername(); $lastUsername = $authenticationUtils->getLastUsername();


return $this->render('@EasyAdmin/page/login.html.twig', [
// parameters usually defined in Symfony login forms
'error' => $error,
'last_username' => $lastUsername,
return $this->render('@EasyAdmin/page/login.html.twig', [
// parameters usually defined in Symfony login forms
'error' => $error,
'last_username' => $lastUsername,


// OPTIONAL parameters to customize the login form:
// OPTIONAL parameters to customize the login form:


// the translation_domain to use (define this option only if you are
// rendering the login template in a regular Symfony controller; when
// rendering it from an EasyAdmin Dashboard this is automatically set to
// the same domain as the rest of the Dashboard)
'translation_domain' => 'admin',
// the translation_domain to use (define this option only if you are
// rendering the login template in a regular Symfony controller; when
// rendering it from an EasyAdmin Dashboard this is automatically set to
// the same domain as the rest of the Dashboard)
'translation_domain' => 'admin',


// the title visible above the login form (define this option only if you are
// rendering the login template in a regular Symfony controller; when rendering
// it from an EasyAdmin Dashboard this is automatically set as the Dashboard title)
'page_title' => '<img src="assets/img/'.$this->get('parameter_bag')->get('app.admin.logo').'" >',
// the title visible above the login form (define this option only if you are
// rendering the login template in a regular Symfony controller; when rendering
// it from an EasyAdmin Dashboard this is automatically set as the Dashboard title)
'page_title' => '<img src="assets/img/' . $this->get('parameter_bag')->get('app.admin.logo') . '" >',


// the string used to generate the CSRF token. If you don't define
// this parameter, the login form won't include a CSRF token
'csrf_token_intention' => 'authenticate',
// the string used to generate the CSRF token. If you don't define
// this parameter, the login form won't include a CSRF token
'csrf_token_intention' => 'authenticate',


// the URL users are redirected to after the login (default: '/admin')
'target_path' => $this->generateUrl('app_admin_dashboard'),
// the URL users are redirected to after the login (default: '/admin')
'target_path' => $this->generateUrl('app_admin_dashboard'),


// the label displayed for the username form field (the |trans filter is applied to it)
'username_label' => 'Your username',
// the label displayed for the username form field (the |trans filter is applied to it)
'username_label' => 'Your username',


// the label displayed for the password form field (the |trans filter is applied to it)
'password_label' => 'Your password',
// the label displayed for the password form field (the |trans filter is applied to it)
'password_label' => 'Your password',


// the label displayed for the Sign In form button (the |trans filter is applied to it)
'sign_in_label' => 'Log in',
// the label displayed for the Sign In form button (the |trans filter is applied to it)
'sign_in_label' => 'Log in',


// the 'name' HTML attribute of the <input> used for the username field (default: '_username')
'username_parameter' => 'email',
// the 'name' HTML attribute of the <input> used for the username field (default: '_username')
'username_parameter' => 'email',


// the 'name' HTML attribute of the <input> used for the password field (default: '_password')
'password_parameter' => 'password',
]);
// the 'name' HTML attribute of the <input> used for the password field (default: '_password')
'password_parameter' => 'password',
]);
} }


/** /**
*/ */
public function logout() public function logout()
{ {
throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
throw new \LogicException(
'This method can be blank - it will be intercepted by the logout key on your firewall.'
);
} }
} }

+ 2
- 2
Controller/Setting/SettingAdminController.php View File

$entityManager->update($site); $entityManager->update($site);
$entityManager->flush(); $entityManager->flush();


$this->addFlash('success', $this->getTranslatorAdmin()->transFlashMessage('settings_saved'));
$this->addFlashTranslator('success', 'updated');
} }


return $this->render( return $this->render(
); );
} }


}
}

+ 2
- 2
Controller/User/AccountAdminController.php View File

$this->entityManager->update($user); $this->entityManager->update($user);
$this->entityManager->flush(); $this->entityManager->flush();


$this->addFlash('success', new TranslatableMessage('form.account_profile.message.success', [], 'admin'));
$this->addFlashTranslator('success', 'updated');
} }


return $this->render( return $this->render(
$this->entityManager->update($user); $this->entityManager->update($user);
$this->entityManager->flush(); $this->entityManager->flush();


$this->addFlash('success', new TranslatableMessage('form.account_password.message.success', [], 'admin'));
$this->addFlashTranslator('success', 'passwordUpdated');
} }


return $this->render( return $this->render(

+ 0
- 50
EventSubscriber/FlashMessageAdminEventSubscriber.php View File

<?php

namespace Lc\SovBundle\EventSubscriber;

use EasyCorp\Bundle\EasyAdminBundle\Event\AfterEntityDeletedEvent;
use EasyCorp\Bundle\EasyAdminBundle\Event\AfterEntityPersistedEvent;
use EasyCorp\Bundle\EasyAdminBundle\Event\AfterEntityUpdatedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Translation\TranslatableMessage;

class FlashMessageAdminEventSubscriber implements EventSubscriberInterface
{
protected $session ;

public function __construct(SessionInterface $session)
{
$this->session = $session ;
}

public static function getSubscribedEvents(): array
{
return [
AfterEntityPersistedEvent::class => ['flashMessageAfterPersist'],
AfterEntityUpdatedEvent::class => ['flashMessageAfterUpdate'],
AfterEntityDeletedEvent::class => ['flashMessageAfterDelete'],
];
}

public function flashMessageAfterPersist(AfterEntityPersistedEvent $event): void
{
$this->session->getFlashBag()->add('success', new TranslatableMessage('flash_message.create', [
'%name%' => (string) $event->getEntityInstance(),
]));
}

public function flashMessageAfterUpdate(AfterEntityUpdatedEvent $event): void
{
$this->session->getFlashBag()->add('success', new TranslatableMessage('flash_message.update', [
'%name%' => (string) $event->getEntityInstance(),
]));
}

public function flashMessageAfterDelete(AfterEntityDeletedEvent $event): void
{
$this->session->getFlashBag()->add('success', new TranslatableMessage('flash_message.delete', [
'%name%' => (string) $event->getEntityInstance(),
]));
}
}

+ 1
- 1
Field/Filter/CheckboxFilter.php View File

); );
$queryBuilder->setParameter($fieldProperty, '%'.$filteredValue.'%'); $queryBuilder->setParameter($fieldProperty, '%'.$filteredValue.'%');
} }
dump($queryBuilder);
} }
} }



+ 11
- 3
Form/Common/CrudFormType.php View File

use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView; use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;


/** /**
DoctrineOrmTypeGuesser $doctrineOrmTypeGuesser, DoctrineOrmTypeGuesser $doctrineOrmTypeGuesser,
\EasyCorp\Bundle\EasyAdminBundle\Form\Type\CrudFormType $crudFormType \EasyCorp\Bundle\EasyAdminBundle\Form\Type\CrudFormType $crudFormType
) { ) {

$this->parent = $crudFormType; $this->parent = $crudFormType;
$this->doctrineOrmTypeGuesser = $doctrineOrmTypeGuesser; $this->doctrineOrmTypeGuesser = $doctrineOrmTypeGuesser;
} }


public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options)
{ {

$this->parent->buildForm($builder, $options); $this->parent->buildForm($builder, $options);
$entityDto = $options['entityDto']; $entityDto = $options['entityDto'];
$formPanels = []; $formPanels = [];
$currentFormPanel = 0; $currentFormPanel = 0;
foreach ($entityDto->getFields() as $fieldDto) { foreach ($entityDto->getFields() as $fieldDto) {

if (null === $formFieldType = $fieldDto->getFormType()) { if (null === $formFieldType = $fieldDto->getFormType()) {
$guessType = $this->doctrineOrmTypeGuesser->guessType($entityDto->getFqcn(), $fieldDto->getProperty()); $guessType = $this->doctrineOrmTypeGuesser->guessType($entityDto->getFqcn(), $fieldDto->getProperty());
$formFieldType = $guessType->getType(); $formFieldType = $guessType->getType();


public function finishView(FormView $view, FormInterface $form, array $options) public function finishView(FormView $view, FormInterface $form, array $options)
{ {
$view->vars['translation_entity_name'] = $options['translation_entity_name'];

$this->parent->finishView($view, $form, $options); $this->parent->finishView($view, $form, $options);
} }


public function configureOptions(OptionsResolver $resolver) public function configureOptions(OptionsResolver $resolver)
{ {
$this->parent->configureOptions($resolver); $this->parent->configureOptions($resolver);
$resolver->setDefaults(
[
'translation_entity_name' => static function (Options $options, $dataClass) {
return $dataClass ?? $options['entityDto']->getFqcn();
}
]
);

} }


public function getBlockPrefix() public function getBlockPrefix()

+ 1
- 1
Notification/MailMailjetNotification.php View File

if (isset($params[self::CONTENT_DATA])) { if (isset($params[self::CONTENT_DATA])) {
$contentData = $params[self::CONTENT_DATA]; $contentData = $params[self::CONTENT_DATA];
} }
dump($emailFrom);
$message->addFrom($emailFrom, $emailFromName) $message->addFrom($emailFrom, $emailFromName)
->setBody($this->templating->render($params[self::CONTENT_TEMPLATE] . '-html.html.twig', $contentData), 'text/html') ->setBody($this->templating->render($params[self::CONTENT_TEMPLATE] . '-html.html.twig', $contentData), 'text/html')
->addPart($this->templating->render($params[self::CONTENT_TEMPLATE] . '-text.html.twig', $contentData)); ->addPart($this->templating->render($params[self::CONTENT_TEMPLATE] . '-text.html.twig', $contentData));

+ 1
- 3
Resources/config/services.yaml View File

public: false public: false
decorates: doctrine.orm.default_entity_manager decorates: doctrine.orm.default_entity_manager
arguments: ["@.inner"] arguments: ["@.inner"]
# EasyCorp\Bundle\EasyAdminBundle\Form\Type\CrudFormType:
# class: Lc\SovBundle\Form\Type\CrudFormType


Lc\SovBundle\Maker\: Lc\SovBundle\Maker\:
resource: '../../Maker/' resource: '../../Maker/'
tags: [ 'maker.command' ]
tags: [ 'maker.command' ]

+ 1
- 1
Resources/views/adminlte/crud/detail.html.twig View File

{% trans_default_domain ea.i18n.translationDomain %} {% trans_default_domain ea.i18n.translationDomain %}


{% block content_title %} {% block content_title %}
{{ 'detail'|sov_trans_admin_title(ea.getEntity().getFqcn(), {id: ea.getEntity().getInstance().getId()}) }}
{{ 'detail'|sov_trans_admin_title(translation_entity_name, {id: ea.getEntity().getInstance().getId()}) }}
{% endblock %} {% endblock %}


{% block content_breadcrumb %} {% block content_breadcrumb %}

+ 6
- 6
Resources/views/adminlte/crud/form.html.twig View File



{% set form = new_form %} {% set form = new_form %}


{% set body_id = 'ea-new-' ~ entity.name ~ '-' ~ entity.primaryKeyValue %}
{% set body_class = 'ea-new ea-new-' ~ entity.name %}
{% set content_title = 'new'|sov_trans_admin_title(ea.getEntity().getFqcn()) %}
{% set body_id = 'ea-new-' ~translation_entity_name ~ '-' ~ entity.primaryKeyValue %}
{% set body_class = 'ea-new ea-new-' ~ translation_entity_name %}
{% set content_title = 'new'|sov_trans_admin_title(translation_entity_name) %}


{% elseif ea.crud.currentAction == 'edit' %} {% elseif ea.crud.currentAction == 'edit' %}
{% set form = edit_form %} {% set form = edit_form %}


{% set body_id = 'ea-edit-' ~ entity.name ~ '-' ~ entity.primaryKeyValue %}
{% set body_class = 'ea-edit ea-edit-' ~ entity.name %}
{% set content_title = 'edit'|sov_trans_admin_title(ea.getEntity().getFqcn(), {id: ea.getEntity().getInstance().getId()}) %}
{% set body_id = 'ea-edit-' ~ translation_entity_name ~ '-' ~ entity.primaryKeyValue %}
{% set body_class = 'ea-edit ea-edit-' ~ translation_entity_name %}
{% set content_title = 'edit'|sov_trans_admin_title(translation_entity_name, {id: ea.getEntity().getInstance().getId()}) %}
{% endif %} {% endif %}





+ 15
- 4
Resources/views/adminlte/crud/form_theme.html.twig View File

{% use '@EasyAdmin/crud/form_theme.html.twig' %} {% use '@EasyAdmin/crud/form_theme.html.twig' %}


{% block form_start %} {% block form_start %}

{% if form.vars.errors|length > 0 and 'ea_crud' in form.vars.block_prefixes|default([]) %} {% if form.vars.errors|length > 0 and 'ea_crud' in form.vars.block_prefixes|default([]) %}
{{ form_errors(form) }} {{ form_errors(form) }}
{% endif %} {% endif %}
{% endblock form_row %} {% endblock form_row %}


{% block form_label -%} {% block form_label -%}

{% if label is same as(false) -%} {% if label is same as(false) -%}
<label>{# the empty <label> is needed to not break the form design #}</label> <label>{# the empty <label> is needed to not break the form design #}</label>
{%- else -%} {%- else -%}
{%- endif -%} {%- endif -%}
{%- endif -%} {%- endif -%}



{% set entityNameOrObject = form.parent.vars.data %} {% set entityNameOrObject = form.parent.vars.data %}

{% if form.parent.vars.translation_entity_name is defined %}
{% set entityNameOrObject = form.parent.vars.translation_entity_name %}
{% endif %}

{#
{% if not entityNameOrObject and form.parent.vars.errors.form.config.dataClass is defined %} {% if not entityNameOrObject and form.parent.vars.errors.form.config.dataClass is defined %}
{% set entityNameOrObject = form.parent.vars.errors.form.config.dataClass %} {% set entityNameOrObject = form.parent.vars.errors.form.config.dataClass %}
{% endif %} {% endif %}
#}


{% if translation_domain == null %} {% if translation_domain == null %}
{% set translation_domain = 'admin' %} {% set translation_domain = 'admin' %}
{% endblock file_manager_widget %} {% endblock file_manager_widget %}


{% block checkbox_radio_label -%} {% 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 -%} {%- 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_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) %} {% 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) %}
{# {{- label is not same as(false) ? (translation_domain is same as(false) ? label : label|trans(label_translation_parameters, translation_domain))|raw -}} #} {# {{- label is not same as(false) ? (translation_domain is same as(false) ? label : label|trans(label_translation_parameters, translation_domain))|raw -}} #}


{% set entityNameOrObject = form.parent.vars.data %} {% set entityNameOrObject = form.parent.vars.data %}
{% if not entityNameOrObject and form.parent.vars.errors.form.config.dataClass is defined %}
{% set entityNameOrObject = form.parent.vars.errors.form.config.dataClass %}

{% if form.parent.vars.translation_entity_name is defined %}
{% set entityNameOrObject = form.parent.vars.translation_entity_name %}
{% endif %} {% endif %}


<!-- lorsque que le name est un entier "case radio"--> <!-- lorsque que le name est un entier "case radio"-->


<textarea class="lc-ckeditor" {{ block('widget_attributes') }}>{{ value }}</textarea> <textarea class="lc-ckeditor" {{ block('widget_attributes') }}>{{ value }}</textarea>


{% endblock %}
{% endblock %}

+ 12
- 3
Resources/views/adminlte/crud/index.html.twig View File

{% block body_class 'index' ~ (entities|length > 0 ? ' index-' ~ entities|first.name : '') %} {% block body_class 'index' ~ (entities|length > 0 ? ' index-' ~ entities|first.name : '') %}


{% block content_title %} {% block content_title %}
{{ 'index'|sov_trans_admin_title(ea.getEntity().getFqcn()) }}
{{ 'index'|sov_trans_admin_title(translation_entity_name) }}
{% endblock %} {% endblock %}


{% block content_breadcrumb %} {% block content_breadcrumb %}
dir="{{ ea.i18n.textDirection }}"> dir="{{ ea.i18n.textDirection }}">
{% if field.isSortable %} {% if field.isSortable %}
<a href="{{ ea_url({ page: 1, sort: { (field.property): next_sort_direction } }).includeReferrer() }}"> <a href="{{ ea_url({ page: 1, sort: { (field.property): next_sort_direction } }).includeReferrer() }}">
{{ field.getProperty|sov_trans_admin_field(ea.getEntity().getFqcn()) }}
{% if field.label is not null %}
{{ field.label|raw }}
{% else %}
{{ field.getProperty|sov_trans_admin_field_index(translation_entity_name) }}
{% endif %}

<i class="fa fa-fw {{ column_icon }}"></i> <i class="fa fa-fw {{ column_icon }}"></i>
</a> </a>
{% else %} {% else %}
<span>{{ field.getProperty|sov_trans_admin_field(ea.getEntity().getFqcn()) }}</span>
{% if field.label is not null %}
<span>{{ field.label|raw }}</span>
{% else %}
<span>{{ field.getProperty|sov_trans_admin_field_index(translation_entity_name) }}</span>
{% endif %}
{% endif %} {% endif %}
</th> </th>
{% endif %} {% endif %}

+ 22
- 0
Session/Flash/FlashBag.php View File

<?php

namespace Lc\SovBundle\Session\Flash;

use \Symfony\Component\HttpFoundation\Session\Flash\FlashBag as SfFlashBag;

/**
* class FlashBag.
*
* @author La clic !!!!
*/
class FlashBag extends SfFlashBag
{

/**
* {@inheritdoc}
*/
public function addTranslatable(string $type, $message, $eedf, $effe)
{
$this->add($type,$message);
}
}

+ 44
- 0
Translation/FlashBagTranslator.php View File

<?php

namespace Lc\SovBundle\Translation;


use Symfony\Component\HttpFoundation\Session\SessionInterface;

/**
* class FlashBag.
*
* @author La clic !!!!
*/
class FlashBagTranslator
{

protected SessionInterface $session;
protected TranslatorAdmin $translatorAdmin;

public function __construct(SessionInterface $session, TranslatorAdmin $translatorAdmin)
{
$this->session = $session;
$this->translatorAdmin = $translatorAdmin;
}

/**
* {@inheritdoc}
*/
public function add(
string $type,
$translationKeyName,
$translationEntityName = null,
$translationParam = array()
): void {
$this->session->getFlashBag()->add(
$type,
$this->translatorAdmin->transFlashMessage(
$type,
$translationKeyName,
$translationEntityName,
$translationParam
)
);
}
}

+ 45
- 19
Translation/TranslatorAdmin.php View File

return $this->trans('menu.' . $menu); return $this->trans('menu.' . $menu);
} }


public function transFlashMessage($name, $params = []): string
public function transFlashMessage($type, $name, $entityClass = false, $params = []): string
{ {
return $this->trans('flash_message.' . $name, $params);
if ($entityClass) {
return $this->transEntityThenDefault(
$this->buildTransIdFlash($type . '.' . $name, $entityClass),
$this->buildTransIdFlash($type . '.' . $name, $entityClass, true)
);
} else {
return $this->trans('flash_message.' . $name, $params);
}
} }


public function transField($fieldName, $entityClass): string public function transField($fieldName, $entityClass): string
{ {
return $this->transEntityThenDefault( return $this->transEntityThenDefault(
$this->buildTransIdField($fieldName, $entityClass),
$this->buildTransIdField($fieldName, $entityClass, true)
$this->buildTransIdField($fieldName, $entityClass),
$this->buildTransIdField($fieldName, $entityClass, true)
); );
} }


public function transChoices(array $choices, string $entityName,string $field): array
public function transFieldIndex($fieldName, $entityClass): string
{
$idTranslationFieldIndex = $this->buildTransIdField($fieldName.'Index', $entityClass);

$translation = $this->trans($idTranslationFieldIndex);

if ($translation == $idTranslationFieldIndex) {
return $this->transField($fieldName, $entityClass);
}else{
return $translation;
}
}

public function transChoices(array $choices, string $entityName, string $field): array
{ {
$newChoices = []; $newChoices = [];
foreach ($choices as $key => $choice) { foreach ($choices as $key => $choice) {
$newChoices[$this->transField($field.'Choices.'.$choice, $entityName)] = $choice;
$newChoices[$this->transField($field . 'Choices.' . $choice, $entityName)] = $choice;
} }


return $newChoices; return $newChoices;
} }


public function transChoice(string $entityName,string $field, string $choice): string
public function transChoice(string $entityName, string $field, string $choice): string
{ {
return $this->transField($field.'Choices.'.$choice, $entityName);
return $this->transField($field . 'Choices.' . $choice, $entityName);
} }


public function transHelp($fieldName, $entityClass): string public function transHelp($fieldName, $entityClass): string
$fieldName = $fieldName . '_help'; $fieldName = $fieldName . '_help';


return $this->transEntityThenDefault( return $this->transEntityThenDefault(
$this->buildTransIdField($fieldName, $entityClass),
$this->buildTransIdField($fieldName, $entityClass, true),
true
$this->buildTransIdField($fieldName, $entityClass),
$this->buildTransIdField($fieldName, $entityClass, true),
true
); );
} }


public function transPanel($panelName, $entityClass): string public function transPanel($panelName, $entityClass): string
{ {
return $this->transEntityThenDefault( return $this->transEntityThenDefault(
$this->buildTransIdPanel($panelName, $entityClass),
$this->buildTransIdPanel($panelName, $entityClass, true)
$this->buildTransIdPanel($panelName, $entityClass),
$this->buildTransIdPanel($panelName, $entityClass, true)
); );
} }


public function transModal($modalName, $entityClass): string public function transModal($modalName, $entityClass): string
{ {
return $this->transEntityThenDefault( return $this->transEntityThenDefault(
$this->buildTransIdModal($modalName, $entityClass),
$this->buildTransIdModal($modalName, $entityClass, true)
$this->buildTransIdModal($modalName, $entityClass),
$this->buildTransIdModal($modalName, $entityClass, true)
); );
} }


$this->buildTransIdBox($cardName, $entityClass, true) $this->buildTransIdBox($cardName, $entityClass, true)
); );
} }

public function transTitle($pageName, $entityClass = null, $params = []): string public function transTitle($pageName, $entityClass = null, $params = []): string
{ {
$entityName = $this->getEntityName($entityClass); $entityName = $this->getEntityName($entityClass);
if ($entityName) { if ($entityName) {
$baseIdEntityLabel = 'entity.' . $entityName; $baseIdEntityLabel = 'entity.' . $entityName;
$paramsTranslation = [ $paramsTranslation = [
'%label%' => $this->trans($baseIdEntityLabel . '.label'),
'%label_plurial%' => $this->trans($baseIdEntityLabel . '.label_plurial'),
'%label%' => $this->trans($baseIdEntityLabel . '.label'),
'%label_plurial%' => $this->trans($baseIdEntityLabel . '.label_plurial'),
]; ];
} }


} }


return $this->trans( return $this->trans(
'title.' . $pageName,
$paramsTranslation
'title.' . $pageName,
$paramsTranslation
); );
} }


return $this->buildTransIdEntitySection($boxName, $entityClass, 'boxes', $default); return $this->buildTransIdEntitySection($boxName, $entityClass, 'boxes', $default);
} }


private function buildTransIdFlash($flashName, $entityClass, $default = false): string
{
return $this->buildTransIdEntitySection($flashName, $entityClass, 'flashes', $default);
}

private function buildTransIdEntitySection($name, $entityClass, $entitySection, $default): string private function buildTransIdEntitySection($name, $entityClass, $entitySection, $default): string
{ {
if ($default) { if ($default) {

+ 6
- 0
Twig/TranslatorTwigExtension.php View File

{ {
return [ return [
new TwigFilter('sov_trans_admin_field', [$this, 'transAdminField']), new TwigFilter('sov_trans_admin_field', [$this, 'transAdminField']),
new TwigFilter('sov_trans_admin_field_index', [$this, 'transAdminFieldIndex']),
new TwigFilter('sov_trans_admin_help', [$this, 'transAdminHelp']), new TwigFilter('sov_trans_admin_help', [$this, 'transAdminHelp']),
new TwigFilter('sov_trans_admin_panel', [$this, 'transAdminPanel']), new TwigFilter('sov_trans_admin_panel', [$this, 'transAdminPanel']),
new TwigFilter('sov_trans_admin_modal', [$this, 'transAdminModal']), new TwigFilter('sov_trans_admin_modal', [$this, 'transAdminModal']),
return $this->translatorAdmin->transField($fieldName, $entityClass); return $this->translatorAdmin->transField($fieldName, $entityClass);
} }


public function transAdminFieldIndex($fieldName, $entityClass)
{
return $this->translatorAdmin->transFieldIndex($fieldName, $entityClass);
}

public function transAdminChoice($choice, $fieldName, $entityClass) public function transAdminChoice($choice, $fieldName, $entityClass)
{ {
return $this->translatorAdmin->transChoice($entityClass, $fieldName, $choice); return $this->translatorAdmin->transChoice($entityClass, $fieldName, $choice);

+ 1
- 1
Twig/TwigExtension.php View File



public function liip($path, $thumb = 'tile', $default = 'default.jpg') public function liip($path, $thumb = 'tile', $default = 'default.jpg')
{ {
$this->fileComponent->liip($path, $thumb, $default);
return $this->fileComponent->liip($path, $thumb, $default);
} }


public function getFileManagerFolder() public function getFileManagerFolder()

Loading…
Cancel
Save