2015-04-28 1 views
0

У меня есть форма, которая содержит 3 поля текста типа и с валидатором даты.Как добавить пользовательскую стратегию гидратора для доктрины Дата гидратор

Этот код находится в Fieldset с помощью доктрины гидратор (связанной с доктриной сущности)

$this->add(
     array(
      'name' => 'endDate', 
      'type' => 'Zend\Form\Element\Text', 
      'options' => array(
       'label' => 'end_date_label', 
       'label_attributes' => array(
        'class' => 'control-label col-xs-3' 
       ), 
      ), 
      'attributes' => array(
       'class' => 'form-control col-xs-3 datepicker-end-date', 
      ) 
     ) 
    ); 


'endDate' => array(
     'required' => true, 
     'allow_empty' => false, 
     'filters' => array(
      array('name' => 'StripTags'), 
      array('name' => 'StringTrim'), 
     ), 
     'validators' => array(
      array(
       'name' => 'Date', 
       'options' => array(
        'format' => 'd/m/Y', 
       ), 
      ), 
     ), 
    ), 

Я работает с французским форматом даты. Когда я верю форму, если я меняю формат на m/d/Y, он работает, но когда моя форма недействительна, мой выбор даты получает неправильную дату (месяц и дни обращаются).

Что я хочу - это действительный формат дат и сохранение в базе данных даты в формате m/d/Y.

В этом формате я получаю ошибку:

DateTime::__construct(): Failed to parse time string (29/04/2015) at position 0 (2): Unexpected character 

Я видел много поста на Stack говорить о пользовательской стратегии доктрины гидратации, но я их не понимаю. Что я должен делать шаг за шагом?

Я пытался добавить стратегию моего поля ENDDATE, но он никогда не называл ... Этот код находится в классе Fieldset незадолго до моего поля декларации:

$this->setHydrator(new DoctrineHydrator($this->getObjectManager(), 'TodoList\Entity\TodoQuestion')) 
      ->setObject(new TodoQuestion()); 
     $this->getHydrator()->addStrategy('endDate', new \Application\Strategy\DateTimeStrategy()); 

И моя стратегия Datetime реализует интерфейс стратегии.

<?php 

namespace Application\Strategy; 

use Zend\Stdlib\Hydrator\Strategy\StrategyInterface; 

class DateTimeStrategy implements StrategyInterface 
{ 
    public function hydrate($value) 
    { 
     if (is_string($value)) { 
      $value = new DateTime($value); 
     } 
     return $value->format('d/m/Y'); 
    } 

    public function extract($value) 
    { 
     return; 
    } 
} 

Если кто-то может объяснить с подробностями, что я делаю неправильно, и помочь мне понять все это дело ..

+0

Как вы хранить значение даты в базе данных? Как варчар? Если это так, сохранение в качестве даты и времени сделает вещи намного проще. – netiul

+0

Я храню время, конечно, –

ответ

0

Вы должны просто вернуть объект DateTime из Стратегии.

namespace Application\Strategy; 

use Zend\Stdlib\Hydrator\Strategy\StrategyInterface; 

class DateTimeStrategy implements StrategyInterface 
{ 
    public function hydrate($value) 
    { 
     if (is_string($value)) { 
      $value = \DateTime::createFormFormat('d/m/Y', $value); 
     } 
     return $value; 
    } 

    public function extract($value) 
    { 
     return $value; 
    } 
} 

Выше не будет работать, так как стратегии называются после преобразования типа гидратора в.

Лучше всего использовать фильтр обратного вызова.

'endDate' => array(
    'required' => true, 
    'allow_empty' => false, 
    'filters' => array(
     array('name' => 'StripTags'), 
     array('name' => 'StringTrim'), 
     array(
      'name' => 'Callback', 
      'options' => array(
       'callback' => function($value) { 
        if (is_string($value)) { 
         $value = \DateTime::createFromFormat('d/m/Y', $value); 
        } 
        return $value; 

       }, 
      ), 
    ), 
    'validators' => array(
     array(
      'name' => 'Date', 
      'options' => array(
       'format' => 'd/m/Y', 
      ), 
     ), 
    ), 
), 

Учение о гидраторе, которое вы используете, кажется устаревшим кстати. Текущая версия не требует указания объекта как второго параметра.

+0

Это действительно раздражает, что я ничего не нашел об этом, weel, я не знал, что искать ... но ваше решение действительно потрясающее! Большое спасибо, работает как шарм –

0

Наткнулся на этот вопрос случайно. Хотя он довольно старый, я недавно работал с Датами в формах ZF2. У меня есть форматирование, как показано ниже, без использования обратного вызова.

Может быть, это поможет кому-то в будущем;)

Ниже было сделано с использованием ZF2 2.5.3

$this->add([ 
     'name' => 'startDate', 
     'required' => true, 
     'filters' => [ 
      [ 
       'name' => DateTimeFormatter::class, 
       'options' => [ 
        'format' => 'Y-m-d', // or d/m/Y 
       ], 
      ], 
     ], 
     'validators' => [ 
      [ 
       'name' => Date::class, 
       'options' => [ 
        'format' => 'Y-m-d', // or d/m/Y 
       ], 
      ], 
     ], 
    ]); 
Смежные вопросы