Guillaume преди 3 години
родител
ревизия
3ac26e560f
променени са 32 файла, в които са добавени 477 реда и са изтрити 238 реда
  1. +15
    -57
      Builder/Ticket/TicketBuilder.php
  2. +10
    -18
      Builder/Ticket/TicketMessageBuilder.php
  3. +8
    -8
      Container/Ticket/TicketContainer.php
  4. +9
    -1
      Controller/AbstractAdminController.php
  5. +66
    -27
      Controller/Ticket/TicketAdminController.php
  6. +39
    -8
      Controller/User/UserAdminController.php
  7. +1
    -0
      Definition/ActionDefinition.php
  8. +0
    -1
      Definition/Field/Site/NewsFieldDefinition.php
  9. +52
    -35
      Definition/Field/Ticket/TicketFieldDefinition.php
  10. +12
    -1
      Definition/Field/User/UserFieldDefinition.php
  11. +30
    -0
      Event/Ticket/TicketEvent.php
  12. +138
    -0
      EventSubscriber/Ticket/SendNotificationTicketEventSubscriber.php
  13. +1
    -14
      Field/Filter/ChoiceFilter.php
  14. +11
    -12
      Field/Filter/FilterManager.php
  15. +3
    -3
      Field/Filter/FilterTrait.php
  16. +1
    -1
      Field/Filter/Ticket/TicketEmailFilter.php
  17. +1
    -1
      Field/Filter/Ticket/TicketFirstnameFilter.php
  18. +1
    -1
      Field/Filter/Ticket/TicketLastnameFilter.php
  19. +3
    -6
      Form/Ticket/TicketFormType.php
  20. +7
    -7
      Form/Ticket/TicketMessageAdminFormType.php
  21. +1
    -0
      Model/Ticket/TicketModel.php
  22. +13
    -11
      Repository/Ticket/TicketRepositoryQuery.php
  23. +2
    -2
      Resources/translations/admin.fr.yaml
  24. +3
    -0
      Resources/views/admin/ticket/detail.html.twig
  25. +31
    -14
      Resources/views/admin/ticket/field/lastmessage.html.twig
  26. +2
    -0
      Resources/views/admin/ticket/field/status.html.twig
  27. +1
    -1
      Resources/views/admin/ticket/macro.html.twig
  28. +4
    -2
      Resources/views/adminlte/block/menu.html.twig
  29. +5
    -1
      Resources/views/adminlte/macro/badge.html.twig
  30. +3
    -2
      Solver/Ticket/TicketSolver.php
  31. +2
    -2
      Translation/TranslatorAdmin.php
  32. +2
    -2
      Twig/TranslatorTwigExtension.php

+ 15
- 57
Builder/Ticket/TicketBuilder.php Целия файл

@@ -3,6 +3,7 @@
namespace Lc\SovBundle\Builder\Ticket;

use Doctrine\ORM\EntityManagerInterface;
use Lc\SovBundle\Event\Ticket\TicketEvent;
use Lc\SovBundle\Notification\MailMailjetNotification;
use Lc\SovBundle\Component\FormComponent;
use Lc\SovBundle\Factory\Ticket\TicketFactory;
@@ -10,6 +11,8 @@ use Lc\SovBundle\Model\Ticket\TicketInterface;
use Lc\SovBundle\Model\Ticket\TicketModel;
use Lc\SovBundle\Repository\User\UserStore;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Security;

@@ -23,6 +26,8 @@ class TicketBuilder
protected TicketFactory $ticketFactory;
protected AuthorizationCheckerInterface $authorizationChecker;
protected UserStore $userStore;
protected EventDispatcherInterface $eventDispatcher;


public function __construct(
Security $security,
@@ -32,7 +37,8 @@ class TicketBuilder
ParameterBagInterface $parameterBag,
AuthorizationCheckerInterface $authorizationChecker,
TicketFactory $ticketFactory,
UserStore $userStore
UserStore $userStore,
EventDispatcherInterface $eventDispatcher
) {
$this->security = $security;
$this->entityManager = $entityManager;
@@ -42,6 +48,7 @@ class TicketBuilder
$this->ticketFactory = $ticketFactory;
$this->userStore = $userStore;
$this->authorizationChecker = $authorizationChecker;
$this->eventDispatcher = $eventDispatcher;
}

public function create(array $params = []): TicketInterface
@@ -50,64 +57,11 @@ class TicketBuilder

$this->init($ticket, $params);

$user = $ticket->getUser();
if ($ticket->getUser()) {
$email = $user->getEmail();
$firstname = $user->getFirstname();
} else {
$email = $params['visitorEmail'];
$firstname = $params['visitorFirstname'];
}

$this->entityManager->create($ticket);
$this->entityManager->flush();

if (isset($params['createByAdmin']) && $params['createByAdmin']) {
// envoi email au client
$this->mailMailjetNotification->send(
[
MailMailjetNotification::SUBJECT => 'Vous avez reçu un nouveau message',
MailMailjetNotification::TO_EMAIL => $email,
MailMailjetNotification::CONTENT_TEMPLATE => 'mail/ticket-new-by-admin',
MailMailjetNotification::CONTENT_DATA => [
'firstname' => $firstname,
'ticket' => $ticket,
],
]
);
} else {
$this->mailMailjetNotification->send(
[
MailMailjetNotification::SUBJECT => 'Nouvelle demande',
MailMailjetNotification::TO_EMAIL => $email,
MailMailjetNotification::CONTENT_TEMPLATE => 'mail/ticket-new',
MailMailjetNotification::CONTENT_DATA => [
'firstname' => $firstname,
'ticket' => $ticket,
],
]
);
}

// notifyAdmin
$usersToNotify = $this->userStore->getByTicketTypesNotification($ticket->getType());

foreach ($usersToNotify as $userToNotify) {
if ($this->authorizationChecker->isGranted('ROLE_ADMIN', $userToNotify)) {
$this->mailMailjetNotification->send(
[
MailMailjetNotification::SUBJECT => 'Nouveau ticket sur Place du Local',
MailMailjetNotification::TO_EMAIL => $userToNotify->getEmail(),
MailMailjetNotification::CONTENT_TEMPLATE => 'mail/ticket-notification',
MailMailjetNotification::CONTENT_DATA => [
'firstname' => $userToNotify->getFirstname(),
'ticket' => $ticket,
'ticketMessage' => $ticket->getTicketMessages()[0],
],
]
);
}
}
$this->eventDispatcher->dispatch(new TicketEvent($ticket), TicketEvent::NEW_TICKET_EVENT);

return $ticket;
}
@@ -115,13 +69,17 @@ class TicketBuilder
public function init(TicketInterface $ticket, array $params = []): void
{
$user = $this->security->getUser();
if($user) {
if ($user) {
$ticket->setCreatedBy($user);
}

if (isset($params['section'])) {
$ticket->setSection($params['section']);
}
$ticket->setMerchant($params['merchant']);

if (isset($params['user'])) {
$ticket->setUser($params['user']);

} else {
$ticket->setVisitorFirstname($params['visitorFirstname']);
$ticket->setVisitorLastname($params['visitorLastname']);

+ 10
- 18
Builder/Ticket/TicketMessageBuilder.php Целия файл

@@ -3,6 +3,7 @@
namespace Lc\SovBundle\Builder\Ticket;

use Doctrine\ORM\EntityManagerInterface;
use Lc\SovBundle\Event\Ticket\TicketEvent;
use Lc\SovBundle\Notification\MailMailjetNotification;
use Lc\SovBundle\Component\FormComponent;
use Lc\SovBundle\Factory\Ticket\TicketFactory;
@@ -11,21 +12,25 @@ use Lc\SovBundle\Model\Ticket\TicketInterface;
use Lc\SovBundle\Model\Ticket\TicketMessageInterface;
use Lc\SovBundle\Model\Ticket\TicketModel;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

class TicketMessageBuilder
{
protected EntityManagerInterface $entityManager;
protected MailMailjetNotification $mailMailjetNotification;
protected TicketMessageFactory $ticketMessageFactory;
protected EventDispatcherInterface $eventDispatcher;

public function __construct(
EntityManagerInterface $entityManager,
MailMailjetNotification $mailMailjetNotification,
TicketMessageFactory $ticketMessageFactory
TicketMessageFactory $ticketMessageFactory,
EventDispatcherInterface $eventDispatcher
) {
$this->entityManager = $entityManager;
$this->mailMailjetNotification = $mailMailjetNotification;
$this->ticketMessageFactory = $ticketMessageFactory;
$this->eventDispatcher = $eventDispatcher;
}

public function create(array $params = []): TicketMessageInterface
@@ -36,24 +41,8 @@ class TicketMessageBuilder
$ticketMessage->setStatus(1);
$ticketMessage->setTicket($ticket);
$ticketMessage->setMessage($params['message']);

if (isset($params['answerByAdmin']) && $params['answerByAdmin']) {
$ticketMessage->setAnswerByAdmin($params['answerByAdmin']);

// envoi email au client
$this->mailMailjetNotification->send(
[
MailMailjetNotification::SUBJECT => 'Réponse à votre demande',
MailMailjetNotification::TO_EMAIL => $ticket->getUser() ? $ticket->getUser()->getEmail(
) : $ticket->getVisitorEmail(),
MailMailjetNotification::CONTENT_TEMPLATE => 'mail/ticket-response',
MailMailjetNotification::CONTENT_DATA => [
'firstname' => $ticket->getUser() ? $ticket->getUser()->getFirstname(
) : $ticket->getVisitorFirstname(),
'ticket' => $ticket,
],
]
);
}
$this->entityManager->persist($ticketMessage);

@@ -66,9 +55,12 @@ class TicketMessageBuilder

$ticket->setUpdatedAt(new \DateTime());

$this->entityManager->persist($ticket);
$this->entityManager->create($ticket);
$this->entityManager->flush();

$this->eventDispatcher->dispatch(new TicketEvent($ticket), TicketEvent::NEW_MESSAGE_EVENT);


return $ticketMessage;
}


+ 8
- 8
Container/Ticket/TicketContainer.php Целия файл

@@ -15,23 +15,23 @@ class TicketContainer
protected TicketBuilder $builder;
protected TicketRepositoryQuery $repositoryQuery;
protected TicketStore $store;
protected TicketFieldDefinition $fieldDefinition;
protected TicketSolver $solver;
protected TicketFieldDefinition $fieldDefinition;

public function __construct(
TicketFactory $factory,
TicketBuilder $builder,
TicketRepositoryQuery $repositoryQuery,
TicketStore $store,
TicketFieldDefinition $fieldDefinition,
TicketSolver $solver
TicketSolver $solver,
TicketFieldDefinition $fieldDefinition
) {
$this->factory = $factory;
$this->builder = $builder;
$this->repositoryQuery = $repositoryQuery;
$this->store = $store;
$this->fieldDefinition = $fieldDefinition;
$this->solver = $solver;
$this->fieldDefinition = $fieldDefinition;
}

public function getFactory(): TicketFactory
@@ -54,13 +54,13 @@ class TicketContainer
return $this->store;
}

public function getFieldDefinition(): TicketFieldDefinition
public function getSolver(): TicketSolver
{
return $this->fieldDefinition;
return $this->solver;
}

public function getSolver(): TicketSolver
public function getFieldDefinition(): TicketFieldDefinition
{
return $this->solver;
return $this->fieldDefinition;
}
}

+ 9
- 1
Controller/AbstractAdminController.php Целия файл

@@ -62,6 +62,7 @@ abstract class AbstractAdminController extends EaAbstractCrudController
use ControllerTrait;

protected FormInterface $filtersForm;
protected bool $isRepositoryQueryFiltered = false;

abstract public function getRepositoryQuery(): RepositoryQueryInterface;

@@ -332,6 +333,13 @@ abstract class AbstractAdminController extends EaAbstractCrudController
return $this->redirect($url);
}

public function isRepositoryQueryFiltered():bool{
if(($this->filtersForm && $this->filtersForm->isSubmitted()) || $this->isRepositoryQueryFiltered){
return true;
}else{
return false;
}
}
public function createIndexRepositoryQuery(
SearchDto $searchDto,
EntityDto $entityDto,
@@ -370,7 +378,7 @@ abstract class AbstractAdminController extends EaAbstractCrudController

$this->filtersForm->handleRequest($searchDto->getRequest());

$filterManager->handleFiltersForm($repositoryQuery, $this->filtersForm, $fields, $entityDto);
$this->isRepositoryQueryFiltered = $filterManager->handleFiltersForm($repositoryQuery, $this->filtersForm, $fields, $entityDto);
return $repositoryQuery;
}


+ 66
- 27
Controller/Ticket/TicketAdminController.php Целия файл

@@ -3,32 +3,23 @@
namespace Lc\SovBundle\Controller\Ticket;

use Doctrine\ORM\EntityManagerInterface;
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Collection\FieldCollection;
use EasyCorp\Bundle\EasyAdminBundle\Collection\FilterCollection;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Assets;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext;
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField;
use EasyCorp\Bundle\EasyAdminBundle\Field\DateField;
use EasyCorp\Bundle\EasyAdminBundle\Field\IntegerField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto;
use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
use Lc\SovBundle\Container\Ticket\TicketContainer;
use Lc\SovBundle\Container\Ticket\TicketMessageContainer;
use Lc\SovBundle\Definition\ActionDefinition;
use Lc\SovBundle\Factory\Ticket\TicketFactory;
use Lc\SovBundle\Factory\Ticket\TicketFactoryInterface;
use Lc\SovBundle\Factory\Ticket\TicketMessageFactory;
use Lc\SovBundle\Factory\Ticket\TicketMessageFactoryInterface;
use Lc\SovBundle\Form\Ticket\TicketFormType;
use Lc\SovBundle\Form\Ticket\TicketMessageFormType;
use Lc\SovBundle\Event\Ticket\TicketEvent;
use Lc\SovBundle\Form\Ticket\TicketMessageAdminFormType;
use Lc\SovBundle\Form\Ticket\TicketStatusType;
use Lc\SovBundle\Model\Ticket\TicketInterface;
use Lc\SovBundle\Controller\AbstractAdminController;
use Lc\SovBundle\Model\Ticket\TicketModel;
use Lc\SovBundle\Repository\RepositoryQueryInterface;
use Lc\SovBundle\Translation\TranslatorAdmin;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RequestStack;

@@ -42,12 +33,28 @@ abstract class TicketAdminController extends AbstractAdminController

public function createEntity(string $entityFqcn)
{
return $this->getTicketContainer()->getFactory()->create();
$ticket = $this->getTicketContainer()->getFactory()->create();
return $ticket;
}

public function persistEntity(EntityManagerInterface $entityManager, $entityInstance): void
{
parent::persistEntity($entityManager, $entityInstance);
$this->getEventDispatcher()->dispatch(new TicketEvent($entityInstance), TicketEvent::NEW_TICKET_EVENT);
}

public function configureCrud(Crud $crud): Crud
{
$crud = parent::configureCrud($crud); // TODO: Change the autogenerated stub
$crud->setDefaultSort(array('updatedAt' => 'DESC'));
return $crud;
}


public function configureFields(string $pageName): iterable
{
return $this->getTicketContainer()->getFieldDefinition()->getFields($pageName);

}

public function configureAssets(Assets $assets): Assets
@@ -59,15 +66,43 @@ abstract class TicketAdminController extends AbstractAdminController
return $assets;
}


public function configureActions(Actions $actions): Actions
{
$actions
->add(Crud::PAGE_INDEX, ActionDefinition::DETAIL)
->remove(Crud::PAGE_INDEX, ActionDefinition::EDIT);
$actions->add(Crud::PAGE_INDEX, ActionDefinition::DETAIL);
$actions = parent::configureActions($actions);
$actions->disable( ActionDefinition::EDIT, ActionDefinition::DUPLICATE);
return $actions;

}

return parent::configureActions($actions);
public function createIndexRepositoryQuery(
SearchDto $searchDto,
EntityDto $entityDto,
FieldCollection $fields,
FilterCollection $filters
): RepositoryQueryInterface {
$repositoryQuery = parent::createIndexRepositoryQuery(
$searchDto,
$entityDto,
$fields,
$filters
);

if(!$this->isRepositoryQueryFiltered()){

$repositoryQuery->filterByStatus(array(
TicketModel::TICKET_STATUS_OPEN,
TicketModel::TICKET_STATUS_BEING_PROCESSED,
TicketModel::TICKET_STATUS_PROCESSED
));
}

return $repositoryQuery;
}



public function detail(AdminContext $context)
{
$adminUrlGenerator = $this->get(AdminUrlGenerator::class);
@@ -87,7 +122,7 @@ abstract class TicketAdminController extends AbstractAdminController
);

$ticketMessage = $this->get(TicketMessageContainer::class)->getFactory()->create($ticket);
$formAddTicketMessage = $this->createForm(TicketMessageFormType::class, $ticketMessage);
$formAddTicketMessage = $this->createForm(TicketMessageAdminFormType::class, $ticketMessage);
$formAddTicketMessage->handleRequest($this->get(RequestStack::class)->getMainRequest());

if ($formAddTicketMessage->isSubmitted() && $formAddTicketMessage->isValid()) {
@@ -96,6 +131,9 @@ abstract class TicketAdminController extends AbstractAdminController
$ticketMessage->setAnswerByAdmin(true);
$this->get(EntityManagerInterface::class)->create($ticketMessage);
$this->get(EntityManagerInterface::class)->flush();
$this->getEventDispatcher()->dispatch(new TicketEvent($ticket), TicketEvent::NEW_MESSAGE_EVENT);

return $this->redirect($this->generateEaUrl());
}

return $this->render(
@@ -109,18 +147,19 @@ abstract class TicketAdminController extends AbstractAdminController
}


public function ticketStatusAction()

public function ticketStatusAction(AdminContext $context, EntityManagerInterface $entityManager)
{
$entityManager = $this->getEntityManager();
$request = $this->getRequestStack()->getMainRequest();
$ticket = $request->attributes->get('easyadmin_context')->getEntity()->getInstance();

$ticket = $context->getEntity()->getInstance();

$formTicketStatusForm = $this->createForm(TicketStatusType::class, $ticket);
$formTicketStatusForm->handleRequest($request);
$formTicketStatusForm->handleRequest($context->getRequest());

$success = false;
if ($formTicketStatusForm->isSubmitted() && $formTicketStatusForm->isValid()) {
$entityManager->persist($ticket);

$entityManager->update($ticket);
$entityManager->flush();
$success = true;
}

+ 39
- 8
Controller/User/UserAdminController.php Целия файл

@@ -2,11 +2,16 @@

namespace Lc\SovBundle\Controller\User;

use EasyCorp\Bundle\EasyAdminBundle\Collection\EntityCollection;
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField;
use EasyCorp\Bundle\EasyAdminBundle\Field\EmailField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use Lc\SovBundle\Container\User\UserContainer;
use Lc\SovBundle\Controller\AbstractAdminController;
use Lc\SovBundle\Definition\ActionDefinition;
use Lc\SovBundle\Definition\RolesDefinition;
use Lc\SovBundle\Definition\RolesDefinitionInterface;
use Lc\SovBundle\Doctrine\EntityManager;
@@ -19,14 +24,40 @@ abstract class UserAdminController extends AbstractAdminController
{
protected RolesDefinitionInterface $rolesDefinition;

public function __construct(
SessionInterface $session,
RequestStack $request,
EntityManager $em,
TranslatorAdmin $translatorAdmin,
RolesDefinitionInterface $rolesDefinition
) {
$this->rolesDefinition = $rolesDefinition;

public function buildIndexActions(Actions $actions): void
{
parent::buildIndexActions($actions); // TODO: Change the autogenerated stub

$actions->add(Crud::PAGE_INDEX, $this->getSwitchUserAction());
}

public function getSwitchUserAction(): Action
{
$switchAction = Action::new(
ActionDefinition::SWITCH_USER,
$this->get(TranslatorAdmin::class)->transAction(ActionDefinition::SWITCH_USER),
'fa fa-fw fa-user-secret'
)
->linkToCrudAction(ActionDefinition::SWITCH_USER)
->setLabel($this->get(TranslatorAdmin::class)->transAction(ActionDefinition::SWITCH_USER))
->setCssClass('in-dropdown text-info action-confirm action_switch');

return $switchAction;
}

public function overrideEntitiesActions(?EntityCollection $entities): void
{
parent::overrideEntitiesActions($entities); // TODO: Change the autogenerated stub
foreach ($entities as $entity) {
foreach ($entity->getActions() as $action){
if($action->getName() == ActionDefinition::SWITCH_USER){
$url = $this->generateUrl($this->getParameter('lc_sov.homepage_route'), array('_switch_user' => $entity->getInstance()->getEmail()));
$action->setLinkUrl($url);
}
}

}
}

public function configureFields(string $pageName): iterable

+ 1
- 0
Definition/ActionDefinition.php Целия файл

@@ -16,4 +16,5 @@ class ActionDefinition {
public const SAVE_AND_CONTINUE = 'saveAndContinue';
public const SAVE_AND_RETURN = 'saveAndReturn';
public const SWITCH_USER = 'switchUser';

}

+ 0
- 1
Definition/Field/Site/NewsFieldDefinition.php Целия файл

@@ -5,7 +5,6 @@ namespace Lc\SovBundle\Definition\Field\Site;
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
use EasyCorp\Bundle\EasyAdminBundle\Field\DateField;
use EasyCorp\Bundle\EasyAdminBundle\Field\NumberField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use Lc\SovBundle\Definition\Field\AbstractFieldDefinition;
use Lc\SovBundle\Field\BooleanField;

+ 52
- 35
Definition/Field/Ticket/TicketFieldDefinition.php Целия файл

@@ -4,27 +4,24 @@ namespace Lc\SovBundle\Definition\Field\Ticket;

use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField;
use EasyCorp\Bundle\EasyAdminBundle\Field\DateField;
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField;
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use Lc\CaracoleBundle\Field\Filter\ProductCategoriesFilter;
use Lc\SovBundle\Field\Filter\Ticket\TicketEmailFilter;
use Lc\SovBundle\Field\Filter\Ticket\TicketFirstnameFilter;
use Lc\SovBundle\Field\Filter\Ticket\TicketLastnameFilter;
use Lc\SovBundle\Form\Ticket\TicketMessageAdminFormType;
use Lc\SovBundle\Solver\Ticket\TicketSolver;
use Lc\SovBundle\Definition\Field\AbstractFieldDefinition;
use Lc\SovBundle\Field\CollectionField;
use Lc\SovBundle\Field\Filter\Ticket\EmailFilter;
use Lc\SovBundle\Field\Filter\Ticket\FirstnameFilter;
use Lc\SovBundle\Field\Filter\Ticket\LastnameFilter;
use Lc\SovBundle\Form\Ticket\TicketMessageType;
use Lc\SovBundle\Solver\Ticket\TicketSolver;
use Lc\SovBundle\Translation\TranslatorAdmin;
use Symfony\Component\Form\Extension\Core\Type\TextType;

class TicketFieldDefinition extends AbstractFieldDefinition
{
protected TicketSolver $ticketSolver;

public function __construct(TranslatorAdmin $translatorAdmin, TicketSolver $ticketSolver)
public function __construct(TranslatorAdmin $translatorAdmin)
{
parent::__construct($translatorAdmin);
$this->ticketSolver = $ticketSolver;
}

public function configureIndex(): array
@@ -32,12 +29,12 @@ class TicketFieldDefinition extends AbstractFieldDefinition
return [
'id',
'createdAt',
'lastname',
'firstname',
'email',
'type',
'visitorFirstname',
'visitorLastname',
'visitorEmail',
'subject',
'lastMessage',
'updatedAt',
'type',
'status'
];
}
@@ -52,49 +49,69 @@ class TicketFieldDefinition extends AbstractFieldDefinition
];
}

public function configurePanels(): array
{
return [];
}

public function configureFields(): array
{
return [
'createdAt' => DateField::new('createdAt')->setFormat('short'),
'visitorFirstname' => TextField::new('visitorFirstname'),
'visitorLastname' => TextField::new('visitorLastname'),
'visitorEmail' => TextField::new('visitorEmail'),
'lastname' => TextField::new('lastname')
->setTemplatePath('@LcSov/admin/ticket/field/lastname.html.twig')
->setCustomOption('filter_fqcn', LastnameFilter::class),
'firstname' => TextField::new('firstname')
'id' => IdField::new('id')
->setSortable(true)
->hideOnForm(),
'createdAt' => DateTimeField::new('createdAt')
->setSortable(true)
->hideOnForm(),
'visitorFirstname' => TextField::new('visitorFirstname')
->setTemplatePath('@LcSov/admin/ticket/field/firstname.html.twig')
->setCustomOption('filter_fqcn', FirstnameFilter::class),
'email' => TextField::new('email')
->setCustomOption('filter_fqcn', TicketFirstnameFilter::class)
->setSortable(true)
->hideOnForm(),
'visitorLastname' => TextField::new('visitorLastname')
->setTemplatePath('@LcSov/admin/ticket/field/lastname.html.twig')
->setCustomOption('filter_fqcn', TicketLastnameFilter::class)
->setSortable(true)
->hideOnForm(),
'visitorEmail' => TextField::new('visitorEmail')
->setTemplatePath('@LcSov/admin/ticket/field/email.html.twig')
->setCustomOption('filter_fqcn', EmailFilter::class),
'user' => AssociationField::new('user'),
->setCustomOption('filter_fqcn', TicketEmailFilter::class)
->setSortable(true)
->hideOnForm(),
'user' => AssociationField::new('user')
->hideOnIndex(),
'subject' => TextField::new('subject')
->setSortable(true),
'updatedAt' => DateTimeField::new('updatedAt')
->setTemplatePath('@LcSov/admin/ticket/field/lastmessage.html.twig')
->setSortable(true)
->hideOnForm(),
'type' => ChoiceField::new('type')
->autocomplete()
->setSortable(true)
->setChoices(
$this->translatorAdmin->transChoices(
$this->ticketSolver->getTypeChoices(),
TicketSolver::getTypeChoices(),
'Ticket',
'type'
)
),
'subject' => TextField::new('subject'),
'lastMessage' => TextField::new('lastMessage')
->setTemplatePath('@LcSov/admin/ticket/field/lastmessage.html.twig'),
'status' => ChoiceField::new('status')
->autocomplete()
->setSortable(true)
->setChoices(
$this->translatorAdmin->transChoices(
$this->ticketSolver->getStatusChoices(),
TicketSolver::getStatusChoices(),
'Ticket',
'status'
)

)
->setTemplatePath('@LcSov/admin/ticket/field/status.html.twig'),

'ticketMessages' => CollectionField::new('ticketMessages')
->setFormTypeOption('entry_type', TicketMessageType::class)
->setFormTypeOption('entry_type', TicketMessageAdminFormType::class)
->setFormTypeOption('allow_add', false)
->setFormTypeOption('allow_delete', false)
];
}


+ 12
- 1
Definition/Field/User/UserFieldDefinition.php Целия файл

@@ -11,6 +11,7 @@ use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use Lc\CaracoleBundle\Field\AssociationField;
use Lc\SovBundle\Definition\Field\AbstractFieldDefinition;
use Lc\SovBundle\Definition\RolesDefinition;
use Lc\SovBundle\Solver\Ticket\TicketSolver;
use Lc\SovBundle\Solver\User\UserSolver;
use Lc\SovBundle\Translation\TranslatorAdmin;

@@ -47,7 +48,8 @@ class UserFieldDefinition extends AbstractFieldDefinition
'email',
'phone',
'birthdate',
'groupUsers'
'groupUsers',
'ticketTypesNotification'
];
}

@@ -72,6 +74,15 @@ class UserFieldDefinition extends AbstractFieldDefinition
'phone' => TextField::new('phone')->setSortable(true),
'birthdate' => DateField::new('birthdate')->setSortable(true),
'groupUsers' => AssociationField::new('groupUsers')->setSortable(true),
'ticketTypesNotification' => ChoiceField::new('ticketTypesNotification')
->setSortable(true)
->setFormTypeOption('expanded', false)
->setFormTypeOption('multiple', true)
->setChoices($this->translatorAdmin->transChoices(
TicketSolver::getTypeChoices(),
'Ticket',
'type'
)),
'roles' => ChoiceField::new('roles')
->allowMultipleChoices()
->autocomplete()

+ 30
- 0
Event/Ticket/TicketEvent.php Целия файл

@@ -0,0 +1,30 @@
<?php

namespace Lc\SovBundle\Event\Ticket;

use Lc\SovBundle\Doctrine\EntityInterface;
use Lc\SovBundle\Model\Ticket\TicketInterface;
use Symfony\Contracts\EventDispatcher\Event;

/**
* class EntityEvent.
*
* @author Simon Vieille <simon@deblan.fr>
*/
class TicketEvent extends Event
{
const NEW_TICKET_EVENT = 'ticket_event.new_ticket';
const NEW_MESSAGE_EVENT = 'ticket_event.new_message';

protected TicketInterface $ticket;

public function __construct(TicketInterface $ticket)
{
$this->ticket = $ticket;
}

public function getTicket(): TicketInterface
{
return $this->ticket;
}
}

+ 138
- 0
EventSubscriber/Ticket/SendNotificationTicketEventSubscriber.php Целия файл

@@ -0,0 +1,138 @@
<?php

namespace Lc\SovBundle\EventSubscriber\Ticket;

use Lc\SovBundle\Event\EntityManager\EntityManagerEvent;
use Lc\SovBundle\Event\Ticket\TicketEvent;
use Lc\SovBundle\Model\Ticket\TicketInterface;
use Lc\SovBundle\Model\Ticket\TicketMessageInterface;
use Lc\SovBundle\Notification\MailMailjetNotification;
use Lc\SovBundle\Repository\User\UserStore;
use Lc\SovBundle\Solver\Ticket\TicketSolver;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;

class SendNotificationTicketEventSubscriber implements EventSubscriberInterface
{
protected MailMailjetNotification $mailMailjetNotification;
protected UserStore $userStore;
protected AuthorizationCheckerInterface $authorizationChecker;
protected TicketSolver $ticketSolver;

public function __construct(
MailMailjetNotification $mailMailjetNotification,
UserStore $userStore,
AuthorizationCheckerInterface $authorizationChecker,
TicketSolver $ticketSolver
) {
$this->mailMailjetNotification = $mailMailjetNotification;
$this->userStore = $userStore;
$this->authorizationChecker = $authorizationChecker;
$this->ticketSolver = $ticketSolver;
}

public static function getSubscribedEvents()
{
return [
TicketEvent::NEW_MESSAGE_EVENT => ['sendNotificationAfterNewMessage'],
TicketEvent::NEW_TICKET_EVENT => ['sendNotificationAfterNewTicket'],
];
}


public function sendNotificationAfterNewTicket(TicketEvent $ticketEvent)
{
$ticket = $ticketEvent->getTicket();
$lastMessage = $this->ticketSolver->getLastMessage($ticket);
if ($ticket->getUser()) {
$firstname = $ticket->getUser()->getFirstname();
$email = $ticket->getUser()->getEmail();
} else {
$firstname = $ticket->getVisitorFirstname();
$email = $ticket->getVisitorEmail();
}

if ($lastMessage->getAnswerByAdmin()) {
// envoi email au client
$this->mailMailjetNotification->send(
[
MailMailjetNotification::SUBJECT => 'Vous avez reçu un nouveau message',
MailMailjetNotification::TO_EMAIL => $email,
MailMailjetNotification::CONTENT_TEMPLATE => 'mail/ticket-new-by-admin',
MailMailjetNotification::CONTENT_DATA => [
'firstname' => $firstname,
'ticket' => $ticket,
],
]
);
} else {
$this->mailMailjetNotification->send(
[
MailMailjetNotification::SUBJECT => 'Nouvelle demande',
MailMailjetNotification::TO_EMAIL => $email,
MailMailjetNotification::CONTENT_TEMPLATE => 'mail/ticket-new',
MailMailjetNotification::CONTENT_DATA => [
'firstname' => $firstname,
'ticket' => $ticket,
],
]
);
}

$this->notifyUser($ticket);
}

public function sendNotificationAfterNewMessage(TicketEvent $ticketEvent)
{
$ticket = $ticketEvent->getTicket();
$lastMessage = $this->ticketSolver->getLastMessage($ticket);
if ($ticket->getUser()) {
$firstname = $ticket->getUser()->getFirstname();
$email = $ticket->getUser()->getEmail();
} else {
$firstname = $ticket->getVisitorFirstname();
$email = $ticket->getVisitorEmail();
}

if ($lastMessage->getAnswerByAdmin()) {
// envoi email au client
$this->mailMailjetNotification->send(
[
MailMailjetNotification::SUBJECT => 'Réponse à votre demande',
MailMailjetNotification::TO_EMAIL => $email,
MailMailjetNotification::CONTENT_TEMPLATE => 'mail/ticket-response',
MailMailjetNotification::CONTENT_DATA => [
'firstname' => $firstname,
'ticket' => $ticket,
],
]
);
}
$this->notifyUser($ticket);
}

protected function notifyUser(TicketInterface $ticket): void
{
// notifyAdmin
$usersToNotify = $this->userStore->getByTicketTypesNotification($ticket->getType());

foreach ($usersToNotify as $userToNotify) {
if ($this->authorizationChecker->isGranted('ROLE_ADMIN', $userToNotify)) {
$this->mailMailjetNotification->send(
[
MailMailjetNotification::SUBJECT => 'Nouveau ticket sur Place du Local',
MailMailjetNotification::TO_EMAIL => $userToNotify->getEmail(),
MailMailjetNotification::CONTENT_TEMPLATE => 'mail/ticket-notification',
MailMailjetNotification::CONTENT_DATA => [
'firstname' => $userToNotify->getFirstname(),
'ticket' => $ticket,
'ticketMessage' => $ticket->getTicketMessages()[0],
],
]
);
}
}
}


}

+ 1
- 14
Field/Filter/ChoiceFilter.php Целия файл

@@ -53,23 +53,10 @@ class ChoiceFilter
{
$fieldProperty = $this->getFieldProperty($fieldDto);
if ($filteredValue !== null) {
// if ($this->isRelationField($fieldProperty)) {
// $aliasRelation = $this->getFieldPropertyRelationAlias($fieldProperty);
// if (array_search($aliasRelation, $repositoryQuery->getAllAliases()) === false) {
// $repositoryQuery->innerJoin('entity.'.$aliasRelation, $aliasRelation);
// }
// $repositoryQuery->andWhere(
// $fieldProperty.' LIKE :'.$this->getFieldPropertySnake($fieldProperty).''
// );
// $repositoryQuery->setParameter(
// $this->getFieldPropertySnake($fieldProperty),
// '%'.$filteredValue.'%'
// );
// } else {
$repositoryQuery->andWhere(
'.'.$fieldProperty.' LIKE :'.$fieldProperty.''
);
$repositoryQuery->setParameter($fieldProperty, '%'.$filteredValue.'%');
$repositoryQuery->setParameter($fieldProperty, $filteredValue);

}
}

+ 11
- 12
Field/Filter/FilterManager.php Целия файл

@@ -29,6 +29,7 @@ use Symfony\Component\HttpFoundation\Session\SessionInterface;
class FilterManager
{
protected $em;
protected bool $isFiltered = false;

use FilterTrait;

@@ -39,7 +40,7 @@ class FilterManager
}


public function handleFiltersForm(RepositoryQueryInterface $repositoryQuery, Form $filtersForm, $fields, EntityDto $entityDto)
public function handleFiltersForm(RepositoryQueryInterface $repositoryQuery, Form $filtersForm, $fields, EntityDto $entityDto):bool
{

foreach ($fields as $field) {
@@ -65,17 +66,25 @@ class FilterManager
$fieldDto->getProperty(),
'dateEnd'
);
if($filteredValue['dateStart'] || $filteredValue['dateEnd']){
$this->isFiltered = true;
}
} else {
$filteredValue['value'] = $this->getFilteredValue(
$filtersForm,
$entityDto->getFqcn(),
$fieldDto->getProperty()
);
if($filteredValue['value'] ){
$this->isFiltered = true;
}
}

$this->applyFilter($repositoryQuery, $fieldDto, $filteredValue);
}
}
}
return $this->isFiltered;
}


@@ -88,7 +97,7 @@ class FilterManager
$customFilter->applyFilter($repositoryQuery, $fieldDto, $filteredValue['value']);
} else {

switch ($this->guessFormType($fieldDto)) {
switch ($fieldDto->getFormType()) {

case CheckboxType::class:
$checkboxFilter = new CheckboxFilter();
@@ -183,14 +192,4 @@ class FilterManager
}
}


protected function guessFormType(FieldDto $fieldDto)
{
if ($fieldDto->getCustomOption('filter_type')) {
return $fieldDto->getCustomOption('filter_type');
} else {
return $fieldDto->getFormType();
}

}
}

+ 3
- 3
Field/Filter/FilterTrait.php Целия файл

@@ -41,9 +41,9 @@ trait FilterTrait
{
$property = $fieldDto->getProperty();
//TODO pas forcément utile, à discuter
if ($fieldDto->getCustomOption('filter_on')) {
$property = $property . '.' . $fieldDto->getCustomOption('filter_on');
}
// if ($fieldDto->getCustomOption('filter_on')) {
// $property = $property . '.' . $fieldDto->getCustomOption('filter_on');
// }
return $property;
}


Field/Filter/Ticket/EmailFilter.php → Field/Filter/Ticket/TicketEmailFilter.php Целия файл

@@ -11,7 +11,7 @@ use Symfony\Component\Form\FormBuilderInterface;
/**
* @author La clic ! <contact@laclic.fr>
*/
class EmailFilter extends AssociationFilter
class TicketEmailFilter extends AssociationFilter
{
public function buildProperty(FormBuilderInterface $builder, FieldDto $fieldDto, $options = array())
{

Field/Filter/Ticket/FirstnameFilter.php → Field/Filter/Ticket/TicketFirstnameFilter.php Целия файл

@@ -11,7 +11,7 @@ use Symfony\Component\Form\FormBuilderInterface;
/**
* @author La clic ! <contact@laclic.fr>
*/
class FirstnameFilter extends AssociationFilter
class TicketFirstnameFilter extends AssociationFilter
{
public function buildProperty(FormBuilderInterface $builder, FieldDto $fieldDto, $options = array())
{

Field/Filter/Ticket/LastnameFilter.php → Field/Filter/Ticket/TicketLastnameFilter.php Целия файл

@@ -11,7 +11,7 @@ use Symfony\Component\Form\FormBuilderInterface;
/**
* @author La clic ! <contact@laclic.fr>
*/
class LastnameFilter extends AssociationFilter
class TicketLastnameFilter extends AssociationFilter
{
public function buildProperty(FormBuilderInterface $builder, FieldDto $fieldDto, $options = array())
{

+ 3
- 6
Form/Ticket/TicketFormType.php Целия файл

@@ -21,16 +21,13 @@ class TicketFormType extends AbstractType
{
protected EntityManager $entityManager;
protected TranslatorAdmin $translatorAdmin;
protected TicketSolver $ticketSolver;

public function __construct(
EntityManager $entityManager,
TranslatorAdmin $translatorAdmin,
TicketSolver $ticketSolver
TranslatorAdmin $translatorAdmin
) {
$this->entityManager = $entityManager;
$this->translatorAdmin = $translatorAdmin;
$this->ticketSolver = $ticketSolver;
}

public function buildForm(FormBuilderInterface $builder, array $options)
@@ -51,7 +48,7 @@ class TicketFormType extends AbstractType
[
'label' => 'Type',
'choices' => $this->translatorAdmin->transChoices(
$this->ticketSolver->getTypeChoices(),
TicketSolver::getTypeChoices(),
'Ticket',
'type'
),
@@ -93,4 +90,4 @@ class TicketFormType extends AbstractType
]
);
}
}
}

Form/Ticket/TicketMessageFormType.php → Form/Ticket/TicketMessageAdminFormType.php Целия файл

@@ -6,12 +6,13 @@ use Lc\SovBundle\Doctrine\EntityManager;
use Lc\SovBundle\Model\Ticket\TicketMessageInterface;
use Lc\SovBundle\Translation\TranslatorAdmin;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class TicketMessageFormType extends AbstractType
class TicketMessageAdminFormType extends AbstractType
{
protected $em;
protected $translatorAdmin;
@@ -31,13 +32,12 @@ class TicketMessageFormType extends AbstractType
'required' => true
]
);

$builder->add(
'submit',
SubmitType::class,
[
'label' => $this->translatorAdmin->transAction('send')
]
'answerByAdmin',
HiddenType::class,
[
'data' => 1
]
);
}


+ 1
- 0
Model/Ticket/TicketModel.php Целия файл

@@ -22,6 +22,7 @@ abstract class TicketModel extends AbstractLightEntity implements TicketInterfac

const TICKET_STATUS_OPEN = 'open';
const TICKET_STATUS_BEING_PROCESSED = 'being-processed';
const TICKET_STATUS_PROCESSED = 'processed';
const TICKET_STATUS_CLOSED = 'closed';

/**

+ 13
- 11
Repository/Ticket/TicketRepositoryQuery.php Целия файл

@@ -8,7 +8,8 @@ use Lc\SovBundle\Repository\AbstractRepositoryQuery;

class TicketRepositoryQuery extends AbstractRepositoryQuery implements TicketRepositoryQueryInterface
{
protected bool $isJoinUser = false;

protected $isJoinUser = false;

public function __construct(TicketRepository $repository, PaginatorInterface $paginator)
{
@@ -22,6 +23,17 @@ class TicketRepositoryQuery extends AbstractRepositoryQuery implements TicketRep
->setParameter('user', $user);
}

public function joinUser(): self
{
if (!$this->isJoinUser) {
$this->isJoinUser = true;

return $this
->leftJoin('.user', 'user');
}
return $this;
}

public function filterByStatus($statusArray): self
{
return $this
@@ -61,14 +73,4 @@ class TicketRepositoryQuery extends AbstractRepositoryQuery implements TicketRep
return $this
->select('count(r.id) as count');
}

public function joinUser(): self
{
if (!$this->isJoinUser) {
$this->isJoinUser = true;

return $this->leftJoin('.user', 'u');
}
return $this;
}
}

+ 2
- 2
Resources/translations/admin.fr.yaml Целия файл

@@ -8,7 +8,7 @@ menu:
account: Mon compte
account_profile: Informations personnelles
account_password: Mot de passe
tickets: Tickets
tickets: Tickets <span class="float-right badge badge-info">%total_ticket_open%</span>
setting_global: Global

title:
@@ -107,7 +107,7 @@ entity:
default:
fields:
id: Id
createdAt: Créé à
createdAt: Créé le
user: Utilisateur
firstname: Prénom
lastname: Nom

+ 3
- 0
Resources/views/admin/ticket/detail.html.twig Целия файл

@@ -86,6 +86,9 @@
<div class="col-12">
{{ form_row(form_add_ticket_message.message) }}
</div>
<div class="col-12 text-right">
<button type="submit" class="btn btn-primary text-right">{{ 'send'|sov_trans_admin_action }}</button>
</div>
</div>
{{ form_end(form_add_ticket_message) }}
</div>

+ 31
- 14
Resources/views/admin/ticket/field/lastmessage.html.twig Целия файл

@@ -1,15 +1,32 @@
{# @TODO : génère une erreur sur le tableau de bord

{% set ticket = entity.instance %}
{% if ticket.ticketMessages %}
{% for message in ticket.ticketMessages %}
{% if loop.last %}
{% if message.answerByAdmin %}
Équipe
{% else %}
Client
{% endif %}
{% endif %}
{% endfor %}
{% if item is not defined %}
{% set item = entity.instance %}
{% endif %}
#}
{% set ticketMessage = ticket_container.solver.getLastMessage(item) %}
{% if ticketMessage.answerByAdmin != true %}
<span class="badge badge-danger">
New
</span>
{% endif %}

{{ ticketMessage.createdAt|date('d/m/Y H:i') }} par

{% if ticketMessage.answerByAdmin %}
Équipe
{% else %}
Client
{% endif %}


{# {% set ticket = entity.instance %} #}
{# {% if ticket.ticketMessages %} #}
{# {% for message in ticket.ticketMessages %} #}
{# {% if loop.last %} #}
{# {% if message.answerByAdmin %} #}
{# Équipe #}
{# {% else %} #}
{# Client #}
{# {% endif %} #}
{# {% endif %} #}
{# {% endfor %} #}
{# {% endif %} #}


+ 2
- 0
Resources/views/admin/ticket/field/status.html.twig Целия файл

@@ -6,6 +6,8 @@
{{ macro.badge_success(status|sov_trans_admin_choice('status','Ticket')) }}
{% elseif status == 'being-processed' %}
{{ macro.badge_warning(status|sov_trans_admin_choice('status','Ticket')) }}
{% elseif status == 'processed' %}
{{ macro.badge_info(status|sov_trans_admin_choice('status','Ticket')) }}
{% elseif status == 'closed' %}
{{ macro.badge_danger(status|sov_trans_admin_choice('status','Ticket')) }}
{% endif %}

+ 1
- 1
Resources/views/admin/ticket/macro.html.twig Целия файл

@@ -5,7 +5,7 @@
<th>Sujet</th>
<th>Statut</th>
<th>Dernier message</th>
<th></th>
<th>Actions</th>
</tr>
</thead>
<tbody>

+ 4
- 2
Resources/views/adminlte/block/menu.html.twig Целия файл

@@ -12,7 +12,9 @@
{% if item.icon is not empty %}
<i class="{{ item.icon }} nav-icon"></i>
{% endif %}
<p>{{ item.label|sov_trans_admin_menu }}</p>

<p>{{ item.label|sov_trans_admin_menu(item.translationParameters)|raw }}</p>

{% if item.hasSubItems %}<i class="right fas fa-angle-left"></i>{% endif %}
</a>
{% endif %}
@@ -46,4 +48,4 @@
</ul>
</nav>

{% block main_menu_after %}{% endblock %}
{% block main_menu_after %}{% endblock %}

+ 5
- 1
Resources/views/adminlte/macro/badge.html.twig Целия файл

@@ -10,6 +10,10 @@
{{ _self.badge('danger', title) }}
{% endmacro %}

{% macro badge_info(title) %}
{{ _self.badge('info', title) }}
{% endmacro %}

{% macro badge(status, title) %}
<span class="badge badge-{{ status }}">{{ title }}</span>
{% endmacro %}
{% endmacro %}

+ 3
- 2
Solver/Ticket/TicketSolver.php Целия файл

@@ -7,7 +7,7 @@ use Lc\SovBundle\Model\Ticket\TicketModel;

class TicketSolver
{
public function getTypeChoices(): array
public static function getTypeChoices(): array
{
return [
TicketModel::TYPE_GENERAL_QUESTION,
@@ -15,11 +15,12 @@ class TicketSolver
];
}

public function getStatusChoices(): array
public static function getStatusChoices(): array
{
return [
TicketModel::TICKET_STATUS_OPEN,
TicketModel::TICKET_STATUS_BEING_PROCESSED,
TicketModel::TICKET_STATUS_PROCESSED,
TicketModel::TICKET_STATUS_CLOSED,
];
}

+ 2
- 2
Translation/TranslatorAdmin.php Целия файл

@@ -21,9 +21,9 @@ class TranslatorAdmin
return $this->trans('action.' . $action);
}

public function transMenu($menu): string
public function transMenu($menu, $params = []): string
{
return $this->trans('menu.' . $menu);
return $this->trans('menu.' . $menu, $params);
}

public function transFlashMessage($type, $name, $entityClass = false, $params = []): string

+ 2
- 2
Twig/TranslatorTwigExtension.php Целия файл

@@ -112,9 +112,9 @@ class TranslatorTwigExtension extends AbstractExtension
return $this->translatorAdmin->transCard($cardName, $entityClass);
}

public function transAdminMenu($menuName)
public function transAdminMenu($menuName, $params = [])
{
return $this->translatorAdmin->transMenu($menuName);;
return $this->translatorAdmin->transMenu($menuName, $params);;
}

public function transAdminAction($actionName)

Loading…
Отказ
Запис