taral
@taral
php программист

Как в yii2 лучше обрабатывать дату с datepicker?

Вопрос исключительно по yii2.
yii\jui\DatePicker возвращает дату в формате dd.yyyy.MM. В базе хранится в поле int. И естественно необходимо преобразовывать дату.
Каким образом это лучше сделать учитывая что форма должна работать правильно.
- Если дата уже выбрана, поле должно заполнятся правильным значением
- В базу должно писаться значение int если поле даты заполнено и чистится если его сделали пустым
----------
Сейчас я решаю так.
/**
 * @property integer $some_time - поле в базе
 */
class News extends ActiveRecord {

    public function rules() {
        return [['someTimeDate', 'date', 'format' => 'php:d.m.Y']];
    }

    public function getSomeTimeDate() {
        return $this->some_time? date('d.m.Y', $this->some_time) : '';
    }

    public function setSomeTimeDate($date) {
        $this->some_time= $date ? strtotime($date) : null;
    }
}
...
echo $form->field($model, 'someTimeDate')->widget('common\widgets\Datepicker', [
    'dateFormat' => 'dd.mm.yy',
])

И работаю с полем someTimeDate. В таком варианте все устраивает кроме необходимости писать геттер и сеттер для поля.
У валидатора yii\validators\DateValidator есть свойство timestampAttribute позволяющее переводить дату в необходимый формат для базы. Но я не нашел применения ему. Поскольку для методов оно уже не нужно. А если использовать свойство отформатированной даты то оно не будет заполнятся значением с базы.
  • Вопрос задан
  • 10614 просмотров
Пригласить эксперта
Ответы на вопрос 3
vyachin
@vyachin
Ищу работу
Потребуется настроить валидацию www.yiiframework.com/doc-2.0/guide-tutorial-core-v... указать формат в котором будет приходить дата от браузера (format=>'php:d.Y.m') и указать название атрибута в базе (timestampAttribute)
Ответ написан
@qorp
Тема рассматривалась давно, но вдруг кому пригодится, сам столкнулся с такой задачей. Как вариант

Создаем поведение DateToTimeBehavior

<?php

namespace common\behaviors;

use yii\behaviors\AttributeBehavior;
use yii\base\InvalidConfigException;
 

class DateToTimeBehavior extends AttributeBehavior {

    public $timeAttribute;

    public function getValue($event) {

        if (empty($this->timeAttribute)) {
            throw new InvalidConfigException('Can`t find "fromAttribute" property in ' . $this->owner->className());
        }
        if (!empty($this->owner->{$this->attributes[$event->name]})) {
            $this->owner->{$this->timeAttribute} = strtotime($this->owner->{$this->attributes[$event->name]});
            return date('d.m.Y', $this->owner->{$this->timeAttribute});
        } else {
            if (!empty($this->owner->{$this->timeAttribute})) {
                $this->owner->{$this->attributes[$event->name]} = date('d.m.Y', $this->owner->{$this->timeAttribute});
                return $this->owner->{$this->attributes[$event->name]};
            }
        }
        
        return date('d.m.Y', time());
    }

}


В модели создаем свойство для хранения даты в формате 'd.m.Y' , или другом удобном для вас формате (про валидацию главное не забыть) . Данное поведение будет записывать значение в поле time если мы что то получили от формы. Иначе будет инициализироваться переменная date в модели по значению в time.

... ... ...
use common\behaviors\DateToTimeBehavior;

... ... ...
   public $date;
... ... ...


И подключаем созданное поведение к нашей модели

... ... ...
public function behaviors() {
        return [
            [
                'class' => DateToTimeBehavior::className(),
                'attributes' => [
                    ActiveRecord::EVENT_BEFORE_VALIDATE => 'date',
                    ActiveRecord::EVENT_AFTER_FIND => 'date',
                ],
                'timeAttribute' => 'time', //Атрибут модели в котором хранится время в int
            ],
        ];
    }
... ... ...


во view в activeField выводим

use kartik\date\DatePicker;

<?php $form = ActiveForm::begin(); ?>
 <?= $form->field($model, 'date')->widget(
       DatePicker::className()
    )?>
<?php ActiveForm::end(); ?>
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы