From 889ed63bc5ab6385d2aabcae1165621017178d4e Mon Sep 17 00:00:00 2001 From: lubiana Date: Sat, 25 Jan 2025 02:27:11 +0100 Subject: [PATCH 1/4] sort and filter menuitems in aliasof select --- src/Form/MenuItemType.php | 45 ++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/src/Form/MenuItemType.php b/src/Form/MenuItemType.php index 96a6020..597d590 100644 --- a/src/Form/MenuItemType.php +++ b/src/Form/MenuItemType.php @@ -14,24 +14,43 @@ use Symfony\Component\OptionsResolver\OptionsResolver; final class MenuItemType extends AbstractType { - #[Override] public function buildForm(FormBuilderInterface $builder, array $options): void { - $vendor = $options['data']->getFoodVendor(); - $vendorId = $vendor->getId(); - $builder - ->add('name') - ->add('aliasOf', EntityType::class, [ + $item = $options['data']; + assert($item instanceof MenuItem); // Ensure it's of the correct type + $vendorId = $item->getFoodVendor()?->getId(); // Use safe navigation operator in case FoodVendor is null + + $builder->add('name'); // Basic field + $builder->add('aliases', EntityType::class, [ 'class' => MenuItem::class, 'choice_label' => 'name', - 'query_builder' => static fn(MenuItemRepository $repository): QueryBuilder => $repository - ->createQueryBuilder('m') - ->where('m.foodVendor = :vendorId') - ->setParameter(':vendorId', $vendorId, UlidType::NAME), - ]) - ; - } + 'multiple' => true, + 'expanded' => true, + 'query_builder' => static function (MenuItemRepository $repository) use ($item, $vendorId): QueryBuilder { + $qb = $repository->createQueryBuilder('m'); + // Build the main query with a NOT EXISTS constraint + $qb + ->where('m.foodVendor = :vendorId') + ->andWhere('m.deletedAt IS NULL') + ->andWhere('m.id != :id') + ->andWhere( + $qb->expr()->notIn('m.id', + $repository->createQueryBuilder('m2') + ->select('m2.id') + ->where('m2.aliasOf != m.id') // Reference m.id in the inner query + ->orWhere('m2.aliasOf IS NOT NULL') + ->getDQL() // The subquery's DQL string + ) + ) + ->orderBy('m.name', 'ASC') + ->setParameter('vendorId', $vendorId, UlidType::NAME) // ULID or appropriate type + ->setParameter('id', $item->getId(), UlidType::NAME); // ULID or appropriate type + + return $qb; + }, + ]); + } #[Override] public function configureOptions(OptionsResolver $resolver): void { From 3a144c5db3d85563b1b15ee14aee96d92b9be02e Mon Sep 17 00:00:00 2001 From: lubiana Date: Sat, 25 Jan 2025 03:17:07 +0100 Subject: [PATCH 2/4] fix --- src/Form/MenuItemType.php | 58 +++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/src/Form/MenuItemType.php b/src/Form/MenuItemType.php index 597d590..4d19aab 100644 --- a/src/Form/MenuItemType.php +++ b/src/Form/MenuItemType.php @@ -12,8 +12,11 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +use function assert; + final class MenuItemType extends AbstractType { + #[Override] public function buildForm(FormBuilderInterface $builder, array $options): void { $item = $options['data']; @@ -22,35 +25,38 @@ final class MenuItemType extends AbstractType $builder->add('name'); // Basic field $builder->add('aliases', EntityType::class, [ - 'class' => MenuItem::class, - 'choice_label' => 'name', - 'multiple' => true, - 'expanded' => true, - 'query_builder' => static function (MenuItemRepository $repository) use ($item, $vendorId): QueryBuilder { - $qb = $repository->createQueryBuilder('m'); + 'class' => MenuItem::class, + 'choice_label' => 'name', + 'multiple' => true, + 'expanded' => true, + 'query_builder' => static function (MenuItemRepository $repository) use ($item, $vendorId): QueryBuilder { + $qb = $repository->createQueryBuilder('m'); - // Build the main query with a NOT EXISTS constraint - $qb - ->where('m.foodVendor = :vendorId') - ->andWhere('m.deletedAt IS NULL') - ->andWhere('m.id != :id') - ->andWhere( - $qb->expr()->notIn('m.id', - $repository->createQueryBuilder('m2') - ->select('m2.id') - ->where('m2.aliasOf != m.id') // Reference m.id in the inner query - ->orWhere('m2.aliasOf IS NOT NULL') - ->getDQL() // The subquery's DQL string - ) - ) - ->orderBy('m.name', 'ASC') - ->setParameter('vendorId', $vendorId, UlidType::NAME) // ULID or appropriate type - ->setParameter('id', $item->getId(), UlidType::NAME); // ULID or appropriate type + // Build the main query with a NOT EXISTS constraint + $qb + ->where('m.foodVendor = :vendorId') + ->andWhere('m.deletedAt IS NULL') + ->andWhere('m.id != :id') + ->andWhere( + $qb->expr() + ->notIn( + 'm.id', + $repository->createQueryBuilder('m2') + ->select('m2.id') + ->where('m2.aliasOf != m.id') // Reference m.id in the inner query + ->orWhere('m2.aliasOf IS NOT NULL') + ->getDQL() // The subquery's DQL string + ) + ) + ->orderBy('m.name', 'ASC') + ->setParameter('vendorId', $vendorId, UlidType::NAME) // ULID or appropriate type + ->setParameter('id', $item->getId(), UlidType::NAME); // ULID or appropriate type - return $qb; - }, - ]); + return $qb; + }, + ]); } + #[Override] public function configureOptions(OptionsResolver $resolver): void { From 7b95ed44eeddeddc4809d8bf8b0de1b5f8de8eef Mon Sep 17 00:00:00 2001 From: lubiana Date: Sat, 25 Jan 2025 02:27:11 +0100 Subject: [PATCH 3/4] sort and filter menuitems in aliasof select --- src/Form/MenuItemType.php | 58 ++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/src/Form/MenuItemType.php b/src/Form/MenuItemType.php index 4d19aab..597d590 100644 --- a/src/Form/MenuItemType.php +++ b/src/Form/MenuItemType.php @@ -12,11 +12,8 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; -use function assert; - final class MenuItemType extends AbstractType { - #[Override] public function buildForm(FormBuilderInterface $builder, array $options): void { $item = $options['data']; @@ -25,38 +22,35 @@ final class MenuItemType extends AbstractType $builder->add('name'); // Basic field $builder->add('aliases', EntityType::class, [ - 'class' => MenuItem::class, - 'choice_label' => 'name', - 'multiple' => true, - 'expanded' => true, - 'query_builder' => static function (MenuItemRepository $repository) use ($item, $vendorId): QueryBuilder { - $qb = $repository->createQueryBuilder('m'); + 'class' => MenuItem::class, + 'choice_label' => 'name', + 'multiple' => true, + 'expanded' => true, + 'query_builder' => static function (MenuItemRepository $repository) use ($item, $vendorId): QueryBuilder { + $qb = $repository->createQueryBuilder('m'); - // Build the main query with a NOT EXISTS constraint - $qb - ->where('m.foodVendor = :vendorId') - ->andWhere('m.deletedAt IS NULL') - ->andWhere('m.id != :id') - ->andWhere( - $qb->expr() - ->notIn( - 'm.id', - $repository->createQueryBuilder('m2') - ->select('m2.id') - ->where('m2.aliasOf != m.id') // Reference m.id in the inner query - ->orWhere('m2.aliasOf IS NOT NULL') - ->getDQL() // The subquery's DQL string - ) - ) - ->orderBy('m.name', 'ASC') - ->setParameter('vendorId', $vendorId, UlidType::NAME) // ULID or appropriate type - ->setParameter('id', $item->getId(), UlidType::NAME); // ULID or appropriate type + // Build the main query with a NOT EXISTS constraint + $qb + ->where('m.foodVendor = :vendorId') + ->andWhere('m.deletedAt IS NULL') + ->andWhere('m.id != :id') + ->andWhere( + $qb->expr()->notIn('m.id', + $repository->createQueryBuilder('m2') + ->select('m2.id') + ->where('m2.aliasOf != m.id') // Reference m.id in the inner query + ->orWhere('m2.aliasOf IS NOT NULL') + ->getDQL() // The subquery's DQL string + ) + ) + ->orderBy('m.name', 'ASC') + ->setParameter('vendorId', $vendorId, UlidType::NAME) // ULID or appropriate type + ->setParameter('id', $item->getId(), UlidType::NAME); // ULID or appropriate type - return $qb; - }, - ]); + return $qb; + }, + ]); } - #[Override] public function configureOptions(OptionsResolver $resolver): void { From b0f945f275322c298487bae4bf185d993dc22d92 Mon Sep 17 00:00:00 2001 From: lubiana Date: Sat, 25 Jan 2025 03:17:07 +0100 Subject: [PATCH 4/4] fix --- src/Form/MenuItemType.php | 58 +++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/src/Form/MenuItemType.php b/src/Form/MenuItemType.php index 597d590..4d19aab 100644 --- a/src/Form/MenuItemType.php +++ b/src/Form/MenuItemType.php @@ -12,8 +12,11 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; +use function assert; + final class MenuItemType extends AbstractType { + #[Override] public function buildForm(FormBuilderInterface $builder, array $options): void { $item = $options['data']; @@ -22,35 +25,38 @@ final class MenuItemType extends AbstractType $builder->add('name'); // Basic field $builder->add('aliases', EntityType::class, [ - 'class' => MenuItem::class, - 'choice_label' => 'name', - 'multiple' => true, - 'expanded' => true, - 'query_builder' => static function (MenuItemRepository $repository) use ($item, $vendorId): QueryBuilder { - $qb = $repository->createQueryBuilder('m'); + 'class' => MenuItem::class, + 'choice_label' => 'name', + 'multiple' => true, + 'expanded' => true, + 'query_builder' => static function (MenuItemRepository $repository) use ($item, $vendorId): QueryBuilder { + $qb = $repository->createQueryBuilder('m'); - // Build the main query with a NOT EXISTS constraint - $qb - ->where('m.foodVendor = :vendorId') - ->andWhere('m.deletedAt IS NULL') - ->andWhere('m.id != :id') - ->andWhere( - $qb->expr()->notIn('m.id', - $repository->createQueryBuilder('m2') - ->select('m2.id') - ->where('m2.aliasOf != m.id') // Reference m.id in the inner query - ->orWhere('m2.aliasOf IS NOT NULL') - ->getDQL() // The subquery's DQL string - ) - ) - ->orderBy('m.name', 'ASC') - ->setParameter('vendorId', $vendorId, UlidType::NAME) // ULID or appropriate type - ->setParameter('id', $item->getId(), UlidType::NAME); // ULID or appropriate type + // Build the main query with a NOT EXISTS constraint + $qb + ->where('m.foodVendor = :vendorId') + ->andWhere('m.deletedAt IS NULL') + ->andWhere('m.id != :id') + ->andWhere( + $qb->expr() + ->notIn( + 'm.id', + $repository->createQueryBuilder('m2') + ->select('m2.id') + ->where('m2.aliasOf != m.id') // Reference m.id in the inner query + ->orWhere('m2.aliasOf IS NOT NULL') + ->getDQL() // The subquery's DQL string + ) + ) + ->orderBy('m.name', 'ASC') + ->setParameter('vendorId', $vendorId, UlidType::NAME) // ULID or appropriate type + ->setParameter('id', $item->getId(), UlidType::NAME); // ULID or appropriate type - return $qb; - }, - ]); + return $qb; + }, + ]); } + #[Override] public function configureOptions(OptionsResolver $resolver): void {