use Lc\SovBundle\Field\Filter\FilterManager; | use Lc\SovBundle\Field\Filter\FilterManager; | ||||
use Lc\SovBundle\Form\Common\FiltersFormType; | use Lc\SovBundle\Form\Common\FiltersFormType; | ||||
use Lc\SovBundle\Form\Common\PositionType; | use Lc\SovBundle\Form\Common\PositionType; | ||||
use Lc\SovBundle\Repository\EntityRepository; | |||||
use Lc\SovBundle\Repository\RepositoryQueryInterface; | |||||
use Lc\SovBundle\Translation\FlashBagTranslator; | use Lc\SovBundle\Translation\FlashBagTranslator; | ||||
use Lc\SovBundle\Translation\TranslatorAdmin; | use Lc\SovBundle\Translation\TranslatorAdmin; | ||||
use Symfony\Component\Form\Extension\Core\Type\CollectionType; | use Symfony\Component\Form\Extension\Core\Type\CollectionType; | ||||
protected FormInterface $filtersForm; | protected FormInterface $filtersForm; | ||||
abstract public function getRepositoryQuery(): RepositoryQueryInterface; | |||||
public function configureResponseParameters(KeyValueStore $responseParameters): KeyValueStore | public function configureResponseParameters(KeyValueStore $responseParameters): KeyValueStore | ||||
{ | { | ||||
if ($responseParameters->get('global_actions')) { | if ($responseParameters->get('global_actions')) { | ||||
return $this->redirect($url); | return $this->redirect($url); | ||||
} | } | ||||
public function createIndexQueryBuilder( | |||||
SearchDto $searchDto, | |||||
EntityDto $entityDto, | |||||
FieldCollection $fields, | |||||
FilterCollection $filters | |||||
): QueryBuilder { | |||||
$queryBuilder = parent::createIndexQueryBuilder( | |||||
$searchDto, | |||||
$entityDto, | |||||
$fields, | |||||
$filters | |||||
); | |||||
public function createIndexRepositoryQuery( | |||||
SearchDto $searchDto, | |||||
EntityDto $entityDto, | |||||
FieldCollection $fields, | |||||
FilterCollection $filters | |||||
): RepositoryQueryInterface | |||||
{ | |||||
$repositoryQuery = $this->get(EntityRepository::class)->createRepositoryQuery($this->getRepositoryQuery(), $searchDto, $entityDto, $fields, $filters); | |||||
//TOdo utiliser les repositoryQuery ? | |||||
// TODO : déplacer dans EntotyRepository | |||||
if ($this->isInstanceOf(TreeInterface::class)) { | if ($this->isInstanceOf(TreeInterface::class)) { | ||||
$entityId = $searchDto->getRequest()->get('entityId'); | |||||
if ($entityId !== null) { | |||||
$queryBuilder->andWhereParent('entity', $entityId); | |||||
if ($entityDto->getInstance()) { | |||||
$repositoryQuery->filterByParent($entityDto->getInstance()); | |||||
} else { | } else { | ||||
$queryBuilder->andWhereParentIsNull('entity'); | |||||
$repositoryQuery->filterIsParent(); | |||||
} | } | ||||
} | } | ||||
$this->filtersForm = $this->createForm( | $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(FilterManager::class); | $filterManager = $this->get(FilterManager::class); | ||||
$this->filtersForm->handleRequest($searchDto->getRequest()); | $this->filtersForm->handleRequest($searchDto->getRequest()); | ||||
$filterManager->handleFiltersForm($queryBuilder, $this->filtersForm, $fields, $entityDto); | |||||
$filterManager->handleFiltersForm($repositoryQuery, $this->filtersForm, $fields, $entityDto); | |||||
return $repositoryQuery; | |||||
} | |||||
public function createIndexQueryBuilder( | |||||
SearchDto $searchDto, | |||||
EntityDto $entityDto, | |||||
FieldCollection $fields, | |||||
FilterCollection $filters | |||||
): QueryBuilder { | |||||
return $queryBuilder; | |||||
$repositoryQuery = $this->createIndexRepositoryQuery($searchDto, $entityDto, $fields, $filters); | |||||
return $repositoryQuery->getQueryBuilder(); | |||||
} | } | ||||
public function createSortQueryBuilder( | public function createSortQueryBuilder( |
use Lc\SovBundle\Container\User\GroupUserContainer; | use Lc\SovBundle\Container\User\GroupUserContainer; | ||||
use Lc\SovBundle\Container\User\UserContainer; | use Lc\SovBundle\Container\User\UserContainer; | ||||
use Lc\SovBundle\Field\Filter\FilterManager; | use Lc\SovBundle\Field\Filter\FilterManager; | ||||
use Lc\SovBundle\Repository\EntityRepository; | |||||
use Lc\SovBundle\Solver\Setting\SettingSolver; | use Lc\SovBundle\Solver\Setting\SettingSolver; | ||||
use Lc\SovBundle\Translation\FlashBagTranslator; | use Lc\SovBundle\Translation\FlashBagTranslator; | ||||
use Lc\SovBundle\Translation\TranslatorAdmin; | use Lc\SovBundle\Translation\TranslatorAdmin; | ||||
public static function getSubscribedServices() | public static function getSubscribedServices() | ||||
{ | { | ||||
return array_merge( | return array_merge( | ||||
parent::getSubscribedServices(), | |||||
[ | |||||
Environment::class => Environment::class, | |||||
Security::class => Security::class, | |||||
EntityManagerInterface::class => EntityManagerInterface::class, | |||||
UrlGeneratorInterface::class => UrlGeneratorInterface::class, | |||||
SessionInterface::class => SessionInterface::class, | |||||
PaginatorInterface::class => PaginatorInterface::class, | |||||
RequestStack::class => RequestStack::class, | |||||
EventDispatcherInterface::class => EventDispatcherInterface::class, | |||||
LoggerInterface::class => LoggerInterface::class, | |||||
TranslatorInterface::class => TranslatorInterface::class, | |||||
TranslatorAdmin::class => TranslatorAdmin::class, | |||||
FilterManager::class => FilterManager::class, | |||||
FlashBagTranslator::class => FlashBagTranslator::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, | |||||
] | |||||
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, | |||||
TranslatorInterface::class => TranslatorInterface::class, | |||||
TranslatorAdmin::class => TranslatorAdmin::class, | |||||
FilterManager::class => FilterManager::class, | |||||
FlashBagTranslator::class => FlashBagTranslator::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, | |||||
] | |||||
); | ); | ||||
} | } | ||||
public function addFlashTranslator( | public function addFlashTranslator( | ||||
string $type, | |||||
$translationKeyName, | |||||
$translationEntityName = null, | |||||
$translationParam = array() | |||||
): void { | |||||
string $type, | |||||
$translationKeyName, | |||||
$translationEntityName = null, | |||||
$translationParam = array() | |||||
): void | |||||
{ | |||||
if ($translationEntityName === null && method_exists($this, 'getTranslationEntityName')) { | if ($translationEntityName === null && method_exists($this, 'getTranslationEntityName')) { | ||||
$translationEntityName = $this->getTranslationEntityName(); | $translationEntityName = $this->getTranslationEntityName(); | ||||
} | } | ||||
$this->get(FlashBagTranslator::class)->add( | $this->get(FlashBagTranslator::class)->add( | ||||
$type, | |||||
$translationKeyName, | |||||
$translationEntityName, | |||||
$translationParam | |||||
$type, | |||||
$translationKeyName, | |||||
$translationEntityName, | |||||
$translationParam | |||||
); | ); | ||||
} | } | ||||
return in_array($interfaceName, class_implements($this->getEntityFqcn())); | return in_array($interfaceName, class_implements($this->getEntityFqcn())); | ||||
} | } | ||||
public function generateEaUrl(string $controller =null, string $action=null, int $entityId=null, array $extraParam = array()): string | |||||
public function generateEaUrl(string $controller = null, string $action = null, int $entityId = null, array $extraParam = array()): string | |||||
{ | { | ||||
$adminUrlGenerator = $this->get(AdminUrlGenerator::class); | $adminUrlGenerator = $this->get(AdminUrlGenerator::class); | ||||
if ($controller) { | if ($controller) { | ||||
if ($entityId) { | if ($entityId) { | ||||
$adminUrlGenerator->setEntityId($entityId); | $adminUrlGenerator->setEntityId($entityId); | ||||
} | } | ||||
if($extraParam){ | |||||
foreach ($extraParam as $key=>$value) { | |||||
if ($extraParam) { | |||||
foreach ($extraParam as $key => $value) { | |||||
$adminUrlGenerator->set($key, $value); | $adminUrlGenerator->set($key, $value); | ||||
} | } | ||||
} | } |
use Lc\SovBundle\Field\BooleanField; | use Lc\SovBundle\Field\BooleanField; | ||||
use Lc\SovBundle\Field\CKEditorField; | use Lc\SovBundle\Field\CKEditorField; | ||||
use Lc\SovBundle\Field\StatusField; | use Lc\SovBundle\Field\StatusField; | ||||
use Lc\SovBundle\Repository\RepositoryQueryInterface; | |||||
abstract class NewsletterAdminController extends AbstractAdminController | abstract class NewsletterAdminController extends AbstractAdminController | ||||
{ | { | ||||
public function getRepositoryQuery() :RepositoryQueryInterface | |||||
{ | |||||
return $this->get(NewsletterContainer::class)->getRepositoryQuery(); | |||||
} | |||||
public function configureFields(string $pageName): iterable | public function configureFields(string $pageName): iterable | ||||
{ | { | ||||
return array_merge( | return array_merge( |
use Lc\SovBundle\Factory\Site\NewsFactory; | use Lc\SovBundle\Factory\Site\NewsFactory; | ||||
use Lc\SovBundle\Field\CKEditorField; | use Lc\SovBundle\Field\CKEditorField; | ||||
use Lc\SovBundle\Field\StatusField; | use Lc\SovBundle\Field\StatusField; | ||||
use Lc\SovBundle\Repository\RepositoryQueryInterface; | |||||
abstract class NewsAdminController extends AbstractAdminController | abstract class NewsAdminController extends AbstractAdminController | ||||
{ | { | ||||
public function getRepositoryQuery() :RepositoryQueryInterface | |||||
{ | |||||
return $this->get(NewsContainer::class)->getRepositoryQuery(); | |||||
} | |||||
public function configureFields(string $pageName): iterable | public function configureFields(string $pageName): iterable | ||||
{ | { | ||||
$panel = parent::configureFields($pageName); | $panel = parent::configureFields($pageName); |
use Lc\SovBundle\Factory\Site\PageFactory; | use Lc\SovBundle\Factory\Site\PageFactory; | ||||
use Lc\SovBundle\Field\CKEditorField; | use Lc\SovBundle\Field\CKEditorField; | ||||
use Lc\SovBundle\Field\StatusField; | use Lc\SovBundle\Field\StatusField; | ||||
use Lc\SovBundle\Repository\RepositoryQueryInterface; | |||||
abstract class PageAdminController extends AbstractAdminController | abstract class PageAdminController extends AbstractAdminController | ||||
{ | { | ||||
public function getRepositoryQuery() :RepositoryQueryInterface | |||||
{ | |||||
return $this->get(PageContainer::class)->getRepositoryQuery(); | |||||
} | |||||
public function configureFields(string $pageName): iterable | public function configureFields(string $pageName): iterable | ||||
{ | { | ||||
$panel = parent::configureFields($pageName); | $panel = parent::configureFields($pageName); |
use Lc\SovBundle\Model\Ticket\TicketInterface; | use Lc\SovBundle\Model\Ticket\TicketInterface; | ||||
use Lc\SovBundle\Controller\AbstractAdminController; | use Lc\SovBundle\Controller\AbstractAdminController; | ||||
use Lc\SovBundle\Model\Ticket\TicketModel; | use Lc\SovBundle\Model\Ticket\TicketModel; | ||||
use Lc\SovBundle\Repository\RepositoryQueryInterface; | |||||
use Lc\SovBundle\Translation\TranslatorAdmin; | use Lc\SovBundle\Translation\TranslatorAdmin; | ||||
use Symfony\Component\HttpFoundation\JsonResponse; | use Symfony\Component\HttpFoundation\JsonResponse; | ||||
use Symfony\Component\HttpFoundation\RequestStack; | use Symfony\Component\HttpFoundation\RequestStack; | ||||
class TicketAdminController extends AbstractAdminController | |||||
abstract class TicketAdminController extends AbstractAdminController | |||||
{ | { | ||||
public static function getEntityFqcn(): string | |||||
public function getRepositoryQuery() :RepositoryQueryInterface | |||||
{ | { | ||||
return TicketInterface::class; | |||||
return $this->getTicketContainer()->getRepositoryQuery(); | |||||
} | } | ||||
public function createEntity(string $entityFqcn) | public function createEntity(string $entityFqcn) | ||||
->hideOnForm(), | ->hideOnForm(), | ||||
DateField::new('createdAt')->setFormat('short') | DateField::new('createdAt')->setFormat('short') | ||||
->hideOnForm(), | ->hideOnForm(), | ||||
TextField::new('visitorFirstName') | |||||
TextField::new('visitorFirstname') | |||||
->setTemplatePath('@LcSov/admin/ticket/field/firstname.html.twig') | ->setTemplatePath('@LcSov/admin/ticket/field/firstname.html.twig') | ||||
->hideOnForm(), | ->hideOnForm(), | ||||
TextField::new('visitorLastName') | |||||
TextField::new('visitorLastname') | |||||
->setTemplatePath('@LcSov/admin/ticket/field/lastname.html.twig') | ->setTemplatePath('@LcSov/admin/ticket/field/lastname.html.twig') | ||||
->hideOnForm(), | ->hideOnForm(), | ||||
TextField::new('visitorEmail') | TextField::new('visitorEmail') |
use Lc\SovBundle\Controller\AbstractAdminController; | use Lc\SovBundle\Controller\AbstractAdminController; | ||||
use Lc\SovBundle\Factory\User\GroupUserFactory; | use Lc\SovBundle\Factory\User\GroupUserFactory; | ||||
use Lc\SovBundle\Field\StatusField; | use Lc\SovBundle\Field\StatusField; | ||||
use Lc\SovBundle\Repository\RepositoryQueryInterface; | |||||
abstract class GroupUserAdminController extends AbstractAdminController | abstract class GroupUserAdminController extends AbstractAdminController | ||||
{ | { | ||||
public function getRepositoryQuery(): RepositoryQueryInterface | |||||
{ | |||||
return $this->get(GroupUserContainer::class)->getRepositoryQuery(); | |||||
} | |||||
public function configureFields(string $pageName): iterable | public function configureFields(string $pageName): iterable | ||||
{ | { |
use Doctrine\ORM\Decorator\EntityManagerDecorator; | use Doctrine\ORM\Decorator\EntityManagerDecorator; | ||||
use Doctrine\ORM\EntityManager as DoctrineEntityManager; | use Doctrine\ORM\EntityManager as DoctrineEntityManager; | ||||
use Doctrine\ORM\EntityManagerInterface; | use Doctrine\ORM\EntityManagerInterface; | ||||
use Knp\Component\Pager\PaginatorInterface; | |||||
use Lc\SovBundle\Event\EntityManager\EntityManagerEvent; | use Lc\SovBundle\Event\EntityManager\EntityManagerEvent; | ||||
use Lc\SovBundle\Repository\RepositoryQueryInterface; | |||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface; | use Symfony\Component\EventDispatcher\EventDispatcherInterface; | ||||
/** | /** |
namespace Lc\SovBundle\Field\Filter; | namespace Lc\SovBundle\Field\Filter; | ||||
use Doctrine\ORM\EntityRepository; | use Doctrine\ORM\EntityRepository; | ||||
use Doctrine\ORM\QueryBuilder; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | ||||
use Lc\SovBundle\Repository\RepositoryQueryInterface; | |||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType; | use Symfony\Bridge\Doctrine\Form\Type\EntityType; | ||||
use Symfony\Component\Form\FormBuilderInterface; | use Symfony\Component\Form\FormBuilderInterface; | ||||
{ | { | ||||
$targetEntity = $options['entity_dto']->getPropertyMetadata($fieldDto->getProperty())->get('targetEntity'); | $targetEntity = $options['entity_dto']->getPropertyMetadata($fieldDto->getProperty())->get('targetEntity'); | ||||
if($fieldDto->getCustomOption('choices')){ | |||||
$choices = $fieldDto->getCustomOption('choices'); | |||||
}else if($fieldDto->getFormTypeOption('choices') !=null){ | |||||
$choices = $fieldDto->getFormTypeOption('choices'); | |||||
}else{ | |||||
$choices = array(); | |||||
} | |||||
//todo utiliser choices plutot que query_builder voir ProductCategoriesFilter | //todo utiliser choices plutot que query_builder voir ProductCategoriesFilter | ||||
$builder->add( | $builder->add( | ||||
$fieldDto->getProperty(), | $fieldDto->getProperty(), | ||||
array( | array( | ||||
'class' => $targetEntity, | 'class' => $targetEntity, | ||||
'placeholder' => '--', | 'placeholder' => '--', | ||||
'query_builder' => function (EntityRepository $repo){ | |||||
return $repo->createQueryBuilder('entity'); | |||||
}, | |||||
'choices' => $choices, | |||||
'required' => false, | 'required' => false, | ||||
'attr' => array( | 'attr' => array( | ||||
'class' => 'select2 input-sm', | 'class' => 'select2 input-sm', | ||||
); | ); | ||||
} | } | ||||
public function applyFilter(QueryBuilder $queryBuilder, string $fieldProperty, $filteredValue = null) | |||||
public function applyFilter(RepositoryQueryInterface $repositoryQuery, string $fieldProperty, $filteredValue = null) | |||||
{ | { | ||||
if ($filteredValue !== null) { | if ($filteredValue !== null) { | ||||
$queryBuilder->andWhere('entity.'.$fieldProperty.' = :'.$fieldProperty.''); | |||||
$queryBuilder->setParameter($fieldProperty, $filteredValue); | |||||
$repositoryQuery->andWhere('.'.$fieldProperty.' = :'.$fieldProperty.''); | |||||
$repositoryQuery->setParameter($fieldProperty, $filteredValue); | |||||
/* //TODO Faut généraliser avec TreeInterface, ça ne doit pas être ici | /* //TODO Faut généraliser avec TreeInterface, ça ne doit pas être ici | ||||
if ($field['property'] == 'productCategories') { | |||||
$queryBuilder->andWhere(':' . $field['property'] . ' MEMBER OF entity.' . $field['property'] . ' OR product_categories.parent = :' . $field['property']); | |||||
$queryBuilder->setParameter($field['property'], $filter); | |||||
if ($field['type_options']['multiple']) { | if ($field['type_options']['multiple']) { | ||||
$queryBuilder->andWhere(':' . $field['property'] . ' MEMBER OF entity.' . $field['property'] . ''); | |||||
$repositoryQuery->andWhere(':' . $field['property'] . ' MEMBER OF entity.' . $field['property'] . ''); | |||||
} else { | } else { | ||||
} | } | ||||
if ($filter instanceof TreeInterface && $filter->getParent() == null) { | if ($filter instanceof TreeInterface && $filter->getParent() == null) { | ||||
$queryBuilder->setParameter($field['property'], array_merge(array($filter), $filter->getChildrens()->toArray())); | |||||
$repositoryQuery->setParameter($field['property'], array_merge(array($filter), $filter->getChildrens()->toArray())); | |||||
} else { | } else { | ||||
}*/ | }*/ | ||||
} | } |
namespace Lc\SovBundle\Field\Filter; | namespace Lc\SovBundle\Field\Filter; | ||||
use Doctrine\ORM\QueryBuilder; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | ||||
use Lc\SovBundle\Repository\RepositoryQueryInterface; | |||||
use Lc\SovBundle\Translation\TranslatorAdmin; | use Lc\SovBundle\Translation\TranslatorAdmin; | ||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | ||||
use Symfony\Component\Form\FormBuilderInterface; | use Symfony\Component\Form\FormBuilderInterface; | ||||
)); | )); | ||||
} | } | ||||
public function applyFilter(QueryBuilder $queryBuilder, string $fieldProperty, string $filteredValue= null) | |||||
public function applyFilter(RepositoryQueryInterface $repositoryQuery, string $fieldProperty, string $filteredValue= null) | |||||
{ | { | ||||
if ($filteredValue !== null) { | if ($filteredValue !== null) { | ||||
if ($this->isRelationField($fieldProperty)) { | if ($this->isRelationField($fieldProperty)) { | ||||
$aliasRelation = $this->getFieldPropertyRelationAlias($fieldProperty); | |||||
if (array_search($aliasRelation, $queryBuilder->getAllAliases()) === false) { | |||||
$queryBuilder->innerJoin('entity.'.$aliasRelation, $aliasRelation); | |||||
} | |||||
$queryBuilder->andWhere( | |||||
$fieldProperty.' = :'.$this->getFieldPropertySnake($fieldProperty).'' | |||||
); | |||||
$queryBuilder->setParameter( | |||||
$this->getFieldPropertySnake($fieldProperty), | |||||
$filteredValue | |||||
); | |||||
// $aliasRelation = $this->getFieldPropertyRelationAlias($fieldProperty); | |||||
// if (array_search($aliasRelation, $repositoryQuery->getAllAliases()) === false) { | |||||
// $repositoryQuery->innerJoin('entity.'.$aliasRelation, $aliasRelation); | |||||
// } | |||||
// $repositoryQuery->andWhere( | |||||
// $fieldProperty.' = :'.$this->getFieldPropertySnake($fieldProperty).'' | |||||
// ); | |||||
// $repositoryQuery->setParameter( | |||||
// $this->getFieldPropertySnake($fieldProperty), | |||||
// $filteredValue | |||||
// ); | |||||
} else { | } else { | ||||
$queryBuilder->andWhere( | |||||
'entity.'.$fieldProperty.' = :'.$fieldProperty.'' | |||||
$repositoryQuery->andWhere( | |||||
'.'.$fieldProperty.' = :'.$fieldProperty.'' | |||||
); | ); | ||||
$queryBuilder->setParameter($fieldProperty, $filteredValue); | |||||
$repositoryQuery->setParameter($fieldProperty, $filteredValue); | |||||
} | } | ||||
} | } |
namespace Lc\SovBundle\Field\Filter; | namespace Lc\SovBundle\Field\Filter; | ||||
use Doctrine\ORM\QueryBuilder; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | ||||
use Lc\SovBundle\Repository\RepositoryQueryInterface; | |||||
use Lc\SovBundle\Translation\TranslatorAdmin; | use Lc\SovBundle\Translation\TranslatorAdmin; | ||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | ||||
use Symfony\Component\Form\FormBuilderInterface; | use Symfony\Component\Form\FormBuilderInterface; | ||||
); | ); | ||||
} | } | ||||
public function applyFilter(QueryBuilder $queryBuilder, string $fieldProperty, string $filteredValue = null) | |||||
public function applyFilter(RepositoryQueryInterface $repositoryQuery , string $fieldProperty, string $filteredValue = null) | |||||
{ | { | ||||
if ($filteredValue !== null) { | if ($filteredValue !== null) { | ||||
if ($this->isRelationField($fieldProperty)) { | |||||
$aliasRelation = $this->getFieldPropertyRelationAlias($fieldProperty); | |||||
if (array_search($aliasRelation, $queryBuilder->getAllAliases()) === false) { | |||||
$queryBuilder->innerJoin('entity.'.$aliasRelation, $aliasRelation); | |||||
} | |||||
$queryBuilder->andWhere( | |||||
$fieldProperty.' LIKE :'.$this->getFieldPropertySnake($fieldProperty).'' | |||||
); | |||||
$queryBuilder->setParameter( | |||||
$this->getFieldPropertySnake($fieldProperty), | |||||
'%'.$filteredValue.'%' | |||||
// if ($this->isRelationField($fieldProperty)) { | |||||
// $aliasRelation = $this->getFieldPropertyRelationAlias($fieldProperty); | |||||
// if (array_search($aliasRelation, $repositoryQuery->getAllAliases()) === false) { | |||||
// $repositoryQuery->innerJoin('entity.'.$aliasRelation, $aliasRelation); | |||||
// } | |||||
// $repositoryQuery->andWhere( | |||||
// $fieldProperty.' LIKE :'.$this->getFieldPropertySnake($fieldProperty).'' | |||||
// ); | |||||
// $repositoryQuery->setParameter( | |||||
// $this->getFieldPropertySnake($fieldProperty), | |||||
// '%'.$filteredValue.'%' | |||||
// ); | |||||
// } else { | |||||
$repositoryQuery->andWhere( | |||||
'.'.$fieldProperty.' LIKE :'.$fieldProperty.'' | |||||
); | ); | ||||
} else { | |||||
$queryBuilder->andWhere( | |||||
'entity.'.$fieldProperty.' LIKE :'.$fieldProperty.'' | |||||
); | |||||
$queryBuilder->setParameter($fieldProperty, '%'.$filteredValue.'%'); | |||||
} | |||||
$repositoryQuery->setParameter($fieldProperty, '%'.$filteredValue.'%'); | |||||
} | } | ||||
} | } | ||||
namespace Lc\SovBundle\Field\Filter; | namespace Lc\SovBundle\Field\Filter; | ||||
use Doctrine\ORM\QueryBuilder; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | ||||
use Lc\SovBundle\Repository\RepositoryQueryInterface; | |||||
use Symfony\Component\Form\Extension\Core\Type\DateType; | use Symfony\Component\Form\Extension\Core\Type\DateType; | ||||
use Symfony\Component\Form\Extension\Core\Type\FormType; | use Symfony\Component\Form\Extension\Core\Type\FormType; | ||||
use Symfony\Component\Form\FormBuilderInterface; | use Symfony\Component\Form\FormBuilderInterface; | ||||
); | ); | ||||
} | } | ||||
public function applyFilter(QueryBuilder $queryBuilder, string $fieldProperty, \DateTime $dateStart = null, \DateTime $dateEnd = null) | |||||
public function applyFilter(RepositoryQueryInterface $repositoryQuery, string $fieldProperty, \DateTime $dateStart = null, \DateTime $dateEnd = null) | |||||
{ | { | ||||
if ($dateStart) { | if ($dateStart) { | ||||
$queryBuilder->andWhere( | |||||
'entity.' . $fieldProperty . ' >= :dateStart' | |||||
$repositoryQuery->andWhere( | |||||
'.' . $fieldProperty . ' >= :dateStart' | |||||
)->setParameter('dateStart', $dateStart); | )->setParameter('dateStart', $dateStart); | ||||
} | } | ||||
if ($dateEnd) { | if ($dateEnd) { | ||||
$dateEnd->setTime(23, 59, 59); | $dateEnd->setTime(23, 59, 59); | ||||
$queryBuilder->andWhere( | |||||
'entity.' . $fieldProperty . ' <= :dateEnd' | |||||
$repositoryQuery->andWhere( | |||||
'.' . $fieldProperty . ' <= :dateEnd' | |||||
)->setParameter('dateEnd', $dateEnd); | )->setParameter('dateEnd', $dateEnd); | ||||
} | } | ||||
} | } |
namespace Lc\SovBundle\Field\Filter; | namespace Lc\SovBundle\Field\Filter; | ||||
use Doctrine\ORM\EntityManagerInterface; | use Doctrine\ORM\EntityManagerInterface; | ||||
use Doctrine\ORM\QueryBuilder; | |||||
use DoctrineExtensions\Query\Mysql\Field; | use DoctrineExtensions\Query\Mysql\Field; | ||||
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; | use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; | ||||
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldInterface; | use EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldInterface; | ||||
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto; | use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto; | ||||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | ||||
use Lc\SovBundle\Repository\RepositoryQueryInterface; | |||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType; | use Symfony\Bridge\Doctrine\Form\Type\EntityType; | ||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType; | use Symfony\Component\Form\Extension\Core\Type\CheckboxType; | ||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | ||||
} | } | ||||
public function handleFiltersForm(QueryBuilder $queryBuilder, Form $filtersForm, $fields, EntityDto $entityDto) | |||||
public function handleFiltersForm(RepositoryQueryInterface $repositoryQuery, Form $filtersForm, $fields, EntityDto $entityDto) | |||||
{ | { | ||||
foreach ($fields as $field) { | foreach ($fields as $field) { | ||||
$fieldDto->getProperty() | $fieldDto->getProperty() | ||||
); | ); | ||||
} | } | ||||
$this->applyFilter($queryBuilder, $fieldDto, $filteredValue); | |||||
$this->applyFilter($repositoryQuery, $fieldDto, $filteredValue); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
return $property; | return $property; | ||||
} | } | ||||
public function applyFilter(QueryBuilder $queryBuilder, FieldDto $fieldDto, array $filteredValue) | |||||
public function applyFilter(RepositoryQueryInterface $repositoryQuery, FieldDto $fieldDto, array $filteredValue) | |||||
{ | { | ||||
if ($fieldDto->getCustomOption('filter_fqcn')) { | if ($fieldDto->getCustomOption('filter_fqcn')) { | ||||
$filterFqcn = $fieldDto->getCustomOption('filter_fqcn'); | $filterFqcn = $fieldDto->getCustomOption('filter_fqcn'); | ||||
$customFilter = new $filterFqcn; | $customFilter = new $filterFqcn; | ||||
$customFilter->applyFilter($queryBuilder, $this->getFieldProperty($fieldDto), $filteredValue['value']); | |||||
$customFilter->applyFilter($repositoryQuery, $this->getFieldProperty($fieldDto), $filteredValue['value']); | |||||
} else { | } else { | ||||
switch ($this->guessFormType($fieldDto)) { | switch ($this->guessFormType($fieldDto)) { | ||||
case CheckboxType::class: | case CheckboxType::class: | ||||
$checkboxFilter = new CheckboxFilter(); | $checkboxFilter = new CheckboxFilter(); | ||||
$checkboxFilter->applyFilter($queryBuilder, $this->getFieldProperty($fieldDto), $filteredValue['value']); | |||||
$checkboxFilter->applyFilter($repositoryQuery, $this->getFieldProperty($fieldDto), $filteredValue['value']); | |||||
break; | break; | ||||
case ChoiceType::class: | case ChoiceType::class: | ||||
$choiceFilter = new ChoiceFilter(); | $choiceFilter = new ChoiceFilter(); | ||||
$choiceFilter->applyFilter($queryBuilder, $this->getFieldProperty($fieldDto), $filteredValue['value']); | |||||
$choiceFilter->applyFilter($repositoryQuery, $this->getFieldProperty($fieldDto), $filteredValue['value']); | |||||
break; | break; | ||||
case IntegerType::class: | case IntegerType::class: | ||||
$integerFilter = new IntegerFilter(); | $integerFilter = new IntegerFilter(); | ||||
$integerFilter->applyFilter($queryBuilder, $this->getFieldProperty($fieldDto), $filteredValue['value']); | |||||
$integerFilter->applyFilter($repositoryQuery, $this->getFieldProperty($fieldDto), $filteredValue['value']); | |||||
break; | break; | ||||
case TextareaType::class: | case TextareaType::class: | ||||
case TextType::class: | case TextType::class: | ||||
$textFilter = new TextFilter(); | $textFilter = new TextFilter(); | ||||
$textFilter->applyFilter($queryBuilder, $this->getFieldProperty($fieldDto), $filteredValue['value']); | |||||
$textFilter->applyFilter($repositoryQuery, $this->getFieldProperty($fieldDto), $filteredValue['value']); | |||||
break; | break; | ||||
case EntityType::class: | case EntityType::class: | ||||
$textFilter = new AssociationFilter(); | $textFilter = new AssociationFilter(); | ||||
$textFilter->applyFilter($queryBuilder, $this->getFieldProperty($fieldDto), $filteredValue['value']); | |||||
$textFilter->applyFilter($repositoryQuery, $this->getFieldProperty($fieldDto), $filteredValue['value']); | |||||
break; | break; | ||||
case DateTimeType::class: | case DateTimeType::class: | ||||
case DateType::class: | case DateType::class: | ||||
$textFilter = new DateFilter(); | $textFilter = new DateFilter(); | ||||
$textFilter->applyFilter( | $textFilter->applyFilter( | ||||
$queryBuilder, | |||||
$repositoryQuery, | |||||
$this->getFieldProperty($fieldDto), | $this->getFieldProperty($fieldDto), | ||||
$filteredValue['dateStart'], | $filteredValue['dateStart'], | ||||
$filteredValue['dateEnd'] | $filteredValue['dateEnd'] |
namespace Lc\SovBundle\Field\Filter; | namespace Lc\SovBundle\Field\Filter; | ||||
use Doctrine\ORM\QueryBuilder; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | ||||
use Lc\SovBundle\Repository\RepositoryQueryInterface; | |||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | ||||
use Symfony\Component\Form\FormBuilderInterface; | use Symfony\Component\Form\FormBuilderInterface; | ||||
} | } | ||||
public function applyFilter(QueryBuilder $queryBuilder, string $fieldProperty, $filteredValue = null) | |||||
public function applyFilter(RepositoryQueryInterface $repositoryQuery, string $fieldProperty, $filteredValue = null) | |||||
{ | { | ||||
if ($filteredValue !== null) { | if ($filteredValue !== null) { | ||||
if($filteredValue === 1){ | if($filteredValue === 1){ | ||||
$queryBuilder->andWhere( | |||||
'entity.' . $fieldProperty . ' IS NOT NULL' | |||||
$repositoryQuery->andWhere( | |||||
'.' . $fieldProperty . ' IS NOT NULL' | |||||
); | ); | ||||
}else{ | }else{ | ||||
$queryBuilder->andWhere( | |||||
'entity.' . $fieldProperty . ' IS NULL' | |||||
$repositoryQuery->andWhere( | |||||
'.' . $fieldProperty . ' IS NULL' | |||||
); | ); | ||||
} | } | ||||
namespace Lc\SovBundle\Field\Filter; | namespace Lc\SovBundle\Field\Filter; | ||||
use Doctrine\ORM\QueryBuilder; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | ||||
use Lc\SovBundle\Repository\RepositoryQueryInterface; | |||||
use Symfony\Component\Form\Extension\Core\Type\IntegerType; | use Symfony\Component\Form\Extension\Core\Type\IntegerType; | ||||
use Symfony\Component\Form\FormBuilderInterface; | use Symfony\Component\Form\FormBuilderInterface; | ||||
); | ); | ||||
} | } | ||||
public function applyFilter(QueryBuilder $queryBuilder, string $fieldProperty, string $filteredValue= null) | |||||
public function applyFilter(RepositoryQueryInterface $repositoryQuery, string $fieldProperty, string $filteredValue= null) | |||||
{ | { | ||||
if ($filteredValue !== null) { | if ($filteredValue !== null) { | ||||
$queryBuilder->andWhere( | |||||
'entity.'.$fieldProperty.' = :'.$fieldProperty.'' | |||||
$repositoryQuery->andWhere( | |||||
'.'.$fieldProperty.' = :'.$fieldProperty.'' | |||||
); | ); | ||||
$queryBuilder->setParameter($fieldProperty, $filteredValue); | |||||
$repositoryQuery->setParameter($fieldProperty, $filteredValue); | |||||
} | } | ||||
} | } | ||||
namespace Lc\SovBundle\Field\Filter; | namespace Lc\SovBundle\Field\Filter; | ||||
use Doctrine\ORM\QueryBuilder; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto; | ||||
use Lc\SovBundle\Repository\RepositoryQueryInterface; | |||||
use Symfony\Component\Form\Extension\Core\Type\TextType; | use Symfony\Component\Form\Extension\Core\Type\TextType; | ||||
use Symfony\Component\Form\FormBuilderInterface; | use Symfony\Component\Form\FormBuilderInterface; | ||||
); | ); | ||||
} | } | ||||
public function applyFilter(QueryBuilder $queryBuilder, string $fieldProperty, string $filteredValue = null) | |||||
public function applyFilter(RepositoryQueryInterface $repositoryQuery, string $fieldProperty, string $filteredValue = null) | |||||
{ | { | ||||
if ($filteredValue !== null) { | if ($filteredValue !== null) { | ||||
if ($this->isRelationField($fieldProperty)) { | |||||
$aliasRelation = $this->getFieldPropertyRelationAlias($fieldProperty); | |||||
if (array_search($aliasRelation, $queryBuilder->getAllAliases()) === false) { | |||||
$queryBuilder->innerJoin('entity.' . $aliasRelation, $aliasRelation); | |||||
} | |||||
$queryBuilder->andWhere( | |||||
$fieldProperty . ' LIKE :' . $this->getFieldPropertySnake($fieldProperty) . '' | |||||
); | |||||
$queryBuilder->setParameter( | |||||
$this->getFieldPropertySnake($fieldProperty), | |||||
'%' . $filteredValue . '%' | |||||
// if ($this->isRelationField($fieldProperty)) { | |||||
// | |||||
// $aliasRelation = $this->getFieldPropertyRelationAlias($fieldProperty); | |||||
// if (array_search($aliasRelation, $repositoryQuery->getAllAliases()) === false) { | |||||
// $repositoryQuery->innerJoin('entity.' . $aliasRelation, $aliasRelation); | |||||
// } | |||||
// $repositoryQuery->andWhere( | |||||
// $fieldProperty . ' LIKE :' . $this->getFieldPropertySnake($fieldProperty) . '' | |||||
// ); | |||||
// $repositoryQuery->setParameter( | |||||
// $this->getFieldPropertySnake($fieldProperty), | |||||
// '%' . $filteredValue . '%' | |||||
// ); | |||||
// } else { | |||||
$repositoryQuery->andWhere( | |||||
'.' . $fieldProperty . ' LIKE :' . $fieldProperty . '' | |||||
); | ); | ||||
} else { | |||||
$queryBuilder->andWhere( | |||||
'entity.' . $fieldProperty . ' LIKE :' . $fieldProperty . '' | |||||
); | |||||
$queryBuilder->setParameter($fieldProperty, '%' . $filteredValue . '%'); | |||||
} | |||||
$repositoryQuery->setParameter($fieldProperty, '%' . $filteredValue . '%'); | |||||
} | } | ||||
} | } | ||||
use Symfony\Component\OptionsResolver\Options; | use Symfony\Component\OptionsResolver\Options; | ||||
use Symfony\Component\OptionsResolver\OptionsResolver; | use Symfony\Component\OptionsResolver\OptionsResolver; | ||||
/** | |||||
* Custom form type that deals with some of the logic used to render the | |||||
* forms used to create and edit EasyAdmin entities. | |||||
* | |||||
* @author Maxime Steinhausser <maxime.steinhausser@gmail.com> | |||||
*/ | |||||
class CrudFormType extends AbstractType | class CrudFormType extends AbstractType | ||||
{ | { | ||||
abstract class TicketModel extends AbstractLightEntity implements TicketInterface, EntityInterface | abstract class TicketModel extends AbstractLightEntity implements TicketInterface, EntityInterface | ||||
{ | { | ||||
const TYPE_TECHNICAL_PROBLEM = 'technical-problem'; | const TYPE_TECHNICAL_PROBLEM = 'technical-problem'; | ||||
const TYPE_GENERAL_QUESTION = 'general-question'; | const TYPE_GENERAL_QUESTION = 'general-question'; | ||||
return $this->repository; | return $this->repository; | ||||
} | } | ||||
public function getQueryBuilder(): QueryBuilder | |||||
{ | |||||
return $this->query; | |||||
} | |||||
protected function populateDqlId(&$data) | protected function populateDqlId(&$data) | ||||
{ | { | ||||
if (is_string($data)) { | if (is_string($data)) { |
<?php | |||||
namespace Lc\SovBundle\Repository; | |||||
use Doctrine\ORM\EntityManagerInterface; | |||||
use Doctrine\ORM\QueryBuilder; | |||||
use Doctrine\Persistence\ManagerRegistry; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Collection\FieldCollection; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Collection\FilterCollection; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Orm\EntityRepositoryInterface; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Dto\FilterDataDto; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Factory\EntityFactory; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Factory\FormFactory; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Form\Type\ComparisonType; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Provider\AdminContextProvider; | |||||
use EasyCorp\Bundle\EasyAdminBundle\Orm\EntityRepository as EaEntityRepository; | |||||
use Knp\Component\Pager\PaginatorInterface; | |||||
use function Symfony\Component\Translation\t; | |||||
class EntityRepository | |||||
{ | |||||
//protected EaEntityRepository $parent; | |||||
protected EntityManagerInterface $entityManager; | |||||
protected PaginatorInterface $paginator; | |||||
public function __construct( | |||||
//EaEntityRepository $entityRepository, | |||||
EntityManagerInterface $entityManager, | |||||
PaginatorInterface $paginator | |||||
) { | |||||
//$this->parent = $entityRepository; | |||||
$this->entityManager = $entityManager; | |||||
$this->paginator = $paginator; | |||||
} | |||||
public function createRepositoryQuery(RepositoryQueryInterface $repositoryQuery,SearchDto $searchDto, EntityDto $entityDto, FieldCollection $fields, FilterCollection $filters) | |||||
{ | |||||
// if (!empty($searchDto->getQuery())) { | |||||
// $this->addSearchClause($repositoryQuery->getQuery(), $searchDto, $entityDto); | |||||
// } | |||||
// | |||||
// if (!empty($searchDto->getAppliedFilters())) { | |||||
// $this->addFilterClause($repositoryQuery->getQuery(), $searchDto, $entityDto, $filters, $fields); | |||||
// } | |||||
$this->addOrderClause($repositoryQuery, $searchDto, $entityDto); | |||||
return $repositoryQuery; | |||||
} | |||||
private function addSearchClause(QueryBuilder $queryBuilder, SearchDto $searchDto, EntityDto $entityDto): void | |||||
{ | |||||
$query = $searchDto->getQuery(); | |||||
$lowercaseQuery = mb_strtolower($query); | |||||
$isNumericQuery = is_numeric($query); | |||||
$isSmallIntegerQuery = ctype_digit($query) && $query >= -32768 && $query <= 32767; | |||||
$isIntegerQuery = ctype_digit($query) && $query >= -2147483648 && $query <= 2147483647; | |||||
$isUuidQuery = 1 === preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i', $query); | |||||
$dqlParameters = [ | |||||
// adding '0' turns the string into a numeric value | |||||
'numeric_query' => is_numeric($query) ? 0 + $query : $query, | |||||
'uuid_query' => $query, | |||||
'text_query' => '%'.$lowercaseQuery.'%', | |||||
'words_query' => explode(' ', $lowercaseQuery), | |||||
]; | |||||
$entitiesAlreadyJoined = []; | |||||
$configuredSearchableProperties = $searchDto->getSearchableProperties(); | |||||
$searchableProperties = empty($configuredSearchableProperties) ? $entityDto->getAllPropertyNames() : $configuredSearchableProperties; | |||||
foreach ($searchableProperties as $propertyName) { | |||||
if ($entityDto->isAssociation($propertyName)) { | |||||
// support arbitrarily nested associations (e.g. foo.bar.baz.qux) | |||||
$associatedProperties = explode('.', $propertyName); | |||||
$numAssociatedProperties = \count($associatedProperties); | |||||
if (1 === $numAssociatedProperties) { | |||||
throw new \InvalidArgumentException(sprintf('The "%s" property included in the setSearchFields() method is not a valid search field. When using associated properties in search, you must also define the exact field used in the search (e.g. \'%s.id\', \'%s.name\', etc.)', $propertyName, $propertyName, $propertyName)); | |||||
} | |||||
$originalPropertyName = $associatedProperties[0]; | |||||
$originalPropertyMetadata = $entityDto->getPropertyMetadata($originalPropertyName); | |||||
$associatedEntityDto = $this->entityFactory->create($originalPropertyMetadata->get('targetEntity')); | |||||
for ($i = 0; $i < $numAssociatedProperties - 1; ++$i) { | |||||
$associatedEntityName = $associatedProperties[$i]; | |||||
$associatedPropertyName = $associatedProperties[$i + 1]; | |||||
if (!\in_array($associatedEntityName, $entitiesAlreadyJoined, true)) { | |||||
$parentEntityName = 0 === $i ? 'entity' : $associatedProperties[$i - 1]; | |||||
$queryBuilder->leftJoin($parentEntityName.'.'.$associatedEntityName, $associatedEntityName); | |||||
$entitiesAlreadyJoined[] = $associatedEntityName; | |||||
} | |||||
if ($i < $numAssociatedProperties - 2) { | |||||
$propertyMetadata = $associatedEntityDto->getPropertyMetadata($associatedPropertyName); | |||||
$targetEntity = $propertyMetadata->get('targetEntity'); | |||||
$associatedEntityDto = $this->entityFactory->create($targetEntity); | |||||
} | |||||
} | |||||
$entityName = $associatedEntityName; | |||||
$propertyName = $associatedPropertyName; | |||||
$propertyDataType = $associatedEntityDto->getPropertyDataType($propertyName); | |||||
} else { | |||||
$entityName = 'entity'; | |||||
$propertyDataType = $entityDto->getPropertyDataType($propertyName); | |||||
} | |||||
$isSmallIntegerProperty = 'smallint' === $propertyDataType; | |||||
$isIntegerProperty = 'integer' === $propertyDataType; | |||||
$isNumericProperty = \in_array($propertyDataType, ['number', 'bigint', 'decimal', 'float']); | |||||
// 'citext' is a PostgreSQL extension (https://github.com/EasyCorp/EasyAdminBundle/issues/2556) | |||||
$isTextProperty = \in_array($propertyDataType, ['string', 'text', 'citext', 'array', 'simple_array']); | |||||
$isGuidProperty = \in_array($propertyDataType, ['guid', 'uuid']); | |||||
// this complex condition is needed to avoid issues on PostgreSQL databases | |||||
if ( | |||||
($isSmallIntegerProperty && $isSmallIntegerQuery) || | |||||
($isIntegerProperty && $isIntegerQuery) || | |||||
($isNumericProperty && $isNumericQuery) | |||||
) { | |||||
$queryBuilder->orWhere(sprintf('%s.%s = :query_for_numbers', $entityName, $propertyName)) | |||||
->setParameter('query_for_numbers', $dqlParameters['numeric_query']); | |||||
} elseif ($isGuidProperty && $isUuidQuery) { | |||||
$queryBuilder->orWhere(sprintf('%s.%s = :query_for_uuids', $entityName, $propertyName)) | |||||
->setParameter('query_for_uuids', $dqlParameters['uuid_query']); | |||||
} elseif ($isTextProperty) { | |||||
$queryBuilder->orWhere(sprintf('LOWER(%s.%s) LIKE :query_for_text', $entityName, $propertyName)) | |||||
->setParameter('query_for_text', $dqlParameters['text_query']); | |||||
$queryBuilder->orWhere(sprintf('LOWER(%s.%s) IN (:query_as_words)', $entityName, $propertyName)) | |||||
->setParameter('query_as_words', $dqlParameters['words_query']); | |||||
} | |||||
} | |||||
} | |||||
private function addOrderClause(RepositoryQueryInterface $repositoryQuery, SearchDto $searchDto, EntityDto $entityDto): void | |||||
{ | |||||
foreach ($searchDto->getSort() as $sortProperty => $sortOrder) { | |||||
$repositoryQuery->addOrderBy('.'.$sortProperty, $sortOrder); | |||||
// $aliases = $queryBuilder->getAllAliases(); | |||||
// $sortFieldIsDoctrineAssociation = $entityDto->isAssociation($sortProperty); | |||||
// | |||||
// if ($sortFieldIsDoctrineAssociation) { | |||||
// $sortFieldParts = explode('.', $sortProperty, 2); | |||||
// // check if join has been added once before. | |||||
// if (!\in_array($sortFieldParts[0], $aliases)) { | |||||
// $queryBuilder->leftJoin('entity.'.$sortFieldParts[0], $sortFieldParts[0]); | |||||
// } | |||||
// | |||||
// if (1 === \count($sortFieldParts)) { | |||||
// $queryBuilder->addOrderBy('entity.'.$sortProperty, $sortOrder); | |||||
// } else { | |||||
// $queryBuilder->addOrderBy($sortProperty, $sortOrder); | |||||
// } | |||||
// } else { | |||||
// $queryBuilder->addOrderBy('entity.'.$sortProperty, $sortOrder); | |||||
// } | |||||
} | |||||
} | |||||
private function addFilterClause(QueryBuilder $queryBuilder, SearchDto $searchDto, EntityDto $entityDto, FilterCollection $configuredFilters, FieldCollection $fields): void | |||||
{ | |||||
$filtersForm = $this->formFactory->createFiltersForm($configuredFilters, $this->adminContextProvider->getContext()->getRequest()); | |||||
if (!$filtersForm->isSubmitted()) { | |||||
return; | |||||
} | |||||
$appliedFilters = $searchDto->getAppliedFilters(); | |||||
$i = 0; | |||||
foreach ($filtersForm as $filterForm) { | |||||
$propertyName = $filterForm->getName(); | |||||
$filter = $configuredFilters->get($propertyName); | |||||
// this filter is not defined or not applied | |||||
if (null === $filter || !isset($appliedFilters[$propertyName])) { | |||||
continue; | |||||
} | |||||
// if the form filter is not valid then we should not apply the filter | |||||
if (!$filterForm->isValid()) { | |||||
continue; | |||||
} | |||||
$submittedData = $filterForm->getData(); | |||||
if (!\is_array($submittedData)) { | |||||
$submittedData = [ | |||||
'comparison' => ComparisonType::EQ, | |||||
'value' => $submittedData, | |||||
]; | |||||
} | |||||
$filterDataDto = FilterDataDto::new($i, $filter, current($queryBuilder->getRootAliases()), $submittedData); | |||||
$filter->apply($queryBuilder, $filterDataDto, $fields->getByProperty($propertyName), $entityDto); | |||||
++$i; | |||||
} | |||||
} | |||||
} |
decorates: EasyCorp\Bundle\EasyAdminBundle\Form\Type\CrudFormType | decorates: EasyCorp\Bundle\EasyAdminBundle\Form\Type\CrudFormType | ||||
arguments: [ '@form.type_guesser.doctrine', '@.inner' ] | arguments: [ '@form.type_guesser.doctrine', '@.inner' ] | ||||
Lc\SovBundle\Doctrine\EntityManager: | Lc\SovBundle\Doctrine\EntityManager: | ||||
public: false | public: false | ||||
decoration_priority: 1 | |||||
decorates: doctrine.orm.default_entity_manager | decorates: doctrine.orm.default_entity_manager | ||||
arguments: ["@.inner"] | |||||
arguments: [ "@.inner" ] | |||||
# Lc\SovBundle\Repository\EntityRepository: | |||||
# decorates: EasyCorp\Bundle\EasyAdminBundle\Orm\EntityRepository | |||||
# decoration_priority: 5 | |||||
# arguments: [ "@.inner", '@doctrine.orm.default_entity_manager', '@Knp\Component\Pager\PaginatorInterface' ] | |||||
Lc\SovBundle\Maker\: | Lc\SovBundle\Maker\: | ||||
resource: '../../Maker/' | resource: '../../Maker/' |