<?php
/**
* Created by simpson <simpsonwork@gmail.com>
* Date: 2019-04-29
* Time: 19:26
*/
namespace App\Form\Type;
use App\Entity\Profile\Profile;
use App\Entity\TakeOutLocations;
use App\Entity\TakeOutPricing;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\DataMapperInterface;
use Symfony\Component\Form\Exception;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\Callback;
use Symfony\Component\Validator\Constraints\GreaterThan;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
class TakeOutPricingType extends AbstractType implements DataMapperInterface
{
/**
* @inheritDoc
*/
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add('one_hour_price', NumberType::class, [
'required' => false,
'constraints' => new GreaterThan(0),
]);
$builder->add('two_hours_price', NumberType::class, [
'required' => false,
'constraints' => new GreaterThan(0),
]);
$builder->add('night_price', NumberType::class, [
'required' => false,
'constraints' => new GreaterThan(0),
]);
$builder->add('locations', ChoiceType::class, [
'required' => false,
'multiple' => true,
'expanded' => true,
'choices' => TakeOutLocations::getList(),
'constraints' => new Callback([$this, 'validateLocations']),
]);
$builder->setDataMapper($this);
}
/**
* @inheritDoc
*/
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => TakeOutPricing::class,
'empty_data' => null,
]);
}
public function validateLocations($value, ExecutionContextInterface $context): void
{
$form = $context->getRoot();
/** @var Profile $profile */
$profile = $form->getData();
$takeOutPricing = $profile->getTakeOutPricing();
$hasLocations = count($value) > 0;
if ($takeOutPricing->isProvided() && !$hasLocations) {
$context
->buildViolation('At least 1 location should be chosen.')
->addViolation()
;
} elseif ($hasLocations && !$takeOutPricing->isProvided()) {
$context
->buildViolation('At least 1 price should be defined.')
->addViolation()
;
}
}
/**
* @inheritDoc
*/
public function mapDataToForms($viewData, $forms)
{
if (null === $viewData) {
return null;
}
if (!$viewData instanceof TakeOutPricing) {
throw new Exception\UnexpectedTypeException($viewData, TakeOutPricing::class);
}
/** @var FormInterface[] $forms */
$forms = iterator_to_array($forms);
$forms['one_hour_price']->setData($viewData->getOneHourPrice());
$forms['two_hours_price']->setData($viewData->getTwoHoursPrice());
$forms['night_price']->setData($viewData->getNightPrice());
$forms['locations']->setData($viewData->getLocations());
}
/**
* @inheritDoc
*/
public function mapFormsToData($forms, &$viewData): void
{
/** @var FormInterface[] $forms */
$forms = iterator_to_array($forms);
$viewData = new TakeOutPricing(
$forms['one_hour_price']->getData(),
$forms['two_hours_price']->getData(),
$forms['night_price']->getData(),
$forms['locations']->getData() ?? []
);
}
}