@@ -2,6 +2,9 @@ | |||
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 Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; | |||
use Symfony\Component\Form\FormFactoryInterface; | |||
@@ -13,6 +16,7 @@ use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; | |||
use Symfony\Component\Security\Core\Security; | |||
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator; | |||
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\Credentials\PasswordCredentials; | |||
use Symfony\Component\Security\Http\Authenticator\Passport\Passport; | |||
@@ -27,17 +31,19 @@ class LoginFormAuthenticator extends AbstractLoginFormAuthenticator | |||
protected UrlGeneratorInterface $urlGenerator; | |||
protected UserStore $userStore; | |||
protected UserBuilder $userBuilder; | |||
protected FormFactoryInterface $formFactory; | |||
protected ParameterBagInterface $parameterBag; | |||
public function __construct( | |||
UrlGeneratorInterface $urlGenerator, | |||
UserStore $userStore, | |||
UserContainer $userContainer, | |||
FormFactoryInterface $formFactory, | |||
ParameterBagInterface $parameterBag | |||
) { | |||
$this->urlGenerator = $urlGenerator; | |||
$this->userStore = $userStore; | |||
$this->userStore = $userContainer->getStore(); | |||
$this->userBuilder = $userContainer->getBuilder(); | |||
$this->formFactory = $formFactory; | |||
$this->parameterBag = $parameterBag; | |||
} | |||
@@ -49,7 +55,8 @@ class LoginFormAuthenticator extends AbstractLoginFormAuthenticator | |||
public function authenticate(Request $request): PassportInterface | |||
{ | |||
$email = $request->request->get('email'); | |||
$email = trim($request->request->get('email')); | |||
$password = $request->request->get('password'); | |||
$csrfToken = $request->request->get('_csrf_token'); | |||
@@ -58,7 +65,10 @@ class LoginFormAuthenticator extends AbstractLoginFormAuthenticator | |||
return $this->userStore->getOneByEmail($userIdentifier); | |||
}), | |||
new PasswordCredentials($password), | |||
[new CsrfTokenBadge('authenticate', $csrfToken)] | |||
[ | |||
new CsrfTokenBadge('authenticate', $csrfToken), | |||
new RememberMeBadge() | |||
] | |||
); | |||
} | |||
@@ -67,17 +77,21 @@ class LoginFormAuthenticator extends AbstractLoginFormAuthenticator | |||
TokenInterface $token, | |||
string $providerKey | |||
): RedirectResponse { | |||
$routeName = 'home'; | |||
$email = $request->request->get('email'); | |||
$email = trim($request->request->get('email')); | |||
$loginRedirection = $this->parameterBag->get('lc_sov.login_redirection'); | |||
$useReferer = $loginRedirection['redirect_referer']; | |||
$rolesRedirection = $loginRedirection['roles_redirection']; | |||
$user = $this->userStore->getOneByEmail($email); | |||
if (isset($useReferer) && $useReferer == true) { | |||
$url = $request->request->get('_target_path'); | |||
} else { | |||
$user = $this->userStore->getOneByEmail($email); | |||
if (!empty($user)) { | |||
$roles = $user->getRoles(); | |||
@@ -88,6 +102,7 @@ class LoginFormAuthenticator extends AbstractLoginFormAuthenticator | |||
} | |||
} | |||
} | |||
$this->userBuilder->setLastLogin($user); | |||
if (isset($url) && !empty($url)) { | |||
return new RedirectResponse($url); |
@@ -3,10 +3,14 @@ | |||
namespace Lc\SovBundle\Builder\User; | |||
use Doctrine\ORM\EntityManagerInterface; | |||
use Lc\CaracoleBundle\Model\Address\AddressInterface; | |||
use Lc\SovBundle\Doctrine\EntityInterface; | |||
use Lc\SovBundle\Doctrine\Extension\BlameableInterface; | |||
use Lc\SovBundle\Factory\User\UserFactory; | |||
use Lc\SovBundle\Model\Newsletter\NewsletterInterface; | |||
use Lc\SovBundle\Model\Ticket\TicketInterface; | |||
use Lc\SovBundle\Model\User\UserInterface; | |||
use Lc\SovBundle\Repository\RepositoryQueryInterface; | |||
use Lc\SovBundle\Repository\User\UserStore; | |||
use Lc\SovBundle\Solver\User\UserSolver; | |||
@@ -15,11 +19,29 @@ class UserBuilder | |||
protected EntityManagerInterface $entityManager; | |||
protected UserStore $userStore; | |||
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->userStore = $userStore; | |||
$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 | |||
@@ -41,6 +63,7 @@ class UserBuilder | |||
return $entity; | |||
} | |||
public function initBlameableUpdatedSystem(EntityInterface $entity) | |||
{ | |||
$userSystem = $this->userStore->getOneByDevAlias('system'); | |||
@@ -63,4 +86,13 @@ class UserBuilder | |||
$entity->setUpdatedBy($user); | |||
} | |||
} | |||
public function setLastLogin(?UserInterface $user) | |||
{ | |||
if ($user instanceof UserInterface) { | |||
$user->setLastLogin(new \DateTime()); | |||
$this->entityManager->update($user); | |||
$this->entityManager->flush(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,20 @@ | |||
<?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; | |||
} | |||
} |
@@ -85,15 +85,20 @@ class CitiesComponent | |||
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; | |||
} | |||
@@ -70,4 +70,9 @@ class DateComponent | |||
return $hour ; | |||
} | |||
public function getTotalMinutes(\DateTimeInterface $time): int | |||
{ | |||
return (int) $time->format('H') * 60 + (int) $time->format('i'); | |||
} | |||
} |
@@ -3,6 +3,7 @@ | |||
namespace Lc\SovBundle\Component; | |||
use Doctrine\ORM\EntityManagerInterface; | |||
use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface; | |||
use Lc\SovBundle\Doctrine\Extension\BlameableInterface; | |||
use Lc\SovBundle\Doctrine\Extension\DevAliasInterface; | |||
use Lc\SovBundle\Doctrine\Extension\SeoInterface; | |||
@@ -31,8 +32,8 @@ class EntityComponent | |||
public function duplicateEntity($entity) | |||
{ | |||
$newEntity = clone $entity; | |||
$classMetadata = $this->entityManager->getClassMetadata(get_class($newEntity)); | |||
//Dupplication de l'image ou du fichier lier | |||
@@ -68,9 +69,11 @@ class EntityComponent | |||
$newEntity->setCreatedAt(new \DateTime()); | |||
} | |||
$this->entityManager->create($newEntity); | |||
$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; | |||
} | |||
@@ -109,4 +112,4 @@ class EntityComponent | |||
} | |||
return $entity; | |||
} | |||
} | |||
} |
@@ -5,16 +5,27 @@ namespace Lc\SovBundle\Component; | |||
use Liip\ImagineBundle\Imagine\Cache\CacheManager; | |||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; | |||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | |||
class FileComponent | |||
{ | |||
protected ParameterBagInterface $parameterBag; | |||
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->liipCacheHelper = $liipCacheHelper; | |||
$this->router = $router; | |||
} | |||
public function getAssetUrl($path) | |||
{ | |||
$context = $this->router->getContext(); | |||
$host = $context->getScheme().'://'.$context->getHost().'/'; | |||
return $host.$path; | |||
} | |||
/** | |||
@@ -34,6 +45,9 @@ class FileComponent | |||
$path = substr($path, 1); | |||
} | |||
// gestion des accents et des espaces | |||
$path = urldecode($path); | |||
if ($path) { | |||
$fileManagerFolder = substr($this->getFileManagerFolder(), 1); |
@@ -4,14 +4,25 @@ namespace Lc\SovBundle\Component; | |||
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(method_exists($entity, 'getMetaTitle')) { | |||
if(method_exists($entity, 'getMetaTitle') && $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() ; | |||
} | |||
} | |||
@@ -22,24 +33,27 @@ class MetaComponent | |||
public function getMetaDescription($entity) | |||
{ | |||
if($entity) { | |||
if(method_exists($entity, 'getMetaDescription')) { | |||
if(method_exists($entity, 'getMetaDescription') && $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 '' ; | |||
} | |||
public function getOpenGraphTitle($entity) | |||
public function getOpenGraphTitle($entity, $title = null) | |||
{ | |||
if($entity) { | |||
if(method_exists($entity, 'getOpenGraphTitle')) { | |||
if(method_exists($entity, 'getOpenGraphTitle') && $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() ; | |||
} | |||
} | |||
@@ -50,11 +64,11 @@ class MetaComponent | |||
public function getOpenGraphDescription($entity) | |||
{ | |||
if($entity) { | |||
if(method_exists($entity, 'getOpenGraphDescription')) { | |||
if(method_exists($entity, 'getOpenGraphDescription') && $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()); | |||
} | |||
} | |||
@@ -64,10 +78,10 @@ class MetaComponent | |||
public function getOpenGraphImage($entity) | |||
{ | |||
if($entity) { | |||
if(method_exists($entity, 'getOpenGraphImage')) { | |||
if(method_exists($entity, 'getOpenGraphImage') && $entity->getOpenGraphImage()) { | |||
return $entity->getOpenGraphImage() ; | |||
} | |||
elseif(method_exists($entity, 'getImage')) { | |||
elseif(method_exists($entity, 'getImage') && $entity->getImage()) { | |||
return $entity->getImage() ; | |||
} | |||
} | |||
@@ -75,4 +89,22 @@ class MetaComponent | |||
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; | |||
} | |||
} |
@@ -2,6 +2,7 @@ | |||
namespace Lc\SovBundle\Container; | |||
use Lc\SovBundle\Component\ArrayComponent; | |||
use Lc\SovBundle\Component\CitiesComponent; | |||
use Lc\SovBundle\Component\CookieComponent; | |||
use Lc\SovBundle\Component\DateComponent; | |||
@@ -25,6 +26,7 @@ class ComponentContainer | |||
protected NumberComponent $numberComponent; | |||
protected PointLocationComponent $pointLocationComponent; | |||
protected StringComponent $stringComponent; | |||
protected ArrayComponent $arrayComponent; | |||
public function __construct( | |||
CitiesComponent $citiesComponent, | |||
@@ -36,7 +38,8 @@ class ComponentContainer | |||
MetaComponent $metaComponent, | |||
NumberComponent $numberComponent, | |||
PointLocationComponent $pointLocationComponent, | |||
StringComponent $stringComponent | |||
StringComponent $stringComponent, | |||
ArrayComponent $arrayComponent | |||
) { | |||
$this->citiesComponent = $citiesComponent; | |||
$this->cookieComponent = $cookieComponent; | |||
@@ -48,6 +51,7 @@ class ComponentContainer | |||
$this->numberComponent = $numberComponent; | |||
$this->pointLocationComponent = $pointLocationComponent; | |||
$this->stringComponent = $stringComponent; | |||
$this->arrayComponent = $arrayComponent; | |||
} | |||
public function getCitiesComponent(): CitiesComponent | |||
@@ -99,4 +103,9 @@ class ComponentContainer | |||
{ | |||
return $this->stringComponent; | |||
} | |||
public function getArrayComponent(): ArrayComponent | |||
{ | |||
return $this->arrayComponent; | |||
} | |||
} |
@@ -2,7 +2,9 @@ | |||
namespace Lc\SovBundle\Container\File; | |||
use App\Entity\File\File; | |||
use Lc\SovBundle\Factory\File\FileFactory; | |||
use Lc\SovBundle\Model\File\FileInterface; | |||
use Lc\SovBundle\Repository\File\FileRepositoryQuery; | |||
use Lc\SovBundle\Repository\File\FileStore; | |||
@@ -22,6 +24,11 @@ class FileContainer | |||
$this->store = $store; | |||
} | |||
public static function getEntityFqcn() | |||
{ | |||
return File::class; | |||
} | |||
public function getFactory(): FileFactory | |||
{ | |||
return $this->factory; | |||
@@ -36,4 +43,5 @@ class FileContainer | |||
{ | |||
return $this->store; | |||
} | |||
} |
@@ -2,6 +2,7 @@ | |||
namespace Lc\SovBundle\Container\Newsletter; | |||
use App\Entity\Newsletter\Newsletter; | |||
use Lc\SovBundle\Definition\Field\Newsletter\NewsletterFieldDefinition; | |||
use Lc\SovBundle\Factory\Newsletter\NewsletterFactory; | |||
use Lc\SovBundle\Repository\Newsletter\NewsletterRepositoryQuery; | |||
@@ -26,6 +27,12 @@ class NewsletterContainer | |||
$this->fieldDefinition = $fieldDefinition; | |||
} | |||
public static function getEntityFqcn() | |||
{ | |||
return Newsletter::class; | |||
} | |||
public function getFactory(): NewsletterFactory | |||
{ | |||
return $this->factory; |
@@ -2,6 +2,7 @@ | |||
namespace Lc\SovBundle\Container\Reminder; | |||
use App\Entity\Reminder\Reminder; | |||
use Lc\SovBundle\Factory\Reminder\ReminderFactory; | |||
use Lc\SovBundle\Repository\Reminder\ReminderRepositoryQuery; | |||
use Lc\SovBundle\Repository\Reminder\ReminderStore; | |||
@@ -22,6 +23,11 @@ class ReminderContainer | |||
$this->store = $store; | |||
} | |||
public static function getEntityFqcn() | |||
{ | |||
return Reminder::class; | |||
} | |||
public function getFactory(): ReminderFactory | |||
{ | |||
return $this->factory; |
@@ -2,6 +2,7 @@ | |||
namespace Lc\SovBundle\Container\Setting; | |||
use App\Entity\Setting\SiteSetting; | |||
use Lc\SovBundle\Definition\SiteSettingDefinition; | |||
use Lc\SovBundle\Factory\Setting\SiteSettingFactory; | |||
use Lc\SovBundle\Repository\Setting\SiteSettingRepositoryQuery; | |||
@@ -30,6 +31,12 @@ class SiteSettingContainer | |||
$this->settingSolver = $settingSolver; | |||
} | |||
public static function getEntityFqcn() | |||
{ | |||
return SiteSetting::class; | |||
} | |||
public function getFactory(): SiteSettingFactory | |||
{ | |||
return $this->factory; |
@@ -2,6 +2,7 @@ | |||
namespace Lc\SovBundle\Container\Site; | |||
use App\Entity\Site\News; | |||
use Lc\SovBundle\Definition\Field\Site\NewsFieldDefinition; | |||
use Lc\SovBundle\Factory\Site\NewsFactory; | |||
use Lc\SovBundle\Repository\Site\NewsRepositoryQuery; | |||
@@ -26,6 +27,11 @@ class NewsContainer | |||
$this->fieldDefinition = $fieldDefinition; | |||
} | |||
public static function getEntityFqcn() | |||
{ | |||
return News::class; | |||
} | |||
public function getFactory(): NewsFactory | |||
{ | |||
return $this->factory; |
@@ -2,6 +2,7 @@ | |||
namespace Lc\SovBundle\Container\Site; | |||
use App\Entity\Site\Page; | |||
use Lc\SovBundle\Definition\Field\Site\PageFieldDefinition; | |||
use Lc\SovBundle\Factory\Site\PageFactory; | |||
use Lc\SovBundle\Repository\Site\PageRepositoryQuery; | |||
@@ -26,6 +27,11 @@ class PageContainer | |||
$this->fieldDefinition = $fieldDefinition; | |||
} | |||
public static function getEntityFqcn() | |||
{ | |||
return Page::class; | |||
} | |||
public function getFactory(): PageFactory | |||
{ | |||
return $this->factory; |
@@ -2,6 +2,7 @@ | |||
namespace Lc\SovBundle\Container\Site; | |||
use App\Entity\Site\Site; | |||
use Lc\SovBundle\Factory\Site\SiteFactory; | |||
use Lc\SovBundle\Repository\Site\SiteRepositoryQuery; | |||
use Lc\SovBundle\Repository\Site\SiteStore; | |||
@@ -22,6 +23,10 @@ class SiteContainer | |||
$this->store = $store; | |||
} | |||
public static function getEntityFqcn() | |||
{ | |||
return Site::class; | |||
} | |||
public function getFactory(): SiteFactory | |||
{ | |||
return $this->factory; |
@@ -2,6 +2,7 @@ | |||
namespace Lc\SovBundle\Container\Ticket; | |||
use App\Entity\Ticket\Ticket; | |||
use Lc\SovBundle\Builder\Ticket\TicketBuilder; | |||
use Lc\SovBundle\Definition\Field\Ticket\TicketFieldDefinition; | |||
use Lc\SovBundle\Factory\Ticket\TicketFactory; | |||
@@ -34,6 +35,12 @@ class TicketContainer | |||
$this->fieldDefinition = $fieldDefinition; | |||
} | |||
public static function getEntityFqcn() | |||
{ | |||
return Ticket::class; | |||
} | |||
public function getFactory(): TicketFactory | |||
{ | |||
return $this->factory; |
@@ -2,6 +2,7 @@ | |||
namespace Lc\SovBundle\Container\Ticket; | |||
use App\Entity\Ticket\TicketMessage; | |||
use Lc\SovBundle\Builder\Ticket\TicketMessageBuilder; | |||
use Lc\SovBundle\Factory\Ticket\TicketMessageFactory; | |||
use Lc\SovBundle\Repository\Ticket\TicketMessageRepositoryQuery; | |||
@@ -26,6 +27,10 @@ class TicketMessageContainer | |||
$this->builder = $builder; | |||
} | |||
public static function getEntityFqcn() | |||
{ | |||
return TicketMessage::class; | |||
} | |||
public function getFactory(): TicketMessageFactory | |||
{ | |||
return $this->factory; |
@@ -2,6 +2,7 @@ | |||
namespace Lc\SovBundle\Container\User; | |||
use App\Entity\User\GroupUser; | |||
use Lc\SovBundle\Factory\User\GroupUserFactory; | |||
use Lc\SovBundle\Repository\User\GroupUserRepositoryQuery; | |||
use Lc\SovBundle\Repository\User\GroupUserStore; | |||
@@ -22,6 +23,10 @@ class GroupUserContainer | |||
$this->store = $store; | |||
} | |||
public static function getEntityFqcn() | |||
{ | |||
return GroupUser::class; | |||
} | |||
public function getFactory(): GroupUserFactory | |||
{ | |||
return $this->factory; |
@@ -2,6 +2,7 @@ | |||
namespace Lc\SovBundle\Container\User; | |||
use App\Entity\User\User; | |||
use Lc\SovBundle\Builder\User\UserBuilder; | |||
use Lc\SovBundle\Definition\Field\User\UserFieldDefinition; | |||
use Lc\SovBundle\Definition\RolesDefinitionInterface; | |||
@@ -37,6 +38,10 @@ class UserContainer | |||
$this->fieldDefinition = $fieldDefinition; | |||
$this->rolesDefinition = $rolesDefinition; | |||
} | |||
public static function getEntityFqcn() | |||
{ | |||
return User::class; | |||
} | |||
public function getFactory(): UserFactory | |||
{ |
@@ -23,6 +23,7 @@ use EasyCorp\Bundle\EasyAdminBundle\Event\AfterCrudActionEvent; | |||
use EasyCorp\Bundle\EasyAdminBundle\Event\AfterEntityUpdatedEvent; | |||
use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeCrudActionEvent; | |||
use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityDeletedEvent; | |||
use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityUpdatedEvent; | |||
use EasyCorp\Bundle\EasyAdminBundle\Exception\ForbiddenActionException; | |||
use EasyCorp\Bundle\EasyAdminBundle\Exception\InsufficientEntityPermissionException; | |||
use EasyCorp\Bundle\EasyAdminBundle\Factory\ControllerFactory; | |||
@@ -36,9 +37,11 @@ use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Provider\AdminContextProvider; | |||
use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator; | |||
use EasyCorp\Bundle\EasyAdminBundle\Security\Permission; | |||
use Lc\CaracoleBundle\Model\Section\SectionInterface; | |||
use Lc\SovBundle\Component\EntityComponent; | |||
use Lc\SovBundle\Definition\ActionDefinition; | |||
use Lc\SovBundle\Doctrine\Extension\DevAliasInterface; | |||
use Lc\SovBundle\Doctrine\Extension\OpenGraphInterface; | |||
use Lc\SovBundle\Doctrine\Extension\SeoInterface; | |||
use Lc\SovBundle\Doctrine\Extension\SortableInterface; | |||
use Lc\SovBundle\Doctrine\Extension\StatusInterface; | |||
@@ -46,6 +49,7 @@ use Lc\SovBundle\Doctrine\Extension\TranslatableInterface; | |||
use Lc\SovBundle\Doctrine\Extension\TreeInterface; | |||
use Lc\SovBundle\Field\CollectionField; | |||
use Lc\SovBundle\Field\Filter\FilterManager; | |||
use Lc\SovBundle\Field\ImageManagerField; | |||
use Lc\SovBundle\Form\Common\FiltersFormType; | |||
use Lc\SovBundle\Form\Common\PositionType; | |||
use Lc\SovBundle\Model\User\UserInterface; | |||
@@ -58,6 +62,7 @@ use Symfony\Component\Form\Extension\Core\Type\TextType; | |||
use Symfony\Component\Form\FormInterface; | |||
use Symfony\Component\HttpFoundation\JsonResponse; | |||
use Symfony\Component\HttpFoundation\RequestStack; | |||
use Symfony\Component\HttpFoundation\Response; | |||
abstract class AbstractAdminController extends EaAbstractCrudController | |||
{ | |||
@@ -80,7 +85,7 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
if (Crud::PAGE_INDEX === $responseParameters->get('pageName')) { | |||
$responseParameters->set('fields', $this->configureFields('index')); | |||
if(isset($this->filtersForm)) { | |||
if (isset($this->filtersForm)) { | |||
$responseParameters->set('filters_form', $this->filtersForm); | |||
} | |||
} | |||
@@ -136,10 +141,10 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
if ($action->getName() == ActionDefinition::WRITE_TO_USER) { | |||
$entity = $context->getEntity()->getInstance(); | |||
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); | |||
} | |||
} else { | |||
@@ -150,16 +155,17 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
} | |||
} | |||
protected function getRequestCrudAction() :string{ | |||
protected function getRequestCrudAction(): string | |||
{ | |||
return $this->getRequestStack()->getCurrentRequest()->get('crudAction'); | |||
} | |||
public function configureCrud(Crud $crud): Crud | |||
{ | |||
$crud = parent::configureCrud($crud); | |||
if($this->getRequestCrudAction() === ActionDefinition::SORT) { | |||
if ($this->getRequestCrudAction() === ActionDefinition::SORT) { | |||
$crud->setPaginatorPageSize(9999); | |||
}else { | |||
} else { | |||
$this->setMaxResults($crud); | |||
} | |||
@@ -167,7 +173,7 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
if ($this->isInstanceOf(SortableInterface::class)) { | |||
$crud->setDefaultSort(['position' => 'ASC']); | |||
}else{ | |||
} else { | |||
$crud->setDefaultSort(['id' => 'DESC']); | |||
} | |||
@@ -276,14 +282,15 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
throw new InsufficientEntityPermissionException($context); | |||
} | |||
$event = new BeforeEntityDeletedEvent($entityInstance); | |||
$event = new BeforeEntityUpdatedEvent($entityInstance); | |||
$this->get('event_dispatcher')->dispatch($event); | |||
$entityInstance = $event->getEntityInstance(); | |||
$entityInstance->setPosition($elm['position']); | |||
$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) | |||
@@ -319,14 +326,15 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
} | |||
public function duplicate( | |||
AdminContext $context, | |||
EntityComponent $entityComponent, | |||
TranslatorAdmin $translatorAdmin, | |||
AdminContext $context, | |||
EntityComponent $entityComponent, | |||
TranslatorAdmin $translatorAdmin, | |||
EntityManagerInterface $em | |||
) { | |||
) | |||
{ | |||
if (!$this->isGranted( | |||
Permission::EA_EXECUTE_ACTION, | |||
['action' => "duplicate", 'entity' => $context->getEntity()] | |||
['action' => ActionDefinition::DUPLICATE, 'entity' => $context->getEntity()] | |||
)) { | |||
throw new ForbiddenActionException($context); | |||
} | |||
@@ -336,7 +344,7 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
} | |||
$newEntity = $entityComponent->duplicateEntity($context->getEntity()->getInstance()); | |||
$em->create($newEntity); | |||
$em->create($newEntity, false); | |||
$em->flush(); | |||
$url = $this->get(AdminUrlGenerator::class) | |||
@@ -344,24 +352,27 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
->setEntityId($newEntity->getId()) | |||
->generateUrl(); | |||
$this->addFlashTranslator('success', 'duplicated'); | |||
$this->addFlashTranslator('success', ActionDefinition::DUPLICATE); | |||
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; | |||
}else{ | |||
} else { | |||
return false; | |||
} | |||
} | |||
public function createIndexRepositoryQuery( | |||
SearchDto $searchDto, | |||
EntityDto $entityDto, | |||
FieldCollection $fields, | |||
SearchDto $searchDto, | |||
EntityDto $entityDto, | |||
FieldCollection $fields, | |||
FilterCollection $filters | |||
): RepositoryQueryInterface { | |||
): RepositoryQueryInterface | |||
{ | |||
$repositoryQuery = $this->get(EntityRepository::class)->createRepositoryQuery( | |||
$this->getRepositoryQuery(), | |||
$searchDto, | |||
@@ -402,29 +413,38 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
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( | |||
SearchDto $searchDto, | |||
EntityDto $entityDto, | |||
FieldCollection $fields, | |||
SearchDto $searchDto, | |||
EntityDto $entityDto, | |||
FieldCollection $fields, | |||
FilterCollection $filters | |||
): QueryBuilder { | |||
): QueryBuilder | |||
{ | |||
$repositoryQuery = $this->createIndexRepositoryQuery($searchDto, $entityDto, $fields, $filters); | |||
return $repositoryQuery->getQueryBuilder(); | |||
} | |||
public function createSortQueryBuilder( | |||
SearchDto $searchDto, | |||
EntityDto $entityDto, | |||
FieldCollection $fields, | |||
SearchDto $searchDto, | |||
EntityDto $entityDto, | |||
FieldCollection $fields, | |||
FilterCollection $filters | |||
): QueryBuilder { | |||
): QueryBuilder | |||
{ | |||
$repositoryQuery = $this->createSortRepositoryQuery($searchDto, $entityDto, $fields, $filters); | |||
return $repositoryQuery->getQueryBuilder(); | |||
} | |||
@@ -466,7 +486,12 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
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(); | |||
$this->get(FlashBagTranslator::class)->add('success', 'deleted', $this->getTranslationEntityName()); | |||
} | |||
@@ -762,12 +787,18 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
public function autocompleteFilter(AdminContext $context): JsonResponse | |||
{ | |||
$queryBuilder = $this->createIndexQueryBuilder( | |||
$repositoryQuery = $this->get(EntityRepository::class)->createRepositoryQuery( | |||
$this->getRepositoryQuery(), | |||
$context->getSearch(), | |||
$context->getEntity(), | |||
FieldCollection::new([]), | |||
FilterCollection::new() | |||
); | |||
if ($this->isInstanceOf(StatusInterface::class)) { | |||
$repositoryQuery->filterIsOnlineAndOffline(); | |||
} | |||
$autocompleteContext = $context->getRequest()->get(AssociationField::PARAM_AUTOCOMPLETE_CONTEXT); | |||
/** @var CrudControllerInterface $controller */ | |||
@@ -782,20 +813,15 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
)->getByProperty($autocompleteContext['propertyName']); | |||
$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(); | |||
foreach ($queryBuilder->getQuery()->getArrayResult() as $result) { | |||
foreach ($repositoryQuery->find() as $result) { | |||
$responses[] = array_values($result)[0]; | |||
} | |||
return JsonResponse::fromJsonString(json_encode($responses)); | |||
} | |||
@@ -816,5 +842,28 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
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; | |||
} | |||
} | |||
@@ -18,7 +18,9 @@ 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 Lc\SovBundle\Definition\ApplicationDefinition; | |||
use Lc\SovBundle\Field\Filter\FilterManager; | |||
use Lc\SovBundle\Generator\PdfGenerator; | |||
use Lc\SovBundle\Repository\EntityRepository; | |||
use Lc\SovBundle\Solver\Setting\SettingSolver; | |||
use Lc\SovBundle\Translation\FlashBagTranslator; | |||
@@ -30,70 +32,76 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface; | |||
use Symfony\Component\HttpFoundation\Request; | |||
use Symfony\Component\HttpFoundation\RequestStack; | |||
use Symfony\Component\HttpFoundation\Session\SessionInterface; | |||
use Symfony\Component\HttpKernel\KernelInterface; | |||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; | |||
use Symfony\Component\Security\Core\Security; | |||
use Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices; | |||
use Symfony\Contracts\Translation\TranslatorInterface; | |||
use Twig\Environment; | |||
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( | |||
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( | |||
string $type, | |||
$translationKeyName, | |||
$translationEntityName = null, | |||
$translationParam = array() | |||
): void | |||
{ | |||
string $type, | |||
$translationKeyName, | |||
$translationEntityName = null, | |||
$translationParam = array() | |||
): void { | |||
if ($translationEntityName === null && method_exists($this, 'getTranslationEntityName')) { | |||
$translationEntityName = $this->getTranslationEntityName(); | |||
} | |||
$this->get(FlashBagTranslator::class)->add( | |||
$type, | |||
$translationKeyName, | |||
$translationEntityName, | |||
$translationParam | |||
$type, | |||
$translationKeyName, | |||
$translationEntityName, | |||
$translationParam | |||
); | |||
} | |||
@@ -102,8 +110,12 @@ trait ControllerTrait | |||
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); | |||
if ($controller) { | |||
$adminUrlGenerator->setController($controller); | |||
@@ -132,6 +144,11 @@ trait ControllerTrait | |||
return $this->get(Environment::class); | |||
} | |||
public function getApplicationDefinition(): ApplicationDefinition | |||
{ | |||
return $this->get(ApplicationDefinition::class); | |||
} | |||
public function getEntityManager(): EntityManagerInterface | |||
{ | |||
return $this->get(EntityManagerInterface::class); | |||
@@ -177,6 +194,11 @@ trait ControllerTrait | |||
return $this->get(TranslatorInterface::class); | |||
} | |||
public function getPdfGenerator(): PdfGenerator | |||
{ | |||
return $this->get(PdfGenerator::class); | |||
} | |||
public function getTranslatorAdmin(): TranslatorAdmin | |||
{ | |||
return $this->get(TranslatorAdmin::class); | |||
@@ -197,6 +219,11 @@ trait ControllerTrait | |||
return $this->get(AdminUrlGenerator::class); | |||
} | |||
public function getKernel(): KernelInterface | |||
{ | |||
return $this->get(KernelInterface::class); | |||
} | |||
public function getSettingSolver(): SettingSolver | |||
{ | |||
return $this->get(SettingSolver::class); | |||
@@ -267,4 +294,10 @@ trait ControllerTrait | |||
return $this->get(SiteSettingContainer::class); | |||
} | |||
} | |||
public function setNoMemoryAndTimeLimit(): void | |||
{ | |||
ini_set('memory_limit', '-1'); | |||
set_time_limit(0); | |||
} | |||
} |
@@ -0,0 +1,50 @@ | |||
<?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); | |||
} | |||
} |
@@ -19,6 +19,9 @@ class DashboardAdminController extends AbstractDashboardController | |||
use ControllerTrait; | |||
/** | |||
* @Route("/admin", name="app_admin_dashboard") | |||
*/ | |||
public function index(): Response | |||
{ | |||
return $this->render('@LcSov/adminlte/dashboard.html.twig'); | |||
@@ -29,8 +32,6 @@ class DashboardAdminController extends AbstractDashboardController | |||
return Dashboard::new() | |||
// the name visible to end users | |||
->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 | |||
->setFaviconPath('assets/img/frontend/favicon-pdl.png') | |||
// the domain used by default is 'messages' |
@@ -2,22 +2,60 @@ | |||
namespace Lc\SovBundle\Controller; | |||
use Symfony\Component\ErrorHandler\Exception\FlattenException; | |||
use Symfony\Component\HttpFoundation\Request; | |||
use Symfony\Component\Mailer\MailerInterface; | |||
use Throwable; | |||
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface; | |||
use Symfony\Component\Mime\Email; | |||
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', [ | |||
"code" => $exception->getCode(), | |||
"code" => $exception->getStatusCode(), | |||
"message" => $exception->getMessage() | |||
]); | |||
} else { | |||
return $this->render('bundles/TwigBundle/Exception/error.html.twig', [ | |||
"code" => $exception->getCode(), | |||
"code" => $exception->getStatusCode(), | |||
"message" => $exception->getMessage() | |||
]); | |||
} |
@@ -40,7 +40,7 @@ class SecurityAdminController extends AbstractController | |||
// the title visible above the login form (define this option only if you are | |||
// rendering the login template in a regular Symfony controller; when rendering | |||
// it from an EasyAdmin Dashboard this is automatically set as the Dashboard title) | |||
'page_title' => '<img src="assets/img/' . $this->get('parameter_bag')->get('app.admin.logo') . '" >', | |||
'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 | |||
// this parameter, the login form won't include a CSRF token | |||
@@ -50,13 +50,13 @@ class SecurityAdminController extends AbstractController | |||
'target_path' => $this->generateUrl('app_admin_dashboard'), | |||
// the label displayed for the username form field (the |trans filter is applied to it) | |||
'username_label' => 'Your username', | |||
'username_label' => 'Email', | |||
// 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) | |||
'sign_in_label' => 'Log in', | |||
'sign_in_label' => 'Connexion', | |||
// the 'name' HTML attribute of the <input> used for the username field (default: '_username') | |||
'username_parameter' => 'email', |
@@ -2,20 +2,36 @@ | |||
namespace Lc\SovBundle\Controller\User; | |||
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException; | |||
use Doctrine\ORM\EntityManagerInterface; | |||
use EasyCorp\Bundle\EasyAdminBundle\Collection\EntityCollection; | |||
use EasyCorp\Bundle\EasyAdminBundle\Config\Action; | |||
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; | |||
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; | |||
use EasyCorp\Bundle\EasyAdminBundle\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\EmailField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Security\Permission; | |||
use Lc\SovBundle\Container\User\UserContainer; | |||
use Lc\SovBundle\Controller\AbstractAdminController; | |||
use Lc\SovBundle\Definition\ActionDefinition; | |||
use Lc\SovBundle\Definition\ApplicationDefinition; | |||
use Lc\SovBundle\Definition\RolesDefinition; | |||
use Lc\SovBundle\Definition\RolesDefinitionInterface; | |||
use Lc\SovBundle\Doctrine\EntityManager; | |||
use Lc\SovBundle\Doctrine\Extension\BlameableInterface; | |||
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 Symfony\Component\HttpFoundation\RequestStack; | |||
use Symfony\Component\HttpFoundation\Session\SessionInterface; | |||
@@ -76,4 +92,108 @@ abstract class UserAdminController extends AbstractAdminController | |||
{ | |||
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; | |||
} | |||
} |
@@ -0,0 +1,88 @@ | |||
<?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; | |||
} | |||
} |
@@ -8,6 +8,8 @@ use EasyCorp\Bundle\EasyAdminBundle\Field\FormField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\IntegerField; | |||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField; | |||
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\ImageManagerField; | |||
use Lc\SovBundle\Field\StatusField; | |||
@@ -29,26 +31,33 @@ abstract class AbstractFieldDefinition | |||
{ | |||
return [ | |||
'id' => IntegerField::new('id')->onlyOnIndex()->setSortable(true), | |||
'title' => TextField::new('title'), | |||
'description' => CKEditorField::new('description'), | |||
'image' => ImageManagerField::new('image'), | |||
'metaTitle' => TextField::new('metaTitle') | |||
->setLabel('Meta : title') | |||
->setHelp('Affiché dans les résultats de recherche Google'), | |||
'metaDescription' => TextareaField::new('metaDescription') | |||
->setLabel('Meta : description') | |||
->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') | |||
->setFormTypeOption('entry_type', TextType::class) | |||
->setLabel('Anciennes urls du document') | |||
->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(), | |||
'status' => StatusField::new('status')->setSortable(true), | |||
'createdAt' => DateTimeField::new('createdAt')->setSortable(true), | |||
'updatedAt' => DateTimeField::new('updatedAt')->setSortable(true), | |||
'createdBy' => AssociationField::new('createdBy'), | |||
'updatedBy' => AssociationField::new('updatedBy') | |||
]; | |||
} | |||
@@ -137,7 +146,7 @@ abstract class AbstractFieldDefinition | |||
$fieldArray = []; | |||
foreach($configureFieldArray as $fieldName) { | |||
if(isset($allFieldArray[$fieldName])) { | |||
$fieldArray[] = $allFieldArray[$fieldName]; | |||
$fieldArray[$fieldName] = $allFieldArray[$fieldName]; | |||
} | |||
else { | |||
throw new \ErrorException('Le field "'.$fieldName.'" n\'est pas défini dans configureFields()'); |
@@ -18,7 +18,7 @@ class PageFieldDefinition extends AbstractFieldDefinition | |||
]; | |||
} | |||
public function configurePanelMain(): array | |||
public function configurePanelGeneral(): array | |||
{ | |||
return [ | |||
'title', | |||
@@ -29,7 +29,7 @@ class PageFieldDefinition extends AbstractFieldDefinition | |||
public function configurePanels(): array | |||
{ | |||
return ['main', 'seo', 'conf']; | |||
return ['general', 'seo', 'opengraph', 'conf']; | |||
} | |||
public function configureFields(): array |
@@ -19,28 +19,28 @@ class SiteSettingDefinition extends AbstractSettingDefinition implements SiteSet | |||
{ | |||
// général | |||
$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( | |||
[ | |||
'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 [ | |||
self::CATEGORY_GENERAL, | |||
self::CATEGORY_GENERAL, | |||
]; | |||
} | |||
@@ -4,5 +4,5 @@ namespace Lc\SovBundle\Definition; | |||
interface SiteSettingDefinitionInterface | |||
{ | |||
public function getCategories(): array; | |||
} |
@@ -9,26 +9,31 @@ use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; | |||
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');*/ | |||
} | |||
} |
@@ -3,8 +3,16 @@ | |||
namespace Lc\SovBundle\Doctrine\Extension; | |||
use Lc\SovBundle\Model\User\UserInterface; | |||
interface BlameableInterface | |||
{ | |||
public function getCreatedBy(): ?UserInterface; | |||
public function setCreatedBy(?UserInterface $createdBy): BlameableInterface; | |||
public function getUpdatedBy(): ?UserInterface; | |||
public function setUpdatedBy(?UserInterface $updatedBy): BlameableInterface; | |||
} |
@@ -12,14 +12,14 @@ trait BlameableTrait | |||
/** | |||
* @Gedmo\Blameable(on="create") | |||
* @ORM\ManyToOne(targetEntity="Lc\SovBundle\Model\User\UserInterface") | |||
* @ORM\JoinColumn(nullable=true) | |||
* @ORM\JoinColumn(nullable=true, onDelete="SET NULL") | |||
*/ | |||
protected $createdBy; | |||
/** | |||
* @Gedmo\Blameable(on="update") | |||
* @ORM\ManyToOne(targetEntity="Lc\SovBundle\Model\User\UserInterface") | |||
* @ORM\JoinColumn(nullable=true) | |||
* @ORM\JoinColumn(nullable=true, onDelete="SET NULL") | |||
*/ | |||
protected $updatedBy; | |||
@@ -4,5 +4,7 @@ namespace Lc\SovBundle\Doctrine\Extension; | |||
interface DevAliasInterface | |||
{ | |||
public function getDevAlias(): ?string; | |||
public function setDevAlias(?string $devAlias): DevAliasInterface; | |||
} |
@@ -0,0 +1,26 @@ | |||
<?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; | |||
} | |||
} |
@@ -2,9 +2,19 @@ | |||
namespace Lc\SovBundle\Doctrine\Extension; | |||
use Lc\SovBundle\Model\File\FileInterface; | |||
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); | |||
} |
@@ -48,12 +48,12 @@ trait OpenGraphTrait | |||
} | |||
public function getOpenGraphImage(): ?FileModel | |||
public function getOpenGraphImage(): ?FileInterface | |||
{ | |||
return $this->openGraphImage; | |||
} | |||
public function setOpenGraphImage(?FileModel $openGraphImage): self | |||
public function setOpenGraphImage(?FileInterface $openGraphImage): self | |||
{ | |||
$this->openGraphImage = $openGraphImage; | |||
@@ -4,7 +4,15 @@ namespace Lc\SovBundle\Doctrine\Extension; | |||
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; | |||
} |
@@ -5,4 +5,7 @@ namespace Lc\SovBundle\Doctrine\Extension; | |||
interface SluggableInterface | |||
{ | |||
public function getSlug(): ?string; | |||
public function setSlug(?string $slug): SluggableInterface; | |||
} |
@@ -5,4 +5,9 @@ namespace Lc\SovBundle\Doctrine\Extension; | |||
interface SortableInterface | |||
{ | |||
public function getPosition(): float; | |||
public function setPosition(float $position): SortableInterface; | |||
public function clearPosition(): SortableInterface; | |||
} |
@@ -5,4 +5,8 @@ namespace Lc\SovBundle\Doctrine\Extension; | |||
interface StatusInterface | |||
{ | |||
public function getStatus(): ?float; | |||
public function setStatus(float $status): StatusInterface; | |||
} |
@@ -4,6 +4,12 @@ namespace Lc\SovBundle\Doctrine\Extension; | |||
interface TimestampableInterface | |||
{ | |||
public function getCreatedAt(): ?\DateTimeInterface; | |||
public function setCreatedAt(\DateTimeInterface $createdAt): TimestampableInterface; | |||
public function getUpdatedAt(): ?\DateTimeInterface; | |||
public function setUpdatedAt(\DateTimeInterface $updatedAt): TimestampableInterface; | |||
} |
@@ -4,6 +4,10 @@ namespace Lc\SovBundle\Doctrine\Extension; | |||
interface TranslatableInterface | |||
{ | |||
public function setTranslatableLocale($locale); | |||
public function getLocalesEnabled(): ?array; | |||
public function setLocalesEnabled(?array $localesEnabled): TranslatableInterface; | |||
} |
@@ -7,6 +7,8 @@ use Lc\SovBundle\Doctrine\Extension\BlameableInterface; | |||
use Lc\SovBundle\Doctrine\Extension\BlameableTrait; | |||
use Lc\SovBundle\Doctrine\Extension\DevAliasInterface; | |||
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\SeoTrait; | |||
use Lc\SovBundle\Doctrine\Extension\SluggableInterface; | |||
@@ -24,12 +26,13 @@ use Lc\SovBundle\Doctrine\Extension\TimestampableTrait; | |||
/** | |||
* @ORM\MappedSuperclass | |||
*/ | |||
abstract class AbstractFullEntity implements BlameableInterface, SeoInterface, SluggableInterface, SortableInterface, | |||
abstract class AbstractFullEntity implements BlameableInterface, SeoInterface, OpenGraphInterface, SluggableInterface, SortableInterface, | |||
StatusInterface, TimestampableInterface, DevAliasInterface, EntityInterface | |||
{ | |||
use BlameableTrait; | |||
use SeoTrait; | |||
use OpenGraphTrait; | |||
use SluggableTrait; | |||
use SortableTrait; | |||
use StatusTrait; |
@@ -22,9 +22,11 @@ class ExceptionListener | |||
// On détecte une erreur interne (500), on remove les sessions qui servent de filtre dans l'admin | |||
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); | |||
} | |||
} | |||
} | |||
} |
@@ -2,7 +2,7 @@ | |||
namespace Lc\SovBundle\Factory\File; | |||
use App\Entity\File\File; | |||
use Lc\SovBundle\Container\File\FileContainer; | |||
use Lc\SovBundle\Factory\AbstractFactory; | |||
use Lc\SovBundle\Model\File\FileInterface; | |||
@@ -10,7 +10,8 @@ class FileFactory extends AbstractFactory | |||
{ | |||
public function create(): FileInterface | |||
{ | |||
$file = new File(); | |||
$class = FileContainer::getEntityFqcn(); | |||
$file = new $class; | |||
return $file; | |||
} |
@@ -2,7 +2,7 @@ | |||
namespace Lc\SovBundle\Factory\Newsletter; | |||
use App\Entity\Newsletter\Newsletter; | |||
use Lc\SovBundle\Container\Newsletter\NewsletterContainer; | |||
use Lc\SovBundle\Factory\AbstractFactory; | |||
use Lc\SovBundle\Model\Newsletter\NewsletterInterface; | |||
@@ -10,7 +10,8 @@ class NewsletterFactory extends AbstractFactory | |||
{ | |||
public function create(): NewsletterInterface | |||
{ | |||
$newsletter = new Newsletter(); | |||
$class = NewsletterContainer::getEntityFqcn(); | |||
$newsletter = new $class; | |||
return $newsletter; | |||
} |
@@ -2,7 +2,7 @@ | |||
namespace Lc\SovBundle\Factory\Reminder; | |||
use App\Entity\Reminder\Reminder; | |||
use Lc\SovBundle\Container\Reminder\ReminderContainer; | |||
use Lc\SovBundle\Factory\AbstractFactory; | |||
use Lc\SovBundle\Model\Reminder\ReminderInterface; | |||
@@ -13,8 +13,8 @@ class ReminderFactory extends AbstractFactory implements ReminderFactoryInterfac | |||
string $crudControllerFqcn = null, | |||
int $entityId = null | |||
): ReminderInterface { | |||
$reminder = new Reminder(); | |||
$class = ReminderContainer::getEntityFqcn(); | |||
$reminder = new $class; | |||
$reminder->setCrudAction($crudAction); | |||
$reminder->setCrudControllerFqcn($crudControllerFqcn); | |||
$reminder->setEntityId($entityId); |
@@ -2,7 +2,13 @@ | |||
namespace Lc\SovBundle\Factory\Reminder; | |||
use Lc\SovBundle\Model\Reminder\ReminderInterface; | |||
interface ReminderFactoryInterface | |||
{ | |||
public function create( | |||
string $crudAction = null, | |||
string $crudControllerFqcn = null, | |||
int $entityId = null | |||
): ReminderInterface; | |||
} |
@@ -2,7 +2,7 @@ | |||
namespace Lc\SovBundle\Factory\Setting; | |||
use App\Entity\Setting\SiteSetting; | |||
use Lc\SovBundle\Container\Setting\SiteSettingContainer; | |||
use Lc\SovBundle\Factory\AbstractFactory; | |||
use Lc\SovBundle\Model\File\FileInterface; | |||
use Lc\SovBundle\Model\Setting\SiteSettingInterface; | |||
@@ -12,7 +12,8 @@ class SiteSettingFactory extends AbstractFactory implements SiteSettingFactoryIn | |||
{ | |||
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->setName($name); |
@@ -2,7 +2,17 @@ | |||
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 | |||
{ | |||
public function create( | |||
SiteInterface $site, | |||
string $name, | |||
string $text = null, | |||
\DateTime $date = null, | |||
FileInterface $file = null | |||
): SiteSettingInterface; | |||
} |
@@ -2,7 +2,7 @@ | |||
namespace Lc\SovBundle\Factory\Site; | |||
use App\Entity\Site\News; | |||
use Lc\SovBundle\Container\Site\NewsContainer; | |||
use Lc\SovBundle\Factory\AbstractFactory; | |||
use Lc\SovBundle\Model\Site\NewsInterface; | |||
@@ -10,8 +10,8 @@ class NewsFactory extends AbstractFactory implements NewsFactoryInterface | |||
{ | |||
public function create(): NewsInterface | |||
{ | |||
$news = new News(); | |||
$class = NewsContainer::getEntityFqcn(); | |||
$news = new $class; | |||
$news->setStatus(1); | |||
return $news; |
@@ -2,7 +2,9 @@ | |||
namespace Lc\SovBundle\Factory\Site; | |||
use Lc\SovBundle\Model\Site\NewsInterface; | |||
interface NewsFactoryInterface | |||
{ | |||
public function create(): NewsInterface; | |||
} |
@@ -2,7 +2,7 @@ | |||
namespace Lc\SovBundle\Factory\Site; | |||
use App\Entity\Site\Page; | |||
use Lc\SovBundle\Container\Site\PageContainer; | |||
use Lc\SovBundle\Factory\AbstractFactory; | |||
use Lc\SovBundle\Model\Site\PageInterface; | |||
@@ -10,7 +10,8 @@ class PageFactory extends AbstractFactory implements PageFactoryInterface | |||
{ | |||
public function create(): PageInterface | |||
{ | |||
$page = new Page(); | |||
$class = PageContainer::getEntityFqcn(); | |||
$page = new $class; | |||
$page->setStatus(1); | |||
@@ -2,7 +2,9 @@ | |||
namespace Lc\SovBundle\Factory\Site; | |||
use Lc\SovBundle\Model\Site\PageInterface; | |||
interface PageFactoryInterface | |||
{ | |||
public function create(): PageInterface; | |||
} |
@@ -2,7 +2,7 @@ | |||
namespace Lc\SovBundle\Factory\Site; | |||
use App\Entity\Site\Site; | |||
use Lc\SovBundle\Container\Site\SiteContainer; | |||
use Lc\SovBundle\Factory\AbstractFactory; | |||
use Lc\SovBundle\Model\Site\SiteInterface; | |||
@@ -10,7 +10,8 @@ class SiteFactory extends AbstractFactory implements SiteFactoryInterface | |||
{ | |||
public function create(string $devAlias = null): SiteInterface | |||
{ | |||
$site = new Site(); | |||
$class = SiteContainer::getEntityFqcn(); | |||
$site = new $class; | |||
$site->setDevAlias($devAlias); | |||
@@ -2,7 +2,9 @@ | |||
namespace Lc\SovBundle\Factory\Site; | |||
use Lc\SovBundle\Model\Site\SiteInterface; | |||
interface SiteFactoryInterface | |||
{ | |||
public function create(string $devAlias = null): SiteInterface; | |||
} |
@@ -2,7 +2,7 @@ | |||
namespace Lc\SovBundle\Factory\Ticket; | |||
use App\Entity\Ticket\Ticket; | |||
use Lc\SovBundle\Container\Ticket\TicketContainer; | |||
use Lc\SovBundle\Factory\AbstractFactory; | |||
use Lc\SovBundle\Model\Ticket\TicketInterface; | |||
use Lc\SovBundle\Model\Ticket\TicketModel; | |||
@@ -11,7 +11,8 @@ class TicketFactory extends AbstractFactory implements TicketFactoryInterface | |||
{ | |||
public function create(): TicketInterface | |||
{ | |||
$ticket = new Ticket(); | |||
$class = TicketContainer::getEntityFqcn(); | |||
$ticket = new $class; | |||
$ticketMessageFactory = new TicketMessageFactory(); | |||
$ticketMessage = $ticketMessageFactory->create($ticket) ; |
@@ -2,7 +2,9 @@ | |||
namespace Lc\SovBundle\Factory\Ticket; | |||
use Lc\SovBundle\Model\Ticket\TicketInterface; | |||
interface TicketFactoryInterface | |||
{ | |||
public function create(): TicketInterface; | |||
} |
@@ -2,7 +2,7 @@ | |||
namespace Lc\SovBundle\Factory\Ticket; | |||
use App\Entity\Ticket\TicketMessage; | |||
use Lc\SovBundle\Container\Ticket\TicketMessageContainer; | |||
use Lc\SovBundle\Factory\AbstractFactory; | |||
use Lc\SovBundle\Model\Ticket\TicketInterface; | |||
use Lc\SovBundle\Model\Ticket\TicketMessageInterface; | |||
@@ -11,7 +11,8 @@ class TicketMessageFactory extends AbstractFactory implements TicketMessageFacto | |||
{ | |||
public function create(TicketInterface $ticket): TicketMessageInterface | |||
{ | |||
$ticketMessage = new TicketMessage(); | |||
$class = TicketMessageContainer::getEntityFqcn(); | |||
$ticketMessage = new $class; | |||
$ticketMessage->setTicket($ticket); | |||
$ticketMessage->setStatus(1); |
@@ -2,7 +2,10 @@ | |||
namespace Lc\SovBundle\Factory\Ticket; | |||
use Lc\SovBundle\Model\Ticket\TicketInterface; | |||
use Lc\SovBundle\Model\Ticket\TicketMessageInterface; | |||
interface TicketMessageFactoryInterface | |||
{ | |||
public function create(TicketInterface $ticket): TicketMessageInterface; | |||
} |
@@ -2,7 +2,7 @@ | |||
namespace Lc\SovBundle\Factory\User; | |||
use App\Entity\User\GroupUser; | |||
use Lc\SovBundle\Container\User\GroupUserContainer; | |||
use Lc\SovBundle\Factory\AbstractFactory; | |||
use Lc\SovBundle\Model\User\GroupUserInterface; | |||
@@ -10,7 +10,8 @@ class GroupUserFactory extends AbstractFactory implements GroupUserFactoryInterf | |||
{ | |||
public function create(): GroupUserInterface | |||
{ | |||
$groupUser = new GroupUser(); | |||
$class = GroupUserContainer::getEntityFqcn(); | |||
$groupUser = new $class; | |||
$groupUser->setStatus(1); | |||
@@ -2,7 +2,9 @@ | |||
namespace Lc\SovBundle\Factory\User; | |||
use Lc\SovBundle\Model\User\GroupUserInterface; | |||
interface GroupUserFactoryInterface | |||
{ | |||
public function create(): GroupUserInterface; | |||
} |
@@ -2,7 +2,7 @@ | |||
namespace Lc\SovBundle\Factory\User; | |||
use App\Entity\User\User; | |||
use Lc\SovBundle\Container\User\UserContainer; | |||
use Lc\SovBundle\Factory\AbstractFactory; | |||
use Lc\SovBundle\Model\User\UserInterface; | |||
@@ -10,7 +10,9 @@ class UserFactory extends AbstractFactory | |||
{ | |||
public function create(): UserInterface | |||
{ | |||
$user = new User(); | |||
$class = UserContainer::getEntityFqcn(); | |||
$user = new $class; | |||
return $user; | |||
} |
@@ -2,7 +2,9 @@ | |||
namespace Lc\SovBundle\Factory\User; | |||
use Lc\SovBundle\Model\User\UserInterface; | |||
interface UserFactoryInterface | |||
{ | |||
public function create(): UserInterface; | |||
} |
@@ -0,0 +1,149 @@ | |||
<?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; | |||
} | |||
} |
@@ -0,0 +1,70 @@ | |||
<?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]; | |||
} | |||
} |
@@ -22,7 +22,6 @@ class FileManagerType extends AbstractType implements DataTransformerInterface | |||
$this->em = $entityManager; | |||
} | |||
public function buildForm(FormBuilderInterface $builder, array $options) | |||
{ | |||
$builder->add('path', HiddenType::class, array( |
@@ -0,0 +1,258 @@ | |||
<?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; | |||
} | |||
} |
@@ -5,6 +5,7 @@ namespace Lc\SovBundle\Form\Setting; | |||
use FOS\CKEditorBundle\Form\Type\CKEditorType; | |||
use Lc\SovBundle\Definition\SiteSettingDefinitionInterface; | |||
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\DateType; | |||
use Symfony\Component\Form\Extension\Core\Type\TextareaType; | |||
@@ -17,13 +18,16 @@ abstract class BaseSettingType extends AbstractType | |||
{ | |||
protected EntityManagerInterface $em; | |||
protected SiteSettingDefinitionInterface $settingDefinition; | |||
protected TranslatorAdmin $translatorAdmin; | |||
public function __construct( | |||
EntityManagerInterface $entityManager, | |||
SiteSettingDefinitionInterface $settingDefinition | |||
SiteSettingDefinitionInterface $settingDefinition, | |||
TranslatorAdmin $translatorAdmin | |||
) { | |||
$this->em = $entityManager; | |||
$this->settingDefinition = $settingDefinition; | |||
$this->translatorAdmin = $translatorAdmin; | |||
} | |||
public function buildFormSetting($label, $form, $settingDefinition, $settingEntity) | |||
@@ -37,7 +41,8 @@ abstract class BaseSettingType extends AbstractType | |||
'text', | |||
TextType::class, | |||
[ | |||
'label' => $label | |||
'label' => $label, | |||
'translation_domain' => 'admin', | |||
] | |||
); | |||
} elseif ($settingType == 'textarea') { | |||
@@ -45,7 +50,8 @@ abstract class BaseSettingType extends AbstractType | |||
'text', | |||
TextareaType::class, | |||
[ | |||
'label' => $label | |||
'label' => $label, | |||
'translation_domain' => 'admin', | |||
] | |||
); | |||
} elseif ($settingType == 'textarea_advanced') { | |||
@@ -54,6 +60,7 @@ abstract class BaseSettingType extends AbstractType | |||
CKEditorType::class, | |||
[ | |||
'label' => $label, | |||
'translation_domain' => 'admin', | |||
'attr' => [ | |||
'class' => 'field-text_editor' | |||
] | |||
@@ -65,6 +72,7 @@ abstract class BaseSettingType extends AbstractType | |||
ChoiceType::class, | |||
[ | |||
'label' => $label, | |||
'translation_domain' => 'admin', | |||
'expanded' => false, | |||
'multiple' => false, | |||
'placeholder' => false, | |||
@@ -77,6 +85,7 @@ abstract class BaseSettingType extends AbstractType | |||
ChoiceType::class, | |||
[ | |||
'label' => $label, | |||
'translation_domain' => 'admin', | |||
'expanded' => true, | |||
'multiple' => false, | |||
'placeholder' => false, | |||
@@ -89,6 +98,7 @@ abstract class BaseSettingType extends AbstractType | |||
DateType::class, | |||
[ | |||
'label' => $label, | |||
'translation_domain' => 'admin', | |||
'widget' => 'single_text', | |||
] | |||
); | |||
@@ -98,6 +108,7 @@ abstract class BaseSettingType extends AbstractType | |||
TimeType::class, | |||
[ | |||
'label' => $label, | |||
'translation_domain' => 'admin', | |||
'input' => 'datetime', | |||
'widget' => 'single_text', | |||
] | |||
@@ -108,6 +119,7 @@ abstract class BaseSettingType extends AbstractType | |||
FileManagerType::class, | |||
[ | |||
'label' => $label, | |||
'translation_domain' => 'admin', | |||
'attr' => [ | |||
'type' => $settingType | |||
] |
@@ -0,0 +1,65 @@ | |||
<?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' | |||
]); | |||
} | |||
} |
@@ -0,0 +1,32 @@ | |||
<?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(); | |||
} | |||
} |
@@ -8,8 +8,8 @@ use Symfony\Component\HttpKernel\Bundle\Bundle; | |||
class LcSovBundle extends Bundle | |||
{ | |||
public function getContainerExtension() | |||
{ | |||
return new LcSovExtension(); | |||
} | |||
public function getContainerExtension() | |||
{ | |||
return new LcSovExtension(); | |||
} | |||
} |
@@ -2,8 +2,54 @@ | |||
namespace Lc\SovBundle\Model\File; | |||
use Lc\SovBundle\Model\User\UserInterface; | |||
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; | |||
} |
@@ -1,8 +1,84 @@ | |||
<?php | |||
namespace Lc\SovBundle\Model\Newsletter ; | |||
namespace Lc\SovBundle\Model\Newsletter; | |||
use Doctrine\Common\Collections\Collection; | |||
use Lc\SovBundle\Model\User\UserInterface; | |||
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); | |||
} |
@@ -2,6 +2,66 @@ | |||
namespace Lc\SovBundle\Model\Reminder; | |||
use Doctrine\Common\Collections\Collection; | |||
use Lc\SovBundle\Model\User\UserInterface; | |||
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); | |||
} |
@@ -2,7 +2,24 @@ | |||
namespace Lc\SovBundle\Model\Setting; | |||
use Lc\SovBundle\Model\File\FileInterface; | |||
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; | |||
} |
@@ -2,7 +2,29 @@ | |||
namespace Lc\SovBundle\Model\Setting; | |||
use Lc\SovBundle\Model\File\FileInterface; | |||
use Lc\SovBundle\Model\Site\SiteInterface; | |||
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; | |||
} |
@@ -1,8 +1,99 @@ | |||
<?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 | |||
{ | |||
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); | |||
} |
@@ -13,10 +13,8 @@ use Lc\SovBundle\Model\Newsletter\NewsletterInterface; | |||
/** | |||
* @ORM\MappedSuperclass() | |||
*/ | |||
abstract class NewsModel extends AbstractFullEntity implements NewsInterface, OpenGraphInterface | |||
abstract class NewsModel extends AbstractFullEntity implements NewsInterface | |||
{ | |||
use OpenGraphTrait; | |||
/** | |||
* @ORM\Column(type="datetime") | |||
* @Gedmo\Timestampable(on="create") |
@@ -2,7 +2,70 @@ | |||
namespace Lc\SovBundle\Model\Site; | |||
use Lc\SovBundle\Model\User\UserInterface; | |||
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); | |||
} |
@@ -2,8 +2,21 @@ | |||
namespace Lc\SovBundle\Model\Site; | |||
use Doctrine\Common\Collections\Collection; | |||
use Lc\SovBundle\Model\Setting\SiteSettingInterface; | |||
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; | |||
} |
@@ -2,7 +2,74 @@ | |||
namespace Lc\SovBundle\Model\Ticket; | |||
use Doctrine\Common\Collections\Collection; | |||
use Lc\SovBundle\Model\User\UserInterface; | |||
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); | |||
} |
@@ -2,7 +2,48 @@ | |||
namespace Lc\SovBundle\Model\Ticket; | |||
use Lc\SovBundle\Model\User\UserInterface; | |||
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); | |||
} |
@@ -66,7 +66,7 @@ abstract class TicketModel extends AbstractLightEntity implements TicketInterfac | |||
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"}) | |||
*/ | |||
protected $ticketMessages; | |||
@@ -76,6 +76,7 @@ abstract class TicketModel extends AbstractLightEntity implements TicketInterfac | |||
*/ | |||
protected $user; | |||
public function __construct() | |||
{ | |||
$this->ticketMessages = new ArrayCollection(); |
@@ -2,7 +2,78 @@ | |||
namespace Lc\SovBundle\Model\User; | |||
use Doctrine\Common\Collections\Collection; | |||
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); | |||
} |
@@ -2,7 +2,107 @@ | |||
namespace Lc\SovBundle\Model\User; | |||
use Doctrine\Common\Collections\Collection; | |||
use Lc\SovBundle\Model\Ticket\TicketInterface; | |||
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; | |||
} |
@@ -11,11 +11,12 @@ use Lc\SovBundle\Doctrine\Extension\DevAliasTrait; | |||
use Lc\SovBundle\Doctrine\Extension\TimestampableTrait; | |||
use Lc\SovBundle\Model\Ticket\TicketInterface; | |||
use Symfony\Component\Security\Core\User\UserInterface; | |||
use Lc\SovBundle\Model\User\UserInterface as SovUserInterface; | |||
/** | |||
* @ORM\MappedSuperclass() | |||
*/ | |||
abstract class UserModel implements EntityInterface, UserInterface, DevAliasInterface | |||
abstract class UserModel implements EntityInterface, UserInterface, SovUserInterface, DevAliasInterface | |||
{ | |||
use DevAliasTrait; | |||
use TimestampableTrait; | |||
@@ -72,7 +73,7 @@ abstract class UserModel implements EntityInterface, UserInterface, DevAliasInte | |||
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; | |||
@@ -81,6 +82,11 @@ abstract class UserModel implements EntityInterface, UserInterface, DevAliasInte | |||
*/ | |||
protected $ticketTypesNotification = []; | |||
/** | |||
* @ORM\Column(type="datetime", nullable=true) | |||
*/ | |||
protected $lastLogin; | |||
public function __construct() | |||
{ | |||
$this->tickets = new ArrayCollection(); | |||
@@ -334,5 +340,15 @@ abstract class UserModel implements EntityInterface, UserInterface, DevAliasInte | |||
return $this; | |||
} | |||
public function getLastLogin() | |||
{ | |||
return $this->lastLogin; | |||
} | |||
public function setLastLogin(\DateTime $time = null) | |||
{ | |||
$this->lastLogin = $time; | |||
return $this; | |||
} | |||
} |
@@ -2,8 +2,149 @@ | |||
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 | |||
{ | |||
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); | |||
} |
@@ -6,6 +6,7 @@ use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; | |||
use Doctrine\ORM\QueryBuilder; | |||
use Knp\Component\Pager\PaginatorInterface; | |||
use Lc\SovBundle\Doctrine\EntityInterface; | |||
use Lc\SovBundle\Model\User\UserInterface; | |||
abstract class AbstractRepositoryQuery implements RepositoryQueryInterface | |||
{ | |||
@@ -130,7 +131,6 @@ abstract class AbstractRepositoryQuery implements RepositoryQueryInterface | |||
return $this; | |||
}*/ | |||
// @TODO : créer un addOrderBy et un orderBy | |||
public function orderBy(string $field, string $sort = 'ASC'): self | |||
{ | |||
if (strpos($field, '.')!==false) { | |||
@@ -140,6 +140,12 @@ abstract class AbstractRepositoryQuery implements RepositoryQueryInterface | |||
} | |||
} | |||
public function setOrderBy(string $field, string $sort = 'ASC'): self | |||
{ | |||
$this->resetDQLParts(['orderBy']); | |||
return $this->orderBy($field, $sort); | |||
} | |||
public function filterById(int $id):self | |||
{ | |||
return $this | |||
@@ -147,6 +153,20 @@ abstract class AbstractRepositoryQuery implements RepositoryQueryInterface | |||
->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) | |||
{ | |||
return $this->andWhere('.'.$field.' = :'.$field)->setParameter($field, $value); | |||
@@ -222,5 +242,28 @@ abstract class AbstractRepositoryQuery implements RepositoryQueryInterface | |||
{ | |||
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); | |||
} | |||
} | |||
@@ -115,6 +115,13 @@ abstract class AbstractStore implements StoreInterface | |||
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) | |||
{ | |||
$query = $this->createDefaultQuery($query); |
@@ -2,7 +2,57 @@ | |||
namespace Lc\SovBundle\Repository\File; | |||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; | |||
use Doctrine\ORM\QueryBuilder; | |||
use Lc\SovBundle\Doctrine\EntityInterface; | |||
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(); | |||
} |
@@ -13,15 +13,14 @@ class FileStore extends AbstractStore implements FileStoreInterface | |||
{ | |||
$this->query = $query; | |||
} | |||
public function orderByDefault(RepositoryQueryInterface $query): RepositoryQueryInterface | |||
{ | |||
return $query; | |||
} | |||
public function filtersDefault(RepositoryQueryInterface $query): RepositoryQueryInterface | |||
{ | |||
return $query; | |||
} | |||
@@ -2,7 +2,37 @@ | |||
namespace Lc\SovBundle\Repository\File; | |||
use Lc\SovBundle\Repository\RepositoryQueryInterface; | |||
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; | |||
} |
@@ -2,7 +2,58 @@ | |||
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 | |||
{ | |||
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(); | |||
} |
@@ -13,15 +13,14 @@ class NewsletterStore extends AbstractStore implements NewsletterStoreInterface | |||
{ | |||
$this->query = $query; | |||
} | |||
public function orderByDefault(RepositoryQueryInterface $query): RepositoryQueryInterface | |||
{ | |||
return $query; | |||
} | |||
public function filtersDefault(RepositoryQueryInterface $query): RepositoryQueryInterface | |||
{ | |||
return $query; | |||
} | |||
@@ -2,7 +2,37 @@ | |||
namespace Lc\SovBundle\Repository\Newsletter; | |||
use Lc\SovBundle\Repository\RepositoryQueryInterface; | |||
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; | |||
} |
@@ -2,7 +2,82 @@ | |||
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 | |||
{ | |||
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; | |||
} |