@@ -3,56 +3,55 @@ | |||
namespace Lc\SovBundle\Component; | |||
use Doctrine\ORM\EntityManagerInterface; | |||
use Lc\CaracoleBundle\Model\Product\ProductFamilyInterface; | |||
use Lc\SovBundle\Doctrine\Extension\SluggableInterface; | |||
use Lc\SovBundle\Event\EntityComponentEvent; | |||
use Lc\SovBundle\Model\File\FileInterface; | |||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; | |||
use Symfony\Component\EventDispatcher\EventDispatcherInterface; | |||
class EntityComponent | |||
{ | |||
protected EntityManagerInterface $entityManager; | |||
protected ParameterBagInterface $parameterBag; | |||
protected EventDispatcherInterface $eventDispatcher; | |||
public function __construct( | |||
EntityManagerInterface $entityManager, | |||
ParameterBagInterface $parameterBag | |||
ParameterBagInterface $parameterBag, | |||
EventDispatcherInterface $eventDispatcher | |||
) { | |||
$this->entityManager = $entityManager; | |||
$this->parameterBag = $parameterBag; | |||
$this->eventDispatcher = $eventDispatcher; | |||
} | |||
public function duplicateEntity($entity, $flush = true) | |||
public function duplicateEntity($entity) | |||
{ | |||
$newEntity = clone $entity; | |||
$classMetadata = $this->entityManager->getClassMetadata(get_class($newEntity)); | |||
foreach ($classMetadata->getAssociationMappings() as $associationMapping){ | |||
if(in_array(FileInterface::class, class_implements($associationMapping['targetEntity']))){ | |||
$methodGet = 'get'.ucfirst($associationMapping['fieldName']); | |||
$methodSet = 'set'.ucfirst($associationMapping['fieldName']); | |||
if(method_exists($newEntity, $methodGet) && method_exists($newEntity, $methodSet)){ | |||
if(!is_null($newEntity->$methodGet())){ | |||
$newFile = clone $newEntity->$methodGet(); | |||
$newEntity->$methodSet($newFile); | |||
} | |||
} | |||
} | |||
if ($newEntity instanceof FileInterface) { | |||
$newEntity = $this->duplicateImage($newEntity); | |||
} | |||
if ($newEntity instanceof ProductFamilyInterface) { | |||
//TODO dispatch event duplicate | |||
/* if ($newEntity instanceof ProductFamilyInterface) { | |||
// @TODO : à adapter | |||
//$newEntity = $this->productFamilyUtils->processBeforePersistProductFamily($newEntity, false, true); | |||
} | |||
*/ | |||
$this->entityManager->create($newEntity); | |||
if (method_exists($newEntity, 'getAddress') && is_object($newEntity->getAddress())) { | |||
$address = $newEntity->getAddress(); | |||
$newAddress = $this->duplicateEntity($address); | |||
$newEntity->setAddress($newAddress); | |||
$this->entityManager->persist($newAddress); | |||
} | |||
if ($newEntity instanceof SluggableInterface) { | |||
$this->entityManager->persist($newEntity); | |||
if ($flush) { | |||
$this->entityManager->flush(); | |||
} | |||
$newEntity->setSlug(null); | |||
} | |||
$this->entityManager->persist($newEntity); | |||
if ($flush) { | |||
$this->entityManager->flush(); | |||
} | |||
$this->eventDispatcher->dispatch(new EntityComponentEvent($newEntity), EntityComponentEvent::DUPLICATE_EVENT); | |||
return $newEntity; | |||
} |
@@ -35,6 +35,8 @@ use EasyCorp\Bundle\EasyAdminBundle\Field\TextareaField; | |||
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\SovBundle\Component\EntityComponent; | |||
use Lc\SovBundle\Doctrine\Extension\DevAliasInterface; | |||
use Lc\SovBundle\Doctrine\Extension\SeoInterface; | |||
use Lc\SovBundle\Doctrine\Extension\SortableInterface; | |||
@@ -63,14 +65,14 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
public static function getSubscribedServices() | |||
{ | |||
return array_merge( | |||
parent::getSubscribedServices(), | |||
[ | |||
'session' => SessionInterface::class, | |||
'request' => RequestStack::class, | |||
'em' => EntityManagerInterface::class, | |||
'translator_admin' => TranslatorAdmin::class, | |||
'filter_manager' => FilterManager::class, | |||
] | |||
parent::getSubscribedServices(), | |||
[ | |||
'session' => SessionInterface::class, | |||
'request' => RequestStack::class, | |||
'em' => EntityManagerInterface::class, | |||
'translator_admin' => TranslatorAdmin::class, | |||
'filter_manager' => FilterManager::class, | |||
] | |||
); | |||
} | |||
@@ -113,9 +115,9 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
if ($entity !== null) { | |||
if ($entity->getParent() !== null) { | |||
$url = $adminUrlGenerator | |||
->setController($context->getCrud()->getControllerFqcn()) | |||
->set('entityId', $entity->getParent()->getId()) | |||
->generateUrl(); | |||
->setController($context->getCrud()->getControllerFqcn()) | |||
->set('entityId', $entity->getParent()->getId()) | |||
->generateUrl(); | |||
$action->setLinkUrl($url); | |||
} | |||
} else { | |||
@@ -127,10 +129,10 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
$entityId = $context->getRequest()->get('entityId'); | |||
if ($entityId != null) { | |||
$url = $adminUrlGenerator | |||
->setController($context->getCrud()->getControllerFqcn()) | |||
->setAction($action->getName()) | |||
->set('entityId', $entityId) | |||
->generateUrl(); | |||
->setController($context->getCrud()->getControllerFqcn()) | |||
->setAction($action->getName()) | |||
->set('entityId', $entityId) | |||
->generateUrl(); | |||
$action->setLinkUrl($url); | |||
} | |||
} | |||
@@ -155,14 +157,14 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
{ | |||
$entityClass = $this->getEntityFqcn(); | |||
$paramListMaxResults = 'listMaxResults'; | |||
$paramSessionListMaxResults = $entityClass . '-' . $paramListMaxResults; | |||
$paramSessionListMaxResults = $entityClass.'-'.$paramListMaxResults; | |||
$requestListMaxResults = $this->get('request')->getCurrentRequest()->get($paramListMaxResults); | |||
if ($requestListMaxResults) { | |||
$this->get('session')->set($paramSessionListMaxResults, $requestListMaxResults); | |||
} | |||
$maxResults = $this->get('session')->get($paramSessionListMaxResults) ? $this->get('session')->get( | |||
$paramSessionListMaxResults | |||
$paramSessionListMaxResults | |||
) : 30; | |||
$crud->setPaginatorPageSize($maxResults); | |||
@@ -172,17 +174,17 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
{ | |||
if ($this->isInstanceOf(SeoInterface::class)) { | |||
return [ | |||
FormField::addPanel('seo')->setTemplateName('crud/field/generic'), | |||
TextField::new('metaTitle')->setLabel('Meta Title')->setHelp( | |||
'Affiché dans les résultats de recherche Google' | |||
)->hideOnIndex(), | |||
TextareaField::new('metaDescription')->setLabel('Meta description')->setHelp( | |||
'Affiché dans les résultats de recherche Google' | |||
)->hideOnIndex(), | |||
CollectionField::new('oldUrls') | |||
->setFormTypeOption('entry_type', TextType::class)->setLabel( | |||
'Anciennes urls du document' | |||
FormField::addPanel('seo')->setTemplateName('crud/field/generic'), | |||
TextField::new('metaTitle')->setLabel('Meta Title')->setHelp( | |||
'Affiché dans les résultats de recherche Google' | |||
)->hideOnIndex(), | |||
TextareaField::new('metaDescription')->setLabel('Meta description')->setHelp( | |||
'Affiché dans les résultats de recherche Google' | |||
)->hideOnIndex(), | |||
CollectionField::new('oldUrls') | |||
->setFormTypeOption('entry_type', TextType::class)->setLabel( | |||
'Anciennes urls du document' | |||
)->hideOnIndex(), | |||
]; | |||
} else { | |||
return null; | |||
@@ -193,8 +195,8 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
{ | |||
if ($this->isInstanceOf(DevAliasInterface::class)) { | |||
return [ | |||
FormField::addPanel('configuration')->setTemplateName('crud/field/generic'), | |||
TextField::new('devAlias')->hideOnIndex(), | |||
FormField::addPanel('configuration')->setTemplateName('crud/field/generic'), | |||
TextField::new('devAlias')->hideOnIndex(), | |||
]; | |||
} else { | |||
return null; | |||
@@ -216,9 +218,9 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
$fields = FieldCollection::new($this->configureFields(Crud::PAGE_INDEX)); | |||
$filters = $this->get(FilterFactory::class)->create( | |||
$context->getCrud()->getFiltersConfig(), | |||
$fields, | |||
$context->getEntity() | |||
$context->getCrud()->getFiltersConfig(), | |||
$fields, | |||
$context->getEntity() | |||
); | |||
$queryBuilder = $this->createIndexQueryBuilder($context->getSearch(), $context->getEntity(), $fields, $filters); | |||
$paginator = $this->get(PaginatorFactory::class)->create($queryBuilder); | |||
@@ -227,16 +229,16 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
$this->get(EntityFactory::class)->processFieldsForAll($entities, $fields); | |||
$sortableForm = $this->createFormBuilder(array('entities', $paginator->getResults())) | |||
->add( | |||
'entities', | |||
CollectionType::class, | |||
array( | |||
'required' => true, | |||
'allow_add' => true, | |||
'entry_type' => PositionType::class, | |||
->add( | |||
'entities', | |||
CollectionType::class, | |||
array( | |||
'required' => true, | |||
'allow_add' => true, | |||
'entry_type' => PositionType::class, | |||
) | |||
) | |||
) | |||
->getForm(); | |||
->getForm(); | |||
$entityManager = $this->getDoctrine()->getManagerForClass($this->getEntityFqcn()); | |||
$repository = $entityManager->getRepository($this->getEntityFqcn()); | |||
@@ -263,26 +265,26 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
} | |||
$url = $this->get(AdminUrlGenerator::class) | |||
->setAction(Action::INDEX) | |||
->generateUrl(); | |||
->setAction(Action::INDEX) | |||
->generateUrl(); | |||
$this->addFlash('success', $this->translatorAdmin->transFlashMessage('sort'), array()); | |||
return $this->redirect($url); | |||
} | |||
$responseParameters = $this->configureResponseParameters( | |||
KeyValueStore::new( | |||
[ | |||
'pageName' => Crud::PAGE_INDEX, | |||
'templatePath' => '@LcSov/adminlte/crud/sort.html.twig', | |||
'entities' => $entities, | |||
'paginator' => $paginator, | |||
'global_actions' => array(), | |||
'batch_actions' => array(), | |||
'filters' => $filters, | |||
'sortable_form' => $sortableForm, | |||
] | |||
) | |||
KeyValueStore::new( | |||
[ | |||
'pageName' => Crud::PAGE_INDEX, | |||
'templatePath' => '@LcSov/adminlte/crud/sort.html.twig', | |||
'entities' => $entities, | |||
'paginator' => $paginator, | |||
'global_actions' => array(), | |||
'batch_actions' => array(), | |||
'filters' => $filters, | |||
'sortable_form' => $sortableForm, | |||
] | |||
) | |||
); | |||
$responseParameters->set('fields', $this->configureFields('index')); | |||
$event = new AfterCrudActionEvent($context, $responseParameters); | |||
@@ -294,17 +296,46 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
return $responseParameters; | |||
} | |||
public function duplicate(AdminContext $context, EntityComponent $entityComponent, TranslatorAdmin $translatorAdmin, EntityManagerInterface $em) | |||
{ | |||
if (!$this->isGranted( | |||
Permission::EA_EXECUTE_ACTION, | |||
['action' => "duplicate", 'entity' => $context->getEntity()] | |||
)) { | |||
throw new ForbiddenActionException($context); | |||
} | |||
if (!$context->getEntity()->isAccessible()) { | |||
throw new InsufficientEntityPermissionException($context); | |||
} | |||
$newEntity = $entityComponent->duplicateEntity($context->getEntity()->getInstance()); | |||
$em->create($newEntity); | |||
$em->flush(); | |||
$url = $this->get(AdminUrlGenerator::class) | |||
->setAction(Action::EDIT) | |||
->setEntityId($newEntity->getId()) | |||
->generateUrl(); | |||
$this->addFlash('success', $translatorAdmin->transFlashMessage('duplicate'), array()); | |||
return $this->redirect($url); | |||
} | |||
public function createIndexQueryBuilder( | |||
SearchDto $searchDto, | |||
EntityDto $entityDto, | |||
FieldCollection $fields, | |||
FilterCollection $filters | |||
SearchDto $searchDto, | |||
EntityDto $entityDto, | |||
FieldCollection $fields, | |||
FilterCollection $filters | |||
): QueryBuilder { | |||
$queryBuilder = parent::createIndexQueryBuilder( | |||
$searchDto, | |||
$entityDto, | |||
$fields, | |||
$filters | |||
$searchDto, | |||
$entityDto, | |||
$fields, | |||
$filters | |||
); | |||
//TOdo utiliser les repositoryQuery ? | |||
@@ -318,14 +349,14 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
} | |||
$this->filtersForm = $this->createForm( | |||
FiltersFormType::class, | |||
null, | |||
array( | |||
'fields' => $fields, | |||
'entity_dto' => $entityDto, | |||
'entity_class' => $this->getEntityFqcn(), | |||
'entity_name' => $entityDto->getName(), | |||
) | |||
FiltersFormType::class, | |||
null, | |||
array( | |||
'fields' => $fields, | |||
'entity_dto' => $entityDto, | |||
'entity_class' => $this->getEntityFqcn(), | |||
'entity_name' => $entityDto->getName(), | |||
) | |||
); | |||
$filterManager = $this->get('filter_manager'); | |||
@@ -341,10 +372,10 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
} | |||
public function createSortQueryBuilder( | |||
SearchDto $searchDto, | |||
EntityDto $entityDto, | |||
FieldCollection $fields, | |||
FilterCollection $filters | |||
SearchDto $searchDto, | |||
EntityDto $entityDto, | |||
FieldCollection $fields, | |||
FilterCollection $filters | |||
): QueryBuilder { | |||
$queryBuilder = $this->createIndexQueryBuilder($searchDto, $entityDto, $fields, $filters); | |||
@@ -373,7 +404,7 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
$context = $this->get(AdminContextProvider::class)->getContext(); | |||
return $context->getCrudControllers()->findCrudFqcnByEntityFqcn( | |||
$this->get('em')->getEntityName($interface) | |||
$this->get('em')->getEntityName($interface) | |||
); | |||
} | |||
@@ -406,69 +437,85 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
return $actions; | |||
} | |||
public function getDuplicateAction(): Action | |||
{ | |||
$duplicateAction = Action::new( | |||
'duplicate', | |||
$this->get('translator_admin')->transAction('duplicate'), | |||
'fa fa-fw fa-copy' | |||
) | |||
->linkToCrudAction('duplicate') | |||
->setLabel($this->get('translator_admin')->transAction('duplicate')) | |||
->setCssClass('in-dropdown text-info action-confirm'); | |||
return $duplicateAction; | |||
} | |||
public function buildIndexActions(Actions $actions): void | |||
{ | |||
$actions->add(Crud::PAGE_INDEX, $this->getDuplicateAction()); | |||
$this->actionUpdate( | |||
$actions, | |||
Crud::PAGE_INDEX, | |||
Action::NEW, | |||
[ | |||
'icon' => 'plus', | |||
'label' => $this->get('translator_admin')->transAction('create'), | |||
'add_class' => 'btn-sm', | |||
] | |||
$actions, | |||
Crud::PAGE_INDEX, | |||
Action::NEW, | |||
[ | |||
'icon' => 'plus', | |||
'label' => $this->get('translator_admin')->transAction('create'), | |||
'add_class' => 'btn-sm', | |||
] | |||
); | |||
$this->actionUpdate( | |||
$actions, | |||
Crud::PAGE_INDEX, | |||
Action::EDIT, | |||
[ | |||
'class' => 'btn btn-sm btn-primary', | |||
'icon' => 'edit', | |||
'label' => false, | |||
'html_attributes' => array( | |||
'data-toggle' => 'tooltip', | |||
'title' => $this->get('translator_admin')->transAction('edit'), | |||
), | |||
] | |||
$actions, | |||
Crud::PAGE_INDEX, | |||
Action::EDIT, | |||
[ | |||
'class' => 'btn btn-sm btn-primary', | |||
'icon' => 'edit', | |||
'label' => false, | |||
'html_attributes' => array( | |||
'data-toggle' => 'tooltip', | |||
'title' => $this->get('translator_admin')->transAction('edit'), | |||
), | |||
] | |||
); | |||
$this->actionUpdate( | |||
$actions, | |||
Crud::PAGE_INDEX, | |||
Action::DETAIL, | |||
[ | |||
'icon' => 'eye', | |||
'add_class' => 'btn btn-sm btn-success', | |||
'label' => false, | |||
'html_attributes' => array( | |||
'data-toggle' => 'tooltip', | |||
'title' => $this->get('translator_admin')->transAction('detail'), | |||
), | |||
] | |||
$actions, | |||
Crud::PAGE_INDEX, | |||
Action::DETAIL, | |||
[ | |||
'icon' => 'eye', | |||
'add_class' => 'btn btn-sm btn-success', | |||
'label' => false, | |||
'html_attributes' => array( | |||
'data-toggle' => 'tooltip', | |||
'title' => $this->get('translator_admin')->transAction('detail'), | |||
), | |||
] | |||
); | |||
$this->actionUpdate( | |||
$actions, | |||
Crud::PAGE_INDEX, | |||
Action::DELETE, | |||
[ | |||
'icon' => 'trash', | |||
'dropdown' => true, | |||
'label' => $this->get('translator_admin')->transAction('delete'), | |||
] | |||
$actions, | |||
Crud::PAGE_INDEX, | |||
Action::DELETE, | |||
[ | |||
'icon' => 'trash', | |||
'dropdown' => true, | |||
'label' => $this->get('translator_admin')->transAction('delete'), | |||
] | |||
); | |||
$this->actionUpdate( | |||
$actions, | |||
Crud::PAGE_INDEX, | |||
Action::BATCH_DELETE, | |||
[ | |||
'class' => 'btn btn-sm btn-danger', | |||
'icon' => 'trash', | |||
'label' => $this->get('translator_admin')->transAction('delete'), | |||
] | |||
$actions, | |||
Crud::PAGE_INDEX, | |||
Action::BATCH_DELETE, | |||
[ | |||
'class' => 'btn btn-sm btn-danger', | |||
'icon' => 'trash', | |||
'label' => $this->get('translator_admin')->transAction('delete'), | |||
] | |||
); | |||
} | |||
@@ -480,47 +527,47 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
$this->actionUpdate( | |||
$actions, | |||
Crud::PAGE_EDIT, | |||
Action::SAVE_AND_RETURN, | |||
[ | |||
'add_class' => 'float-right', | |||
'icon' => 'check', | |||
'label' => $this->get('translator_admin')->transAction('save_and_return'), | |||
] | |||
$actions, | |||
Crud::PAGE_EDIT, | |||
Action::SAVE_AND_RETURN, | |||
[ | |||
'add_class' => 'float-right', | |||
'icon' => 'check', | |||
'label' => $this->get('translator_admin')->transAction('save_and_return'), | |||
] | |||
); | |||
$this->actionUpdate( | |||
$actions, | |||
Crud::PAGE_EDIT, | |||
Action::INDEX, | |||
[ | |||
'icon' => 'chevron-left', | |||
'class' => 'btn btn-link', | |||
'label' => $this->get('translator_admin')->transAction('back_index'), | |||
] | |||
$actions, | |||
Crud::PAGE_EDIT, | |||
Action::INDEX, | |||
[ | |||
'icon' => 'chevron-left', | |||
'class' => 'btn btn-link', | |||
'label' => $this->get('translator_admin')->transAction('back_index'), | |||
] | |||
); | |||
$this->actionUpdate( | |||
$actions, | |||
Crud::PAGE_EDIT, | |||
Action::SAVE_AND_CONTINUE, | |||
[ | |||
'class' => 'btn btn-info float-right', | |||
'label' => $this->get('translator_admin')->transAction('save_and_continue'), | |||
] | |||
$actions, | |||
Crud::PAGE_EDIT, | |||
Action::SAVE_AND_CONTINUE, | |||
[ | |||
'class' => 'btn btn-info float-right', | |||
'label' => $this->get('translator_admin')->transAction('save_and_continue'), | |||
] | |||
); | |||
$this->actionUpdate( | |||
$actions, | |||
Crud::PAGE_EDIT, | |||
Action::DELETE, | |||
[ | |||
'icon' => 'trash', | |||
'class' => 'btn btn-outline-danger action-delete', | |||
'label' => $this->get('translator_admin')->transAction('delete'), | |||
] | |||
$actions, | |||
Crud::PAGE_EDIT, | |||
Action::DELETE, | |||
[ | |||
'icon' => 'trash', | |||
'class' => 'btn btn-outline-danger action-delete', | |||
'label' => $this->get('translator_admin')->transAction('delete'), | |||
] | |||
); | |||
} | |||
@@ -533,35 +580,35 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
$actions->add(Crud::PAGE_NEW, Action::INDEX); | |||
$this->actionUpdate( | |||
$actions, | |||
Crud::PAGE_EDIT, | |||
Action::SAVE_AND_RETURN, | |||
[ | |||
'add_class' => 'float-right', | |||
'icon' => 'check', | |||
'label' => $this->get('translator_admin')->transAction('save_and_return'), | |||
] | |||
$actions, | |||
Crud::PAGE_EDIT, | |||
Action::SAVE_AND_RETURN, | |||
[ | |||
'add_class' => 'float-right', | |||
'icon' => 'check', | |||
'label' => $this->get('translator_admin')->transAction('save_and_return'), | |||
] | |||
); | |||
$this->actionUpdate( | |||
$actions, | |||
Crud::PAGE_EDIT, | |||
Action::INDEX, | |||
[ | |||
'icon' => 'chevron-left', | |||
'class' => 'btn btn-link', | |||
'label' => $this->get('translator_admin')->transAction('back_index'), | |||
] | |||
$actions, | |||
Crud::PAGE_EDIT, | |||
Action::INDEX, | |||
[ | |||
'icon' => 'chevron-left', | |||
'class' => 'btn btn-link', | |||
'label' => $this->get('translator_admin')->transAction('back_index'), | |||
] | |||
); | |||
$this->actionUpdate( | |||
$actions, | |||
Crud::PAGE_EDIT, | |||
Action::SAVE_AND_ADD_ANOTHER, | |||
[ | |||
'class' => 'btn btn-info float-right', | |||
'label' => $this->get('translator_admin')->transAction('save_and_add_another'), | |||
] | |||
$actions, | |||
Crud::PAGE_EDIT, | |||
Action::SAVE_AND_ADD_ANOTHER, | |||
[ | |||
'class' => 'btn btn-info float-right', | |||
'label' => $this->get('translator_admin')->transAction('save_and_add_another'), | |||
] | |||
); | |||
} | |||
@@ -569,13 +616,13 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
{ | |||
if ($this->isInstanceOf(TranslatableInterface::class)) { | |||
$actions->update( | |||
Crud::PAGE_INDEX, | |||
Action::EDIT, | |||
function (Action $action) { | |||
$action->setTemplatePath('@LcSov/adminlte/crud/action/translatable.html.twig'); | |||
Crud::PAGE_INDEX, | |||
Action::EDIT, | |||
function (Action $action) { | |||
$action->setTemplatePath('@LcSov/adminlte/crud/action/translatable.html.twig'); | |||
return $action; | |||
} | |||
return $action; | |||
} | |||
); | |||
} | |||
} | |||
@@ -584,9 +631,9 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
{ | |||
if ($this->isInstanceOf(SortableInterface::class)) { | |||
$sortAction = Action::new('sort', $this->get('translator_admin')->transAction('sort'), 'fa fa-sort') | |||
->linkToCrudAction('sort') | |||
->setCssClass('btn btn-sm btn-success') | |||
->createAsGlobalAction(); | |||
->linkToCrudAction('sort') | |||
->setCssClass('btn btn-sm btn-success') | |||
->createAsGlobalAction(); | |||
$actions->add(Crud::PAGE_INDEX, $sortAction); | |||
} | |||
@@ -597,24 +644,24 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
{ | |||
if ($this->isInstanceOf(TreeInterface::class)) { | |||
$indexChildAction = Action::new( | |||
'index_children', | |||
$this->get('translator_admin')->transAction('index_children'), | |||
'fa fa-list' | |||
'index_children', | |||
$this->get('translator_admin')->transAction('index_children'), | |||
'fa fa-list' | |||
) | |||
->linkToCrudAction(Action::INDEX) | |||
->setLabel('') | |||
->setHtmlAttributes(array('data-toggle' => 'tooltip', 'title' => 'Afficher les enfants')) | |||
->setTemplatePath('@LcSov/adminlte/crud/action/index_children.html.twig') | |||
->setCssClass('btn btn-sm btn-success'); | |||
->linkToCrudAction(Action::INDEX) | |||
->setLabel('') | |||
->setHtmlAttributes(array('data-toggle' => 'tooltip', 'title' => 'Afficher les enfants')) | |||
->setTemplatePath('@LcSov/adminlte/crud/action/index_children.html.twig') | |||
->setCssClass('btn btn-sm btn-success'); | |||
$backParentAction = Action::new( | |||
'index_parent', | |||
$this->get('translator_admin')->transAction('index_parent'), | |||
'fa fa-chevron-left' | |||
'index_parent', | |||
$this->get('translator_admin')->transAction('index_parent'), | |||
'fa fa-chevron-left' | |||
) | |||
->linkToCrudAction(Action::INDEX) | |||
->setCssClass('btn btn-sm btn-info') | |||
->createAsGlobalAction(); | |||
->linkToCrudAction(Action::INDEX) | |||
->setCssClass('btn btn-sm btn-info') | |||
->createAsGlobalAction(); | |||
$actions->add(Crud::PAGE_INDEX, $backParentAction); | |||
$actions->add(Crud::PAGE_INDEX, $indexChildAction); | |||
@@ -625,35 +672,35 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
{ | |||
if ($actions->getAsDto('actions')->getAction($crudActionName, $actionName)) { | |||
$actions->update( | |||
$crudActionName, | |||
$actionName, | |||
function (Action $action) use ($button) { | |||
if (isset($button['add_class'])) { | |||
$action->addCssClass($button['add_class']); | |||
} | |||
$crudActionName, | |||
$actionName, | |||
function (Action $action) use ($button) { | |||
if (isset($button['add_class'])) { | |||
$action->addCssClass($button['add_class']); | |||
} | |||
if (isset($button['class'])) { | |||
$action->setCssClass($button['class']); | |||
} | |||
if (isset($button['class'])) { | |||
$action->setCssClass($button['class']); | |||
} | |||
if (isset($button['icon'])) { | |||
$action->setIcon('fa fa-' . $button['icon']); | |||
} | |||
if (isset($button['icon'])) { | |||
$action->setIcon('fa fa-'.$button['icon']); | |||
} | |||
if (isset($button['label'])) { | |||
$action->setLabel($button['label']); | |||
} | |||
if (isset($button['label'])) { | |||
$action->setLabel($button['label']); | |||
} | |||
if (isset($button['dropdown']) && $button['dropdown']) { | |||
$action->addCssClass('in-dropdown'); | |||
} | |||
if (isset($button['dropdown']) && $button['dropdown']) { | |||
$action->addCssClass('in-dropdown'); | |||
} | |||
if (isset($button['html_attributes']) && $button['html_attributes']) { | |||
$action->setHtmlAttributes($button['html_attributes']); | |||
} | |||
if (isset($button['html_attributes']) && $button['html_attributes']) { | |||
$action->setHtmlAttributes($button['html_attributes']); | |||
} | |||
return $action; | |||
} | |||
return $action; | |||
} | |||
); | |||
} | |||
} | |||
@@ -661,22 +708,22 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
public function autocompleteFilter(AdminContext $context): JsonResponse | |||
{ | |||
$queryBuilder = $this->createIndexQueryBuilder( | |||
$context->getSearch(), | |||
$context->getEntity(), | |||
FieldCollection::new([]), | |||
FilterCollection::new() | |||
$context->getSearch(), | |||
$context->getEntity(), | |||
FieldCollection::new([]), | |||
FilterCollection::new() | |||
); | |||
$autocompleteContext = $context->getRequest()->get(AssociationField::PARAM_AUTOCOMPLETE_CONTEXT); | |||
/** @var CrudControllerInterface $controller */ | |||
$controller = $this->get(ControllerFactory::class)->getCrudControllerInstance( | |||
$autocompleteContext[EA::CRUD_CONTROLLER_FQCN], | |||
Action::INDEX, | |||
$context->getRequest() | |||
$autocompleteContext[EA::CRUD_CONTROLLER_FQCN], | |||
Action::INDEX, | |||
$context->getRequest() | |||
); | |||
/** @var FieldDto $field */ | |||
$field = FieldCollection::new( | |||
$controller->configureFields($autocompleteContext['originatingPage']) | |||
$controller->configureFields($autocompleteContext['originatingPage']) | |||
)->getByProperty($autocompleteContext['propertyName']); | |||
$filterManager = $this->get('filter_manager'); | |||
@@ -685,7 +732,7 @@ abstract class AbstractAdminController extends EaAbstractCrudController | |||
if ($filterManager->isRelationField($field->getProperty())) { | |||
$queryBuilder->select($autocompleteContext['propertyName']); | |||
} else { | |||
$queryBuilder->select('entity.' . $autocompleteContext['propertyName']); | |||
$queryBuilder->select('entity.'.$autocompleteContext['propertyName']); | |||
} | |||
$responses = array(); |
@@ -43,31 +43,39 @@ class EntityManager extends EntityManagerDecorator | |||
return new $entityName; | |||
} | |||
public function create(EntityInterface $entity): self | |||
public function create(EntityInterface $entity, bool $dispatchEvent = true): self | |||
{ | |||
$this->eventDispatcher->dispatch(new EntityManagerEvent($entity), EntityManagerEvent::PRE_CREATE_EVENT); | |||
if($dispatchEvent) { | |||
$this->eventDispatcher->dispatch(new EntityManagerEvent($entity), EntityManagerEvent::PRE_CREATE_EVENT); | |||
} | |||
$this->persist($entity); | |||
$this->eventDispatcher->dispatch(new EntityManagerEvent($entity), EntityManagerEvent::POST_CREATE_EVENT); | |||
if($dispatchEvent) { | |||
$this->eventDispatcher->dispatch(new EntityManagerEvent($entity), EntityManagerEvent::POST_CREATE_EVENT); | |||
} | |||
return $this; | |||
} | |||
public function update(EntityInterface $entity): self | |||
public function update(EntityInterface $entity, bool $dispatchEvent = true): self | |||
{ | |||
$this->eventDispatcher->dispatch(new EntityManagerEvent($entity), EntityManagerEvent::PRE_UPDATE_EVENT); | |||
if($dispatchEvent){ | |||
$this->eventDispatcher->dispatch(new EntityManagerEvent($entity), EntityManagerEvent::PRE_UPDATE_EVENT); | |||
} | |||
$this->persist($entity); | |||
$this->eventDispatcher->dispatch(new EntityManagerEvent($entity), EntityManagerEvent::POST_UPDATE_EVENT); | |||
if($dispatchEvent) { | |||
$this->eventDispatcher->dispatch(new EntityManagerEvent($entity), EntityManagerEvent::POST_UPDATE_EVENT); | |||
} | |||
return $this; | |||
} | |||
public function delete(EntityInterface $entity): self | |||
public function delete(EntityInterface $entity, bool $dispatchEvent = true): self | |||
{ | |||
$this->eventDispatcher->dispatch(new EntityManagerEvent($entity), EntityManagerEvent::PRE_DELETE_EVENT); | |||
if($dispatchEvent) { | |||
$this->eventDispatcher->dispatch(new EntityManagerEvent($entity), EntityManagerEvent::PRE_DELETE_EVENT); | |||
} | |||
$this->remove($entity); | |||
$this->eventDispatcher->dispatch(new EntityManagerEvent($entity), EntityManagerEvent::POST_DELETE_EVENT); | |||
if($dispatchEvent) { | |||
$this->eventDispatcher->dispatch(new EntityManagerEvent($entity), EntityManagerEvent::POST_DELETE_EVENT); | |||
} | |||
return $this; | |||
} | |||
@@ -0,0 +1,15 @@ | |||
<?php | |||
namespace Lc\SovBundle\Doctrine\Extension; | |||
trait ClearIdTrait | |||
{ | |||
public function clearId($id): self | |||
{ | |||
$this->id = $id; | |||
return $this; | |||
} | |||
} |
@@ -9,7 +9,7 @@ trait SluggableTrait | |||
{ | |||
/** | |||
* @ORM\Column(type="string", length=255) | |||
* @Gedmo\Slug(fields={"title"}) | |||
* @Gedmo\Slug(fields={"title"}, unique=true) | |||
*/ | |||
protected $slug; | |||
@@ -0,0 +1,28 @@ | |||
<?php | |||
namespace Lc\SovBundle\Event; | |||
use Lc\SovBundle\Doctrine\EntityInterface; | |||
use Symfony\Contracts\EventDispatcher\Event; | |||
/** | |||
* class EntityEvent. | |||
* | |||
* @author Simon Vieille <simon@deblan.fr> | |||
*/ | |||
class EntityComponentEvent extends Event | |||
{ | |||
const DUPLICATE_EVENT = 'entity_component_event.duplicate'; | |||
protected EntityInterface $entity; | |||
public function __construct(EntityInterface $entity) | |||
{ | |||
$this->entity = $entity; | |||
} | |||
public function getEntity(): EntityInterface | |||
{ | |||
return $this->entity; | |||
} | |||
} |
@@ -0,0 +1,52 @@ | |||
<?php | |||
namespace Lc\SovBundle\EventSubscriber; | |||
use Doctrine\ORM\EntityManagerInterface; | |||
use Lc\SovBundle\Doctrine\EntityInterface; | |||
use Lc\SovBundle\Doctrine\Extension\SluggableInterface; | |||
use Lc\SovBundle\Doctrine\Extension\SortableInterface; | |||
use Lc\SovBundle\Doctrine\Extension\StatusInterface; | |||
use Lc\SovBundle\Doctrine\Extension\TreeInterface; | |||
use Lc\SovBundle\Event\EntityComponentEvent; | |||
use Lc\SovBundle\Event\EntityManager\EntityManagerEvent; | |||
use Lc\SovBundle\Repository\AbstractRepositoryInterface; | |||
use Symfony\Component\EventDispatcher\EventSubscriberInterface; | |||
class SluggablePropertyEventSubscriber implements EventSubscriberInterface | |||
{ | |||
protected $em; | |||
protected $adminUrlGenerator; | |||
public function __construct(EntityManagerInterface $entityManager) | |||
{ | |||
$this->em = $entityManager; | |||
} | |||
public static function getSubscribedEvents() | |||
{ | |||
return [ | |||
EntityComponentEvent::DUPLICATE_EVENT => ['setSluggablePropertyDuplicateEvent'], | |||
EntityManagerEvent::POST_UPDATE_EVENT => ['setSluggablePropertyUpdateEvent'], | |||
]; | |||
} | |||
public function setSluggablePropertyDuplicateEvent(EntityComponentEvent $event) | |||
{ | |||
$entity = $event->getEntity(); | |||
if ($entity instanceof SluggableInterface) { | |||
$entity->clearId(null); | |||
$entity->setSlug(null); | |||
} | |||
} | |||
public function setSluggablePropertyUpdateEvent(EntityManagerEvent $event) | |||
{ | |||
$entity = $event->getEntity(); | |||
if ($entity instanceof SluggableInterface) { | |||
$entity->setSlug(null); | |||
} | |||
} | |||
} |
@@ -12,7 +12,7 @@ use Lc\SovBundle\Event\EntityManager\EntityManagerEvent; | |||
use Lc\SovBundle\Repository\AbstractRepositoryInterface; | |||
use Symfony\Component\EventDispatcher\EventSubscriberInterface; | |||
class CommonPropertyEventSubscriber implements EventSubscriberInterface | |||
class SortablePropertyEventSubscriber implements EventSubscriberInterface | |||
{ | |||
protected $em; | |||
protected $adminUrlGenerator; |
@@ -75,15 +75,17 @@ abstract class AbstractRepository extends ServiceEntityRepository implements Ser | |||
return $query; | |||
} | |||
public function findSimilarSlug($merchant) | |||
public function findBySimilarSlug($slug) | |||
{ | |||
$qb = $this->createQueryBuilder('entity') | |||
->select('entity.id, COUNT(entity.slug) as niche') | |||
->select('COUNT(entity.slug) as totalSimilar') | |||
->andWhere('entity.status>=0') | |||
->andWhere('entity.slug LIKE :slug') | |||
->setParameter('slug', $slug) | |||
->groupBy('entity.slug') | |||
->having('COUNT(entity.slug) >1'); | |||
->having('COUNT(entity.slug) >=1'); | |||
return $qb->getQuery()->getResult(); | |||
return $qb->getQuery()->getOneOrNullResult(); | |||
} | |||
public function findAll() |
@@ -46,19 +46,29 @@ abstract class AbstractRepositoryQuery | |||
return $this; | |||
} | |||
public function count(): string | |||
{ | |||
return $this->query->getQuery() | |||
->getSingleScalarResult(); | |||
} | |||
public function findOne() | |||
{ | |||
return $this->query->getQuery() | |||
->setMaxResults(1) | |||
->getOneOrNullResult() | |||
; | |||
->getOneOrNullResult(); | |||
} | |||
public function find() :array | |||
public function find(): array | |||
{ | |||
return $this->query->getQuery()->getResult(); | |||
} | |||
public function limit(int $maxResults) | |||
{ | |||
return $this->query->setMaxResults($maxResults); | |||
} | |||
public function paginate(int $page = 1, int $limit = 20) | |||
{ | |||
return $this->paginator->paginate($this->query->getQuery(), $page, $limit); | |||
@@ -76,7 +86,7 @@ abstract class AbstractRepositoryQuery | |||
foreach ($words as $k => $v) { | |||
if (isset($v[0]) && '.' === $v[0]) { | |||
$words[$k] = $this->id.$v; | |||
$words[$k] = $this->id . $v; | |||
} | |||
} | |||
@@ -90,13 +100,13 @@ abstract class AbstractRepositoryQuery | |||
return $data; | |||
} | |||
public function orderBy($field, $sort){ | |||
if(substr($field,0,1)=== '.'){ | |||
return $this->addOrderBy($field, $sort) ; | |||
}else{ | |||
return $this->addOrderBy('.'.$field, $sort) ; | |||
public function orderBy(string $field, string $sort = 'ASC'): self | |||
{ | |||
if (substr($field, 0, 1) === '.') { | |||
return $this->addOrderBy($field, $sort); | |||
} else { | |||
return $this->addOrderBy('.' . $field, $sort); | |||
} | |||
} | |||
} | |||
@@ -3,75 +3,105 @@ | |||
namespace Lc\SovBundle\Repository\Reminder; | |||
use Knp\Component\Pager\PaginatorInterface; | |||
use Lc\SovBundle\Model\User\UserInterface; | |||
use Lc\SovBundle\Repository\AbstractRepositoryQuery; | |||
class ReminderRepositoryQuery extends AbstractRepositoryQuery implements ReminderRepositoryQueryInterface | |||
{ | |||
protected $isJoinUser = false; | |||
public function __construct(ReminderRepository $repository, PaginatorInterface $paginator) | |||
{ | |||
parent::__construct($repository, 'r', $paginator); | |||
} | |||
public function filterDone($done = false) | |||
public function filterByDone($done = false): self | |||
{ | |||
return $this | |||
->andWhere('.done = :done') | |||
->setParameter(':done', $done); | |||
->andWhere('.done = :done') | |||
->setParameter(':done', $done); | |||
} | |||
public function filterUser($user) | |||
public function joinUser(): self | |||
{ | |||
if (!$this->isJoinUser) { | |||
$this->isJoinUser = true; | |||
return $this | |||
->leftJoin('.users', 'u'); | |||
} | |||
return $this; | |||
} | |||
public function filterByUser(UserInterface $user): self | |||
{ | |||
$this->joinUser(); | |||
return $this | |||
->leftJoin('.users', 'u') | |||
->having('COUNT(u.id) = 0') | |||
->orHaving(':user MEMBER OF .users') | |||
->setParameter(':user', $user) | |||
->groupBy('.id'); | |||
->having('COUNT(u.id) = 0') | |||
->orHaving(':user MEMBER OF .users') | |||
->setParameter(':user', $user); | |||
} | |||
public function filterCrudAction($crudAction) | |||
public function filterByCrudAction(?string $crudAction= null): self | |||
{ | |||
if(is_null($crudAction)) { | |||
if (is_null($crudAction)) { | |||
return $this | |||
->andWhere('.crudControllerFqcn IS NULL'); | |||
} | |||
else { | |||
->andWhere('.crudControllerFqcn IS NULL'); | |||
} else { | |||
return $this | |||
->andWhere('.crudAction = :crudAction') | |||
->setParameter(':crudAction', $crudAction); | |||
->andWhere('.crudAction = :crudAction') | |||
->setParameter(':crudAction', $crudAction); | |||
} | |||
} | |||
public function filterCrudControllerFqcn($crudControllerFqcn) | |||
public function filterByCrudControllerFqcn(?string $crudControllerFqcn= null): self | |||
{ | |||
if(is_null($crudControllerFqcn)) { | |||
if (is_null($crudControllerFqcn)) { | |||
return $this | |||
->andWhere('.crudControllerFqcn IS NULL'); | |||
} | |||
else { | |||
->andWhere('.crudControllerFqcn IS NULL'); | |||
} else { | |||
return $this | |||
->andWhere('.crudControllerFqcn = :crudControllerFqcn') | |||
->setParameter(':crudControllerFqcn', $crudControllerFqcn); | |||
->andWhere('.crudControllerFqcn = :crudControllerFqcn') | |||
->setParameter(':crudControllerFqcn', $crudControllerFqcn); | |||
} | |||
} | |||
public function filterEntityId($entityId) | |||
public function filterByEntityId(?int $entityId=null): self | |||
{ | |||
if(is_null($entityId)) { | |||
if (is_null($entityId)) { | |||
return $this | |||
->andWhere('.entityId IS NULL'); | |||
} | |||
else { | |||
->andWhere('.entityId IS NULL'); | |||
} else { | |||
return $this | |||
->andWhere('.entityId = :entityId') | |||
->setParameter(':entityId', $entityId); | |||
->andWhere('.entityId = :entityId') | |||
->setParameter(':entityId', $entityId); | |||
} | |||
} | |||
public function orderDefault() | |||
public function filterIsNotDone(): self | |||
{ | |||
return $this | |||
->orderBy('.dateReminder', 'ASC'); | |||
->andWhere('.done = 0'); | |||
} | |||
public function filterLikeCrudAction(string $crudAction): self | |||
{ | |||
return $this | |||
->andWhere('.crudAction LIKE :crudAction') | |||
->setParameter('crudAction', $crudAction); | |||
} | |||
public function filterLikeCrudControllerFqcn(string $crudControllerFqcn): self | |||
{ | |||
return $this | |||
->andWhere('.crudControllerFqcn LIKE :crudControllerFqcn') | |||
->setParameter('crudControllerFqcn', $crudControllerFqcn); | |||
} | |||
public function filterLikeEntityId(int $entityId): self | |||
{ | |||
return $this | |||
->andWhere('.entityId LIKE :id') | |||
->setParameter('entityId', $entityId); | |||
} | |||
} |
@@ -2,6 +2,7 @@ | |||
namespace Lc\SovBundle\Repository\Reminder; | |||
use Lc\SovBundle\Model\User\UserInterface; | |||
use Lc\SovBundle\Repository\AbstractStore; | |||
class ReminderStore extends AbstractStore implements ReminderStoreInterface | |||
@@ -19,99 +20,132 @@ class ReminderStore extends AbstractStore implements ReminderStoreInterface | |||
$query = $this->query->create(); | |||
} | |||
$query->filterDone(); | |||
$query->filterByDone(); | |||
if (array_key_exists('user', $params)) { | |||
$query->filterUser($params['user']); | |||
$query | |||
->filterByUser($params['user']) | |||
->groupBy('.id'); | |||
} | |||
if (array_key_exists('crudAction', $params)) { | |||
$query->filterCrudAction($params['crudAction']); | |||
$query->filterByCrudAction($params['crudAction']); | |||
} | |||
if (array_key_exists('crudControllerFqcn', $params)) { | |||
$query->filterCrudControllerFqcn($params['crudControllerFqcn']); | |||
$query->filterByCrudControllerFqcn($params['crudControllerFqcn']); | |||
} | |||
if (array_key_exists('entityId', $params)) { | |||
$query->filterEntityId($params['entityId']); | |||
$query->filterByEntityId($params['entityId']); | |||
} | |||
$query->orderDefault(); | |||
$query->orderBy('.dateReminder'); | |||
return $query->find(); | |||
} | |||
/* | |||
public function getRemindersByUser($user) | |||
{ | |||
$reminderRepo = $this->em->getRepository(ReminderInterface::class); | |||
$reminders = $reminderRepo->findByUser($user); | |||
$entitiesRepo = array(); | |||
$entitiesConfig = array(); | |||
if (count($reminders) > 0) { | |||
foreach ($reminders as $reminder) { | |||
if ($reminder->getEntityName()) { | |||
if (!isset($entitiesConfig[$reminder->getEntityName()])) { | |||
$entitiesConfig[$reminder->getEntityName()] = $this->configManager->getEntityConfig($reminder->getEntityName()); | |||
} | |||
if ($reminder->getEntityAction() == 'edit' || $reminder->getEntityAction() == 'show') { | |||
if (!isset($entitiesRepo[$reminder->getEntityName()])) { | |||
$entitiesRepo[$reminder->getEntityName()] = $this->em->getRepository($entitiesConfig[$reminder->getEntityName()]['class']); | |||
} | |||
if ($reminder->getEntityId()) { | |||
$reminder->relatedPage = $entitiesRepo[$reminder->getEntityName()]->find($reminder->getEntityId())->__toString(); | |||
} | |||
} else { | |||
$reminder->relatedPage = 'Liste de ' . $entitiesConfig[$reminder->getEntityName()]['label']; | |||
} | |||
} | |||
} | |||
} | |||
return $reminders; | |||
// findByUser | |||
public function getByUser(UserInterface $user, $query = null): array | |||
{ | |||
if (is_null($query)) { | |||
$query = $this->query->create(); | |||
} | |||
*/ | |||
$query = $this->query->create(); | |||
/* | |||
public function findByUser($user) | |||
{ | |||
$qb = $this->createQueryBuilder('e') | |||
->leftJoin('e.users', 'u') | |||
->having('COUNT(u.id) = 0') | |||
->orHaving(':user MEMBER OF e.users') | |||
->andWhere('e.done = 0') | |||
->setParameter('user', $user) | |||
->orderBy('e.dateReminder', 'ASC') | |||
->groupBy('e.id'); | |||
return $qb->getQuery()->getResult(); | |||
$query | |||
->filterByUser($user) | |||
->filterIsNotDone() | |||
->orderBy('.dateReminder') | |||
->groupBy('.id'); | |||
return $query->find(); | |||
} | |||
public function findByEasyAdminConfigAndUser($crudAction, $crudControllerFqcn, $user, $entityId = null) | |||
{ | |||
$qb = $this->createQueryBuilder('e'); | |||
$qb->leftJoin('e.users', 'u'); | |||
$qb->having('COUNT(u.id) = 0'); | |||
$qb->orHaving(':user MEMBER OF e.users'); | |||
$qb->andWhere('e.done = 0'); | |||
$qb->andWhere('e.crudAction LIKE :crudAction'); | |||
$qb->andWhere('e.crudControllerFqcn LIKE :entity'); | |||
$qb->setParameter('crudAction', $crudAction); | |||
$qb->setParameter('crudControllerFqcn', $crudControllerFqcn); | |||
$qb->setParameter('user', $user); | |||
// findByEasyAdminConfigAndUser | |||
public function getByEasyAdminConfigAndUser( | |||
string $crudAction, | |||
string $crudControllerFqcn, | |||
UserInterface $user, | |||
int $entityId = null, | |||
$query = null | |||
): array { | |||
if (is_null($query)) { | |||
$query = $this->query->create(); | |||
} | |||
$query | |||
->filterByUser($user) | |||
->filterLikeCrudAction($crudAction) | |||
->filterLikeCrudControllerFqcn($crudControllerFqcn) | |||
->filterIsNotDone(); | |||
if ($entityId) { | |||
$qb->andWhere('e.entityId LIKE :id'); | |||
$qb->setParameter('entityId', $entityId); | |||
$query | |||
->filterLikeEntityId($entityId); | |||
} | |||
$qb->orderBy('e.dateReminder', 'ASC'); | |||
$qb->groupBy('e.id'); | |||
$query | |||
->orderBy('.dateReminder') | |||
->groupBy('.id'); | |||
return $query->find(); | |||
} | |||
return $qb->getQuery()->getResult(); | |||
}*/ | |||
// public function findByEasyAdminConfigAndUser($crudAction, $crudControllerFqcn, $user, $entityId = null) | |||
// { | |||
// $qb = $this->createQueryBuilder('e'); | |||
// $qb->leftJoin('e.users', 'u'); | |||
// $qb->having('COUNT(u.id) = 0'); | |||
// $qb->orHaving(':user MEMBER OF e.users'); | |||
// $qb->andWhere('e.done = 0'); | |||
// $qb->andWhere('e.crudAction LIKE :crudAction'); | |||
// $qb->andWhere('e.crudControllerFqcn LIKE :entity'); | |||
// $qb->setParameter('crudAction', $crudAction); | |||
// $qb->setParameter('crudControllerFqcn', $crudControllerFqcn); | |||
// $qb->setParameter('user', $user); | |||
// if ($entityId) { | |||
// $qb->andWhere('e.entityId LIKE :id'); | |||
// $qb->setParameter('entityId', $entityId); | |||
// } | |||
// $qb->orderBy('e.dateReminder', 'ASC'); | |||
// $qb->groupBy('e.id'); | |||
// | |||
// return $qb->getQuery()->getResult(); | |||
// } | |||
} | |||
/* | |||
public function getRemindersByUser($user) | |||
{ | |||
$reminderRepo = $this->em->getRepository(ReminderInterface::class); | |||
$reminders = $reminderRepo->findByUser($user); | |||
$entitiesRepo = array(); | |||
$entitiesConfig = array(); | |||
if (count($reminders) > 0) { | |||
foreach ($reminders as $reminder) { | |||
if ($reminder->getEntityName()) { | |||
if (!isset($entitiesConfig[$reminder->getEntityName()])) { | |||
$entitiesConfig[$reminder->getEntityName()] = $this->configManager->getEntityConfig($reminder->getEntityName()); | |||
} | |||
if ($reminder->getEntityAction() == 'edit' || $reminder->getEntityAction() == 'show') { | |||
if (!isset($entitiesRepo[$reminder->getEntityName()])) { | |||
$entitiesRepo[$reminder->getEntityName()] = $this->em->getRepository($entitiesConfig[$reminder->getEntityName()]['class']); | |||
} | |||
if ($reminder->getEntityId()) { | |||
$reminder->relatedPage = $entitiesRepo[$reminder->getEntityName()]->find($reminder->getEntityId())->__toString(); | |||
} | |||
} else { | |||
$reminder->relatedPage = 'Liste de ' . $entitiesConfig[$reminder->getEntityName()]['label']; | |||
} | |||
} | |||
} | |||
} | |||
return $reminders; | |||
} | |||
*/ |
@@ -3,10 +3,13 @@ | |||
namespace Lc\SovBundle\Repository\Site; | |||
use Knp\Component\Pager\PaginatorInterface; | |||
use Lc\CaracoleBundle\Repository\StatusRepositoryQueryTrait; | |||
use Lc\SovBundle\Repository\AbstractRepositoryQuery; | |||
class NewsRepositoryQuery extends AbstractRepositoryQuery implements NewsRepositoryQueryInterface | |||
{ | |||
use StatusRepositoryQueryTrait; | |||
public function __construct(NewsRepository $repository, PaginatorInterface $paginator) | |||
{ | |||
parent::__construct($repository, 'r', $paginator); |
@@ -12,4 +12,36 @@ class NewsStore extends AbstractStore implements NewsStoreInterface | |||
{ | |||
$this->query = $query; | |||
} | |||
//findLatests | |||
public function getLatests(int $maxResults = 0, $query = null): array | |||
{ | |||
if (is_null($query)) { | |||
$query = $this->query->create(); | |||
} | |||
$query | |||
->filterIsOnline() | |||
->orderBy('.date', 'DESC'); | |||
if ($maxResults) { | |||
$query | |||
->limit($maxResults); | |||
} | |||
return $query->find(); | |||
} | |||
public function findLatests($maxResults = 0) | |||
{ | |||
$result = $this->findByMerchantQuery() | |||
->orderBy('e.date', 'DESC'); | |||
$result->andWhere('e.status = 1'); | |||
if ($maxResults) { | |||
$result->setMaxResults($maxResults); | |||
} | |||
return $result->getQuery()->getResult(); | |||
} | |||
} |
@@ -11,4 +11,11 @@ class PageRepositoryQuery extends AbstractRepositoryQuery implements PageReposit | |||
{ | |||
parent::__construct($repository, 'r', $paginator); | |||
} | |||
public function filterBySlug(string $slug) | |||
{ | |||
return $this | |||
->andWhere('.slug = :slug') | |||
->setParameter('slug', $slug); | |||
} | |||
} |
@@ -2,6 +2,7 @@ | |||
namespace Lc\SovBundle\Repository\Site; | |||
use Lc\SovBundle\Model\Site\PageInterface; | |||
use Lc\SovBundle\Repository\AbstractStore; | |||
class PageStore extends AbstractStore implements PageStoreInterface | |||
@@ -12,4 +13,15 @@ class PageStore extends AbstractStore implements PageStoreInterface | |||
{ | |||
$this->query = $query; | |||
} | |||
//findPageBySlug | |||
public function getBySlug(string $slug): ?PageInterface | |||
{ | |||
$query = $this->query->create(); | |||
$query | |||
->filterBySlug($slug); | |||
return $query->findOne(); | |||
} | |||
} |
@@ -13,10 +13,23 @@ class TicketRepositoryQuery extends AbstractRepositoryQuery implements TicketRep | |||
parent::__construct($repository, 'r', $paginator); | |||
} | |||
public function filterByUser(UserInterface $user) | |||
public function filterByUser(UserInterface $user): self | |||
{ | |||
return $this | |||
->andWhere('.user = :user') | |||
->setParameter('user', $user); | |||
->andWhere('.user = :user') | |||
->setParameter('user', $user); | |||
} | |||
public function filterByStatus($statusArray): self | |||
{ | |||
return $this | |||
->andWhere('.status IN (:status)') | |||
->setParameter('status', $statusArray); | |||
} | |||
public function selectCount(): self | |||
{ | |||
return $this | |||
->select('count(r.id) as count'); | |||
} | |||
} |
@@ -2,6 +2,8 @@ | |||
namespace Lc\SovBundle\Repository\Ticket; | |||
use App\Entity\Ticket\Ticket; | |||
use Lc\SovBundle\Model\Ticket\TicketInterface; | |||
use Lc\SovBundle\Repository\AbstractStore; | |||
class TicketStore extends AbstractStore implements TicketStoreInterface | |||
@@ -14,12 +16,42 @@ class TicketStore extends AbstractStore implements TicketStoreInterface | |||
} | |||
// getTicketsByUser | |||
public function getByUser($user) | |||
public function getByUser($user, $query = null): array | |||
{ | |||
$query = $this->query->create(); | |||
if (is_null($query)) { | |||
$query = $this->query->create(); | |||
} | |||
$query->filterByUser($user); | |||
return $query->find(); | |||
} | |||
// findAllOpen | |||
public function getAllOpen(int $limit = 0, $query = null): array | |||
{ | |||
if (is_null($query)) { | |||
$query = $this->query->create(); | |||
} | |||
$query | |||
->filterByStatus(Ticket::TICKET_STATUS_OPEN) | |||
->limit($limit) | |||
->orderBy('r.id', 'DESC'); | |||
return $query->find(); | |||
} | |||
//countAllOpen | |||
public function countAllOpen($query = null): string | |||
{ | |||
if (is_null($query)) { | |||
$query = $this->query->create(); | |||
} | |||
$query | |||
->selectCount() | |||
->filterByStatus(Ticket::TICKET_STATUS_OPEN); | |||
return $query->count(); | |||
} | |||
} |
@@ -29,11 +29,12 @@ class UserRepository extends AbstractRepository | |||
$this->_em->flush(); | |||
} | |||
public function findByRole($role) { | |||
public function findByRole($role) | |||
{ | |||
return $this->createQueryBuilder('u') | |||
->andWhere('u.roles LIKE :role') | |||
->setParameter('role', '%'.$role.'%') | |||
->getQuery() | |||
->getResult(); | |||
->andWhere('u.roles LIKE :role') | |||
->setParameter('role', '%' . $role . '%') | |||
->getQuery() | |||
->getResult(); | |||
} | |||
} |
@@ -2,6 +2,8 @@ | |||
namespace Lc\SovBundle\Repository\User; | |||
use App\Entity\Merchant\Merchant; | |||
use App\Entity\Newsletter\Newsletter; | |||
use Knp\Component\Pager\PaginatorInterface; | |||
use Lc\SovBundle\Repository\AbstractRepositoryQuery; | |||
@@ -11,4 +13,25 @@ class UserRepositoryQuery extends AbstractRepositoryQuery implements UserReposit | |||
{ | |||
parent::__construct($repository, 'r', $paginator); | |||
} | |||
public function filterByNewsletter(Newsletter $newsletter): self | |||
{ | |||
return $this | |||
->andWhere(':newsletter MEMBER OF .newsletters') | |||
->setParameter('newsletter', $newsletter->getId()); | |||
} | |||
public function filterLikeRole(string $role): self | |||
{ | |||
return $this | |||
->andWhere('.roles LIKE :roles') | |||
->setParameter('roles', '%"' . $role . '"%'); | |||
} | |||
public function filterLikeTicketTypeNotification(string $ticketType): self | |||
{ | |||
return $this | |||
->andWhere('.ticketTypesNotification LIKE :ticketType') | |||
->setParameter('ticketType', '%"' . $ticketType . '"%'); | |||
} | |||
} |
@@ -2,7 +2,7 @@ | |||
namespace Lc\SovBundle\Repository\User; | |||
use Lc\SovBundle\Model\User\UserInterface; | |||
use App\Entity\Newsletter\Newsletter; | |||
use Lc\SovBundle\Repository\AbstractStore; | |||
class UserStore extends AbstractStore implements UserStoreInterface | |||
@@ -13,4 +13,37 @@ class UserStore extends AbstractStore implements UserStoreInterface | |||
{ | |||
$this->query = $query; | |||
} | |||
//findAllByNewsletter | |||
public function getByNewsletter(Newsletter $newsletter, $query = null): array | |||
{ | |||
if (is_null($query)) { | |||
$query = $this->query->create(); | |||
} | |||
$query | |||
->filterByNewsletter($newsletter); | |||
return $query->find(); | |||
} | |||
//findByRole | |||
public function getByRole(string $role): array | |||
{ | |||
$query = $this->query->create(); | |||
$query | |||
->filterLikeRole($role); | |||
return $query->find(); | |||
} | |||
//findByTicketTypesNotification | |||
public function getByTicketTypesNotification(string $ticketType): array | |||
{ | |||
$query = $this->query->create(); | |||
$query | |||
->filterLikeTicketTypeNotification($ticketType); | |||
return $query->find(); | |||
} | |||
} |
@@ -4,15 +4,19 @@ window.addEventListener('load', (event) => { | |||
SovNotification.init(); | |||
SovWidgets.setDateRange(); | |||
SovWidgets.setAutoCompleteField(); | |||
$('.btn-confirm-js, .action-confirm').click(function () { | |||
return confirm('Êtes-vous sûr de vouloir réaliser cette action ?'); | |||
}); | |||
/* Tooltip */ | |||
$('[data-toggle="tooltip"]').tooltip(); | |||
/* Select2 */ | |||
if ($('.select2, select.form-control').length) { | |||
if ($('.form-select, .select2, select.form-control').length) { | |||
$('form .form-widget>select.form-control, .select2').each(function (i, elm) { | |||
$('form .form-widget>select.form-control, .select2, .form-select').each(function (i, elm) { | |||
if (!$(this).hasClass('disable-select2')) { | |||
SovWidgets.setSelect2($(elm)); | |||
} | |||
@@ -77,5 +81,7 @@ window.addEventListener('load', (event) => { | |||
} | |||
} | |||
SovWidgets.setAutoCompleteField(); | |||
}); |
@@ -19,7 +19,7 @@ export class SovPrices { | |||
static applyReductionPercent(price, percentage) | |||
{ | |||
return applyPercent(price, -percentage); | |||
return this.applyPercent(price, -percentage); | |||
} | |||
static applyReductionAmount(price, amount) |
@@ -97,7 +97,7 @@ export class SovWidgets { | |||
autocompleteFields.each(function () { | |||
var $this = $(this), | |||
url = $this.data('lc-autocomplete-url'); | |||
SovTools.log($this); | |||
$this.autoComplete({ | |||
noResultsText: 'Aucun résultat n\'a été trouvé.', | |||
resolverSettings: { |
@@ -32,6 +32,8 @@ action: | |||
change: Changer | |||
detail: Voir | |||
send: Envoyer | |||
duplicate: Dupliquer | |||
cancel: Annuler | |||
index_children: Afficher les enfants | |||
index_parent: Retour au parent | |||
back_index: Retour à la liste | |||
@@ -44,6 +46,7 @@ flash_message: | |||
update: Le contenu "%name%" a été mis à jour avec succès. | |||
delete: Le contenu "%name%" a été supprimé avec succès. | |||
sort: Position modifiée | |||
duplicate: Le document a bien été dupliqué | |||
entity: | |||
User: |
@@ -26,9 +26,9 @@ class TranslatorAdmin | |||
return $this->trans('menu.' . $menu); | |||
} | |||
public function transFlashMessage($name) | |||
public function transFlashMessage($name, $params = []) | |||
{ | |||
return $this->trans('flash_message.' . $name); | |||
return $this->trans('flash_message.' . $name, $params); | |||
} | |||
public function transField($fieldName, $entityClass): string |