Yii Dataprovider сортировка даты

У меня ArrayDataProvider с полем типа DateTime — дата рождения.
Я использую этот поставщик данных для вида сетки в разделе просмотра.

Поскольку даты рождения включают год рождения, сортировка работает не так, как ожидалось.
Есть ли способ как-то сказать механизму сортировки не учитывать годы, а сортировать только по месяцам и дням? Пользовательская функция сортировки возможно?

Редактировать: Что-то вроде sort в C ++, где вы можете передать функцию сравнения.

Отредактировано текущее описание решения:
Мое решение в настоящее время состоит в том, чтобы включить год рождения в качестве отдельного поля в массиве, а годы рождения установлены на текущий год. Теперь даты с того же года и сортировка работает. Но отдельное поле для года рождения не кажется правильным. Я хотел бы получить все необходимые данные из одного объекта даты.

Это отдельное поле размалывает мои механизмы. Это не идеально.

Редактировать:
Ох, и его Yii2

Обновить
Есть также функции сортировки массивов PHP, которые принимают обратный вызов сравнения — например, uasort, который можно использовать в ассоциативных массивах, таких как мой:

uasort($persons, function($a, $b){
return strcasecmp( $b['date']->format('m-d'), $a['date']->format('m-d') );
});

Теперь мне нужно найти способ реализовать его в ArrayDataProvider. Есть идеи здесь?

3

Решение

Если у вас есть поставщик данных массива, вы, конечно, не можете использовать сортировку базы данных.

Чтобы разрешить сортировку по какому-либо выражению, необходимо предварительно рассчитать значение и настроить сортировку для атрибута, чтобы использовать вычисленное значение вместо исходного:

// assuming $data contains your data and 'birthdate' is the value you want to use for sorting

foreach($data as $key => $value) {
$data[$key]['sort_birthdate'] = date('m-d', strtotime($value['birthdate']));
}
$dataProvider = new \yii\data\ArrayDataProvider([
'allModels' => $data,
'sort' => [
'attributes' => [
'birthdate' => [
'asc' => [
'sort_birthdate' => SORT_ASC,
],
'desc' => [
'sort_birthdate' => SORT_DESC,
],
'label' => 'Date',
'default' => SORT_ASC
],
// list all other attributes here
],
]
]);

Если вам нужна пользовательская функция сравнения, вы должны расширить класс Yii для поддержки этого.
Вы можете создать кастом ArrayDataProvider класс, который происходит от того, который поставляется с Yii и переопределить sortModels ()-метод.

3

Другие решения

Вы должны попробовать что-то вроде

use yii\db\Expression;
$dataProvider->setSort([
'attributes' => [
................................
'birthday' => [
'asc' => [
new Expression('DATE_FORMAT(birthday, "%m%d")') => SORT_ASC,
],
'desc' => [
new Expression('DATE_FORMAT(birthday, "%m%d")') => SORT_DESC,
],
'label' => 'Birthday',
'default' => SORT_ASC
],
................................
]
]);

Я не пробовал это.

Что работает наверняка, это сделать что-то вроде этого

$query->select([
new Expression('DATE_FORMAT(birthday, "%m%d") as show_date'),
.................................
]);

затем

    /**
* Setup your sorting attributes
* Note: This is setup before the $this->load($params)
* statement below
*/
$dataProvider->setSort([
'attributes' => [
'id',
'show_date' => [
'asc' => [
'sort_date' => SORT_ASC,
],
'desc' => [
'sort_date' => SORT_DESC,
],
'label' => 'Date',
'default' => SORT_ASC
],
'price',
'gst',
'cost',
'quantity',
'profit',
]
]);
1