擴展了前面兩個關於form structure和validating collections的問題我已經遇到下一個問題。ZF2 + Doctrine 2 - 當需求未滿足且值爲空時創建的實體
我的表單正確驗證。通過Fieldsets包括包含的集合。但是如果它的值沒有設置,最內層的Fieldset不應該導致實體和FK關聯到父項。
一個Address
可能有或可能沒有鏈接Coordinates
。可以在同一個表單中創建所有這些。
但是,Coordinates
不應該創建,並且不應鏈接從Address
如果沒有在窗體中給出座標。它們在表單中不是必需的,實體Coordinates
本身要求設置經度和緯度的屬性。
下面,首先是實體。以下是用於AddressForm
的Fieldsets。我已經刪除了與Address
- >Coordinates
鏈無關的內容。
Address.php
class Address extends AbstractEntity
{
// Properties
/**
* @var Coordinates
* @ORM\OneToOne(targetEntity="Country\Entity\Coordinates", cascade={"persist"}, fetch="EAGER", orphanRemoval=true)
* @ORM\JoinColumn(name="coordinates_id", referencedColumnName="id", nullable=true)
*/
protected $coordinates;
// Getters/Setters
}
Coordinates.php
class Coordinates extends AbstractEntity
{
/**
* @var string
* @ORM\Column(name="latitude", type="string", nullable=false)
*/
protected $latitude;
/**
* @var string
* @ORM\Column(name="longitude", type="string", nullable=false)
*/
protected $longitude;
// Getters/Setters
}
如上實體能夠被看見。 Address
與Coordinates
具有OneToOne
單向關係。 Coordinates
實體需要latitude
和longitude
屬性,如nullable=false
所示。
它在那裏,它出錯了。如果創建了Address
,但在表單中未設置Coordinates
的屬性,它仍會創建Coordinates
實體,但會將latitude
和longitude
屬性留空,即使它們是必需的。
因此,簡而言之:
- 一個
Coordinates
實體創建其中不應該存在 - 到
Coordinates
的鏈接從Address
創建其中不應該存在
下面的字段集和InputFilters進一步澄清事情。
AddressFieldset.php
class AddressFieldset extends AbstractFieldset
{
public function init()
{
parent::init();
// Other properties
$this->add([
'type' => CoordinatesFieldset::class,
'required' => false,
'name' => 'coordinates',
'options' => [
'use_as_base_fieldset' => false,
],
]);
}
}
CoordinatesFieldset.php
class CoordinatesFieldset extends AbstractFieldset
{
public function init()
{
parent::init();
$this->add([
'name' => 'latitude',
'required' => true,
'type' => Text::class,
'options' => [
'label' => _('Latitude'),
],
]);
$this->add([
'name' => 'longitude',
'required' => true,
'type' => Text::class,
'options' => [
'label' => _('Longitude'),
],
]);
}
}
AddressFieldsetInputFilter.php
class AddressFieldsetInputFilter extends AbstractFieldsetInputFilter
{
/** @var CoordinatesFieldsetInputFilter $coordinatesFieldsetInputFilter */
protected $coordinatesFieldsetInputFilter;
public function __construct(
CoordinatesFieldsetInputFilter $filter,
EntityManager $objectManager,
Translator $translator
) {
$this->coordinatesFieldsetInputFilter = $filter;
parent::__construct([
'object_manager' => $objectManager,
'object_repository' => $objectManager->getRepository(Address::class),
'translator' => $translator,
]);
}
/**
* Sets AddressFieldset Element validation
*/
public function init()
{
parent::init();
$this->add($this->coordinatesFieldsetInputFilter, 'coordinates');
// Other filters/validators
}
}
CoordinatesFieldsetInputFilter.php
class CoordinatesFieldsetInputFilter extends AbstractFieldsetInputFilter
{
public function init()
{
parent::init();
$this->add([
'name' => 'latitude',
'required' => true,
'allow_empty' => true,
'filters' => [
['name' => StringTrim::class],
['name' => StripTags::class],
],
'validators' => [
[
'name' => StringLength::class,
'options' => [
'min' => 2,
'max' => 255,
],
],
[
'name' => Callback::class,
'options' => [
'callback' => function($value, $context) {
//If longitude has a value, mark required
if(empty($context['longitude']) && strlen($value) > 0) {
$validatorChain = $this->getInputs()['longitude']->getValidatorChain();
$validatorChain->attach(new NotEmpty(['type' => NotEmpty::NULL]));
$this->getInputs()['longitude']->setValidatorChain($validatorChain);
return false;
}
return true;
},
'messages' => [
'callbackValue' => _('Longitude is required when setting Latitude. Give both or neither.'),
],
],
],
],
]);
// Another, pretty much identical function for longitude (reverse some params and you're there...)
}
}
編輯:添加數據庫轉儲映像。顯示空的緯度,經度。
EDIT2:當我刪除從AddressFieldsetInputFilter
輸入'allow_empty' => true,
和填單輸入(經緯度),然後它驗證正確,除非你離開兩個輸入爲空,那麼它將立即脫落到返回輸入是必需的。 (Value is required and can't be empty
)。