Локализованное форматирование даты в Laravel

в 8:30, , рубрики: laravel, php, Веб-разработка, разработка сайтов

Сейчас я приведу очень простой способ того, как можно сделать в проекте локализованное форматирование даты на фреймворке Laravel. В конечном итоге мы получим результат, при котором получая свойство модели, к примеру, created_at (timestamp формат: 2014-10-31 10:08:56) — преобразуется в «20 Октября в 19:45». Форматирование можно будет настроить по вкусу или исходя из нужд.

Создание файла с переводами

Создаем date.php в директории app/lang/ru (если текущий язык русский). В его содержании будет формат вывода даты со временем и правильные окончания для месяцев.

<?php

return [
    'later'             => ':date в :time',
    'today'             => 'сегодня в :time',
    'yesterday'         => 'вчера в :time',
    'month_declensions' => [
        'January'   => 'Января',
        'February'  => 'Февраля',
        'March'     => 'Марта',
        'April'     => 'Апреля',
        'May'       => 'Мая',
        'June'      => 'Июня',
        'July'      => 'Июля',
        'August'    => 'Августа',
        'September' => 'Сентября',
        'October'   => 'Октября',
        'November'  => 'Ноября',
        'December'  => 'Декабря'
    ]
];
Для английского языка:

<?php

return [
    'later'             => ':date at :time',
    'today'             => 'today at :time',
    'yesterday'         => 'yesterday at :time',
    'month_declensions' => [
        'January'   => 'January',
        'February'  => 'February',
        'March'     => 'March',
        'April'     => 'April',
        'May'       => 'May',
        'June'      => 'June',
        'July'      => 'July',
        'August'    => 'August',
        'September' => 'September',
        'October'   => 'October',
        'November'  => 'November',
        'December'  => 'December'
    ]
];

Создание библиотеки

Теперь реализуем библиотеку, которая будет выполнять всю нашу логику для преобразования даты.
Создаем папку app/libraries (если ее нету) и файл DateFormat.php в папке Date, полный путь будет — app/libraries/Date/DateFormat.php.

<?php

namespace Date;

class DateFormat
{

    /**
     * данный метод написан на коленке (нужно переписать)
     */
    public static function post($time)
    {
        $timestamp = strtotime($time);
        $published = date('d.m.Y', $timestamp);

        if ($published === date('d.m.Y')) {
            return trans('date.today', ['time' => date('H:i', $timestamp)]);
        } elseif ($published === date('d.m.Y', strtotime('-1 day'))) {
            return trans('date.yesterday', ['time' => date('H:i', $timestamp)]);
        } else {
            $formatted = trans('date.later', [
                'time' => date('H:i', $timestamp),
                'date' => date('d F' . (date('Y', $timestamp) === date('Y') ? null : ' Y'), $timestamp)
            ]);

            return strtr($formatted, trans('date.month_declensions'));
        }
    }

}

Автозагрузка библиотек

Для того, чтобы все библиотеки были доступны для использования, добавим в composer.json автозагрузку классов с нашей директории app/libraries:

{
    "autoload": {
        "classmap": [
            "app/libraries"
        ]
    }
}

И обновим кэш composer'a:

composer dump-autoload

Базовая модель

Здесь можно поступить несколькими способами:

  • Создать абстрактную базовую модель и унаследоваться от нее;
  • Создать типаж (trait) и добавлять его использование в наши модели.

Я выбрал первый способ, так как он показался более практичным.

В созданном файле app/models/Model.php добавляем метод, который будет вызываться при получении свойства created_at.
Вызываться он будет автоматически, нам делать для этого ничего не нужно.

<?php

use DateDateFormat;
use IlluminateDatabaseEloquentModel as Eloquent;

abstract class Model extends Eloquent
{

    public function getCreatedAtAttribute($attr)
    {
        return DateFormat::post($attr);
    }

}

Данный код говорит сам за себя: при получении свойства модели created_at (название атрибута преобразуется в camelCase), верни значение обработанное методом post с помощью нашей библиотеки DateFormat. Также, можно создать методы для атрибутов updated_at, deleted_at и прочих.

Теперь можно проверить все на практике, ниже будет пример модели и контроллера для получения всех постов.

Модель app/models/Post.php:

<?php

class Post extends Model
{

    /**
     * @var string The table associated with the model.
     */
    protected $table = 'posts';
}

Контроллер app/controllers/PostController.php

<?php

class PostController extends Controller
{

    public function index()
    {
        return Post::all();
    }

}

Обратимся к нашему контроллеру (не забудьте прописать условия маршрутизации) и получим на выходе массив наших постов в json-формате, где свойство created_at будет отформатировано в необходимом языке и формате.

Реализовать такой функционал можно с помощью ServiceProvider, что будет еще более простым способом. Но данный способ нагляднее.

Буду рад услышать комментарии по коду. Хотелось бы узнать, какие есть best practices для решения подобных задач.

Автор: Khaperets

Источник

Поделиться

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