<?php
namespace App\Form\Forms;
use App\Model\Searching\AbstractSearch;
use Products\SchoolNowBundle\Form\Type\SimpleSelectType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* Base search form that all other search forms should extend.
* NOTE: since this is a base class, be sure to call parent methods when overriding anything.
*/
abstract class SearchForm extends AbstractType
{
/**
* Override to set a more appropriate search class type.
*/
protected const DATA_CLASS = AbstractSearch::class;
/**
* {@inheritDoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
// form should have a search type assigned to it
$search = $builder->getData();
if ( ! $search instanceof AbstractSearch) {
throw new \Exception();
}
// all search forms will be get requests (so data comes across in url query string)
$builder->setMethod('GET');
// filters are not always used
if ($search::FILTERS) {
$builder->add('filter', SimpleSelectType::class, [
'empty_data' => $search::FILTERS__DEFAULT,
'choices' => $search::FILTERS,
'choice_label' => function ($choice, $key, $value) use ($options) {
if ($options['search_filters_label_format']) {
return sprintf(
$options['search_filters_label_format'],
$value,
);
}
return $value;
},
]);
}
// attach fields
$builder
->add('sort', HiddenType::class, [
'empty_data' => $search::SORTS__DEFAULT,
])
->add('direction', HiddenType::class, [
'empty_data' => $search::DIRECTIONS[$search::SORTS__DEFAULT],
])
;
}
/**
* {@inheritDoc}
*/
public function buildView(FormView $view, FormInterface $form, array $options)
{
// form should have a sort type assigned to it
$search = $form->getData();
if ( ! $search instanceof AbstractSearch) {
throw new \Exception();
}
// attach information about the sorting so that we can use it in templates
$view->vars['filters'] = $options['search_filters'];
$view->vars['sorts'] = $options['search_sorts'];
$view->vars['dirs'] = $search::DIRECTIONS;
// legacy
$view->vars['search_filters'] = $search::FILTERS;
$view->vars['search_sorts'] = $search::DIRECTIONS;
}
/**
* {@inheritDoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'csrf_protection' => false,
'data_class' => static::DATA_CLASS,
'search_filters' => defined(static::DATA_CLASS . '::FILTERS') ? constant(static::DATA_CLASS . '::FILTERS') : [],
'search_sorts' => array_keys(defined(static::DATA_CLASS . '::DIRECTIONS') ? constant(static::DATA_CLASS . '::DIRECTIONS') : []),
'search_filters_label_format' => null,
]);
}
/**
* {@inheritDoc}
*/
public function getBlockPrefix(): string
{
// all search forms will use the same naming pattern
return 'query';
}
}