我想为Location
实体提供一个独立的表单类型,可以将其添加到所需的任何位置。如果为null,则应为null,而不是空的Location
。
我的问题是,当我提交null
时,将使用先前设置的位置,或者当我解决此问题时,该位置重复且不是唯一。
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Location::class,
'by_reference' => false
]);
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('place_id', null, ['property_path' => 'placeId'])
->add('latitude')
->add('longitude')
->add('description')
;
// [...] See below examples [...]
}
$builder->addEventListener(FormEvents::SUBMIT, function (FormEvent $event)
{
// $event->setData($this->locationRepository->find(19));
// $event->getForm()->setData($this->locationRepository->find(17));
// /** @var Location $value */
$value = $event->getData();
// var_dump(1, $value, $event->getForm()->getData()->getId());
$location = null;
if ($value)
{
$location = $this->locationRepository->findOneBy(['latitude' => $value->getLatitude(), 'longitude' => $value->getLongitude()]);
// var_dump('Location found', $location->getId());
if(!$location)
{
var_dump('-------------------- NEW LOCATION ----------------------------');
$location = new Location();
$location->setLongitude($value->getLongitude());
$location->setLatitude($value->getLatitude());
$location->setDescription($value->getDescription());
$location->setPlaceId($value->getPlaceId());
}
// $event->setData($location);
// $event->getForm()->setData($location);
}
$event->setData($location);
// var_dump($location->getId());
它工作得很好-但是当我要将其设置为null
时不是,因为那样的话它将被忽略,并且将使用过去的位置。
{}
{}
确定,因为尚未提交location
,因此将其忽略。 $clearMissing = false
-> $form->submit($request->request->all(), false);
{"location": {"latitude": 12.0, "longitude": 99.0}}
{"location": {
"latitude": 12.0,
"longitude": 99.0
}}
确定,因为未找到lat / log 时创建新实体,并在lat / lng 找到。
{"location": null}
{"location": {
"latitude": 12.0,
"longitude": 99.0
}}
错误,我希望这里的位置为null,而不是父位置。
class UniqueLocationTransformer implements DataTransformerInterface
{
private $locationRepository;
public function __construct(LocationRepository $locationRepository)
{
$this->locationRepository = $locationRepository;
}
public function transform($value)
{
return $value;
}
public function reverseTransform($value)
{
if ($value)
{
$location = $this->locationRepository->findOneBy(['latitude' => $value->getLatitude(), 'longitude' => $value->getLongitude()]);
if($location)
{
return $location;
}
$location = new Location();
$location->setLongitude($value->getLongitude());
$location->setLatitude($value->getLatitude());
$location->setDescription($value->getDescription());
$location->setPlaceId($value->getPlaceId());
}
return $value;
}
}
它也可以正常工作,但即使设置为空也存在问题。
{}
{}
确定,因为尚未提交location
,因此将其忽略。 $clearMissing = false
-> $form->submit($request->request->all(), false);
{"location": {"latitude": 12.0, "longitude": 99.0}}
{"location": {
"latitude": 12.0,
"longitude": 99.0
}}
确定,因为未找到lat / log 时创建新实体,并在lat / lng 找到。
{"location": null}
{"location": {
"latitude": 12.0,
"longitude": 99.0
}}
错误,我希望这里的位置为null,而不是父位置。
prePersist
侦听器这里的问题是,它不被要求进行更新,而且效果也不佳,因为它超出了类型范围。
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event)
{
$value = $event->getData();
$location = null;
if (is_array($value) && array_key_exists('latitude', $value))
{
$location = $this->locationRepository->findOneBy(['latitude' => $value['latitude'], 'longitude' => @$value['longitude'] || 0]);
if(!$location)
{
$location = new Location();
$location->setLongitude(array_key_exists('longitude', $value) ? $value['longitude'] : null);
$location->setLatitude(array_key_exists('latitude', $value) ? $value['latitude'] : null);
$location->setDescription(array_key_exists('description', $value) ? $value['description'] : null);
$location->setPlaceId(array_key_exists('place_id', $value) ? $value['place_id'] : null);
}
}
var_dump($location);
$event->setData($location);
});
我现在更改了事件监听器,以使其在PRE_SUBMIT
上监听并添加了选项required
,该选项设置为false
。
但是提交有效内容时出现错误。
请求:
{"location": {"latitude": 13, "longitude": 14}}
响应:
{
"location": [
"This value is not valid."
]
}
:(