Charly 11 months ago
parent
commit
31ed564668
100 changed files with 2668 additions and 259 deletions
  1. +22
    -7
      Authenticator/LoginFormAuthenticator.php
  2. +33
    -1
      Builder/User/UserBuilder.php
  3. +20
    -0
      Component/ArrayComponent.php
  4. +12
    -7
      Component/CitiesComponent.php
  5. +5
    -0
      Component/DateComponent.php
  6. +6
    -3
      Component/EntityComponent.php
  7. +15
    -1
      Component/FileComponent.php
  8. +46
    -14
      Component/MetaComponent.php
  9. +10
    -1
      Container/ComponentContainer.php
  10. +8
    -0
      Container/File/FileContainer.php
  11. +7
    -0
      Container/Newsletter/NewsletterContainer.php
  12. +6
    -0
      Container/Reminder/ReminderContainer.php
  13. +7
    -0
      Container/Setting/SiteSettingContainer.php
  14. +6
    -0
      Container/Site/NewsContainer.php
  15. +6
    -0
      Container/Site/PageContainer.php
  16. +5
    -0
      Container/Site/SiteContainer.php
  17. +7
    -0
      Container/Ticket/TicketContainer.php
  18. +5
    -0
      Container/Ticket/TicketMessageContainer.php
  19. +5
    -0
      Container/User/GroupUserContainer.php
  20. +5
    -0
      Container/User/UserContainer.php
  21. +99
    -50
      Controller/AbstractAdminController.php
  22. +81
    -48
      Controller/ControllerTrait.php
  23. +50
    -0
      Controller/Dashboard/CommandAdminController.php
  24. +3
    -2
      Controller/Dashboard/DashboardAdminController.php
  25. +43
    -5
      Controller/ErrorController.php
  26. +4
    -4
      Controller/Security/SecurityAdminController.php
  27. +120
    -0
      Controller/User/UserAdminController.php
  28. +88
    -0
      Definition/ApplicationDefinition.php
  29. +16
    -7
      Definition/Field/AbstractFieldDefinition.php
  30. +2
    -2
      Definition/Field/Site/PageFieldDefinition.php
  31. +13
    -13
      Definition/SiteSettingDefinition.php
  32. +1
    -1
      Definition/SiteSettingDefinitionInterface.php
  33. +21
    -16
      DependencyInjection/LcSovExtension.php
  34. +9
    -1
      Doctrine/Extension/BlameableInterface.php
  35. +2
    -2
      Doctrine/Extension/BlameableTrait.php
  36. +2
    -0
      Doctrine/Extension/DevAliasInterface.php
  37. +26
    -0
      Doctrine/Extension/ImageTrait.php
  38. +10
    -0
      Doctrine/Extension/OpenGraphInterface.php
  39. +2
    -2
      Doctrine/Extension/OpenGraphTrait.php
  40. +8
    -0
      Doctrine/Extension/SeoInterface.php
  41. +3
    -0
      Doctrine/Extension/SluggableInterface.php
  42. +5
    -0
      Doctrine/Extension/SortableInterface.php
  43. +4
    -0
      Doctrine/Extension/StatusInterface.php
  44. +6
    -0
      Doctrine/Extension/TimestampableInterface.php
  45. +5
    -1
      Doctrine/Extension/TranslatableInterface.php
  46. +4
    -1
      Doctrine/Pattern/AbstractFullEntity.php
  47. +5
    -3
      EventListener/ExceptionListener.php
  48. +3
    -2
      Factory/File/FileFactory.php
  49. +3
    -2
      Factory/Newsletter/NewsletterFactory.php
  50. +3
    -3
      Factory/Reminder/ReminderFactory.php
  51. +7
    -1
      Factory/Reminder/ReminderFactoryInterface.php
  52. +3
    -2
      Factory/Setting/SiteSettingFactory.php
  53. +11
    -1
      Factory/Setting/SiteSettingFactoryInterface.php
  54. +3
    -3
      Factory/Site/NewsFactory.php
  55. +3
    -1
      Factory/Site/NewsFactoryInterface.php
  56. +3
    -2
      Factory/Site/PageFactory.php
  57. +3
    -1
      Factory/Site/PageFactoryInterface.php
  58. +3
    -2
      Factory/Site/SiteFactory.php
  59. +3
    -1
      Factory/Site/SiteFactoryInterface.php
  60. +3
    -2
      Factory/Ticket/TicketFactory.php
  61. +3
    -1
      Factory/Ticket/TicketFactoryInterface.php
  62. +3
    -2
      Factory/Ticket/TicketMessageFactory.php
  63. +4
    -1
      Factory/Ticket/TicketMessageFactoryInterface.php
  64. +3
    -2
      Factory/User/GroupUserFactory.php
  65. +3
    -1
      Factory/User/GroupUserFactoryInterface.php
  66. +4
    -2
      Factory/User/UserFactory.php
  67. +3
    -1
      Factory/User/UserFactoryInterface.php
  68. +149
    -0
      Field/AssociationField.php
  69. +70
    -0
      Form/Common/CookieConsentTypeExtension.php
  70. +0
    -1
      Form/Common/FileManagerType.php
  71. +258
    -0
      Form/Common/FileUploadType.php
  72. +15
    -3
      Form/Setting/BaseSettingType.php
  73. +65
    -0
      Form/User/ConfirmDeleteUserFormType.php
  74. +32
    -0
      Generator/PdfGenerator.php
  75. +4
    -4
      LcSovBundle.php
  76. +48
    -2
      Model/File/FileInterface.php
  77. +77
    -1
      Model/Newsletter/NewsletterInterface.php
  78. +61
    -1
      Model/Reminder/ReminderInterface.php
  79. +17
    -0
      Model/Setting/SettingInterface.php
  80. +22
    -0
      Model/Setting/SiteSettingInterface.php
  81. +93
    -2
      Model/Site/NewsInterface.php
  82. +1
    -3
      Model/Site/NewsModel.php
  83. +64
    -1
      Model/Site/PageInterface.php
  84. +15
    -2
      Model/Site/SiteInterface.php
  85. +68
    -1
      Model/Ticket/TicketInterface.php
  86. +42
    -1
      Model/Ticket/TicketMessageInterface.php
  87. +2
    -1
      Model/Ticket/TicketModel.php
  88. +72
    -1
      Model/User/GroupUserInterface.php
  89. +101
    -1
      Model/User/UserInterface.php
  90. +18
    -2
      Model/User/UserModel.php
  91. +142
    -1
      Repository/AbstractRepositoryInterface.php
  92. +44
    -1
      Repository/AbstractRepositoryQuery.php
  93. +7
    -0
      Repository/AbstractStore.php
  94. +50
    -0
      Repository/File/FileRepositoryQueryInterface.php
  95. +1
    -2
      Repository/File/FileStore.php
  96. +30
    -0
      Repository/File/FileStoreInterface.php
  97. +51
    -0
      Repository/Newsletter/NewsletterRepositoryQueryInterface.php
  98. +1
    -2
      Repository/Newsletter/NewsletterStore.php
  99. +30
    -0
      Repository/Newsletter/NewsletterStoreInterface.php
  100. +76
    -1
      Repository/Reminder/ReminderRepositoryQueryInterface.php

+ 22
- 7
Authenticator/LoginFormAuthenticator.php View File



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


use Lc\SovBundle\Builder\User\UserBuilder;
use Lc\SovBundle\Container\User\UserContainer;
use Lc\SovBundle\Model\User\UserInterface;
use Lc\SovBundle\Repository\User\UserStore; 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\Form\FormFactoryInterface;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator; use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\RememberMeBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; 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\Credentials\PasswordCredentials;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport; use Symfony\Component\Security\Http\Authenticator\Passport\Passport;


protected UrlGeneratorInterface $urlGenerator; protected UrlGeneratorInterface $urlGenerator;
protected UserStore $userStore; protected UserStore $userStore;
protected UserBuilder $userBuilder;
protected FormFactoryInterface $formFactory; protected FormFactoryInterface $formFactory;
protected ParameterBagInterface $parameterBag; protected ParameterBagInterface $parameterBag;


public function __construct( public function __construct(
UrlGeneratorInterface $urlGenerator, UrlGeneratorInterface $urlGenerator,
UserStore $userStore,
UserContainer $userContainer,
FormFactoryInterface $formFactory, FormFactoryInterface $formFactory,
ParameterBagInterface $parameterBag ParameterBagInterface $parameterBag
) { ) {
$this->urlGenerator = $urlGenerator; $this->urlGenerator = $urlGenerator;
$this->userStore = $userStore;
$this->userStore = $userContainer->getStore();
$this->userBuilder = $userContainer->getBuilder();
$this->formFactory = $formFactory; $this->formFactory = $formFactory;
$this->parameterBag = $parameterBag; $this->parameterBag = $parameterBag;
} }


public function authenticate(Request $request): PassportInterface public function authenticate(Request $request): PassportInterface
{ {
$email = $request->request->get('email');

$email = trim($request->request->get('email'));
$password = $request->request->get('password'); $password = $request->request->get('password');
$csrfToken = $request->request->get('_csrf_token'); $csrfToken = $request->request->get('_csrf_token');


return $this->userStore->getOneByEmail($userIdentifier); return $this->userStore->getOneByEmail($userIdentifier);
}), }),
new PasswordCredentials($password), new PasswordCredentials($password),
[new CsrfTokenBadge('authenticate', $csrfToken)]
[
new CsrfTokenBadge('authenticate', $csrfToken),
new RememberMeBadge()
]
); );
} }


TokenInterface $token, TokenInterface $token,
string $providerKey string $providerKey
): RedirectResponse { ): RedirectResponse {



$routeName = 'home'; $routeName = 'home';
$email = $request->request->get('email');
$email = trim($request->request->get('email'));
$loginRedirection = $this->parameterBag->get('lc_sov.login_redirection'); $loginRedirection = $this->parameterBag->get('lc_sov.login_redirection');
$useReferer = $loginRedirection['redirect_referer']; $useReferer = $loginRedirection['redirect_referer'];
$rolesRedirection = $loginRedirection['roles_redirection']; $rolesRedirection = $loginRedirection['roles_redirection'];



$user = $this->userStore->getOneByEmail($email);

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->userStore->getOneByEmail($email);

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


} }
} }
} }
$this->userBuilder->setLastLogin($user);


if (isset($url) && !empty($url)) { if (isset($url) && !empty($url)) {
return new RedirectResponse($url); return new RedirectResponse($url);

+ 33
- 1
Builder/User/UserBuilder.php View File

namespace Lc\SovBundle\Builder\User; namespace Lc\SovBundle\Builder\User;


use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Lc\CaracoleBundle\Model\Address\AddressInterface;
use Lc\SovBundle\Doctrine\EntityInterface; use Lc\SovBundle\Doctrine\EntityInterface;
use Lc\SovBundle\Doctrine\Extension\BlameableInterface; use Lc\SovBundle\Doctrine\Extension\BlameableInterface;
use Lc\SovBundle\Factory\User\UserFactory;
use Lc\SovBundle\Model\Newsletter\NewsletterInterface; use Lc\SovBundle\Model\Newsletter\NewsletterInterface;
use Lc\SovBundle\Model\Ticket\TicketInterface;
use Lc\SovBundle\Model\User\UserInterface; use Lc\SovBundle\Model\User\UserInterface;
use Lc\SovBundle\Repository\RepositoryQueryInterface;
use Lc\SovBundle\Repository\User\UserStore; use Lc\SovBundle\Repository\User\UserStore;
use Lc\SovBundle\Solver\User\UserSolver; use Lc\SovBundle\Solver\User\UserSolver;


protected EntityManagerInterface $entityManager; protected EntityManagerInterface $entityManager;
protected UserStore $userStore; protected UserStore $userStore;
protected UserSolver $userSolver; protected UserSolver $userSolver;
public function __construct(EntityManagerInterface $entityManager, UserStore $userStore, UserSolver $userSolver)
protected UserFactory $userFactory;

public function __construct(EntityManagerInterface $entityManager, UserStore $userStore, UserSolver $userSolver, UserFactory $userFactory)
{ {
$this->entityManager = $entityManager; $this->entityManager = $entityManager;
$this->userStore = $userStore; $this->userStore = $userStore;
$this->userSolver = $userSolver; $this->userSolver = $userSolver;
$this->userFactory = $userFactory;
}


public function create(string $email, string $password, array $roles = [])
{
$user = $this->userFactory->create();
$user->setEmail($email);
$user->setPassword($password);

$user->setRoles($roles);
$this->entityManager->create($user);
$this->entityManager->flush();

return $user;

} }


public function setNewsletter(UserInterface $user, NewsletterInterface $newsletter, bool $subscribeNewsletter): void public function setNewsletter(UserInterface $user, NewsletterInterface $newsletter, bool $subscribeNewsletter): void


return $entity; return $entity;
} }

public function initBlameableUpdatedSystem(EntityInterface $entity) public function initBlameableUpdatedSystem(EntityInterface $entity)
{ {
$userSystem = $this->userStore->getOneByDevAlias('system'); $userSystem = $this->userStore->getOneByDevAlias('system');
$entity->setUpdatedBy($user); $entity->setUpdatedBy($user);
} }
} }

public function setLastLogin(?UserInterface $user)
{
if ($user instanceof UserInterface) {
$user->setLastLogin(new \DateTime());
$this->entityManager->update($user);
$this->entityManager->flush();
}
}
} }

+ 20
- 0
Component/ArrayComponent.php View File

<?php

namespace Lc\SovBundle\Component;

use Cocur\Slugify\Slugify;

class ArrayComponent
{
public function contains(array $array, $entity): bool
{
foreach($array as $entityTest) {
if(get_class($entityTest) == get_class($entity)
&& $entityTest->getId() == $entity->getId()) {
return true;
}
}

return false;
}
}

+ 12
- 7
Component/CitiesComponent.php View File



public function callAddressApi($query) public function callAddressApi($query)
{ {
$provider = $this->getGeocoderProvider() ;;
$query = GeocodeQuery::create($query)->withData('type', 'housenumber');
$results = $provider->geocodeQuery($query);
$resultsToReturn = array();
foreach($results as $result) {
if ($result->getStreetNumber() && strlen($result->getStreetNumber()) > 0) {
$resultsToReturn[] = $result;
$resultsToReturn = [];

if(!is_null($query)) {
$provider = $this->getGeocoderProvider() ;
$query = GeocodeQuery::create($query)->withData('type', 'housenumber');
$results = $provider->geocodeQuery($query);

foreach($results as $result) {
if ($result->getStreetNumber() && strlen($result->getStreetNumber()) > 0) {
$resultsToReturn[] = $result;
}
} }
} }

return $resultsToReturn; return $resultsToReturn;
} }



+ 5
- 0
Component/DateComponent.php View File

return $hour ; return $hour ;
} }


public function getTotalMinutes(\DateTimeInterface $time): int
{
return (int) $time->format('H') * 60 + (int) $time->format('i');
}

} }

+ 6
- 3
Component/EntityComponent.php View File

namespace Lc\SovBundle\Component; namespace Lc\SovBundle\Component;


use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface;
use Lc\SovBundle\Doctrine\Extension\BlameableInterface; use Lc\SovBundle\Doctrine\Extension\BlameableInterface;
use Lc\SovBundle\Doctrine\Extension\DevAliasInterface; use Lc\SovBundle\Doctrine\Extension\DevAliasInterface;
use Lc\SovBundle\Doctrine\Extension\SeoInterface; use Lc\SovBundle\Doctrine\Extension\SeoInterface;


public function duplicateEntity($entity) public function duplicateEntity($entity)
{ {

$newEntity = clone $entity; $newEntity = clone $entity;

$classMetadata = $this->entityManager->getClassMetadata(get_class($newEntity)); $classMetadata = $this->entityManager->getClassMetadata(get_class($newEntity));


//Dupplication de l'image ou du fichier lier //Dupplication de l'image ou du fichier lier
$newEntity->setCreatedAt(new \DateTime()); $newEntity->setCreatedAt(new \DateTime());
} }


$this->entityManager->create($newEntity);
$this->eventDispatcher->dispatch(new EntityComponentEvent($newEntity), EntityComponentEvent::DUPLICATE_EVENT); $this->eventDispatcher->dispatch(new EntityComponentEvent($newEntity), EntityComponentEvent::DUPLICATE_EVENT);


//Ne pas utiliser create ici! Sinon pour certaine entité comme ProductFamily on réajoute un orginProduct
$this->entityManager->create($newEntity, false);

return $newEntity; return $newEntity;
} }


} }
return $entity; return $entity;
} }
}
}

+ 15
- 1
Component/FileComponent.php View File



use Liip\ImagineBundle\Imagine\Cache\CacheManager; use Liip\ImagineBundle\Imagine\Cache\CacheManager;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;


class FileComponent class FileComponent
{ {
protected ParameterBagInterface $parameterBag; protected ParameterBagInterface $parameterBag;
protected CacheManager $liipCacheHelper; protected CacheManager $liipCacheHelper;
protected UrlGeneratorInterface $router;


public function __construct(ParameterBagInterface $parameterBag, CacheManager $liipCacheHelper)
public function __construct(ParameterBagInterface $parameterBag, CacheManager $liipCacheHelper, UrlGeneratorInterface $router)
{ {
$this->parameterBag = $parameterBag; $this->parameterBag = $parameterBag;
$this->liipCacheHelper = $liipCacheHelper; $this->liipCacheHelper = $liipCacheHelper;
$this->router = $router;
}

public function getAssetUrl($path)
{
$context = $this->router->getContext();
$host = $context->getScheme().'://'.$context->getHost().'/';

return $host.$path;
} }


/** /**
$path = substr($path, 1); $path = substr($path, 1);
} }


// gestion des accents et des espaces
$path = urldecode($path);

if ($path) { if ($path) {


$fileManagerFolder = substr($this->getFileManagerFolder(), 1); $fileManagerFolder = substr($this->getFileManagerFolder(), 1);

+ 46
- 14
Component/MetaComponent.php View File



class MetaComponent class MetaComponent
{ {
protected FileComponent $fileComponent;
protected StringComponent $stringComponent;


public function getMetaTitle($entity)
public function __construct(FileComponent $fileComponent, StringComponent $stringComponent)
{
$this->fileComponent = $fileComponent;
$this->stringComponent = $stringComponent;
}

public function getMetaTitle($entity, $title = null)
{ {
if($entity) { if($entity) {
if(method_exists($entity, 'getMetaTitle')) {
if(method_exists($entity, 'getMetaTitle') && $entity->getMetaTitle()) {
return $entity->getMetaTitle() ; return $entity->getMetaTitle() ;
} }
elseif(method_exists($entity, 'getTitle')) {
elseif(!is_null($title)) {
return $title;
}
elseif(method_exists($entity, 'getTitle') && $entity->getTitle()) {
return $entity->getTitle() ; return $entity->getTitle() ;
} }
} }
public function getMetaDescription($entity) public function getMetaDescription($entity)
{ {
if($entity) { if($entity) {
if(method_exists($entity, 'getMetaDescription')) {
if(method_exists($entity, 'getMetaDescription') && $entity->getMetaDescription()) {
return $entity->getMetaDescription() ; return $entity->getMetaDescription() ;
} }
elseif(method_exists($entity, 'getDescription')) {
return $entity->getDescription() ;
elseif(method_exists($entity, 'getDescription') && $entity->getDescription()) {
return $this->formatDescription($entity->getDescription());
} }
} }


return '' ; return '' ;
} }


public function getOpenGraphTitle($entity)
public function getOpenGraphTitle($entity, $title = null)
{ {
if($entity) { if($entity) {
if(method_exists($entity, 'getOpenGraphTitle')) {
if(method_exists($entity, 'getOpenGraphTitle') && $entity->getOpenGraphTitle()) {
return $entity->getOpenGraphTitle() ; return $entity->getOpenGraphTitle() ;
} }
elseif(method_exists($entity, 'getTitle')) {
elseif(!is_null($title)) {
return $title;
}
elseif(method_exists($entity, 'getTitle') && $entity->getTitle()) {
return $entity->getTitle() ; return $entity->getTitle() ;
} }
} }
public function getOpenGraphDescription($entity) public function getOpenGraphDescription($entity)
{ {
if($entity) { if($entity) {
if(method_exists($entity, 'getOpenGraphDescription')) {
if(method_exists($entity, 'getOpenGraphDescription') && $entity->getOpenGraphDescription()) {
return $entity->getOpenGraphDescription() ; return $entity->getOpenGraphDescription() ;
} }
elseif(method_exists($entity, 'getDescription')) {
return $entity->getDescription() ;
elseif(method_exists($entity, 'getDescription') && $entity->getDescription()) {
return $this->formatDescription($entity->getDescription());
} }
} }


public function getOpenGraphImage($entity) public function getOpenGraphImage($entity)
{ {
if($entity) { if($entity) {
if(method_exists($entity, 'getOpenGraphImage')) {
if(method_exists($entity, 'getOpenGraphImage') && $entity->getOpenGraphImage()) {
return $entity->getOpenGraphImage() ; return $entity->getOpenGraphImage() ;
} }
elseif(method_exists($entity, 'getImage')) {
elseif(method_exists($entity, 'getImage') && $entity->getImage()) {
return $entity->getImage() ; return $entity->getImage() ;
} }
} }
return '' ; return '' ;
} }


public function getOpenGraphImageUrl($entity)
{
$image = $this->getOpenGraphImage($entity);
if($image && $image->getPath() && strlen($image->getPath()) > 0) {
return $this->fileComponent->getAssetUrl($image->getPath());
}

return '';
}

public function formatDescription($description)
{
$description = trim($description);
$description = $this->stringComponent->limitText($description, 50);
$description = str_replace("\r\n","",$description);

return $description;
}
} }

+ 10
- 1
Container/ComponentContainer.php View File



namespace Lc\SovBundle\Container; namespace Lc\SovBundle\Container;


use Lc\SovBundle\Component\ArrayComponent;
use Lc\SovBundle\Component\CitiesComponent; use Lc\SovBundle\Component\CitiesComponent;
use Lc\SovBundle\Component\CookieComponent; use Lc\SovBundle\Component\CookieComponent;
use Lc\SovBundle\Component\DateComponent; use Lc\SovBundle\Component\DateComponent;
protected NumberComponent $numberComponent; protected NumberComponent $numberComponent;
protected PointLocationComponent $pointLocationComponent; protected PointLocationComponent $pointLocationComponent;
protected StringComponent $stringComponent; protected StringComponent $stringComponent;
protected ArrayComponent $arrayComponent;


public function __construct( public function __construct(
CitiesComponent $citiesComponent, CitiesComponent $citiesComponent,
MetaComponent $metaComponent, MetaComponent $metaComponent,
NumberComponent $numberComponent, NumberComponent $numberComponent,
PointLocationComponent $pointLocationComponent, PointLocationComponent $pointLocationComponent,
StringComponent $stringComponent
StringComponent $stringComponent,
ArrayComponent $arrayComponent
) { ) {
$this->citiesComponent = $citiesComponent; $this->citiesComponent = $citiesComponent;
$this->cookieComponent = $cookieComponent; $this->cookieComponent = $cookieComponent;
$this->numberComponent = $numberComponent; $this->numberComponent = $numberComponent;
$this->pointLocationComponent = $pointLocationComponent; $this->pointLocationComponent = $pointLocationComponent;
$this->stringComponent = $stringComponent; $this->stringComponent = $stringComponent;
$this->arrayComponent = $arrayComponent;
} }


public function getCitiesComponent(): CitiesComponent public function getCitiesComponent(): CitiesComponent
{ {
return $this->stringComponent; return $this->stringComponent;
} }

public function getArrayComponent(): ArrayComponent
{
return $this->arrayComponent;
}
} }

+ 8
- 0
Container/File/FileContainer.php View File



namespace Lc\SovBundle\Container\File; namespace Lc\SovBundle\Container\File;


use App\Entity\File\File;
use Lc\SovBundle\Factory\File\FileFactory; use Lc\SovBundle\Factory\File\FileFactory;
use Lc\SovBundle\Model\File\FileInterface;
use Lc\SovBundle\Repository\File\FileRepositoryQuery; use Lc\SovBundle\Repository\File\FileRepositoryQuery;
use Lc\SovBundle\Repository\File\FileStore; use Lc\SovBundle\Repository\File\FileStore;


$this->store = $store; $this->store = $store;
} }


public static function getEntityFqcn()
{
return File::class;
}

public function getFactory(): FileFactory public function getFactory(): FileFactory
{ {
return $this->factory; return $this->factory;
{ {
return $this->store; return $this->store;
} }

} }

+ 7
- 0
Container/Newsletter/NewsletterContainer.php View File



namespace Lc\SovBundle\Container\Newsletter; namespace Lc\SovBundle\Container\Newsletter;


use App\Entity\Newsletter\Newsletter;
use Lc\SovBundle\Definition\Field\Newsletter\NewsletterFieldDefinition; use Lc\SovBundle\Definition\Field\Newsletter\NewsletterFieldDefinition;
use Lc\SovBundle\Factory\Newsletter\NewsletterFactory; use Lc\SovBundle\Factory\Newsletter\NewsletterFactory;
use Lc\SovBundle\Repository\Newsletter\NewsletterRepositoryQuery; use Lc\SovBundle\Repository\Newsletter\NewsletterRepositoryQuery;
$this->fieldDefinition = $fieldDefinition; $this->fieldDefinition = $fieldDefinition;
} }


public static function getEntityFqcn()
{
return Newsletter::class;
}


public function getFactory(): NewsletterFactory public function getFactory(): NewsletterFactory
{ {
return $this->factory; return $this->factory;

+ 6
- 0
Container/Reminder/ReminderContainer.php View File



namespace Lc\SovBundle\Container\Reminder; namespace Lc\SovBundle\Container\Reminder;


use App\Entity\Reminder\Reminder;
use Lc\SovBundle\Factory\Reminder\ReminderFactory; use Lc\SovBundle\Factory\Reminder\ReminderFactory;
use Lc\SovBundle\Repository\Reminder\ReminderRepositoryQuery; use Lc\SovBundle\Repository\Reminder\ReminderRepositoryQuery;
use Lc\SovBundle\Repository\Reminder\ReminderStore; use Lc\SovBundle\Repository\Reminder\ReminderStore;
$this->store = $store; $this->store = $store;
} }


public static function getEntityFqcn()
{
return Reminder::class;
}

public function getFactory(): ReminderFactory public function getFactory(): ReminderFactory
{ {
return $this->factory; return $this->factory;

+ 7
- 0
Container/Setting/SiteSettingContainer.php View File



namespace Lc\SovBundle\Container\Setting; namespace Lc\SovBundle\Container\Setting;


use App\Entity\Setting\SiteSetting;
use Lc\SovBundle\Definition\SiteSettingDefinition; use Lc\SovBundle\Definition\SiteSettingDefinition;
use Lc\SovBundle\Factory\Setting\SiteSettingFactory; use Lc\SovBundle\Factory\Setting\SiteSettingFactory;
use Lc\SovBundle\Repository\Setting\SiteSettingRepositoryQuery; use Lc\SovBundle\Repository\Setting\SiteSettingRepositoryQuery;
$this->settingSolver = $settingSolver; $this->settingSolver = $settingSolver;
} }



public static function getEntityFqcn()
{
return SiteSetting::class;
}

public function getFactory(): SiteSettingFactory public function getFactory(): SiteSettingFactory
{ {
return $this->factory; return $this->factory;

+ 6
- 0
Container/Site/NewsContainer.php View File



namespace Lc\SovBundle\Container\Site; namespace Lc\SovBundle\Container\Site;


use App\Entity\Site\News;
use Lc\SovBundle\Definition\Field\Site\NewsFieldDefinition; use Lc\SovBundle\Definition\Field\Site\NewsFieldDefinition;
use Lc\SovBundle\Factory\Site\NewsFactory; use Lc\SovBundle\Factory\Site\NewsFactory;
use Lc\SovBundle\Repository\Site\NewsRepositoryQuery; use Lc\SovBundle\Repository\Site\NewsRepositoryQuery;
$this->fieldDefinition = $fieldDefinition; $this->fieldDefinition = $fieldDefinition;
} }



public static function getEntityFqcn()
{
return News::class;
}
public function getFactory(): NewsFactory public function getFactory(): NewsFactory
{ {
return $this->factory; return $this->factory;

+ 6
- 0
Container/Site/PageContainer.php View File



namespace Lc\SovBundle\Container\Site; namespace Lc\SovBundle\Container\Site;


use App\Entity\Site\Page;
use Lc\SovBundle\Definition\Field\Site\PageFieldDefinition; use Lc\SovBundle\Definition\Field\Site\PageFieldDefinition;
use Lc\SovBundle\Factory\Site\PageFactory; use Lc\SovBundle\Factory\Site\PageFactory;
use Lc\SovBundle\Repository\Site\PageRepositoryQuery; use Lc\SovBundle\Repository\Site\PageRepositoryQuery;
$this->fieldDefinition = $fieldDefinition; $this->fieldDefinition = $fieldDefinition;
} }


public static function getEntityFqcn()
{
return Page::class;
}

public function getFactory(): PageFactory public function getFactory(): PageFactory
{ {
return $this->factory; return $this->factory;

+ 5
- 0
Container/Site/SiteContainer.php View File



namespace Lc\SovBundle\Container\Site; namespace Lc\SovBundle\Container\Site;


use App\Entity\Site\Site;
use Lc\SovBundle\Factory\Site\SiteFactory; use Lc\SovBundle\Factory\Site\SiteFactory;
use Lc\SovBundle\Repository\Site\SiteRepositoryQuery; use Lc\SovBundle\Repository\Site\SiteRepositoryQuery;
use Lc\SovBundle\Repository\Site\SiteStore; use Lc\SovBundle\Repository\Site\SiteStore;
$this->store = $store; $this->store = $store;
} }


public static function getEntityFqcn()
{
return Site::class;
}
public function getFactory(): SiteFactory public function getFactory(): SiteFactory
{ {
return $this->factory; return $this->factory;

+ 7
- 0
Container/Ticket/TicketContainer.php View File



namespace Lc\SovBundle\Container\Ticket; namespace Lc\SovBundle\Container\Ticket;


use App\Entity\Ticket\Ticket;
use Lc\SovBundle\Builder\Ticket\TicketBuilder; use Lc\SovBundle\Builder\Ticket\TicketBuilder;
use Lc\SovBundle\Definition\Field\Ticket\TicketFieldDefinition; use Lc\SovBundle\Definition\Field\Ticket\TicketFieldDefinition;
use Lc\SovBundle\Factory\Ticket\TicketFactory; use Lc\SovBundle\Factory\Ticket\TicketFactory;
$this->fieldDefinition = $fieldDefinition; $this->fieldDefinition = $fieldDefinition;
} }



public static function getEntityFqcn()
{
return Ticket::class;
}

public function getFactory(): TicketFactory public function getFactory(): TicketFactory
{ {
return $this->factory; return $this->factory;

+ 5
- 0
Container/Ticket/TicketMessageContainer.php View File



namespace Lc\SovBundle\Container\Ticket; namespace Lc\SovBundle\Container\Ticket;


use App\Entity\Ticket\TicketMessage;
use Lc\SovBundle\Builder\Ticket\TicketMessageBuilder; use Lc\SovBundle\Builder\Ticket\TicketMessageBuilder;
use Lc\SovBundle\Factory\Ticket\TicketMessageFactory; use Lc\SovBundle\Factory\Ticket\TicketMessageFactory;
use Lc\SovBundle\Repository\Ticket\TicketMessageRepositoryQuery; use Lc\SovBundle\Repository\Ticket\TicketMessageRepositoryQuery;
$this->builder = $builder; $this->builder = $builder;
} }


public static function getEntityFqcn()
{
return TicketMessage::class;
}
public function getFactory(): TicketMessageFactory public function getFactory(): TicketMessageFactory
{ {
return $this->factory; return $this->factory;

+ 5
- 0
Container/User/GroupUserContainer.php View File



namespace Lc\SovBundle\Container\User; namespace Lc\SovBundle\Container\User;


use App\Entity\User\GroupUser;
use Lc\SovBundle\Factory\User\GroupUserFactory; use Lc\SovBundle\Factory\User\GroupUserFactory;
use Lc\SovBundle\Repository\User\GroupUserRepositoryQuery; use Lc\SovBundle\Repository\User\GroupUserRepositoryQuery;
use Lc\SovBundle\Repository\User\GroupUserStore; use Lc\SovBundle\Repository\User\GroupUserStore;
$this->store = $store; $this->store = $store;
} }


public static function getEntityFqcn()
{
return GroupUser::class;
}
public function getFactory(): GroupUserFactory public function getFactory(): GroupUserFactory
{ {
return $this->factory; return $this->factory;

+ 5
- 0
Container/User/UserContainer.php View File



namespace Lc\SovBundle\Container\User; namespace Lc\SovBundle\Container\User;


use App\Entity\User\User;
use Lc\SovBundle\Builder\User\UserBuilder; use Lc\SovBundle\Builder\User\UserBuilder;
use Lc\SovBundle\Definition\Field\User\UserFieldDefinition; use Lc\SovBundle\Definition\Field\User\UserFieldDefinition;
use Lc\SovBundle\Definition\RolesDefinitionInterface; use Lc\SovBundle\Definition\RolesDefinitionInterface;
$this->fieldDefinition = $fieldDefinition; $this->fieldDefinition = $fieldDefinition;
$this->rolesDefinition = $rolesDefinition; $this->rolesDefinition = $rolesDefinition;
} }
public static function getEntityFqcn()
{
return User::class;
}


public function getFactory(): UserFactory public function getFactory(): UserFactory
{ {

+ 99
- 50
Controller/AbstractAdminController.php View File

use EasyCorp\Bundle\EasyAdminBundle\Event\AfterEntityUpdatedEvent; use EasyCorp\Bundle\EasyAdminBundle\Event\AfterEntityUpdatedEvent;
use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeCrudActionEvent; use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeCrudActionEvent;
use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityDeletedEvent; use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityDeletedEvent;
use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityUpdatedEvent;
use EasyCorp\Bundle\EasyAdminBundle\Exception\ForbiddenActionException; use EasyCorp\Bundle\EasyAdminBundle\Exception\ForbiddenActionException;
use EasyCorp\Bundle\EasyAdminBundle\Exception\InsufficientEntityPermissionException; use EasyCorp\Bundle\EasyAdminBundle\Exception\InsufficientEntityPermissionException;
use EasyCorp\Bundle\EasyAdminBundle\Factory\ControllerFactory; use EasyCorp\Bundle\EasyAdminBundle\Factory\ControllerFactory;
use EasyCorp\Bundle\EasyAdminBundle\Provider\AdminContextProvider; use EasyCorp\Bundle\EasyAdminBundle\Provider\AdminContextProvider;
use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator; use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
use EasyCorp\Bundle\EasyAdminBundle\Security\Permission; use EasyCorp\Bundle\EasyAdminBundle\Security\Permission;
use Lc\CaracoleBundle\Model\Section\SectionInterface;
use Lc\SovBundle\Component\EntityComponent; use Lc\SovBundle\Component\EntityComponent;
use Lc\SovBundle\Definition\ActionDefinition; use Lc\SovBundle\Definition\ActionDefinition;
use Lc\SovBundle\Doctrine\Extension\DevAliasInterface; use Lc\SovBundle\Doctrine\Extension\DevAliasInterface;
use Lc\SovBundle\Doctrine\Extension\OpenGraphInterface;
use Lc\SovBundle\Doctrine\Extension\SeoInterface; use Lc\SovBundle\Doctrine\Extension\SeoInterface;
use Lc\SovBundle\Doctrine\Extension\SortableInterface; use Lc\SovBundle\Doctrine\Extension\SortableInterface;
use Lc\SovBundle\Doctrine\Extension\StatusInterface; use Lc\SovBundle\Doctrine\Extension\StatusInterface;
use Lc\SovBundle\Doctrine\Extension\TreeInterface; use Lc\SovBundle\Doctrine\Extension\TreeInterface;
use Lc\SovBundle\Field\CollectionField; use Lc\SovBundle\Field\CollectionField;
use Lc\SovBundle\Field\Filter\FilterManager; use Lc\SovBundle\Field\Filter\FilterManager;
use Lc\SovBundle\Field\ImageManagerField;
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\Model\User\UserInterface; use Lc\SovBundle\Model\User\UserInterface;
use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;


abstract class AbstractAdminController extends EaAbstractCrudController abstract class AbstractAdminController extends EaAbstractCrudController
{ {
if (Crud::PAGE_INDEX === $responseParameters->get('pageName')) { if (Crud::PAGE_INDEX === $responseParameters->get('pageName')) {
$responseParameters->set('fields', $this->configureFields('index')); $responseParameters->set('fields', $this->configureFields('index'));


if(isset($this->filtersForm)) {
if (isset($this->filtersForm)) {
$responseParameters->set('filters_form', $this->filtersForm); $responseParameters->set('filters_form', $this->filtersForm);
} }
} }
if ($action->getName() == ActionDefinition::WRITE_TO_USER) { if ($action->getName() == ActionDefinition::WRITE_TO_USER) {
$entity = $context->getEntity()->getInstance(); $entity = $context->getEntity()->getInstance();
if ($entity !== null) { if ($entity !== null) {
if(method_exists($entity, 'getUser')){
$url = $this->generateEaUrl(UserA) ->setController($context->getCrud()->getControllerFqcn())
->set('entityId', $entity->getParent()->getId())
->generateUrl();
if (method_exists($entity, 'getUser')) {
$url = $this->generateEaUrl(UserA)->setController($context->getCrud()->getControllerFqcn())
->set('entityId', $entity->getParent()->getId())
->generateUrl();
$action->setLinkUrl($url); $action->setLinkUrl($url);
} }
} else { } else {
} }
} }


protected function getRequestCrudAction() :string{
protected function getRequestCrudAction(): string
{
return $this->getRequestStack()->getCurrentRequest()->get('crudAction'); return $this->getRequestStack()->getCurrentRequest()->get('crudAction');
} }


public function configureCrud(Crud $crud): Crud public function configureCrud(Crud $crud): Crud
{ {
$crud = parent::configureCrud($crud); $crud = parent::configureCrud($crud);
if($this->getRequestCrudAction() === ActionDefinition::SORT) {
if ($this->getRequestCrudAction() === ActionDefinition::SORT) {
$crud->setPaginatorPageSize(9999); $crud->setPaginatorPageSize(9999);
}else {
} else {
$this->setMaxResults($crud); $this->setMaxResults($crud);
} }




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


throw new InsufficientEntityPermissionException($context); throw new InsufficientEntityPermissionException($context);
} }


$event = new BeforeEntityDeletedEvent($entityInstance);
$event = new BeforeEntityUpdatedEvent($entityInstance);
$this->get('event_dispatcher')->dispatch($event); $this->get('event_dispatcher')->dispatch($event);
$entityInstance = $event->getEntityInstance(); $entityInstance = $event->getEntityInstance();


$entityInstance->setPosition($elm['position']); $entityInstance->setPosition($elm['position']);
$this->updateEntity($entityManager, $entityInstance); $this->updateEntity($entityManager, $entityInstance);


$this->get('event_dispatcher')->dispatch(new AfterEntityUpdatedEvent($entityInstance));
// @TODO : ce dispatch déclenche UpdateProductfamilyAfterFlushEventSubscriber dans Caracole et on tombe sur une erreur "Maximum execution time"
//$this->get('event_dispatcher')->dispatch(new AfterEntityUpdatedEvent($entityInstance));
} }


$url = $this->get(AdminUrlGenerator::class) $url = $this->get(AdminUrlGenerator::class)
} }


public function duplicate( public function duplicate(
AdminContext $context,
EntityComponent $entityComponent,
TranslatorAdmin $translatorAdmin,
AdminContext $context,
EntityComponent $entityComponent,
TranslatorAdmin $translatorAdmin,
EntityManagerInterface $em EntityManagerInterface $em
) {
)
{
if (!$this->isGranted( if (!$this->isGranted(
Permission::EA_EXECUTE_ACTION, Permission::EA_EXECUTE_ACTION,
['action' => "duplicate", 'entity' => $context->getEntity()]
['action' => ActionDefinition::DUPLICATE, 'entity' => $context->getEntity()]
)) { )) {
throw new ForbiddenActionException($context); throw new ForbiddenActionException($context);
} }
} }


$newEntity = $entityComponent->duplicateEntity($context->getEntity()->getInstance()); $newEntity = $entityComponent->duplicateEntity($context->getEntity()->getInstance());
$em->create($newEntity);
$em->create($newEntity, false);
$em->flush(); $em->flush();


$url = $this->get(AdminUrlGenerator::class) $url = $this->get(AdminUrlGenerator::class)
->setEntityId($newEntity->getId()) ->setEntityId($newEntity->getId())
->generateUrl(); ->generateUrl();


$this->addFlashTranslator('success', 'duplicated');
$this->addFlashTranslator('success', ActionDefinition::DUPLICATE);


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


public function isRepositoryQueryFiltered():bool{
if(($this->filtersForm && $this->filtersForm->isSubmitted()) || $this->isRepositoryQueryFiltered){
public function isRepositoryQueryFiltered(): bool
{
if (($this->filtersForm && $this->filtersForm->isSubmitted()) || $this->isRepositoryQueryFiltered) {
return true; return true;
}else{
} else {
return false; return false;
} }
} }

public function createIndexRepositoryQuery( public function createIndexRepositoryQuery(
SearchDto $searchDto,
EntityDto $entityDto,
FieldCollection $fields,
SearchDto $searchDto,
EntityDto $entityDto,
FieldCollection $fields,
FilterCollection $filters FilterCollection $filters
): RepositoryQueryInterface {
): RepositoryQueryInterface
{
$repositoryQuery = $this->get(EntityRepository::class)->createRepositoryQuery( $repositoryQuery = $this->get(EntityRepository::class)->createRepositoryQuery(
$this->getRepositoryQuery(), $this->getRepositoryQuery(),
$searchDto, $searchDto,




public function createSortRepositoryQuery( public function createSortRepositoryQuery(
SearchDto $searchDto,
EntityDto $entityDto,
FieldCollection $fields,
FilterCollection $filters
): RepositoryQueryInterface {
return $this->createIndexRepositoryQuery($searchDto,$entityDto, $fields, $filters);
SearchDto $searchDto,
EntityDto $entityDto,
FieldCollection $fields,
FilterCollection $filters
): RepositoryQueryInterface
{
$repositoryQuery = $this->createIndexRepositoryQuery($searchDto, $entityDto, $fields, $filters);
if ($this->isInstanceOf(StatusInterface::class)) {
$repositoryQuery->filterIsOnline();
}
$repositoryQuery->orderBy('position', 'asc');
return $repositoryQuery;
} }

public function createIndexQueryBuilder( public function createIndexQueryBuilder(
SearchDto $searchDto,
EntityDto $entityDto,
FieldCollection $fields,
SearchDto $searchDto,
EntityDto $entityDto,
FieldCollection $fields,
FilterCollection $filters FilterCollection $filters
): QueryBuilder {
): QueryBuilder
{
$repositoryQuery = $this->createIndexRepositoryQuery($searchDto, $entityDto, $fields, $filters); $repositoryQuery = $this->createIndexRepositoryQuery($searchDto, $entityDto, $fields, $filters);
return $repositoryQuery->getQueryBuilder(); return $repositoryQuery->getQueryBuilder();
} }


public function createSortQueryBuilder( public function createSortQueryBuilder(
SearchDto $searchDto,
EntityDto $entityDto,
FieldCollection $fields,
SearchDto $searchDto,
EntityDto $entityDto,
FieldCollection $fields,
FilterCollection $filters FilterCollection $filters
): QueryBuilder {
): QueryBuilder
{
$repositoryQuery = $this->createSortRepositoryQuery($searchDto, $entityDto, $fields, $filters); $repositoryQuery = $this->createSortRepositoryQuery($searchDto, $entityDto, $fields, $filters);
return $repositoryQuery->getQueryBuilder(); return $repositoryQuery->getQueryBuilder();
} }


public function deleteEntity(EntityManagerInterface $entityManager, $entityInstance): void public function deleteEntity(EntityManagerInterface $entityManager, $entityInstance): void
{ {
$entityManager->delete($entityInstance);
if ($this->isInstanceOf(StatusInterface::class)) {
$entityInstance->setStatus(-1);
$entityManager->update($entityInstance);
} else {
$entityManager->delete($entityInstance);
}
$entityManager->flush(); $entityManager->flush();
$this->get(FlashBagTranslator::class)->add('success', 'deleted', $this->getTranslationEntityName()); $this->get(FlashBagTranslator::class)->add('success', 'deleted', $this->getTranslationEntityName());
} }


public function autocompleteFilter(AdminContext $context): JsonResponse public function autocompleteFilter(AdminContext $context): JsonResponse
{ {
$queryBuilder = $this->createIndexQueryBuilder(
$repositoryQuery = $this->get(EntityRepository::class)->createRepositoryQuery(
$this->getRepositoryQuery(),
$context->getSearch(), $context->getSearch(),
$context->getEntity(), $context->getEntity(),
FieldCollection::new([]), FieldCollection::new([]),
FilterCollection::new() FilterCollection::new()
); );

if ($this->isInstanceOf(StatusInterface::class)) {
$repositoryQuery->filterIsOnlineAndOffline();
}

$autocompleteContext = $context->getRequest()->get(AssociationField::PARAM_AUTOCOMPLETE_CONTEXT); $autocompleteContext = $context->getRequest()->get(AssociationField::PARAM_AUTOCOMPLETE_CONTEXT);


/** @var CrudControllerInterface $controller */ /** @var CrudControllerInterface $controller */
)->getByProperty($autocompleteContext['propertyName']); )->getByProperty($autocompleteContext['propertyName']);


$filterManager = $this->get(FilterManager::class); $filterManager = $this->get(FilterManager::class);

$filterManager->applyFilter($queryBuilder, $field, $context->getRequest()->query->get('q'));
if ($filterManager->isRelationField($field->getProperty())) {
$queryBuilder->select($autocompleteContext['propertyName']);
} else {
$queryBuilder->select('entity.' . $autocompleteContext['propertyName']);
}
$filteredValue = ['value' => $context->getRequest()->query->get('q')];
$filterManager->applyFilter($repositoryQuery, $field, $filteredValue);
$repositoryQuery->select('.' . $autocompleteContext['propertyName']);


$responses = array(); $responses = array();
foreach ($queryBuilder->getQuery()->getArrayResult() as $result) {
foreach ($repositoryQuery->find() as $result) {
$responses[] = array_values($result)[0]; $responses[] = array_values($result)[0];
} }



return JsonResponse::fromJsonString(json_encode($responses)); return JsonResponse::fromJsonString(json_encode($responses));
} }


return $this->createForm($class, $data, $options); return $this->createForm($class, $data, $options);
} }


public function eaBeforeCrudActionEventDelete(AdminContext $context): ?Response
{
$event = new BeforeCrudActionEvent($context);
$this->container->get('event_dispatcher')->dispatch($event);
if ($event->isPropagationStopped()) {
return $event->getResponse();
}

if (!$this->isGranted(Permission::EA_EXECUTE_ACTION, ['action' => Action::DELETE, 'entity' => $context->getEntity()])) {
throw new ForbiddenActionException($context);
}
if (!$context->getEntity()->isAccessible()) {
throw new InsufficientEntityPermissionException($context);
}

$csrfToken = $context->getRequest()->request->get('token');

if (!$this->isCsrfTokenValid('ea-delete', $csrfToken)) {
return $this->redirectToRoute($context->getDashboardRouteName());
}
return null;
}

} }



+ 81
- 48
Controller/ControllerTrait.php View File

use Lc\SovBundle\Container\Ticket\TicketMessageContainer; use Lc\SovBundle\Container\Ticket\TicketMessageContainer;
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\Definition\ApplicationDefinition;
use Lc\SovBundle\Field\Filter\FilterManager; use Lc\SovBundle\Field\Filter\FilterManager;
use Lc\SovBundle\Generator\PdfGenerator;
use Lc\SovBundle\Repository\EntityRepository; use Lc\SovBundle\Repository\EntityRepository;
use Lc\SovBundle\Solver\Setting\SettingSolver; use Lc\SovBundle\Solver\Setting\SettingSolver;
use Lc\SovBundle\Translation\FlashBagTranslator; use Lc\SovBundle\Translation\FlashBagTranslator;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices;
use Symfony\Contracts\Translation\TranslatorInterface; use Symfony\Contracts\Translation\TranslatorInterface;
use Twig\Environment; use Twig\Environment;


trait ControllerTrait trait ControllerTrait
{ {
public static function getSubscribedServices()
/*
* Fonctions privées
*/
protected function _setNoLimitMemoryAndTime()
{
ini_set('memory_limit', '-1');
set_time_limit(0);
}

//TODO si vous avez une erreur avec le :array c'est qu'il faut passer à symfony 5.4.
//Suivez la procédure suivante : https://symfony.com/doc/current/setup/unstable_versions.html#upgrading-your-project-to-an-unstable-symfony-version
//En gros il faut changer tout les dépendances symfony/ qui sont en 5.3 par 5.4 dans composer.json
public static function getSubscribedServices(): array
{ {
return array_merge( return array_merge(
parent::getSubscribedServices(),
[
Environment::class => Environment::class,
Security::class => Security::class,
EntityManagerInterface::class => EntityManagerInterface::class,
UrlGeneratorInterface::class => UrlGeneratorInterface::class,
SessionInterface::class => SessionInterface::class,
PaginatorInterface::class => PaginatorInterface::class,
RequestStack::class => RequestStack::class,
EventDispatcherInterface::class => EventDispatcherInterface::class,
LoggerInterface::class => LoggerInterface::class,
ParameterBagInterface::class => ParameterBagInterface::class,
TranslatorInterface::class => TranslatorInterface::class,
TranslatorAdmin::class => TranslatorAdmin::class,
FilterManager::class => FilterManager::class,
FlashBagTranslator::class => FlashBagTranslator::class,
MailjetTransport::class => MailjetTransport::class,
AdminUrlGenerator::class => AdminUrlGenerator::class,
SettingSolver::class => SettingSolver::class,
ComponentContainer::class => ComponentContainer::class,
FileContainer::class => FileContainer::class,
NewsletterContainer::class => NewsletterContainer::class,
ReminderContainer::class => ReminderContainer::class,
NewsContainer::class => NewsContainer::class,
PageContainer::class => PageContainer::class,
SiteContainer::class => SiteContainer::class,
TicketContainer::class => TicketContainer::class,
TicketMessageContainer::class => TicketMessageContainer::class,
GroupUserContainer::class => GroupUserContainer::class,
UserContainer::class => UserContainer::class,
SiteSettingContainer::class => SiteSettingContainer::class,
EntityRepository::class => EntityRepository::class,
FileComponent::class => FileComponent::class,
]
parent::getSubscribedServices(),
ApplicationDefinition::getSubscribedContainerServices(),
[
ApplicationDefinition::class => ApplicationDefinition::class,
Environment::class => Environment::class,
Security::class => Security::class,
EntityManagerInterface::class => EntityManagerInterface::class,
UrlGeneratorInterface::class => UrlGeneratorInterface::class,
SessionInterface::class => SessionInterface::class,
PaginatorInterface::class => PaginatorInterface::class,
RequestStack::class => RequestStack::class,
EventDispatcherInterface::class => EventDispatcherInterface::class,
LoggerInterface::class => LoggerInterface::class,
ParameterBagInterface::class => ParameterBagInterface::class,
TranslatorInterface::class => TranslatorInterface::class,
PdfGenerator::class => PdfGenerator::class,
TranslatorAdmin::class => TranslatorAdmin::class,
FilterManager::class => FilterManager::class,
FlashBagTranslator::class => FlashBagTranslator::class,
MailjetTransport::class => MailjetTransport::class,
AdminUrlGenerator::class => AdminUrlGenerator::class,
SettingSolver::class => SettingSolver::class,
ComponentContainer::class => ComponentContainer::class,
EntityRepository::class => EntityRepository::class,
FileComponent::class => FileComponent::class,
KernelInterface::class => KernelInterface::class
]
); );
} }


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




$this->get(FlashBagTranslator::class)->add( $this->get(FlashBagTranslator::class)->add(
$type,
$translationKeyName,
$translationEntityName,
$translationParam
$type,
$translationKeyName,
$translationEntityName,
$translationParam
); );
} }


return in_array($interfaceName, class_implements($this->getEntityFqcn())); return in_array($interfaceName, class_implements($this->getEntityFqcn()));
} }


public function generateEaUrl(string $controller = null, string $action = null, int $entityId = null, array $extraParam = array()): string
{
public function generateEaUrl(
string $controller = null,
string $action = null,
int $entityId = null,
array $extraParam = array()
): string {
$adminUrlGenerator = $this->get(AdminUrlGenerator::class); $adminUrlGenerator = $this->get(AdminUrlGenerator::class);
if ($controller) { if ($controller) {
$adminUrlGenerator->setController($controller); $adminUrlGenerator->setController($controller);
return $this->get(Environment::class); return $this->get(Environment::class);
} }


public function getApplicationDefinition(): ApplicationDefinition
{
return $this->get(ApplicationDefinition::class);
}

public function getEntityManager(): EntityManagerInterface public function getEntityManager(): EntityManagerInterface
{ {
return $this->get(EntityManagerInterface::class); return $this->get(EntityManagerInterface::class);
return $this->get(TranslatorInterface::class); return $this->get(TranslatorInterface::class);
} }


public function getPdfGenerator(): PdfGenerator
{
return $this->get(PdfGenerator::class);
}

public function getTranslatorAdmin(): TranslatorAdmin public function getTranslatorAdmin(): TranslatorAdmin
{ {
return $this->get(TranslatorAdmin::class); return $this->get(TranslatorAdmin::class);
return $this->get(AdminUrlGenerator::class); return $this->get(AdminUrlGenerator::class);
} }


public function getKernel(): KernelInterface
{
return $this->get(KernelInterface::class);
}

public function getSettingSolver(): SettingSolver public function getSettingSolver(): SettingSolver
{ {
return $this->get(SettingSolver::class); return $this->get(SettingSolver::class);
return $this->get(SiteSettingContainer::class); return $this->get(SiteSettingContainer::class);
} }


}
public function setNoMemoryAndTimeLimit(): void
{
ini_set('memory_limit', '-1');
set_time_limit(0);
}

}

+ 50
- 0
Controller/Dashboard/CommandAdminController.php View File

<?php

namespace Lc\SovBundle\Controller\Dashboard;

use Lc\SovBundle\Controller\ControllerTrait;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class CommandAdminController extends AbstractController
{
use ControllerTrait;

/**
* @Route("/admin/command/cache/clear", name="admin_command_cache_clear")
*/
public function cacheClear(Request $request)
{
$this->doCommand('cache:clear');

$this->addFlashTranslator('success', 'command.cacheClear');

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

private function doCommand($command)
{
$kernel = $this->getKernel();
$env = $kernel->getEnvironment();

$application = new Application($kernel);
$application->setAutoExit(false);

$input = new ArrayInput(array(
'command' => $command,
'--env' => $env
));

$output = new BufferedOutput();
$application->run($input, $output);

$content = $output->fetch();

//return new Response($content);
}
}

+ 3
- 2
Controller/Dashboard/DashboardAdminController.php View File



use ControllerTrait; use ControllerTrait;


/**
* @Route("/admin", name="app_admin_dashboard")
*/
public function index(): Response public function index(): Response
{ {
return $this->render('@LcSov/adminlte/dashboard.html.twig'); return $this->render('@LcSov/adminlte/dashboard.html.twig');
return Dashboard::new() return Dashboard::new()
// the name visible to end users // the name visible to end users
->setTitle('LA CLIC !') ->setTitle('LA CLIC !')
// you can include HTML contents too (e.g. to link to an image)
->setTitle('<img src="assets/img/'.$this->get('parameter_bag')->get('app.admin.logo').'" width="100px">')
// the path defined in this method is passed to the Twig asset() function // the path defined in this method is passed to the Twig asset() function
->setFaviconPath('assets/img/frontend/favicon-pdl.png') ->setFaviconPath('assets/img/frontend/favicon-pdl.png')
// the domain used by default is 'messages' // the domain used by default is 'messages'

+ 43
- 5
Controller/ErrorController.php View File



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


use Symfony\Component\ErrorHandler\Exception\FlattenException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Mailer\MailerInterface;
use Throwable; use Throwable;
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
use Symfony\Component\Mime\Email;


class ErrorController extends AbstractController class ErrorController extends AbstractController
{ {


public function show(Throwable $exception, DebugLoggerInterface $logger = null)
{
if ($this->getRequestStack()->getCurrentRequest()->getPathInfo() == "/admin") {
public function show(
Request $request,
FlattenException $exception,
DebugLoggerInterface $logger = null,
MailerInterface $mailer
) {
//Si != de 404 on envoit un mail de debug
if ($exception->getStatusCode() != 404) {
$mailDebug = $this->getParameter('app.mail_debug');
if ($mailDebug) {
$message = "URL : " . $request->getUri() . "<br>";
$message .= "Code : " . $exception->getStatusCode() . "<br>";
$message .= "Message : " . $exception->getMessage() . "<br>";
$message .= "File : " . $exception->getFile() . "<br>";
$message .= "Line : " . $exception->getLine() . "<br><br>";
$message .= "Trace : <br>" . str_replace("\n", "<br>", $exception->getTraceAsString());
$siteName = $this->getParameter('app.site_name');
$email = (new Email())
->from('nepasrepondre@laclic.fr')
->to($mailDebug)
->subject(
'[' . $siteName . '] [ERREUR ' . $exception->getStatusCode() . '] ' . $exception->getMessage() . ''
)
->text(strip_tags($message))
->html($message);

$mailer->send($email);
}
}

if ($exception->getStatusCode() == 404) {
return $this->render('bundles/TwigBundle/Exception/error404.html.twig', [
"code" => $exception->getStatusCode(),
"message" => $exception->getMessage()
]);
}
if (str_contains($this->getRequestStack()->getCurrentRequest(), "/admin")) {
return $this->render('@LcSov/exception/error.html.twig', [ return $this->render('@LcSov/exception/error.html.twig', [
"code" => $exception->getCode(),
"code" => $exception->getStatusCode(),
"message" => $exception->getMessage() "message" => $exception->getMessage()
]); ]);
} else { } else {
return $this->render('bundles/TwigBundle/Exception/error.html.twig', [ return $this->render('bundles/TwigBundle/Exception/error.html.twig', [
"code" => $exception->getCode(),
"code" => $exception->getStatusCode(),
"message" => $exception->getMessage() "message" => $exception->getMessage()
]); ]);
} }

+ 4
- 4
Controller/Security/SecurityAdminController.php View File

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


// the string used to generate the CSRF token. If you don't define // the string used to generate the CSRF token. If you don't define
// this parameter, the login form won't include a CSRF token // this parameter, the login form won't include a CSRF token
'target_path' => $this->generateUrl('app_admin_dashboard'), 'target_path' => $this->generateUrl('app_admin_dashboard'),


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


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


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


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

+ 120
- 0
Controller/User/UserAdminController.php View File



namespace Lc\SovBundle\Controller\User; namespace Lc\SovBundle\Controller\User;


use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
use Doctrine\ORM\EntityManagerInterface;
use EasyCorp\Bundle\EasyAdminBundle\Collection\EntityCollection; use EasyCorp\Bundle\EasyAdminBundle\Collection\EntityCollection;
use EasyCorp\Bundle\EasyAdminBundle\Config\Action; use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Config\KeyValueStore;
use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext;
use EasyCorp\Bundle\EasyAdminBundle\Event\AfterCrudActionEvent;
use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeCrudActionEvent;
use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityDeletedEvent;
use EasyCorp\Bundle\EasyAdminBundle\Exception\EntityRemoveException;
use EasyCorp\Bundle\EasyAdminBundle\Exception\ForbiddenActionException;
use EasyCorp\Bundle\EasyAdminBundle\Exception\InsufficientEntityPermissionException;
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField; use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField;
use EasyCorp\Bundle\EasyAdminBundle\Field\EmailField; use EasyCorp\Bundle\EasyAdminBundle\Field\EmailField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use EasyCorp\Bundle\EasyAdminBundle\Security\Permission;
use Lc\SovBundle\Container\User\UserContainer; use Lc\SovBundle\Container\User\UserContainer;
use Lc\SovBundle\Controller\AbstractAdminController; use Lc\SovBundle\Controller\AbstractAdminController;
use Lc\SovBundle\Definition\ActionDefinition; use Lc\SovBundle\Definition\ActionDefinition;
use Lc\SovBundle\Definition\ApplicationDefinition;
use Lc\SovBundle\Definition\RolesDefinition; use Lc\SovBundle\Definition\RolesDefinition;
use Lc\SovBundle\Definition\RolesDefinitionInterface; use Lc\SovBundle\Definition\RolesDefinitionInterface;
use Lc\SovBundle\Doctrine\EntityManager; use Lc\SovBundle\Doctrine\EntityManager;
use Lc\SovBundle\Doctrine\Extension\BlameableInterface;
use Lc\SovBundle\Factory\User\UserFactory; use Lc\SovBundle\Factory\User\UserFactory;
use Lc\SovBundle\Form\User\ConfirmDeleteUserFormType;
use Lc\SovBundle\Model\User\UserInterface;
use Lc\SovBundle\Translation\FlashBagTranslator;
use Lc\SovBundle\Translation\TranslatorAdmin; use Lc\SovBundle\Translation\TranslatorAdmin;
use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpFoundation\Session\SessionInterface;
{ {
return $this->get(UserContainer::class)->getFactory()->create(); return $this->get(UserContainer::class)->getFactory()->create();
} }

public function delete(AdminContext $context)
{
$entityManager = $this->getEntityManager();

// Todo envisager un refactor similaire pour toutes les fonctions CRUD
$eaBeforeCrudActionEventDelete = $this->eaBeforeCrudActionEventDelete($context);
if (!is_null($eaBeforeCrudActionEventDelete)) {
return $eaBeforeCrudActionEventDelete;
}

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

$event = new BeforeEntityDeletedEvent($user);
$this->container->get('event_dispatcher')->dispatch($event);
if ($event->isPropagationStopped()) {
return $event->getResponse();
}

$user = $event->getEntityInstance();


// Creéer formulaire avec un champ confirm
$confirmDeleteUserForm = $this->createForm(ConfirmDeleteUserFormType::class, null, array(
'action' => $this->getAdminUrlGenerator()->generateUrl()
));
$confirmDeleteUserForm->handleRequest($context->getRequest());

$entityManager->delete($user);

$warningMessages = $this->getDeleteUserWarningMessageList($user);

//Avant la suppression on s'assure que l'utilisateur à confirmer et qu'il n'y aucun message d'erreur
if ($confirmDeleteUserForm->isSubmitted() && count($warningMessages['danger']) === 0) {
//Détecter les tables qui possède des relations avec un champ qui n'existe plus
//Dans le cas ci-dessous détecter les adresses lié à un utilisateur qui n'existe plus
//SELECT * FROM address a LEFT OUTER JOIN user u ON(u.id=a.user_id) WHERE u.id is null
try {
$entityManager->flush();
$this->addFlashTranslator('success', 'deleted');
} catch (ForeignKeyConstraintViolationException $e) {
throw new EntityRemoveException(['entity_name' => $context->getEntity()->getName(), 'message' => $e->getMessage()]);
}
return $this->redirect($this->getAdminUrlGenerator()->setAction(Crud::PAGE_INDEX)->setEntityId(null)->generateUrl());

}else{
if($confirmDeleteUserForm->isSubmitted()){
$this->addFlashTranslator('error', 'cannotDelete');
}
}

$responseParameters = $this->configureResponseParameters(KeyValueStore::new([
'pageName' => Crud::PAGE_DETAIL,
'templatePath' => '@LcSov/adminlte/crud/delete.html.twig',
'confirm_delete_user_form' => $confirmDeleteUserForm->createView(),
'global_actions' => array(),
'batch_actions' => array(),
'warning_message_list' => $warningMessages
]));

$event = new AfterCrudActionEvent($context, $responseParameters);
$this->get('event_dispatcher')->dispatch($event);
if ($event->isPropagationStopped()) {
return $event->getResponse();
}

return $responseParameters;
}

public function getDeleteUserWarningMessageList(UserInterface $user): array
{
$warningMessages = array();
$warningMessages['danger'] = [];
$warningMessages['warning'] = [];
$warningMessages['info'] = [];


$entityManager = $this->getEntityManager();

$entityToDeleteListCount = array();
$entityToDeleteListName = array();
foreach ($entityManager->getUnitOfWork()->getScheduledEntityDeletions() as $entityToDelete) {
if (isset($entityToDeleteListCount[(new \ReflectionClass($entityToDelete))->getShortName()])) {
$entityToDeleteListCount[(new \ReflectionClass($entityToDelete))->getShortName()]++;
} else {
$entityToDeleteListCount[(new \ReflectionClass($entityToDelete))->getShortName()] = 1;
}
$entityToDeleteListName[(new \ReflectionClass($entityToDelete))->getShortName()][] = $entityToDelete->getId();
}

foreach ($entityToDeleteListCount as $entityName => $entityToDeleteCount) {
$warningMessages['info'][] = $this->getTranslatorAdmin()->transFlashMessage(
'error',
'deleteEntityCascade',
'User',
array(
'%entity%' => $this->getTranslatorAdmin()->trans('entity.'.$entityName.'.label_plurial'),
'%count%' => $entityToDeleteCount
)
);
}

return $warningMessages;
}
} }

+ 88
- 0
Definition/ApplicationDefinition.php View File

<?php

namespace Lc\SovBundle\Definition;

use Lc\SovBundle\Container\ComponentContainer;
use Lc\SovBundle\Container\File\FileContainer;
use Lc\SovBundle\Container\Newsletter\NewsletterContainer;
use Lc\SovBundle\Container\Reminder\ReminderContainer;
use Lc\SovBundle\Container\Setting\SiteSettingContainer;
use Lc\SovBundle\Container\Site\NewsContainer;
use Lc\SovBundle\Container\Site\PageContainer;
use Lc\SovBundle\Container\Site\SiteContainer;
use Lc\SovBundle\Container\Ticket\TicketContainer;
use Lc\SovBundle\Container\Ticket\TicketMessageContainer;
use Lc\SovBundle\Container\User\GroupUserContainer;
use Lc\SovBundle\Container\User\UserContainer;
use function Symfony\Component\String\u;

class ApplicationDefinition
{

public static function getContainerList(): array
{
return [
FileContainer::class,
NewsletterContainer::class,
ReminderContainer::class,
NewsContainer::class,
PageContainer::class,
SiteContainer::class,
TicketContainer::class,
TicketMessageContainer::class,
GroupUserContainer::class,
UserContainer::class,
SiteSettingContainer::class,
ComponentContainer::class
];
}

public function getContainerByEntityFqcn(string $entityFqcn)
{
foreach (static::getContainerList() as $containerFqcn){
if($this->isContainerManageEntity($containerFqcn)){
if ($containerFqcn::getEntityFqcn() == $entityFqcn) {
return $containerFqcn;
}
}
}
return null;
}

public function isContainerManageEntity(string $containerFqcn)
{
if(method_exists($containerFqcn, 'getEntityFqcn') ){
return true;
}
return false;
}

public static function getSubscribedContainerServices(): array
{
$array = [];


foreach (static::getContainerList() as $container) {
$array[$container] = $container;
}

return $array;
}


public static function getContainerListForTwigGlobals(): array
{
$array = [];

foreach (static::getContainerList() as $containerNamespace) {
//récupère le nom du fichier dans le namespace du container
$key = u(substr($containerNamespace, strrpos($containerNamespace, '\\')))->snake();

$array[$key->toString()] = '@' . $containerNamespace;
}

return $array;
}


}

+ 16
- 7
Definition/Field/AbstractFieldDefinition.php View File

use EasyCorp\Bundle\EasyAdminBundle\Field\IntegerField; use EasyCorp\Bundle\EasyAdminBundle\Field\IntegerField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField; use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use Lc\SovBundle\Field\AssociationField;
use Lc\SovBundle\Field\CKEditorField;
use Lc\SovBundle\Field\CollectionField; use Lc\SovBundle\Field\CollectionField;
use Lc\SovBundle\Field\ImageManagerField; use Lc\SovBundle\Field\ImageManagerField;
use Lc\SovBundle\Field\StatusField; use Lc\SovBundle\Field\StatusField;
{ {
return [ return [
'id' => IntegerField::new('id')->onlyOnIndex()->setSortable(true), 'id' => IntegerField::new('id')->onlyOnIndex()->setSortable(true),
'title' => TextField::new('title'),
'description' => CKEditorField::new('description'),
'image' => ImageManagerField::new('image'),
'metaTitle' => TextField::new('metaTitle') 'metaTitle' => TextField::new('metaTitle')
->setLabel('Meta : title') ->setLabel('Meta : title')
->setHelp('Affiché dans les résultats de recherche Google'), ->setHelp('Affiché dans les résultats de recherche Google'),
'metaDescription' => TextareaField::new('metaDescription') 'metaDescription' => TextareaField::new('metaDescription')
->setLabel('Meta : description') ->setLabel('Meta : description')
->setHelp('Affiché dans les résultats de recherche Google'), ->setHelp('Affiché dans les résultats de recherche Google'),
'openGraphTitle' => TextField::new('openGraphTitle')
->setLabel('OpenGraph : titre'),
'openGraphDescription' => TextareaField::new('openGraphDescription')
->setLabel('OpenGraph : description'),
'openGraphImage' => ImageManagerField::new('openGraphImage')
->setLabel('OpenGraph : image'),
'oldUrls' => CollectionField::new('oldUrls') 'oldUrls' => CollectionField::new('oldUrls')
->setFormTypeOption('entry_type', TextType::class) ->setFormTypeOption('entry_type', TextType::class)
->setLabel('Anciennes urls du document') ->setLabel('Anciennes urls du document')
->hideOnIndex(), ->hideOnIndex(),
'openGraphTitle' => TextField::new('openGraphTitle')
->setLabel('OpenGraph : titre')
->setHelp('Utilisé par les réseaux sociaux pour récupérer le titre de la page'),
'openGraphDescription' => TextareaField::new('openGraphDescription')
->setLabel('OpenGraph : description')
->setHelp('Utilisé par les réseaux sociaux pour récupérer la description de la page'),
'openGraphImage' => ImageManagerField::new('openGraphImage')
->setLabel('OpenGraph : image'),
'devAlias' => TextField::new('devAlias')->hideOnIndex(), 'devAlias' => TextField::new('devAlias')->hideOnIndex(),
'status' => StatusField::new('status')->setSortable(true), 'status' => StatusField::new('status')->setSortable(true),
'createdAt' => DateTimeField::new('createdAt')->setSortable(true), 'createdAt' => DateTimeField::new('createdAt')->setSortable(true),
'updatedAt' => DateTimeField::new('updatedAt')->setSortable(true), 'updatedAt' => DateTimeField::new('updatedAt')->setSortable(true),
'createdBy' => AssociationField::new('createdBy'),
'updatedBy' => AssociationField::new('updatedBy')
]; ];
} }


$fieldArray = []; $fieldArray = [];
foreach($configureFieldArray as $fieldName) { foreach($configureFieldArray as $fieldName) {
if(isset($allFieldArray[$fieldName])) { if(isset($allFieldArray[$fieldName])) {
$fieldArray[] = $allFieldArray[$fieldName];
$fieldArray[$fieldName] = $allFieldArray[$fieldName];
} }
else { else {
throw new \ErrorException('Le field "'.$fieldName.'" n\'est pas défini dans configureFields()'); throw new \ErrorException('Le field "'.$fieldName.'" n\'est pas défini dans configureFields()');

+ 2
- 2
Definition/Field/Site/PageFieldDefinition.php View File

]; ];
} }


public function configurePanelMain(): array
public function configurePanelGeneral(): array
{ {
return [ return [
'title', 'title',


public function configurePanels(): array public function configurePanels(): array
{ {
return ['main', 'seo', 'conf'];
return ['general', 'seo', 'opengraph', 'conf'];
} }


public function configureFields(): array public function configureFields(): array

+ 13
- 13
Definition/SiteSettingDefinition.php View File

{ {
// général // général
$this->addSettingSelect( $this->addSettingSelect(
[
'category' => self::CATEGORY_GENERAL,
'name' => self::SETTING_MAINTENANCE,
'choices' => [
'Non' => 0,
'Oui' => 1,
]
[
'category' => self::CATEGORY_GENERAL,
'name' => self::SETTING_MAINTENANCE,
'choices' => [
'Non' => 0,
'Oui' => 1,
] ]
]
); );


$this->addSettingText( $this->addSettingText(
[
'category' => self::CATEGORY_GENERAL,
'name' => self::SETTING_MAINTENANCE_IP_AUTHORIZED,
]
[
'category' => self::CATEGORY_GENERAL,
'name' => self::SETTING_MAINTENANCE_IP_AUTHORIZED,
]
); );
} }


public function getCategories()
public function getCategories(): array
{ {
return [ return [
self::CATEGORY_GENERAL,
self::CATEGORY_GENERAL,
]; ];
} }



+ 1
- 1
Definition/SiteSettingDefinitionInterface.php View File



interface SiteSettingDefinitionInterface interface SiteSettingDefinitionInterface
{ {
public function getCategories(): array;
} }

+ 21
- 16
DependencyInjection/LcSovExtension.php View File

use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;




class LcSovExtension extends Extension implements PrependExtensionInterface
class LcSovExtension extends Extension implements PrependExtensionInterface
{ {




public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);


foreach ($config as $parameter => $value)
$container->setParameter(sprintf('lc_sov.%s', $parameter), $value);

$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yaml');
foreach ($config as $parameter => $value) {
$container->setParameter(sprintf('lc_sov.%s', $parameter), $value);
} }


public function prepend(ContainerBuilder $container)
{
/*$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config/easy_admin'));
$loader->load('base.yaml');
$loader->load('entities/merchant.yaml');*/
}
$loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));

$loader->load('services.yaml');
}

public function prepend(ContainerBuilder $container)
{
$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config/packages'));
$loader->load('ch_cookie_consent.yaml');

/*$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config/easy_admin'));
$loader->load('base.yaml');
$loader->load('entities/merchant.yaml');*/
}
} }

+ 9
- 1
Doctrine/Extension/BlameableInterface.php View File

namespace Lc\SovBundle\Doctrine\Extension; namespace Lc\SovBundle\Doctrine\Extension;




use Lc\SovBundle\Model\User\UserInterface;

interface BlameableInterface interface BlameableInterface
{ {


public function getCreatedBy(): ?UserInterface;

public function setCreatedBy(?UserInterface $createdBy): BlameableInterface;

public function getUpdatedBy(): ?UserInterface;

public function setUpdatedBy(?UserInterface $updatedBy): BlameableInterface;
} }

+ 2
- 2
Doctrine/Extension/BlameableTrait.php View File

/** /**
* @Gedmo\Blameable(on="create") * @Gedmo\Blameable(on="create")
* @ORM\ManyToOne(targetEntity="Lc\SovBundle\Model\User\UserInterface") * @ORM\ManyToOne(targetEntity="Lc\SovBundle\Model\User\UserInterface")
* @ORM\JoinColumn(nullable=true)
* @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
*/ */
protected $createdBy; protected $createdBy;


/** /**
* @Gedmo\Blameable(on="update") * @Gedmo\Blameable(on="update")
* @ORM\ManyToOne(targetEntity="Lc\SovBundle\Model\User\UserInterface") * @ORM\ManyToOne(targetEntity="Lc\SovBundle\Model\User\UserInterface")
* @ORM\JoinColumn(nullable=true)
* @ORM\JoinColumn(nullable=true, onDelete="SET NULL")
*/ */
protected $updatedBy; protected $updatedBy;



+ 2
- 0
Doctrine/Extension/DevAliasInterface.php View File



interface DevAliasInterface interface DevAliasInterface
{ {
public function getDevAlias(): ?string;


public function setDevAlias(?string $devAlias): DevAliasInterface;
} }

+ 26
- 0
Doctrine/Extension/ImageTrait.php View File

<?php

namespace Lc\SovBundle\Doctrine\Extension;

use App\Entity\File\File;
use Doctrine\ORM\Mapping as ORM;

trait ImageTrait
{
/**
* @ORM\ManyToOne(targetEntity="Lc\SovBundle\Model\File\FileInterface", cascade={"persist", "remove"}, fetch="EAGER")
*/
protected $image;

public function getImage(): ?File
{
return $this->image;
}

public function setImage(?File $image): self
{
$this->image = $image;

return $this;
}
}

+ 10
- 0
Doctrine/Extension/OpenGraphInterface.php View File



namespace Lc\SovBundle\Doctrine\Extension; namespace Lc\SovBundle\Doctrine\Extension;


use Lc\SovBundle\Model\File\FileInterface;

interface OpenGraphInterface interface OpenGraphInterface
{ {
public function getOpenGraphTitle(): ?string;

public function setOpenGraphTitle(string $openGraphTitle): OpenGraphInterface;

public function getOpenGraphDescription(): ?string;


public function setOpenGraphDescription(?string $openGraphDescription): OpenGraphInterface;


public function getOpenGraphImage(): ?FileInterface;


public function setOpenGraphImage(?FileInterface $openGraphImage);
} }

+ 2
- 2
Doctrine/Extension/OpenGraphTrait.php View File

} }




public function getOpenGraphImage(): ?FileModel
public function getOpenGraphImage(): ?FileInterface
{ {
return $this->openGraphImage; return $this->openGraphImage;
} }


public function setOpenGraphImage(?FileModel $openGraphImage): self
public function setOpenGraphImage(?FileInterface $openGraphImage): self
{ {
$this->openGraphImage = $openGraphImage; $this->openGraphImage = $openGraphImage;



+ 8
- 0
Doctrine/Extension/SeoInterface.php View File



interface SeoInterface interface SeoInterface
{ {
public function getMetaTitle(): ?string;


public function setMetaTitle(?string $metaTitle): SeoInterface;


public function getMetaDescription(): ?string;


public function setMetaDescription(?string $metaDescription): SeoInterface;

public function getOldUrls(): ?array;

public function setOldUrls($oldUrls): SeoInterface;
} }

+ 3
- 0
Doctrine/Extension/SluggableInterface.php View File

interface SluggableInterface interface SluggableInterface
{ {


public function getSlug(): ?string;

public function setSlug(?string $slug): SluggableInterface;
} }

+ 5
- 0
Doctrine/Extension/SortableInterface.php View File

interface SortableInterface interface SortableInterface
{ {


public function getPosition(): float;

public function setPosition(float $position): SortableInterface;

public function clearPosition(): SortableInterface;
} }

+ 4
- 0
Doctrine/Extension/StatusInterface.php View File

interface StatusInterface interface StatusInterface
{ {


public function getStatus(): ?float;

public function setStatus(float $status): StatusInterface;

} }

+ 6
- 0
Doctrine/Extension/TimestampableInterface.php View File



interface TimestampableInterface interface TimestampableInterface
{ {
public function getCreatedAt(): ?\DateTimeInterface;


public function setCreatedAt(\DateTimeInterface $createdAt): TimestampableInterface;

public function getUpdatedAt(): ?\DateTimeInterface;

public function setUpdatedAt(\DateTimeInterface $updatedAt): TimestampableInterface;


} }

+ 5
- 1
Doctrine/Extension/TranslatableInterface.php View File



interface TranslatableInterface interface TranslatableInterface
{ {


public function setTranslatableLocale($locale);

public function getLocalesEnabled(): ?array;

public function setLocalesEnabled(?array $localesEnabled): TranslatableInterface;
} }

+ 4
- 1
Doctrine/Pattern/AbstractFullEntity.php View File

use Lc\SovBundle\Doctrine\Extension\BlameableTrait; use Lc\SovBundle\Doctrine\Extension\BlameableTrait;
use Lc\SovBundle\Doctrine\Extension\DevAliasInterface; use Lc\SovBundle\Doctrine\Extension\DevAliasInterface;
use Lc\SovBundle\Doctrine\Extension\DevAliasTrait; use Lc\SovBundle\Doctrine\Extension\DevAliasTrait;
use Lc\SovBundle\Doctrine\Extension\OpenGraphInterface;
use Lc\SovBundle\Doctrine\Extension\OpenGraphTrait;
use Lc\SovBundle\Doctrine\Extension\SeoInterface; use Lc\SovBundle\Doctrine\Extension\SeoInterface;
use Lc\SovBundle\Doctrine\Extension\SeoTrait; use Lc\SovBundle\Doctrine\Extension\SeoTrait;
use Lc\SovBundle\Doctrine\Extension\SluggableInterface; use Lc\SovBundle\Doctrine\Extension\SluggableInterface;
/** /**
* @ORM\MappedSuperclass * @ORM\MappedSuperclass
*/ */
abstract class AbstractFullEntity implements BlameableInterface, SeoInterface, SluggableInterface, SortableInterface,
abstract class AbstractFullEntity implements BlameableInterface, SeoInterface, OpenGraphInterface, SluggableInterface, SortableInterface,
StatusInterface, TimestampableInterface, DevAliasInterface, EntityInterface StatusInterface, TimestampableInterface, DevAliasInterface, EntityInterface
{ {


use BlameableTrait; use BlameableTrait;
use SeoTrait; use SeoTrait;
use OpenGraphTrait;
use SluggableTrait; use SluggableTrait;
use SortableTrait; use SortableTrait;
use StatusTrait; use StatusTrait;

+ 5
- 3
EventListener/ExceptionListener.php View File



// On détecte une erreur interne (500), on remove les sessions qui servent de filtre dans l'admin // On détecte une erreur interne (500), on remove les sessions qui servent de filtre dans l'admin
if ($exception instanceof HttpExceptionInterface != true) { if ($exception instanceof HttpExceptionInterface != true) {
foreach ($this->session->all() as $key => $s) {
if (str_contains($key, "_filter")) {
$this->session->remove($key);
if (!headers_sent()) {
foreach ($this->session->all() as $key => $s) {
if (str_contains($key, "_filter")) {
$this->session->remove($key);
}
} }
} }
} }

+ 3
- 2
Factory/File/FileFactory.php View File



namespace Lc\SovBundle\Factory\File; namespace Lc\SovBundle\Factory\File;


use App\Entity\File\File;
use Lc\SovBundle\Container\File\FileContainer;
use Lc\SovBundle\Factory\AbstractFactory; use Lc\SovBundle\Factory\AbstractFactory;
use Lc\SovBundle\Model\File\FileInterface; use Lc\SovBundle\Model\File\FileInterface;


{ {
public function create(): FileInterface public function create(): FileInterface
{ {
$file = new File();
$class = FileContainer::getEntityFqcn();
$file = new $class;


return $file; return $file;
} }

+ 3
- 2
Factory/Newsletter/NewsletterFactory.php View File



namespace Lc\SovBundle\Factory\Newsletter; namespace Lc\SovBundle\Factory\Newsletter;


use App\Entity\Newsletter\Newsletter;
use Lc\SovBundle\Container\Newsletter\NewsletterContainer;
use Lc\SovBundle\Factory\AbstractFactory; use Lc\SovBundle\Factory\AbstractFactory;
use Lc\SovBundle\Model\Newsletter\NewsletterInterface; use Lc\SovBundle\Model\Newsletter\NewsletterInterface;


{ {
public function create(): NewsletterInterface public function create(): NewsletterInterface
{ {
$newsletter = new Newsletter();
$class = NewsletterContainer::getEntityFqcn();
$newsletter = new $class;


return $newsletter; return $newsletter;
} }

+ 3
- 3
Factory/Reminder/ReminderFactory.php View File



namespace Lc\SovBundle\Factory\Reminder; namespace Lc\SovBundle\Factory\Reminder;


use App\Entity\Reminder\Reminder;
use Lc\SovBundle\Container\Reminder\ReminderContainer;
use Lc\SovBundle\Factory\AbstractFactory; use Lc\SovBundle\Factory\AbstractFactory;
use Lc\SovBundle\Model\Reminder\ReminderInterface; use Lc\SovBundle\Model\Reminder\ReminderInterface;


string $crudControllerFqcn = null, string $crudControllerFqcn = null,
int $entityId = null int $entityId = null
): ReminderInterface { ): ReminderInterface {
$reminder = new Reminder();
$class = ReminderContainer::getEntityFqcn();
$reminder = new $class;
$reminder->setCrudAction($crudAction); $reminder->setCrudAction($crudAction);
$reminder->setCrudControllerFqcn($crudControllerFqcn); $reminder->setCrudControllerFqcn($crudControllerFqcn);
$reminder->setEntityId($entityId); $reminder->setEntityId($entityId);

+ 7
- 1
Factory/Reminder/ReminderFactoryInterface.php View File



namespace Lc\SovBundle\Factory\Reminder; namespace Lc\SovBundle\Factory\Reminder;


use Lc\SovBundle\Model\Reminder\ReminderInterface;

interface ReminderFactoryInterface interface ReminderFactoryInterface
{ {

public function create(
string $crudAction = null,
string $crudControllerFqcn = null,
int $entityId = null
): ReminderInterface;
} }

+ 3
- 2
Factory/Setting/SiteSettingFactory.php View File



namespace Lc\SovBundle\Factory\Setting; namespace Lc\SovBundle\Factory\Setting;


use App\Entity\Setting\SiteSetting;
use Lc\SovBundle\Container\Setting\SiteSettingContainer;
use Lc\SovBundle\Factory\AbstractFactory; use Lc\SovBundle\Factory\AbstractFactory;
use Lc\SovBundle\Model\File\FileInterface; use Lc\SovBundle\Model\File\FileInterface;
use Lc\SovBundle\Model\Setting\SiteSettingInterface; use Lc\SovBundle\Model\Setting\SiteSettingInterface;
{ {
public function create(SiteInterface $site, string $name, string $text = null, \DateTime $date = null, FileInterface $file = null): SiteSettingInterface public function create(SiteInterface $site, string $name, string $text = null, \DateTime $date = null, FileInterface $file = null): SiteSettingInterface
{ {
$siteSetting = new SiteSetting();
$class = SiteSettingContainer::getEntityFqcn();
$siteSetting = new $class;


$siteSetting->setSite($site); $siteSetting->setSite($site);
$siteSetting->setName($name); $siteSetting->setName($name);

+ 11
- 1
Factory/Setting/SiteSettingFactoryInterface.php View File



namespace Lc\SovBundle\Factory\Setting; namespace Lc\SovBundle\Factory\Setting;


use Lc\SovBundle\Model\File\FileInterface;
use Lc\SovBundle\Model\Setting\SiteSettingInterface;
use Lc\SovBundle\Model\Site\SiteInterface;

interface SiteSettingFactoryInterface interface SiteSettingFactoryInterface
{ {

public function create(
SiteInterface $site,
string $name,
string $text = null,
\DateTime $date = null,
FileInterface $file = null
): SiteSettingInterface;
} }

+ 3
- 3
Factory/Site/NewsFactory.php View File



namespace Lc\SovBundle\Factory\Site; namespace Lc\SovBundle\Factory\Site;


use App\Entity\Site\News;
use Lc\SovBundle\Container\Site\NewsContainer;
use Lc\SovBundle\Factory\AbstractFactory; use Lc\SovBundle\Factory\AbstractFactory;
use Lc\SovBundle\Model\Site\NewsInterface; use Lc\SovBundle\Model\Site\NewsInterface;


{ {
public function create(): NewsInterface public function create(): NewsInterface
{ {
$news = new News();
$class = NewsContainer::getEntityFqcn();
$news = new $class;
$news->setStatus(1); $news->setStatus(1);


return $news; return $news;

+ 3
- 1
Factory/Site/NewsFactoryInterface.php View File



namespace Lc\SovBundle\Factory\Site; namespace Lc\SovBundle\Factory\Site;


use Lc\SovBundle\Model\Site\NewsInterface;

interface NewsFactoryInterface interface NewsFactoryInterface
{ {
public function create(): NewsInterface;
} }

+ 3
- 2
Factory/Site/PageFactory.php View File



namespace Lc\SovBundle\Factory\Site; namespace Lc\SovBundle\Factory\Site;


use App\Entity\Site\Page;
use Lc\SovBundle\Container\Site\PageContainer;
use Lc\SovBundle\Factory\AbstractFactory; use Lc\SovBundle\Factory\AbstractFactory;
use Lc\SovBundle\Model\Site\PageInterface; use Lc\SovBundle\Model\Site\PageInterface;


{ {
public function create(): PageInterface public function create(): PageInterface
{ {
$page = new Page();
$class = PageContainer::getEntityFqcn();
$page = new $class;


$page->setStatus(1); $page->setStatus(1);



+ 3
- 1
Factory/Site/PageFactoryInterface.php View File



namespace Lc\SovBundle\Factory\Site; namespace Lc\SovBundle\Factory\Site;


use Lc\SovBundle\Model\Site\PageInterface;

interface PageFactoryInterface interface PageFactoryInterface
{ {
public function create(): PageInterface;
} }

+ 3
- 2
Factory/Site/SiteFactory.php View File



namespace Lc\SovBundle\Factory\Site; namespace Lc\SovBundle\Factory\Site;


use App\Entity\Site\Site;
use Lc\SovBundle\Container\Site\SiteContainer;
use Lc\SovBundle\Factory\AbstractFactory; use Lc\SovBundle\Factory\AbstractFactory;
use Lc\SovBundle\Model\Site\SiteInterface; use Lc\SovBundle\Model\Site\SiteInterface;


{ {
public function create(string $devAlias = null): SiteInterface public function create(string $devAlias = null): SiteInterface
{ {
$site = new Site();
$class = SiteContainer::getEntityFqcn();
$site = new $class;


$site->setDevAlias($devAlias); $site->setDevAlias($devAlias);



+ 3
- 1
Factory/Site/SiteFactoryInterface.php View File



namespace Lc\SovBundle\Factory\Site; namespace Lc\SovBundle\Factory\Site;


use Lc\SovBundle\Model\Site\SiteInterface;

interface SiteFactoryInterface interface SiteFactoryInterface
{ {
public function create(string $devAlias = null): SiteInterface;
} }

+ 3
- 2
Factory/Ticket/TicketFactory.php View File



namespace Lc\SovBundle\Factory\Ticket; namespace Lc\SovBundle\Factory\Ticket;


use App\Entity\Ticket\Ticket;
use Lc\SovBundle\Container\Ticket\TicketContainer;
use Lc\SovBundle\Factory\AbstractFactory; use Lc\SovBundle\Factory\AbstractFactory;
use Lc\SovBundle\Model\Ticket\TicketInterface; use Lc\SovBundle\Model\Ticket\TicketInterface;
use Lc\SovBundle\Model\Ticket\TicketModel; use Lc\SovBundle\Model\Ticket\TicketModel;
{ {
public function create(): TicketInterface public function create(): TicketInterface
{ {
$ticket = new Ticket();
$class = TicketContainer::getEntityFqcn();
$ticket = new $class;


$ticketMessageFactory = new TicketMessageFactory(); $ticketMessageFactory = new TicketMessageFactory();
$ticketMessage = $ticketMessageFactory->create($ticket) ; $ticketMessage = $ticketMessageFactory->create($ticket) ;

+ 3
- 1
Factory/Ticket/TicketFactoryInterface.php View File



namespace Lc\SovBundle\Factory\Ticket; namespace Lc\SovBundle\Factory\Ticket;


use Lc\SovBundle\Model\Ticket\TicketInterface;

interface TicketFactoryInterface interface TicketFactoryInterface
{ {
public function create(): TicketInterface;
} }

+ 3
- 2
Factory/Ticket/TicketMessageFactory.php View File



namespace Lc\SovBundle\Factory\Ticket; namespace Lc\SovBundle\Factory\Ticket;


use App\Entity\Ticket\TicketMessage;
use Lc\SovBundle\Container\Ticket\TicketMessageContainer;
use Lc\SovBundle\Factory\AbstractFactory; use Lc\SovBundle\Factory\AbstractFactory;
use Lc\SovBundle\Model\Ticket\TicketInterface; use Lc\SovBundle\Model\Ticket\TicketInterface;
use Lc\SovBundle\Model\Ticket\TicketMessageInterface; use Lc\SovBundle\Model\Ticket\TicketMessageInterface;
{ {
public function create(TicketInterface $ticket): TicketMessageInterface public function create(TicketInterface $ticket): TicketMessageInterface
{ {
$ticketMessage = new TicketMessage();
$class = TicketMessageContainer::getEntityFqcn();
$ticketMessage = new $class;


$ticketMessage->setTicket($ticket); $ticketMessage->setTicket($ticket);
$ticketMessage->setStatus(1); $ticketMessage->setStatus(1);

+ 4
- 1
Factory/Ticket/TicketMessageFactoryInterface.php View File



namespace Lc\SovBundle\Factory\Ticket; namespace Lc\SovBundle\Factory\Ticket;


use Lc\SovBundle\Model\Ticket\TicketInterface;
use Lc\SovBundle\Model\Ticket\TicketMessageInterface;

interface TicketMessageFactoryInterface interface TicketMessageFactoryInterface
{ {

public function create(TicketInterface $ticket): TicketMessageInterface;
} }

+ 3
- 2
Factory/User/GroupUserFactory.php View File



namespace Lc\SovBundle\Factory\User; namespace Lc\SovBundle\Factory\User;


use App\Entity\User\GroupUser;
use Lc\SovBundle\Container\User\GroupUserContainer;
use Lc\SovBundle\Factory\AbstractFactory; use Lc\SovBundle\Factory\AbstractFactory;
use Lc\SovBundle\Model\User\GroupUserInterface; use Lc\SovBundle\Model\User\GroupUserInterface;


{ {
public function create(): GroupUserInterface public function create(): GroupUserInterface
{ {
$groupUser = new GroupUser();
$class = GroupUserContainer::getEntityFqcn();
$groupUser = new $class;


$groupUser->setStatus(1); $groupUser->setStatus(1);



+ 3
- 1
Factory/User/GroupUserFactoryInterface.php View File



namespace Lc\SovBundle\Factory\User; namespace Lc\SovBundle\Factory\User;


use Lc\SovBundle\Model\User\GroupUserInterface;

interface GroupUserFactoryInterface interface GroupUserFactoryInterface
{ {
public function create(): GroupUserInterface;
} }

+ 4
- 2
Factory/User/UserFactory.php View File



namespace Lc\SovBundle\Factory\User; namespace Lc\SovBundle\Factory\User;


use App\Entity\User\User;
use Lc\SovBundle\Container\User\UserContainer;
use Lc\SovBundle\Factory\AbstractFactory; use Lc\SovBundle\Factory\AbstractFactory;
use Lc\SovBundle\Model\User\UserInterface; use Lc\SovBundle\Model\User\UserInterface;


{ {
public function create(): UserInterface public function create(): UserInterface
{ {
$user = new User();

$class = UserContainer::getEntityFqcn();
$user = new $class;


return $user; return $user;
} }

+ 3
- 1
Factory/User/UserFactoryInterface.php View File



namespace Lc\SovBundle\Factory\User; namespace Lc\SovBundle\Factory\User;


use Lc\SovBundle\Model\User\UserInterface;

interface UserFactoryInterface interface UserFactoryInterface
{ {
public function create(): UserInterface;
} }

+ 149
- 0
Field/AssociationField.php View File

<?php

namespace Lc\SovBundle\Field;

use Doctrine\ORM\EntityRepository;
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldInterface;
use EasyCorp\Bundle\EasyAdminBundle\Field\FieldTrait;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;

final class AssociationField implements FieldInterface
{
use FieldTrait;

public const OPTION_AUTOCOMPLETE = 'autocomplete';
public const OPTION_CRUD_CONTROLLER = 'crudControllerFqcn';
public const OPTION_WIDGET = 'widget';
public const OPTION_QUERY_BUILDER_CALLABLE = 'queryBuilderCallable';
/** @internal this option is intended for internal use only */
public const OPTION_RELATED_URL = 'relatedUrl';
/** @internal this option is intended for internal use only */
public const OPTION_DOCTRINE_ASSOCIATION_TYPE = 'associationType';

public const WIDGET_AUTOCOMPLETE = 'autocomplete';
public const WIDGET_NATIVE = 'native';

/** @internal this option is intended for internal use only */
public const PARAM_AUTOCOMPLETE_CONTEXT = 'autocompleteContext';

protected $queryBuilderParameters = array();

/**
* @param string|false|null $label
*/
public static function new(string $propertyName, $label = null): self
{
return (new self())
->setProperty($propertyName)
->setLabel($label)
->setTemplatePath('@LcSov/adminlte/crud/field/association.html.twig')
->setFormType(EntityType::class)
->addCssClass('field-association')
->setCustomOption(self::OPTION_AUTOCOMPLETE, false)
->setCustomOption(self::OPTION_CRUD_CONTROLLER, null)
->setCustomOption(self::OPTION_WIDGET, self::WIDGET_AUTOCOMPLETE)
->setCustomOption(self::OPTION_QUERY_BUILDER_CALLABLE, null)
->setCustomOption(self::OPTION_RELATED_URL, '')
->setCustomOption(self::OPTION_DOCTRINE_ASSOCIATION_TYPE, null);
}

public function setFilterOnDevAlias(string $devAlias): self
{
$this->queryBuilderParameters['devAlias'] = $devAlias;

return $this;
}

public function setFilterIsOnline(): self
{
$this->queryBuilderParameters['status'] = 1;

return $this;
}

public function setLeftJoin($entityName): self
{
$this->queryBuilderParameters['leftJoin'][] = $entityName;

return $this;
}

public function addAndWhere($whereClause, $key, $value): self
{
$this->queryBuilderParameters['andWhere'][] = [
'whereClause' => $whereClause,
'key' => $key,
'value' => $value
];

return $this;
}

public function addOrderBy($field, $direction = 'ASC'): self
{
$this->queryBuilderParameters['orderBy'][] = $field;
$this->queryBuilderParameters['orderByDirection'][] = $direction;

return $this;
}

/**
* @deprecated Utiliser setFormTypeOption('choices', $choices) avec $choices issu d'un Store.
*/
public function initQueryBuilder(): self
{
$param = $this->queryBuilderParameters;
$this->setFormTypeOption(
'query_builder',
function (EntityRepository $er) use ($param) {
$qb = $er->createQueryBuilder('e');

if (isset($param['status'])) {
$qb->andWhere('e.status = :status')->setParameter('status', $param['status']);
}

if (isset($param['orderBy'])) {
foreach ($param['orderBy'] as $i => $field) {
$qb->addOrderBy('e.' . $param['orderBy'][$i], $param['orderByDirection'][$i]);
}
}

if (isset($param['leftJoin'])) {
foreach ($param['leftJoin'] as $i => $entityName) {
$qb->leftJoin('e.' . $entityName, $entityName)->addSelect($entityName);
}
}

if (isset($param['andWhere'])) {
foreach ($param['andWhere'] as $i => $whereClause) {
$qb->andWhere($whereClause['whereClause'])->setParameter($whereClause['key'], $whereClause['value']);
}
}

return $qb;
}
);
return $this;
}

public function autocomplete(): self
{
$this->setCustomOption(self::OPTION_AUTOCOMPLETE, true);

return $this;
}

public function renderAsNativeWidget(bool $asNative = true): self
{
$this->setCustomOption(self::OPTION_WIDGET, $asNative ? self::WIDGET_NATIVE : self::WIDGET_AUTOCOMPLETE);

return $this;
}

public function setCrudController(string $crudControllerFqcn): self
{
$this->setCustomOption(self::OPTION_CRUD_CONTROLLER, $crudControllerFqcn);

return $this;
}
}

+ 70
- 0
Form/Common/CookieConsentTypeExtension.php View File

<?php

namespace Lc\SovBundle\Form\Common;

use ConnectHolland\CookieConsentBundle\Cookie\CookieChecker;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use ConnectHolland\CookieConsentBundle\Form\CookieConsentType as BaseCookieConsentType;

class CookieConsentTypeExtension extends AbstractTypeExtension
{
/**
* @var CookieChecker
*/
protected $cookieChecker;

/**
* @var array
*/
protected $cookieCategories;

/**
* @var bool
*/
protected $cookieConsentSimplified;

public function __construct(
CookieChecker $cookieChecker,
array $cookieCategories = [],
bool $cookieConsentSimplified = null
) {
$this->cookieChecker = $cookieChecker;
$this->cookieCategories = $cookieCategories;
$this->cookieConsentSimplified = $cookieConsentSimplified;
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
foreach ($this->cookieCategories as $category) {
$builder->remove($category);

$data = 'true';
if ($this->cookieChecker->isCookieConsentSavedByUser() && !$this->cookieChecker->isCategoryAllowedByUser(
$category
)) {
$data = 'false';
}

$builder->add(
$category,
ChoiceType::class,
[
'expanded' => true,
'multiple' => false,
'data' => $data,
'choices' => [
['ch_cookie_consent.yes' => 'true'],
['ch_cookie_consent.no' => 'false'],
],
]
);
}
}

public static function getExtendedTypes(): iterable
{
return [BaseCookieConsentType::class];
}
}

+ 0
- 1
Form/Common/FileManagerType.php View File

$this->em = $entityManager; $this->em = $entityManager;
} }



public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options)
{ {
$builder->add('path', HiddenType::class, array( $builder->add('path', HiddenType::class, array(

+ 258
- 0
Form/Common/FileUploadType.php View File

<?php

namespace Lc\SovBundle\Form\Common;

use EasyCorp\Bundle\EasyAdminBundle\Form\DataTransformer\StringToFileTransformer;
use EasyCorp\Bundle\EasyAdminBundle\Form\Type\Model\FileUploadState;
use Lc\SovBundle\Model\File\FileInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Form\DataMapperInterface;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\File\File;
use Lc\SovBundle\Doctrine\EntityManager;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\OptionsResolver\Exception\InvalidArgumentException;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\String\Slugger\AsciiSlugger;
use Symfony\Component\Uid\Ulid;
use Symfony\Component\Uid\Uuid;

class FileUploadType extends AbstractType implements DataMapperInterface, DataTransformerInterface
{
protected string $projectDir;
protected EntityManager $entityManager;

public function __construct(EntityManager $entityManager, ParameterBagInterface $parameterBag)
{
$this->projectDir = $parameterBag->get('kernel.project_dir');
$this->entityManager = $entityManager;
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
$uploadDir = $options['upload_dir'];
$uploadFilename = $options['upload_filename'];
$uploadValidate = $options['upload_validate'];
$allowAdd = $options['allow_add'];
unset($options['upload_dir'], $options['upload_new'], $options['upload_delete'], $options['upload_filename'], $options['upload_validate'], $options['download_path'], $options['allow_add'], $options['allow_delete'], $options['compound']);

$builder->add('path', FileType::class, $options);
$builder->add('legend', TextType::class, array(
'attr' => [
"placeholder" => 'Légende'
],
'label' => false
));
$builder->add('delete', CheckboxType::class, ['required' => false, 'mapped' => false]);

$builder->setDataMapper($this);
$builder->setAttribute('state', new FileUploadState($allowAdd));
$builder->addModelTransformer(new StringToFileTransformer($uploadDir, $uploadFilename, $uploadValidate, $options['multiple']));

/*
$builder->add('path', FileType::class, array(
'block_prefix' => 'file_manager_image',
'label' => false
));

$builder->add('legend', TextType::class, array(
'block_prefix' => 'file_upload_legend',
'attr' => array(
"placeholder" => 'Légende'
),
'label' => false
));

$builder->add('position', HiddenType::class, array(
'block_prefix' => 'file_upload_position',
'empty_data' => 0,
'required' => true,
'attr' => array(
'class' => 'field-position'
),
'label' => false
));
*/
}

/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver): void
{
$uploadNew = static function (UploadedFile $file, string $uploadDir, string $fileName) {
$file->move($uploadDir, $fileName);
};

$uploadDelete = static function (File $file) {
unlink($file->getPathname());
};

$uploadFilename = static function (UploadedFile $file): string {
return $file->getClientOriginalName();
};

$uploadValidate = static function (string $filename): string {
if (!file_exists($filename)) {
return $filename;
}

$index = 1;
$pathInfo = pathinfo($filename);
while (file_exists($filename = sprintf('%s/%s_%d.%s', $pathInfo['dirname'], $pathInfo['filename'], $index, $pathInfo['extension']))) {
++$index;
}

return $filename;
};

$downloadPath = function (Options $options) {
return mb_substr($options['upload_dir'], mb_strlen($this->projectDir.'/public/'));
};

$allowAdd = static function (Options $options) {
return $options['multiple'];
};

$dataClass = static function (Options $options) {
return $options['multiple'] ? null : File::class;
};

$emptyData = static function (Options $options) {
return $options['multiple'] ? [] : null;
};

$resolver->setDefaults([
'upload_dir' => $this->projectDir.'/public/uploads/files/',
'upload_new' => $uploadNew,
'upload_delete' => $uploadDelete,
'upload_filename' => $uploadFilename,
'upload_validate' => $uploadValidate,
'download_path' => $downloadPath,
'allow_add' => $allowAdd,
'allow_delete' => true,
//'data_class' => $dataClass,
'data_class' => $this->entityManager->getEntityName(FileInterface::class),
'empty_data' => $emptyData,
'multiple' => false,
'required' => false,
'error_bubbling' => false,
'allow_file_upload' => true,
]);

$resolver->setAllowedTypes('upload_dir', 'string');
$resolver->setAllowedTypes('upload_new', 'callable');
$resolver->setAllowedTypes('upload_delete', 'callable');
$resolver->setAllowedTypes('upload_filename', ['string', 'callable']);
$resolver->setAllowedTypes('upload_validate', 'callable');
$resolver->setAllowedTypes('download_path', ['null', 'string']);
$resolver->setAllowedTypes('allow_add', 'bool');
$resolver->setAllowedTypes('allow_delete', 'bool');

$resolver->setNormalizer('upload_dir', function (Options $options, string $value): string {
if (\DIRECTORY_SEPARATOR !== mb_substr($value, -1)) {
$value .= \DIRECTORY_SEPARATOR;
}

if (0 !== mb_strpos($value, $this->projectDir)) {
$value = $this->projectDir.'/'.$value;
}

if ('' !== $value && (!is_dir($value) || !is_writable($value))) {
throw new InvalidArgumentException(sprintf('Invalid upload directory "%s" it does not exist or is not writable.', $value));
}

return $value;
});
$resolver->setNormalizer('upload_filename', static function (Options $options, $fileNamePatternOrCallable) {
if (\is_callable($fileNamePatternOrCallable)) {
return $fileNamePatternOrCallable;
}

return static function (UploadedFile $file) use ($fileNamePatternOrCallable) {
return strtr($fileNamePatternOrCallable, [
'[contenthash]' => sha1_file($file->getRealPath()),
'[day]' => date('d'),
'[extension]' => $file->guessClientExtension(),
'[month]' => date('m'),
'[name]' => pathinfo($file->getClientOriginalName(), \PATHINFO_FILENAME),
'[randomhash]' => bin2hex(random_bytes(20)),
'[slug]' => (new AsciiSlugger())
->slug(pathinfo($file->getClientOriginalName(), \PATHINFO_FILENAME))
->lower()
->toString(),
'[timestamp]' => time(),
'[uuid]' => Uuid::v4()->toRfc4122(),
'[ulid]' => new Ulid(),
'[year]' => date('Y'),
]);
};
});
$resolver->setNormalizer('allow_add', static function (Options $options, string $value): bool {
if ($value && !$options['multiple']) {
throw new InvalidArgumentException('Setting "allow_add" option to "true" when "multiple" option is "false" is not supported.');
}

return $value;
});
}

/**
* {@inheritdoc}
*/
public function mapDataToForms($currentFiles, $forms): void
{
/** @var FormInterface $fileForm */
$fileForm = current(iterator_to_array($forms));
$fileForm->setData($currentFiles);
}

/**
* {@inheritdoc}
*/
public function mapFormsToData($forms, &$currentFiles): void
{
/** @var FormInterface[] $children */
$children = iterator_to_array($forms);
$uploadedFiles = $children['path']->getData();

/** @var FileUploadState $state */
$state = $children['path']->getParent()->getConfig()->getAttribute('state');
$state->setCurrentFiles($currentFiles);
$state->setUploadedFiles($uploadedFiles);
$state->setDelete($children['delete']->getData());

if (!$state->isModified()) {
return;
}

if ($state->isAddAllowed() && !$state->isDelete()) {
$currentFiles = array_merge($currentFiles, $uploadedFiles);
} else {
$currentFiles = $uploadedFiles;
}
}

/**
* {@inheritdoc}
*/
public function transform($data)
{
return $data;
}

/**
* {@inheritdoc}
*/
public function reverseTransform($data)
{
return null === $data ? '' : $data;
}
}

+ 15
- 3
Form/Setting/BaseSettingType.php View File

use FOS\CKEditorBundle\Form\Type\CKEditorType; use FOS\CKEditorBundle\Form\Type\CKEditorType;
use Lc\SovBundle\Definition\SiteSettingDefinitionInterface; use Lc\SovBundle\Definition\SiteSettingDefinitionInterface;
use Lc\SovBundle\Form\Common\FileManagerType; use Lc\SovBundle\Form\Common\FileManagerType;
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\DateType; use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Form\Extension\Core\Type\TextareaType;
{ {
protected EntityManagerInterface $em; protected EntityManagerInterface $em;
protected SiteSettingDefinitionInterface $settingDefinition; protected SiteSettingDefinitionInterface $settingDefinition;
protected TranslatorAdmin $translatorAdmin;


public function __construct( public function __construct(
EntityManagerInterface $entityManager, EntityManagerInterface $entityManager,
SiteSettingDefinitionInterface $settingDefinition
SiteSettingDefinitionInterface $settingDefinition,
TranslatorAdmin $translatorAdmin
) { ) {
$this->em = $entityManager; $this->em = $entityManager;
$this->settingDefinition = $settingDefinition; $this->settingDefinition = $settingDefinition;
$this->translatorAdmin = $translatorAdmin;
} }


public function buildFormSetting($label, $form, $settingDefinition, $settingEntity) public function buildFormSetting($label, $form, $settingDefinition, $settingEntity)
'text', 'text',
TextType::class, TextType::class,
[ [
'label' => $label
'label' => $label,
'translation_domain' => 'admin',
] ]
); );
} elseif ($settingType == 'textarea') { } elseif ($settingType == 'textarea') {
'text', 'text',
TextareaType::class, TextareaType::class,
[ [
'label' => $label
'label' => $label,
'translation_domain' => 'admin',
] ]
); );
} elseif ($settingType == 'textarea_advanced') { } elseif ($settingType == 'textarea_advanced') {
CKEditorType::class, CKEditorType::class,
[ [
'label' => $label, 'label' => $label,
'translation_domain' => 'admin',
'attr' => [ 'attr' => [
'class' => 'field-text_editor' 'class' => 'field-text_editor'
] ]
ChoiceType::class, ChoiceType::class,
[ [
'label' => $label, 'label' => $label,
'translation_domain' => 'admin',
'expanded' => false, 'expanded' => false,
'multiple' => false, 'multiple' => false,
'placeholder' => false, 'placeholder' => false,
ChoiceType::class, ChoiceType::class,
[ [
'label' => $label, 'label' => $label,
'translation_domain' => 'admin',
'expanded' => true, 'expanded' => true,
'multiple' => false, 'multiple' => false,
'placeholder' => false, 'placeholder' => false,
DateType::class, DateType::class,
[ [
'label' => $label, 'label' => $label,
'translation_domain' => 'admin',
'widget' => 'single_text', 'widget' => 'single_text',
] ]
); );
TimeType::class, TimeType::class,
[ [
'label' => $label, 'label' => $label,
'translation_domain' => 'admin',
'input' => 'datetime', 'input' => 'datetime',
'widget' => 'single_text', 'widget' => 'single_text',
] ]
FileManagerType::class, FileManagerType::class,
[ [
'label' => $label, 'label' => $label,
'translation_domain' => 'admin',
'attr' => [ 'attr' => [
'type' => $settingType 'type' => $settingType
] ]

+ 65
- 0
Form/User/ConfirmDeleteUserFormType.php View File

<?php

namespace Lc\SovBundle\Form\User;


use Lc\SovBundle\Doctrine\EntityManager;
use Lc\SovBundle\Translation\TranslatorAdmin;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class ConfirmDeleteUserFormType extends AbstractType
{

protected $em;
protected $translatorAdmin;

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

/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{

$builder->add(
'confirmDelete',
CheckboxType::class,
[
'translation_domain' => 'admin',
]
);

$builder->add(
'delete',
SubmitType::class,
array(
'label'=> 'action.delete'
)

);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
// enable/disable CSRF protection for this form
'csrf_protection' => true,
// the name of the hidden HTML field that stores the token
'csrf_field_name' => '_token',
// an arbitrary string used to generate the value of the token
// using a different string for each form improves its security
'csrf_token_id' => 'ea-delete',
'translation_domain'=> 'admin'
]);
}


}

+ 32
- 0
Generator/PdfGenerator.php View File

<?php

namespace Lc\SovBundle\Generator;

use Dompdf\Dompdf;
use Dompdf\Options;
use Twig\Environment;

class PdfGenerator
{
protected Environment $templating;

public function __construct(Environment $templating)
{
$this->templating = $templating;
}

public function render($filename, $view, $viewParams)
{
$pdfOptions = new Options();
$pdfOptions->set('defaultFont', 'Arial');
$dompdf = new Dompdf($pdfOptions);
$html = $this->templating->render($view, $viewParams);
$dompdf->loadHtml($html);
$dompdf->setPaper('A4', 'portrait');
$dompdf->render();
$dompdf->stream($filename, [
"Attachment" => true
]);
die();
}
}

+ 4
- 4
LcSovBundle.php View File



class LcSovBundle extends Bundle class LcSovBundle extends Bundle
{ {
public function getContainerExtension()
{
return new LcSovExtension();
}
public function getContainerExtension()
{
return new LcSovExtension();
}
} }

+ 48
- 2
Model/File/FileInterface.php View File



namespace Lc\SovBundle\Model\File; namespace Lc\SovBundle\Model\File;


use Lc\SovBundle\Model\User\UserInterface;

interface FileInterface interface FileInterface
{ {
public function getCreatedBy(): ?UserInterface;

public function setCreatedBy(?UserInterface $createdBy): FileInterface;

public function getUpdatedBy(): ?UserInterface;

public function setUpdatedBy(?UserInterface $updatedBy): FileInterface;

public function getDevAlias(): ?string;

public function setDevAlias(?string $devAlias): FileInterface;

public function getPath(): ?string;

public function setPath(?string $path): FileInterface;

public function getLegend(): ?string;

public function setLegend(?string $legend): FileInterface;

/**
* @return float
*/
public function getPosition(): float;

/**
* @param float $position
* @return $this
*/
public function setPosition(float $position): FileInterface;

public function clearPosition(): FileInterface;

public function getCreatedAt(): ?\DateTimeInterface;

public function setCreatedAt(\DateTimeInterface $createdAt): FileInterface;

public function getUpdatedAt(): ?\DateTimeInterface;

public function setUpdatedAt(\DateTimeInterface $updatedAt): FileInterface;

public function setTranslatableLocale($locale);

public function getLocalesEnabled(): ?array;


}
public function setLocalesEnabled(?array $localesEnabled): FileInterface;
}

+ 77
- 1
Model/Newsletter/NewsletterInterface.php View File

<?php <?php


namespace Lc\SovBundle\Model\Newsletter ;
namespace Lc\SovBundle\Model\Newsletter;


use Doctrine\Common\Collections\Collection;
use Lc\SovBundle\Model\User\UserInterface;


interface NewsletterInterface interface NewsletterInterface
{ {
public function getTitle(): ?string;

public function setTitle(string $title);

public function getDescription(): ?string;

public function setDescription(?string $description);

public function getCreatedBy(): ?UserInterface;

public function setCreatedBy(?UserInterface $createdBy);

public function getUpdatedBy(): ?UserInterface;

public function setUpdatedBy(?UserInterface $updatedBy);

public function getDevAlias(): ?string;

public function setDevAlias(?string $devAlias);

/**
* @return Collection|UserInterface[]
*/
public function getUsers(): Collection;

public function addUser(UserInterface $user): NewsletterInterface;

public function removeUser(UserInterface $user): NewsletterInterface;

public function getIsMain(): ?bool;

public function setIsMain(?bool $isMain): NewsletterInterface;

public function getMetaTitle(): ?string;

public function setMetaTitle(?string $metaTitle);

public function getMetaDescription(): ?string;

public function setMetaDescription(?string $metaDescription);

public function setOldUrls($oldUrls);

public function getOldUrls(): ?array;

public function getSlug(): ?string;

public function setSlug(?string $slug);

/**
* @return float
*/
public function getPosition(): float;

/**
* @param float $position
* @return $this
*/
public function setPosition(float $position);

public function clearPosition();

public function getStatus(): ?float;

public function setStatus(float $status);

public function getCreatedAt(): ?\DateTimeInterface;

public function setCreatedAt(\DateTimeInterface $createdAt);

public function getUpdatedAt(): ?\DateTimeInterface;


public function setUpdatedAt(\DateTimeInterface $updatedAt);
} }

+ 61
- 1
Model/Reminder/ReminderInterface.php View File



namespace Lc\SovBundle\Model\Reminder; namespace Lc\SovBundle\Model\Reminder;



use Doctrine\Common\Collections\Collection;
use Lc\SovBundle\Model\User\UserInterface;

interface ReminderInterface interface ReminderInterface
{ {
}
public function getCreatedBy(): ?UserInterface;

public function setCreatedBy(?UserInterface $createdBy);

public function getUpdatedBy(): ?UserInterface;

public function setUpdatedBy(?UserInterface $updatedBy);

public function getDevAlias(): ?string;

public function setDevAlias(?string $devAlias);

public function getTitle(): ?string;

public function setTitle(string $title): ReminderInterface;

public function getDescription(): ?string;

public function setDescription(?string $description): ReminderInterface;

public function getCrudAction(): ?string;

public function setCrudAction(?string $crudAction): ReminderInterface;

public function getCrudControllerFqcn(): ?string;

public function setCrudControllerFqcn(?string $crudControllerFqcn): ReminderInterface;

public function getEntityId(): ?int;

public function setEntityId(?int $entityId): ReminderInterface;

/**
* @return Collection|UserInterface[]
*/
public function getUsers(): Collection;

public function addUser(UserInterface $user): ReminderInterface;

public function removeUser(UserInterface $user): ReminderInterface;

public function getDateReminder(): ?\DateTimeInterface;

public function setDateReminder(?\DateTimeInterface $dateReminder): ReminderInterface;

public function getDone(): ?bool;

public function setDone(?bool $done): ReminderInterface;

public function getCreatedAt(): ?\DateTimeInterface;

public function setCreatedAt(\DateTimeInterface $createdAt);

public function getUpdatedAt(): ?\DateTimeInterface;

public function setUpdatedAt(\DateTimeInterface $updatedAt);
}

+ 17
- 0
Model/Setting/SettingInterface.php View File



namespace Lc\SovBundle\Model\Setting; namespace Lc\SovBundle\Model\Setting;



use Lc\SovBundle\Model\File\FileInterface;

interface SettingInterface interface SettingInterface
{ {
public function getName(): ?string;

public function setName(?string $name): SettingInterface;

public function getText(): ?string;

public function setText($text): SettingInterface;

public function getDate(): ?\DateTimeInterface;

public function setDate(?\DateTimeInterface $date): SettingInterface;

public function getFile(): ?FileInterface;


public function setFile(?FileInterface $file): SettingInterface;
} }

+ 22
- 0
Model/Setting/SiteSettingInterface.php View File



namespace Lc\SovBundle\Model\Setting; namespace Lc\SovBundle\Model\Setting;



use Lc\SovBundle\Model\File\FileInterface;
use Lc\SovBundle\Model\Site\SiteInterface;

interface SiteSettingInterface interface SiteSettingInterface
{ {
public function getName(): ?string;

public function setName(?string $name);

public function getText(): ?string;

public function setText($text);

public function getDate(): ?\DateTimeInterface;

public function setDate(?\DateTimeInterface $date);

public function getFile(): ?FileInterface;

public function setFile(?FileInterface $file);

public function getSite(): ?SiteInterface;


public function setSite(?SiteInterface $site): SiteSettingInterface;
} }

+ 93
- 2
Model/Site/NewsInterface.php View File

<?php <?php


namespace Lc\SovBundle\Model\Site ;
namespace Lc\SovBundle\Model\Site;

use Lc\SovBundle\Doctrine\Extension\OpenGraphInterface;
use Lc\SovBundle\Model\File\FileInterface;
use Lc\SovBundle\Model\File\FileModel;
use Lc\SovBundle\Model\Newsletter\NewsletterInterface;
use Lc\SovBundle\Model\User\UserInterface;


interface NewsInterface interface NewsInterface
{ {
public function getTitle(): ?string;

public function setTitle(string $title);

public function getDescription(): ?string;

public function setDescription(?string $description);

public function getCreatedBy(): ?UserInterface;

public function setCreatedBy(?UserInterface $createdBy);

public function getUpdatedBy(): ?UserInterface;

public function setUpdatedBy(?UserInterface $updatedBy);

public function getDevAlias(): ?string;

public function setDevAlias(?string $devAlias);

public function getDate(): ?\DateTimeInterface;

public function setDate(\DateTimeInterface $date): NewsInterface;

public function getIsSent(): ?bool;

public function setIsSent(?bool $isSent): NewsInterface;

public function getImage(): ?FileInterface;

public function setImage(?FileInterface $image): NewsInterface;

public function getNewsletter(): ?NewsletterInterface;

public function setNewsletter(?NewsletterInterface $newsletter): NewsInterface;

public function getOpenGraphTitle(): ?string;

public function setOpenGraphTitle(string $openGraphTitle): OpenGraphInterface;

public function getOpenGraphDescription(): ?string;

public function setOpenGraphDescription(?string $openGraphDescription): OpenGraphInterface;

public function getOpenGraphImage(): ?FileInterface;

public function setOpenGraphImage(?FileInterface $openGraphImage): OpenGraphInterface;

public function setMetaTitle(?string $metaTitle);

public function getMetaDescription(): ?string;

public function setMetaDescription(?string $metaDescription);

public function setOldUrls($oldUrls);

public function getOldUrls(): ?array;

public function getSlug(): ?string;

public function setSlug(?string $slug);

/**
* @return float
*/
public function getPosition(): float;

/**
* @param float $position
* @return $this
*/
public function setPosition(float $position);

public function clearPosition();

public function getStatus(): ?float;

public function setStatus(float $status);

public function getCreatedAt(): ?\DateTimeInterface;

public function setCreatedAt(\DateTimeInterface $createdAt);

public function getUpdatedAt(): ?\DateTimeInterface;


}
public function setUpdatedAt(\DateTimeInterface $updatedAt);
}

+ 1
- 3
Model/Site/NewsModel.php View File

/** /**
* @ORM\MappedSuperclass() * @ORM\MappedSuperclass()
*/ */
abstract class NewsModel extends AbstractFullEntity implements NewsInterface, OpenGraphInterface
abstract class NewsModel extends AbstractFullEntity implements NewsInterface
{ {
use OpenGraphTrait;

/** /**
* @ORM\Column(type="datetime") * @ORM\Column(type="datetime")
* @Gedmo\Timestampable(on="create") * @Gedmo\Timestampable(on="create")

+ 64
- 1
Model/Site/PageInterface.php View File



namespace Lc\SovBundle\Model\Site; namespace Lc\SovBundle\Model\Site;



use Lc\SovBundle\Model\User\UserInterface;


interface PageInterface interface PageInterface
{ {
public function getTitle(): ?string;

public function setTitle(string $title);

public function getDescription(): ?string;

public function setDescription(?string $description);

public function getCreatedBy(): ?UserInterface;

public function setCreatedBy(?UserInterface $createdBy);

public function getUpdatedBy(): ?UserInterface;

public function setUpdatedBy(?UserInterface $updatedBy);

public function getDevAlias(): ?string;

public function setDevAlias(?string $devAlias);

public function getMetaTitle(): ?string;

public function setMetaTitle(?string $metaTitle);

public function getMetaDescription(): ?string;

public function setMetaDescription(?string $metaDescription);

public function setOldUrls($oldUrls);

public function getOldUrls(): ?array;

public function getSlug(): ?string;

public function setSlug(?string $slug);

/**
* @return float
*/
public function getPosition(): float;

/**
* @param float $position
* @return $this
*/
public function setPosition(float $position);

public function clearPosition();

public function getStatus(): ?float;

public function setStatus(float $status);

public function getCreatedAt(): ?\DateTimeInterface;

public function setCreatedAt(\DateTimeInterface $createdAt);

public function getUpdatedAt(): ?\DateTimeInterface;


}
public function setUpdatedAt(\DateTimeInterface $updatedAt);
}

+ 15
- 2
Model/Site/SiteInterface.php View File



namespace Lc\SovBundle\Model\Site; namespace Lc\SovBundle\Model\Site;


use Doctrine\Common\Collections\Collection;
use Lc\SovBundle\Model\Setting\SiteSettingInterface;

interface SiteInterface interface SiteInterface
{ {
public function getDevAlias(): ?string;

public function setDevAlias(?string $devAlias): SiteInterface;

/**
* @return Collection|SiteSettingInterface[]
*/
public function getSettings(): Collection;

public function addSetting(SiteSettingInterface $setting): SiteInterface;


}
public function removeSetting(SiteSettingInterface $setting): SiteInterface;
}

+ 68
- 1
Model/Ticket/TicketInterface.php View File



namespace Lc\SovBundle\Model\Ticket; namespace Lc\SovBundle\Model\Ticket;



use Doctrine\Common\Collections\Collection;
use Lc\SovBundle\Model\User\UserInterface;

interface TicketInterface interface TicketInterface
{ {
public function getCreatedBy(): ?UserInterface;

public function setCreatedBy(?UserInterface $createdBy);

public function getUpdatedBy(): ?UserInterface;

public function setUpdatedBy(?UserInterface $updatedBy);

public function getDevAlias(): ?string;

public function setDevAlias(?string $devAlias);

public function getType(): ?string;

public function setType(string $type): TicketInterface;

public function getStatus(): ?string;

public function setStatus(string $status);

public function getSubject(): ?string;

public function setSubject(string $subject): TicketInterface;

public function getTags(): ?array;

public function setTags(?array $tags): TicketInterface;

public function getVisitorFirstname(): ?string;

public function setVisitorFirstname(?string $visitorFirstname): TicketInterface;

public function getVisitorLastname(): ?string;

public function setVisitorLastname(?string $visitorLastname): TicketInterface;

public function getVisitorEmail(): ?string;

public function setVisitorEmail(?string $visitorEmail): TicketInterface;

public function getVisitorToken(): ?string;

public function setVisitorToken(?string $visitorToken): TicketInterface;

/**
* @return Collection|TicketMessageInterface[]
*/
public function getTicketMessages(): Collection;

public function addTicketMessage(TicketMessageInterface $ticketMessage): TicketInterface;

public function removeTicketMessage(TicketMessageInterface $ticketMessage): TicketInterface;

public function getUser(): ?UserInterface;

public function setUser(?UserInterface $user): TicketInterface;

public function getCreatedAt(): ?\DateTimeInterface;

public function setCreatedAt(\DateTimeInterface $createdAt);

public function getUpdatedAt(): ?\DateTimeInterface;


}
public function setUpdatedAt(\DateTimeInterface $updatedAt);
}

+ 42
- 1
Model/Ticket/TicketMessageInterface.php View File



namespace Lc\SovBundle\Model\Ticket; namespace Lc\SovBundle\Model\Ticket;



use Lc\SovBundle\Model\User\UserInterface;

interface TicketMessageInterface interface TicketMessageInterface
{ {
public function getCreatedBy(): ?UserInterface;

public function setCreatedBy(?UserInterface $createdBy);

public function getUpdatedBy(): ?UserInterface;

public function setUpdatedBy(?UserInterface $updatedBy);

public function getDevAlias(): ?string;

public function setDevAlias(?string $devAlias);

public function getStatus(): ?float;

public function setStatus(float $status): TicketMessageInterface;

public function getMessage(): ?string;

public function setMessage(string $message): TicketMessageInterface;

public function getTicket(): TicketInterface;

public function setTicket(TicketInterface $ticket): TicketMessageInterface;

public function getAnswerByAdmin(): ?bool;

public function setAnswerByAdmin(?bool $answerByAdmin): TicketMessageInterface;

public function getImageFilename(): ?string;

public function setImageFilename(?string $imageFilename): TicketMessageInterface;

public function getCreatedAt(): ?\DateTimeInterface;

public function setCreatedAt(\DateTimeInterface $createdAt);

public function getUpdatedAt(): ?\DateTimeInterface;


}
public function setUpdatedAt(\DateTimeInterface $updatedAt);
}

+ 2
- 1
Model/Ticket/TicketModel.php View File

protected $visitorToken; protected $visitorToken;


/** /**
* @ORM\OneToMany(targetEntity="Lc\SovBundle\Model\Ticket\TicketMessageInterface", mappedBy="ticket", orphanRemoval=true, cascade={"persist", "remove"})
* @ORM\OneToMany(targetEntity="Lc\SovBundle\Model\Ticket\TicketMessageInterface", mappedBy="ticket",cascade={"persist", "remove"}, orphanRemoval=true)
* @ORM\OrderBy({"id" = "ASC"}) * @ORM\OrderBy({"id" = "ASC"})
*/ */
protected $ticketMessages; protected $ticketMessages;
*/ */
protected $user; protected $user;



public function __construct() public function __construct()
{ {
$this->ticketMessages = new ArrayCollection(); $this->ticketMessages = new ArrayCollection();

+ 72
- 1
Model/User/GroupUserInterface.php View File



namespace Lc\SovBundle\Model\User; namespace Lc\SovBundle\Model\User;



use Doctrine\Common\Collections\Collection;

interface GroupUserInterface interface GroupUserInterface
{ {
public function getDescription(): ?string;

public function setDescription(?string $description);

public function getCreatedBy(): ?UserInterface;

public function setCreatedBy(?UserInterface $createdBy);

public function getUpdatedBy(): ?UserInterface;

public function setUpdatedBy(?UserInterface $updatedBy);

public function getDevAlias(): ?string;

public function setDevAlias(?string $devAlias);

public function getTitle(): ?string;

public function setTitle(string $title);

public function addUser(UserInterface $user): GroupUserInterface;

/**
* @return Collection|UserInterface[]
*/
public function getUsers(): Collection;

public function removeUser(UserInterface $user): GroupUserInterface;

public function getMetaTitle(): ?string;

public function setMetaTitle(?string $metaTitle);

public function getMetaDescription(): ?string;

public function setMetaDescription(?string $metaDescription);

public function setOldUrls($oldUrls);

public function getOldUrls(): ?array;

public function getSlug(): ?string;

public function setSlug(?string $slug);

/**
* @return float
*/
public function getPosition(): float;

/**
* @param float $position
* @return $this
*/
public function setPosition(float $position);

public function clearPosition();

public function getStatus(): ?float;

public function setStatus(float $status);

public function getCreatedAt(): ?\DateTimeInterface;

public function setCreatedAt(\DateTimeInterface $createdAt);

public function getUpdatedAt(): ?\DateTimeInterface;


}
public function setUpdatedAt(\DateTimeInterface $updatedAt);
}

+ 101
- 1
Model/User/UserInterface.php View File



namespace Lc\SovBundle\Model\User; namespace Lc\SovBundle\Model\User;



use Doctrine\Common\Collections\Collection;
use Lc\SovBundle\Model\Ticket\TicketInterface;


interface UserInterface interface UserInterface
{ {
public function getDevAlias(): ?string;

public function setDevAlias(?string $devAlias): UserInterface;

public function getCreatedAt(): ?\DateTimeInterface;

public function setCreatedAt(\DateTimeInterface $createdAt): UserInterface;

public function getUpdatedAt(): ?\DateTimeInterface;

public function setUpdatedAt(\DateTimeInterface $updatedAt): UserInterface;

public function getEmail(): ?string;

public function setEmail(string $email): UserInterface;

/**
* A visual identifier that represents this user.
*
* @see UserInterface
*/
public function getUsername(): string;

public function getGender(): ?bool;

public function setGender(?bool $gender): UserInterface;

public function getBirthdate(): ?\DateTimeInterface;

public function setBirthdate(?\DateTimeInterface $birthdate): UserInterface;

/**
* @see UserInterface
*/
public function getRoles(): array;

public function setRoles(array $roles): UserInterface;

public function hasRole($role);

/**
* @see UserInterface
*/
public function getPassword(): string;

public function setPassword(string $password): UserInterface;

public function generatePassword($length = 8): string;

/**
* @see UserIn
*/
public function getSalt();

/**
* @see UserInterface
*/
public function eraseCredentials();

public function getLastname(): ?string;

public function setLastname(?string $lastname): UserInterface;

public function getFirstname(): ?string;

public function setFirstname(?string $firstname): UserInterface;

public function getPhone(): ?string;

public function setPhone(?string $phone): UserInterface;

public function isVerified(): bool;

public function setIsVerified(bool $isVerified): UserInterface;

/**
* @return Collection|GroupUserInterface[]
*/
public function getGroupUsers(): Collection;

public function addGroupUser(GroupUserInterface $groupUser): UserInterface;

public function removeGroupUser(GroupUserInterface $groupUser): UserInterface;

/**
* @return Collection|TicketInterface[]
*/
public function getTickets(): Collection;

public function addTicket(TicketInterface $ticket): UserInterface;

public function removeTicket(TicketInterface $ticket): UserInterface;

public function getTicketTypesNotification(): ?array;


}
public function setTicketTypesNotification(?array $ticketTypesNotification): UserInterface;
}

+ 18
- 2
Model/User/UserModel.php View File

use Lc\SovBundle\Doctrine\Extension\TimestampableTrait; use Lc\SovBundle\Doctrine\Extension\TimestampableTrait;
use Lc\SovBundle\Model\Ticket\TicketInterface; use Lc\SovBundle\Model\Ticket\TicketInterface;
use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserInterface;
use Lc\SovBundle\Model\User\UserInterface as SovUserInterface;


/** /**
* @ORM\MappedSuperclass() * @ORM\MappedSuperclass()
*/ */
abstract class UserModel implements EntityInterface, UserInterface, DevAliasInterface
abstract class UserModel implements EntityInterface, UserInterface, SovUserInterface, DevAliasInterface
{ {
use DevAliasTrait; use DevAliasTrait;
use TimestampableTrait; use TimestampableTrait;
protected $groupUsers; protected $groupUsers;


/** /**
* @ORM\OneToMany(targetEntity="Lc\SovBundle\Model\Ticket\TicketInterface", mappedBy="user")
* @ORM\OneToMany(targetEntity="Lc\SovBundle\Model\Ticket\TicketInterface", mappedBy="user", cascade={"remove"})
*/ */
protected $tickets; protected $tickets;


*/ */
protected $ticketTypesNotification = []; protected $ticketTypesNotification = [];


/**
* @ORM\Column(type="datetime", nullable=true)
*/
protected $lastLogin;

public function __construct() public function __construct()
{ {
$this->tickets = new ArrayCollection(); $this->tickets = new ArrayCollection();
return $this; return $this;
} }


public function getLastLogin()
{
return $this->lastLogin;
}


public function setLastLogin(\DateTime $time = null)
{
$this->lastLogin = $time;

return $this;
}
} }

+ 142
- 1
Repository/AbstractRepositoryInterface.php View File



namespace Lc\SovBundle\Repository; namespace Lc\SovBundle\Repository;


use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\AbstractQuery;
use Doctrine\ORM\LazyCriteriaCollection;
use Doctrine\ORM\NativeQuery;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query\ResultSetMappingBuilder;
use Doctrine\ORM\QueryBuilder;


interface AbstractRepositoryInterface interface AbstractRepositoryInterface
{ {
public function setDefaultLocale($locale);


}
public function getOneOrNullResult(QueryBuilder $qb, $locale = null, $hydrationMode = null);

public function getResult(QueryBuilder $qb, $locale = null, $hydrationMode = AbstractQuery::HYDRATE_OBJECT);

public function getArrayResult(QueryBuilder $qb, $locale = null);

public function getSingleResult(QueryBuilder $qb, $locale = null, $hydrationMode = null);

public function getScalarResult(QueryBuilder $qb, $locale = null);

public function getSingleScalarResult(QueryBuilder $qb, $locale = null);

/**
* Creates a new QueryBuilder instance that is prepopulated for this entity name.
*
* @param string $alias
* @param string $indexBy The index for the from.
*
* @return QueryBuilder
*/
public function createQueryBuilder($alias, $indexBy = null);

/**
* Creates a new result set mapping builder for this entity.
*
* The column naming strategy is "INCREMENT".
*
* @param string $alias
*
* @return ResultSetMappingBuilder
*/
public function createResultSetMappingBuilder($alias);

/**
* Creates a new Query instance based on a predefined metadata named query.
*
* @param string $queryName
*
* @return Query
* @deprecated
*
*/
public function createNamedQuery($queryName);

/**
* Creates a native SQL query.
*
* @param string $queryName
*
* @return NativeQuery
* @deprecated
*
*/
public function createNativeNamedQuery($queryName);

/**
* Clears the repository, causing all managed entities to become detached.
*
* @deprecated 2.8 This method is being removed from the ORM and won't have any replacement
*
* @return void
*/
public function clear();

/**
* Finds an entity by its primary key / identifier.
*
* @param mixed $id The identifier.
* @param int|null $lockMode One of the \Doctrine\DBAL\LockMode::* constants
* or NULL if no specific lock mode should be used
* during the search.
* @param int|null $lockVersion The lock version.
*
* @return object|null The entity instance or NULL if the entity can not be found.
* @psalm-return ?T
*/
public function find($id, $lockMode = null, $lockVersion = null);

/**
* Finds all entities in the repository.
*
* @psalm-return list<T> The entities.
*/
public function findAll();

/**
* Finds entities by a set of criteria.
*
* @param int|null $limit
* @param int|null $offset
* @psalm-param array<string, mixed> $criteria
* @psalm-param array<string, string>|null $orderBy
*
* @psalm-return list<T> The objects.
*/
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null);

/**
* Finds a single entity by a set of criteria.
*
* @psalm-param array<string, mixed> $criteria
* @psalm-param array<string, string>|null $orderBy
*
* @return object|null The entity instance or NULL if the entity can not be found.
* @psalm-return ?T
*/
public function findOneBy(array $criteria, ?array $orderBy = null);

/**
* Counts entities by a set of criteria.
*
* @psalm-param array<string, mixed> $criteria
*
* @return int The cardinality of the objects that match the given criteria.
*
* @todo Add this method to `ObjectRepository` interface in the next major release
*/
public function count(array $criteria);

/**
* @return string
*/
public function getClassName();

/**
* Select all elements from a selectable that match the expression and
* return a new collection containing these elements.
*
* @return LazyCriteriaCollection
* @psalm-return Collection<int, T>
*/
public function matching(Criteria $criteria);
}

+ 44
- 1
Repository/AbstractRepositoryQuery.php View File

use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use Knp\Component\Pager\PaginatorInterface; use Knp\Component\Pager\PaginatorInterface;
use Lc\SovBundle\Doctrine\EntityInterface; use Lc\SovBundle\Doctrine\EntityInterface;
use Lc\SovBundle\Model\User\UserInterface;


abstract class AbstractRepositoryQuery implements RepositoryQueryInterface abstract class AbstractRepositoryQuery implements RepositoryQueryInterface
{ {
return $this; return $this;
}*/ }*/


// @TODO : créer un addOrderBy et un orderBy
public function orderBy(string $field, string $sort = 'ASC'): self public function orderBy(string $field, string $sort = 'ASC'): self
{ {
if (strpos($field, '.')!==false) { if (strpos($field, '.')!==false) {
} }
} }


public function setOrderBy(string $field, string $sort = 'ASC'): self
{
$this->resetDQLParts(['orderBy']);
return $this->orderBy($field, $sort);
}

public function filterById(int $id):self public function filterById(int $id):self
{ {
return $this return $this
->setParameter('id', $id); ->setParameter('id', $id);
} }


public function filterByCreatedBy(UserInterface $user):self
{
return $this
->andWhere('.createdBy = :user')
->setParameter('user', $user);
}

public function filterByUpdatedBy(UserInterface $user):self
{
return $this
->andWhere('.updatedBy = :user')
->setParameter('user', $user);
}

public function andWhereEqual($field, $value) public function andWhereEqual($field, $value)
{ {
return $this->andWhere('.'.$field.' = :'.$field)->setParameter($field, $value); return $this->andWhere('.'.$field.' = :'.$field)->setParameter($field, $value);
{ {
return $this->andWhere('.status >= 0'); return $this->andWhere('.status >= 0');
} }

/*
* POSITION
*/

public function filterByPositionBiggerThan(int $position)
{
return $this->andWhere('.position > :position')->setParameter('position', $position);
}

public function filterByPositionSmallerThan(int $position)
{
return $this->andWhere('.position < :position')->setParameter('position', $position);
}

public function enableCache($lifetime, $idCache)
{
return $this->getQueryBuilder()->getQuery()
->useQueryCache(true)
->setQueryCacheLifetime($lifetime)
->enableResultCache($lifetime, $idCache);
}

} }



+ 7
- 0
Repository/AbstractStore.php View File

return $query->find(); return $query->find();
} }


public function getOnlineAndOffline($query = null)
{
$query = $this->createDefaultQuery($query);
$query->filterIsOnlineAndOffline();
return $query->find();
}

public function getParent(bool $isOnline = true, $query = null) public function getParent(bool $isOnline = true, $query = null)
{ {
$query = $this->createDefaultQuery($query); $query = $this->createDefaultQuery($query);

+ 50
- 0
Repository/File/FileRepositoryQueryInterface.php View File



namespace Lc\SovBundle\Repository\File; namespace Lc\SovBundle\Repository\File;


use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\QueryBuilder;
use Lc\SovBundle\Doctrine\EntityInterface;

interface FileRepositoryQueryInterface interface FileRepositoryQueryInterface
{ {
public function create();

public function call(callable $fn);

public function count();

public function findOne();

public function find(): array;

public function limit(int $maxResults);

public function paginate(int $page = 1, int $limit = 20);

public function getRepository(): ServiceEntityRepository;

public function getQueryBuilder(): QueryBuilder;

public function groupBy(string $field);

public function orderBy(string $field, string $sort = 'ASC');

public function filterById(int $id);

public function andWhereEqual($field, $value);

public function filterByOldUrl(string $oldUrl);

public function resetRelationsJoin(): void;

public function filterByDevAlias(string $devAlias);

public function filterBySlug(string $slug);

public function filterIsParent();

public function filterIsChildren();

public function filterByParent(EntityInterface $parent = null);

public function filterIsOffline();

public function filterIsOnline();

public function filterIsDeleted();


public function filterIsOnlineAndOffline();
} }

+ 1
- 2
Repository/File/FileStore.php View File

{ {
$this->query = $query; $this->query = $query;
} }

public function orderByDefault(RepositoryQueryInterface $query): RepositoryQueryInterface public function orderByDefault(RepositoryQueryInterface $query): RepositoryQueryInterface
{ {

return $query; return $query;
} }


public function filtersDefault(RepositoryQueryInterface $query): RepositoryQueryInterface public function filtersDefault(RepositoryQueryInterface $query): RepositoryQueryInterface
{ {

return $query; return $query;
} }



+ 30
- 0
Repository/File/FileStoreInterface.php View File



namespace Lc\SovBundle\Repository\File; namespace Lc\SovBundle\Repository\File;


use Lc\SovBundle\Repository\RepositoryQueryInterface;

interface FileStoreInterface interface FileStoreInterface
{ {
public function createDefaultQuery(RepositoryQueryInterface $query = null): RepositoryQueryInterface;

public function createQuery(RepositoryQueryInterface $query = null): RepositoryQueryInterface;

public function getRepositoryQuery();

public function getOneById(int $id);

public function getOneBySlug(string $slug, bool $isOnline = true, $query = null);

public function getOneByDevAlias(string $devAlias, $query = null);

public function getOneOnlineByDevAlias(string $devAlias, $query = null);

public function getOneByOldUrl(string $oldUrl, $query = null);

public function get($query = null);

public function getAll($query = null);

public function getOnline($query = null);

public function getParent(bool $isOnline = true, $query = null);

public function orderByDefault(RepositoryQueryInterface $query): RepositoryQueryInterface;

public function filtersDefault(RepositoryQueryInterface $query): RepositoryQueryInterface;


public function relationsDefault(RepositoryQueryInterface $query): RepositoryQueryInterface;
} }

+ 51
- 0
Repository/Newsletter/NewsletterRepositoryQueryInterface.php View File



namespace Lc\SovBundle\Repository\Newsletter; namespace Lc\SovBundle\Repository\Newsletter;


use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\QueryBuilder;
use Lc\SovBundle\Doctrine\EntityInterface;
use Lc\SovBundle\Repository\AbstractRepositoryQuery;

interface NewsletterRepositoryQueryInterface interface NewsletterRepositoryQueryInterface
{ {
public function create();

public function call(callable $fn);

public function count();

public function findOne();

public function find(): array;

public function limit(int $maxResults);

public function paginate(int $page = 1, int $limit = 20);

public function getRepository(): ServiceEntityRepository;

public function getQueryBuilder(): QueryBuilder;

public function groupBy(string $field);

public function orderBy(string $field, string $sort = 'ASC');

public function filterById(int $id);

public function andWhereEqual($field, $value);

public function filterByOldUrl(string $oldUrl);

public function resetRelationsJoin(): void;

public function filterByDevAlias(string $devAlias);

public function filterBySlug(string $slug);

public function filterIsParent();

public function filterIsChildren();

public function filterByParent(EntityInterface $parent = null);

public function filterIsOffline();

public function filterIsOnline();

public function filterIsDeleted();


public function filterIsOnlineAndOffline();
} }

+ 1
- 2
Repository/Newsletter/NewsletterStore.php View File

{ {
$this->query = $query; $this->query = $query;
} }

public function orderByDefault(RepositoryQueryInterface $query): RepositoryQueryInterface public function orderByDefault(RepositoryQueryInterface $query): RepositoryQueryInterface
{ {

return $query; return $query;
} }


public function filtersDefault(RepositoryQueryInterface $query): RepositoryQueryInterface public function filtersDefault(RepositoryQueryInterface $query): RepositoryQueryInterface
{ {

return $query; return $query;
} }



+ 30
- 0
Repository/Newsletter/NewsletterStoreInterface.php View File



namespace Lc\SovBundle\Repository\Newsletter; namespace Lc\SovBundle\Repository\Newsletter;


use Lc\SovBundle\Repository\RepositoryQueryInterface;

interface NewsletterStoreInterface interface NewsletterStoreInterface
{ {
public function createDefaultQuery(RepositoryQueryInterface $query = null): RepositoryQueryInterface;

public function createQuery(RepositoryQueryInterface $query = null): RepositoryQueryInterface;

public function getRepositoryQuery();

public function getOneById(int $id);

public function getOneBySlug(string $slug, bool $isOnline = true, $query = null);

public function getOneByDevAlias(string $devAlias, $query = null);

public function getOneOnlineByDevAlias(string $devAlias, $query = null);

public function getOneByOldUrl(string $oldUrl, $query = null);

public function get($query = null);

public function getAll($query = null);

public function getOnline($query = null);

public function getParent(bool $isOnline = true, $query = null);

public function orderByDefault(RepositoryQueryInterface $query): RepositoryQueryInterface;

public function filtersDefault(RepositoryQueryInterface $query): RepositoryQueryInterface;


public function relationsDefault(RepositoryQueryInterface $query): RepositoryQueryInterface;
} }

+ 76
- 1
Repository/Reminder/ReminderRepositoryQueryInterface.php View File



namespace Lc\SovBundle\Repository\Reminder; namespace Lc\SovBundle\Repository\Reminder;


use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\QueryBuilder;
use Lc\SovBundle\Doctrine\EntityInterface;
use Lc\SovBundle\Model\User\UserInterface;
use Lc\SovBundle\Repository\AbstractRepositoryQuery;

interface ReminderRepositoryQueryInterface interface ReminderRepositoryQueryInterface
{ {
public function create();

public function call(callable $fn);

public function count();

public function findOne();

public function find(): array;

public function limit(int $maxResults);

public function paginate(int $page = 1, int $limit = 20);

public function getRepository(): ServiceEntityRepository;

public function getQueryBuilder(): QueryBuilder;

public function groupBy(string $field);

public function orderBy(string $field, string $sort = 'ASC');

public function filterById(int $id);

public function andWhereEqual($field, $value);

public function filterByOldUrl(string $oldUrl);

public function resetRelationsJoin(): void;

public function filterByDevAlias(string $devAlias);

public function filterBySlug(string $slug);

public function filterIsParent();

public function filterIsChildren();

public function filterByParent(EntityInterface $parent = null);

public function filterIsOffline();

public function filterIsOnline();

public function filterIsDeleted();

public function filterIsOnlineAndOffline();

public function filterByDone($done = false): ReminderRepositoryQueryInterface;

public function joinUser(): ReminderRepositoryQueryInterface;

public function filterByUser(UserInterface $user): ReminderRepositoryQueryInterface;

public function filterByCrudAction(?string $crudAction = null
): ReminderRepositoryQueryInterface;

public function filterByCrudControllerFqcn(?string $crudControllerFqcn = null
): ReminderRepositoryQueryInterface;

public function filterByEntityId(?int $entityId = null): ReminderRepositoryQueryInterface;

public function filterIsNotDone(): ReminderRepositoryQueryInterface;

public function filterLikeCrudAction(string $crudAction): ReminderRepositoryQueryInterface;

public function filterLikeCrudControllerFqcn(string $crudControllerFqcn
): ReminderRepositoryQueryInterface;


}
public function filterLikeEntityId(int $entityId): ReminderRepositoryQueryInterface;
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save