diff --git a/app/config/service/form.yml b/app/config/service/form.yml index 8dcc806..5693b10 100644 --- a/app/config/service/form.yml +++ b/app/config/service/form.yml @@ -1,7 +1,20 @@ services: form.filter.category: - class: AppBundle\Form\Filter\CategoryFilterType + class: AppBundle\Form\Filter\Model\CategoryFilterType arguments: - '@manager.ldraw.category' tags: - - { name: form.type } \ No newline at end of file + - { name: form.type } + + form.filter.brickset: + class: AppBundle\Form\FilterSetType + arguments: ['@api.manager.brickset'] + tags: + - { name: form.type } + + form.filter.theme: + class: AppBundle\Form\Filter\Set\ThemeFilterType + arguments: + - '@local.manager.rebrickable' + tags: + - { name: form.type } diff --git a/app/config/service/manager.yml b/app/config/service/manager.yml index e1a56f1..152fe18 100644 --- a/app/config/service/manager.yml +++ b/app/config/service/manager.yml @@ -1,4 +1,14 @@ services: + local.manager.base: + abstract: true + class: AppBundle\Manager\BaseManager + calls: + - [setEntityManager, ['@doctrine.orm.entity_manager']] + + local.manager.rebrickable: + class: AppBundle\Manager\RebrickableManager + parent: local.manager.base + manager.ldraw.keyword: class: AppBundle\Manager\LDraw\KeywordManager arguments: @@ -20,5 +30,3 @@ services: arguments: - "@repository.ldraw.alias" - - diff --git a/app/config/service/service.yml b/app/config/service/service.yml index 8c294b5..e33fd1b 100644 --- a/app/config/service/service.yml +++ b/app/config/service/service.yml @@ -8,12 +8,6 @@ services: - '@manager.ldraw.model' - '@manager.ldraw.alias' - app.form.filter_set: - class: AppBundle\Form\FilterSetType - arguments: ['@api.manager.brickset'] - tags: - - { name: form.type } - app.twig_extension: class: AppBundle\Twig\AppExtension public: false diff --git a/src/AppBundle/Controller/Brickset/SetController.php b/src/AppBundle/Controller/Brickset/SetController.php index 294a0b9..96658d3 100644 --- a/src/AppBundle/Controller/Brickset/SetController.php +++ b/src/AppBundle/Controller/Brickset/SetController.php @@ -31,11 +31,17 @@ class SetController extends Controller if ($form->isSubmitted() && $form->isValid()) { $data = $form->getData(); - $sets = $this->get('api.client.brickset')->getSets([ - 'theme' => $data['theme'] ? $data['theme']->getTheme() : '', - 'subtheme' => $data['subtheme'] ? $data['subtheme']->getSubtheme() : '', - 'year' => $data['years'] ? $data['years']->getYear() : '', - ]); + try { + $sets = $this->get('api.client.brickset')->getSets([ + 'theme' => $data['theme'] ? $data['theme']->getTheme() : '', + 'subtheme' => $data['subtheme'] ? $data['subtheme']->getSubtheme() : '', + 'year' => $data['years'] ? $data['years']->getYear() : '', + ]); + } catch (EmptyResponseException $e) { + $this->addFlash('warning', 'No set found on '.$e->getService()); + } catch (\Exception $e) { + $this->addFlash('error', $e->getMessage()); + } } return $this->render('brickset/browse.html.twig', [ diff --git a/src/AppBundle/Controller/ModelController.php b/src/AppBundle/Controller/ModelController.php index 306f766..3a41fbb 100644 --- a/src/AppBundle/Controller/ModelController.php +++ b/src/AppBundle/Controller/ModelController.php @@ -5,7 +5,7 @@ namespace AppBundle\Controller; use AppBundle\Entity\LDraw\Model; use AppBundle\Entity\Rebrickable\Part; use AppBundle\Entity\Rebrickable\Set; -use AppBundle\Form\Filter\ModelFilterType; +use AppBundle\Form\Filter\Model\ModelFilterType; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Bundle\FrameworkBundle\Controller\Controller; @@ -26,8 +26,6 @@ class ModelController extends Controller */ public function indexAction(Request $request) { - $em = $this->getDoctrine()->getManager(); - $form = $this->get('form.factory')->create(ModelFilterType::class); $filterBuilder = $this->get('repository.ldraw.model') diff --git a/src/AppBundle/Controller/SetController.php b/src/AppBundle/Controller/SetController.php index a2d0d90..c9bd5f3 100644 --- a/src/AppBundle/Controller/SetController.php +++ b/src/AppBundle/Controller/SetController.php @@ -6,9 +6,11 @@ use AppBundle\Api\Exception\EmptyResponseException; use AppBundle\Entity\LDraw\Model; use AppBundle\Entity\Rebrickable\Color; use AppBundle\Entity\Rebrickable\Inventory_Part; +use AppBundle\Entity\Rebrickable\Inventory_Set; use AppBundle\Entity\Rebrickable\Part; use AppBundle\Entity\Rebrickable\Set; use AppBundle\Entity\Rebrickable\Theme; +use AppBundle\Form\Filter\Set\SetFilterType; use AppBundle\Form\FilterSetType; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Bundle\FrameworkBundle\Controller\Controller; @@ -25,19 +27,29 @@ class SetController extends Controller */ public function indexAction(Request $request) { - $em = $this->getDoctrine()->getManager(); + $form = $this->get('form.factory')->create(SetFilterType::class); - $qb = $em->getRepository(Set::class)->createQueryBuilder('s'); + $filterBuilder = $this->get('repository.rebrickable.set') + ->createQueryBuilder('s'); + + if ($request->query->has($form->getName())) { + // manually bind values from the request + $form->submit($request->query->get($form->getName())); + + // build the query from the given form object + $this->get('lexik_form_filter.query_builder_updater')->addFilterConditions($form, $filterBuilder); + } $paginator = $this->get('knp_paginator'); $sets = $paginator->paginate( - $qb->getQuery(), + $filterBuilder->getQuery(), $request->query->getInt('page', 1)/*page number*/, $request->query->getInt('limit', 30)/*limit per page*/ ); return $this->render('set/index.html.twig', [ 'sets' => $sets, + 'form' => $form->createView() ]); } @@ -48,6 +60,9 @@ class SetController extends Controller { $brset = null; $rbset = null; + $inventorySets = null; + + $inventorySets = $this->getDoctrine()->getManager()->getRepository(Inventory_Set::class)->findAllBySetNumber($number); try { if(($rbset = $this->getDoctrine()->getManager()->getRepository(Set::class)->find($number)) == null) { $this->addFlash('warning', 'Set not found in Rebrickable database'); @@ -62,6 +77,7 @@ class SetController extends Controller return $this->render('set/detail.html.twig', [ 'rbset' => $rbset, + 'inventorySets' => $inventorySets, 'brset' => $brset, ]); } diff --git a/src/AppBundle/Form/Filter/CategoryFilterType.php b/src/AppBundle/Form/Filter/Model/CategoryFilterType.php similarity index 97% rename from src/AppBundle/Form/Filter/CategoryFilterType.php rename to src/AppBundle/Form/Filter/Model/CategoryFilterType.php index 90f068f..d21ab29 100644 --- a/src/AppBundle/Form/Filter/CategoryFilterType.php +++ b/src/AppBundle/Form/Filter/Model/CategoryFilterType.php @@ -1,6 +1,6 @@ add('search', Filters\TextFilterType::class, [ + 'apply_filter' => [$this, 'setSearchCallback'], + 'label' => 'filter.part.search', + ]); + + $builder->add('theme', ThemeFilterType::class, [ + 'add_shared' => function (FilterBuilderExecuterInterface $builderExecuter) { + $builderExecuter->addOnce($builderExecuter->getAlias().'.theme', 'c', function (QueryBuilder $filterBuilder, $alias, $joinAlias, $expr) { + $filterBuilder->leftJoin($alias.'.theme', $joinAlias); + }); + }, + ]); + } + + public function getBlockPrefix() + { + return 'model_filter'; + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'csrf_protection' => false, + 'validation_groups' => ['filtering'], // avoid NotBlank() constraint-related message + ]); + } + + public function setSearchCallback(QueryInterface $filterQuery, $field, $values) + { + if (empty($values['value'])) { + return null; + } + + // expression that represent the condition + $expression = $filterQuery->getExpr()->orX( + $filterQuery->getExpr()->like('s.name', ':value'), + $filterQuery->getExpr()->like('s.number', ':value') + ); + + return $filterQuery->createCondition($expression, ['value' => '%'.$values['value'].'%']); + } +} diff --git a/src/AppBundle/Form/Filter/Set/ThemeFilterType.php b/src/AppBundle/Form/Filter/Set/ThemeFilterType.php new file mode 100644 index 0000000..6657665 --- /dev/null +++ b/src/AppBundle/Form/Filter/Set/ThemeFilterType.php @@ -0,0 +1,58 @@ +rebrickableManager = $rebrickableManager; + } + + public function buildForm(FormBuilderInterface $builder, array $options) + { + $builder->add('id', Filters\ChoiceFilterType::class, [ + 'choices' => $this->rebrickableManager->FindAllThemes(), + 'choice_label' => function ($allChoices, $currentChoiceKey) { + + dump($currentChoiceKey); + + $parent = $allChoices->getParent(); + + return $parent ? $parent->getName().' > '.$allChoices->getName() : $allChoices->getName(); + }, + 'label' => 'filter.set.theme', + ]); + } + + public function getParent() + { + return Filters\SharedableFilterType::class; // this allow us to use the "add_shared" option + } + + public function getBlockPrefix() + { + return 'theme_filter'; + } + + public function setDefaultOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'data_class' => Theme::class, + 'csrf_protection' => false, + 'validation_groups' => ['filtering'], // avoid NotBlank() constraint-related message + 'method' => 'GET', + ]); + } +}