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); | ||||
} | } | ||||
} | |||||
} |
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 | ||||
{ | { |
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); | ||||
} | } | ||||
} | |||||
} |
$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')); |
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.' | |||||
); | |||||
} | } | ||||
} | } |
$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( | ||||
); | ); | ||||
} | } | ||||
} | |||||
} |
$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( |
<?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(), | |||||
])); | |||||
} | |||||
} |
); | ); | ||||
$queryBuilder->setParameter($fieldProperty, '%'.$filteredValue.'%'); | $queryBuilder->setParameter($fieldProperty, '%'.$filteredValue.'%'); | ||||
} | } | ||||
dump($queryBuilder); | |||||
} | } | ||||
} | } | ||||
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() |
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)); |
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' ] |
{% 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 %} |
{% 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 %} | ||||
{% 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 %} |
{% 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 %} |
<?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); | |||||
} | |||||
} |
<?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 | |||||
) | |||||
); | |||||
} | |||||
} |
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) { |
{ | { | ||||
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); |
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() |