Laravel Timestamp Validator

в 8:30, , рубрики: laravel, php, timestamp, validator

image

Laravel 5.1, Laravel 5.2, Lara… Код прогрессирует, оптимизируется и развивается. В новой (5.2) версии появился валидатор массивов, например, но что делать, если необходимо провалидировать входящий timestamp? Правильно, писать костыль своё решение.

Жил был и живёт один проект на Laravel 5.1. Точнее, живёт его API сторона. Есть необходимость «гонять» туда-сюда различные даты. Но как их гонять, если существуют часовые пояса? Принято решение установить сервер в UTC+0 и общаться с помощью timestamp, который на фронтенде легко преобразуется в нужное время. Окей, вопросов по этому не возникло. Кроме одного — как валидировать входящие данные? Создадим собственный валидатор.

Полный код валидатора в самом конце статьи.

Поехали!

В папке app/Extensions/Validators создаём файл и именуем TimestampValidator.php.

namespace LameExtensionsValidators;

use IlluminateValidationValidator;

class TimestampValidator extends Validator{
}

Нам необходимо принимать, чтобы входящая дата подходила под «до» и «после».

Рассмотрим первый пример. У нас есть дата рождения пользователя. Пользователь должен быть старше 10 лет, т.е. рождён до 2016 года. Соответственно, нам необходимо принимать дату, которая будет до 2016 года. В правилах валидации указываем:

/** Берем текущую дату, отнимаем 10 лет, прибавляем один день и получаем timestamp от необходимой даты */
$date = Carbon::now()->subYears(10)->addDay(1)->timestamp;

/** Указываем, что входящая дата в формате timestamp должна быть до нужной даты в timestamp */
$rules = [
  "bDay" => "numeric|before_timestamp:".$date,
];

Появилось правило «before_timestamp». Возвращаемся в наш валидатор и создаём метод, который будет осуществлять нужную проверку. Название метода должно иметь следующую структуру: «validate<правило в camelCase формате>». $value среди входящих параметров — значение, которое поступило из вне. $parameters — массив параметров, которые указали в правилах (before_timestamp:".$date).

public function validateBeforeTimestamp($attribute, $value, $parameters)
{
    $value = (int)$value;

    if ((int)$parameters[0] <= 0) {
        throw new Exception("Timestamp parameter in the beforeTimestamp validator not valid!");
    }

    if ($value != "" && $value >= $parameters[0]) {
        return false;
    }

    return true;
}

Второй пример. Нам необходимо создать задачу с дедлайном. Минимальный дедлайн — 4 часа. Создаём правила:

$date = Carbon::now()->addHours(Callback::getDeadlineHour())->timestamp;
$rules = [
  "deadline" => "required|numeric|after_timestamp:".$date
];

Появилось новое правило — «after_timestamp». Обработаем его в нашем валидаторе:

public function validateAfterTimestamp($attribute, $value, $parameters)
{
    $value = (int)$value;

    if ((int)$parameters[0] <= 0) {
        throw new Exception("Timestamp parameter in the beforeTimestamp validator not valid!");
    }

    if ($value != "" && $value <= $parameters[0]) {
        return false;
    }

    return true;
}

Чтобы подключить наш валидатор, я создал свой ServiceProvider в папке app/Providers — CustomValidateServiceProvider.php.

<?php
namespace LameProviders;

use IlluminateSupportServiceProvider;
use LameExtensionsValidatorsTimestampValidator;
use Validator;

class CustomValidateServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Validator::resolver(function ($translator, $data, $rules, $messages) {
            return new TimestampValidator($translator, $data, $rules, $messages);
        });
    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

На этом, в принципе всё. Сообщения об ошибках указываются в файле validation.php.

"custom" => [
    "deadline" => [
        "after_timestamp" => "Deadline should be minimum 4 hours"
    ],

    "bDay" => [
        "before_timestamp" => "Age should be minimum 10 years",
        "numeric" => "Birthday date should be in timestamp"
    ]
]

Полный код класса

<?php
namespace LameExtensionsValidators;

use IlluminateValidationValidator;

class TimestampValidator extends Validator
{
    #region timestamp valitators - after_timestamp:{timestamp} | before_timestamp:{timestamp}
    /**
     * @param $attribute
     * @param $value
     * @param $parameters = ["date" => "Date before which should be input timestamp"]
     * @return bool
     * @throws Exception
     */
    public function validateBeforeTimestamp($attribute, $value, $parameters)
    {
        $value = (int)$value;

        if ((int)$parameters[0] <= 0) {
            throw new Exception("Timestamp parameter in the beforeTimestamp validator not valid!");
        }

        if ($value != "" && $value >= $parameters[0]) {
            return false;
        }

        return true;
    }

    /**
     * @param $attribute
     * @param $value
     * @param $parameters = ["date" => "Date before which should be input timestamp"]
     * @return bool
     * @throws Exception
     */
    public function validateAfterTimestamp($attribute, $value, $parameters)
    {
        $value = (int)$value;

        if ((int)$parameters[0] <= 0) {
            throw new Exception("Timestamp parameter in the beforeTimestamp validator not valid!");
        }

        if ($value != "" && $value <= $parameters[0]) {
            return false;
        }

        return true;
    }
    #endregion
}

С помощью date, after, before timestamp не проверишь. Или можно проверить? Если можно, буду рад в комментариях, сообщениях прочитать существующие варианты.

Автор: alutskevich

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js