2016-03-10 7 views
1

Я использую аннотацию в классе Entity Doctrine. Краткое описание для поля являются:ZF2 + Doctrine2 Форма аннотации обязательна & AllowEmpty

/** 
* @var integer 
* 
* @ORM\Column(name="duree", type="integer", nullable=true) 
* 
* @Form\Type("Zend\Form\Element\Number") 
* @Form\Attributes({"required":false, "placeholder":"Durée", "min":"1", "max":"20"}) 
* @Form\Required(false) 
* @Form\AllowEmpty() 
* @Form\Options({"label":"Durée :"}) 
* @Form\Filter({"name": "Int"}) 
* @Form\Validator({"name":"IsInt"}) 
*/ 
private $duree; 

Так колонка DB может быть пустой (обнуляемым), так и в виде я wan't одинаковый (т.е. пользователь может оставить вход пустым). У меня есть аннотация Required (false) и allowEmpty, но форма никогда не действительна (для этого поля всегда есть isEmpty).

Если я установил @Form \ Type в «Text», он работает нормально (форма является допустимым событием, если вход пуст). Но с классом Number это не то же самое.

У меня такой же pb с элементом Select (соответствует отношениям). Аннотации:

/** 
* @var \Application\Entity\CcCategorie 
* 
* @ORM\ManyToOne(targetEntity="Application\Entity\CcCategorie") 
* @ORM\JoinColumns({ 
* @ORM\JoinColumn(name="categorie", referencedColumnName="id", nullable=true, onDelete="SET NULL") 
* }) 
* 
* @Form\Type("DoctrineModule\Form\Element\ObjectSelect") 
* @Form\Attributes({"type":"select", "required":false}) 
* @Form\Options({"label":"Catégorie :"}) 
* @Form\Required(false) 
* @Form\AllowEmpty() 
* @Form\Options({ 
*  "label":"Catégorie :", 
*  "empty_option": "---", 
*  "target_class": "Application\Entity\CcCategorie", 
*  "property": "label" 
* })  
*/ 
private $categorie; 

Но, с этим полем имеет ошибки (IsEmpty), если для параметра Выбрать пустую опцию при проверке формы.

Единственный способ решения проблемы я нашел это установить аннотацию

* @Form\Type("\Application\Form\Entity\CcRepriseFieldset") 

в верхней части класса сущностей. Класс CcRepriseFieldset расширяет Fieldset и реализует InputFilterProviderInterface. Затем я указываю функцию в этом классе:

public function getInputFilterSpecification() 
    { 
     return array(
      array(
       "name" => "duree", 
       'required' => false, 
       'allow_empty' => true, 
      ), 
      array(
       "name" => "categorie", 
       'required' => false, 
       'allow_empty' => true, 
      ), 
     ); 
    } 

С этим оно работает ... Но это не аннотации. я не понимаю, почему аннотации не работают

благодаря

+0

Человек, некоторые советы - шаг в сторону от аннотации формы. Создайте надлежащий, кэшируемый код и отделите свои входные фильтры от конструкции формы; это маленькое сообщение в блоге могло бы помочь http://circlical.com/blog/2015/7/6/zend-framework-2-forms-factories-inputfilters-and-hydration – Saeven

+0

Вы пытались явно указать allow empty должно быть правдой?то есть '@Form \ AllowEmpty (true)' Я не использую аннотации форм (такое же мнение, как @Saeven), но я бы полностью ожидал оставить этот параметр пустым, поскольку вы должны интерпретироваться как значение 'false'y – Crisp

+0

@Saeven Спасибо за помощь. Я нашел преимущество в использовании аннотаций доктрины и формы: вся информация находится на том же месте. Я обнаружил, что существует смысл, что если определение ORM имеет тип = «integer», nullable = true, в том же месте вы определяете, что поле формы, в котором хранятся эти данные, представляет собой Number, которые допускают пустое значение и имеют Int Validator и фильтр, и, конечно же, имеют одно и то же имя. Когда вам нужно что-то изменить в базе данных, вам нужно только отредактировать точечный блок, а затем запустить инструмент доктрины, чтобы изменить db. Все остальные настройки относятся к классу (расширение Fieldset). – gregf

ответ

0

Ok я нашел то, что является Probleme. Аннотация Builder сделал массив со всеми полями спецификации, как это:

array (size=7) 
    'name' => string 'reprise' (length=7) 
    'attributes' => array (size=0) 
    'elements' => 
     array (size=8) 
     1 =>array (size=2) 
... 
    'fieldsets' => array (size=0) empty 
    'type' => string '\Application\Form\Entity\CcRepriseFieldset' 
(length=42) 
    'input_filter' => 
    array (size=8) 
     'name' => 
     array (size=4) 
      'name' => string 'name' (length=4) 
      'required' => boolean true 
      'filters' => 
      array (size=3) 
       ... 
      'validators' => 
      array (size=2) 
... 

Но этот массив является массив для Fieldset прикрепленный к Сущности. Таким образом, Zend \ Form \ Factory никогда не анализирует это, потому что «input_filter» анализирует только элемент ZendForm, но не для набора полей (конечно, потому что у Fieldset нет метода SetInputFilter) ...

0

Ok У меня есть обходное решение, но Я не очень доволен этим. Сначала я создать новую FormFactory:

namespace Application\Form; 
use Zend\Form\FieldsetInterface; 
Class EntityFormFactory extends \Zend\Form\Factory { 
    public function configureFieldset(FieldsetInterface $fieldset, $spec) 
    { 
     $fieldset=parent::configureFieldset($fieldset, $spec); 

     $fieldset->input_filter_factory= $spec['input_filter']; 
     return $fieldset; 
    } 
} 

Так этот завод добавить «input_filter» к input_filter_factory переменной полей.

Тогда в Fieldset классе:

class CcRepriseFieldset extends Fieldset implements \Zend\InputFilter\InputFilterProviderInterface 
{ 
    public function getInputFilterSpecification() 
    { 
     if (isset($this->input_filter_factory)){ 
      return $this->input_filter_factory; 
     }   
    } 
} 

И, наконец, когда я использую annotationbuilder я изменить FormFactory:

$builder = new AnnotationBuilder($this->_em); 
$builder->setFormFactory(new EntityFormFactory()); 

С этим все работает нормально ... Я не sur это лучший способ сделать это.

Смежные вопросы