Я пытаюсь создать список архивов для статей в блогах. Список архивов должен отображать год и дату в обратном хронологическом порядке следующим образом:
2013 (21) - May (2) - April (3) - March (5) - February (1) - January (10) 2012 (10) - December (6) - November (4)
Число внутри ()
– это количество сообщений за этот период времени. Когда выбран год или месяц года, должны отображаться только сообщения в блоге за выбранный период времени.
Пока мне удалось узнать год и месяц каждого блога, сделав:
$posts = Post::all(); $archive = array(); foreach ($posts as $post) { $year = date('Y', strtotime($post->created_at)); $month = date('m', strtotime($post->created_at)); }
Как я могу достичь вышеуказанных целей?
Для создания ссылок на какой-либо панели навигации вы можете выполнять большую часть обработки на стороне БД и не извлекать все записи записей в блогах с таким запросом
SELECT YEAR(created_at) year, MONTH(created_at) month, MONTHNAME(created_at) month_name, COUNT(*) post_count FROM post GROUP BY year, MONTH(created_at) ORDER BY year DESC, month DESC;
Вывод:
| YEAR | MONTH | MONTH_NAME | POST_COUNT | ------------------------------------------ | 2013 | 5 | May | 5 | | 2013 | 4 | April | 3 | | 2013 | 3 | March | 4 | | 2013 | 2 | February | 3 | | 2013 | 1 | January | 2 | | 2012 | 12 | December | 2 | | 2012 | 11 | November | 3 |
Я не специалист в laravel, но это должно быть достигнуто с чем-то похожим на это
$links = DB::table('post') ->select(DB::raw('YEAR(created_at) year, MONTH(created_at) month, MONTHNAME(created_at) month_name, COUNT(*) post_count')) ->groupBy('year') ->groupBy('month') ->orderBy('year', 'desc') ->orderBy('month', 'desc') ->get();
Если вы хотите, вы можете добавить промежуточные итоги в строки года, подобные этому
SELECT YEAR(created_at) year, MONTH(created_at) month, MONTHNAME(created_at) month_name, COUNT(*) post_count FROM post GROUP BY year, MONTH(created_at) UNION ALL SELECT YEAR(created_at) year, 13 month, NULL month_name, COUNT(*) post_count FROM post GROUP BY year ORDER BY year DESC, month DESC;
Вывод:
| YEAR | MONTH | MONTH_NAME | POST_COUNT | ------------------------------------------ | 2013 | 13 | (null) | 17 | | 2013 | 5 | May | 5 | | 2013 | 4 | April | 3 | | 2013 | 3 | March | 4 | | 2013 | 2 | February | 3 | | 2013 | 1 | January | 2 | | 2012 | 13 | (null) | 5 | | 2012 | 12 | December | 2 | | 2012 | 11 | November | 3 |
SQLFiddle
Это самый элегантный способ сделать это, чтобы передать закрытие в метод groupBy ().
$posts_by_date = Post::all()->groupBy(function($date) { return Carbon::parse($date->created_at)->format('Y-m'); });
Затем вы можете пропустить его в своем шаблоне лезвия, подобном этому:
@foreach ($posts_by_date as $date => $posts) <h2>{{ $date }}</h2> @foreach ($posts as $post) <h3>{{ $post->title }}</h3> {{ $post->content }} @endforeach @endforeach
Я думаю, вы близки, но вам нужно проверить данные, это то, что вы спрашиваете?
Вы также можете запросить данные.
Я не говорю, что это единственный способ решить проблему, но как это будет работать? Для каждого оператора можно было хранить данные в массиве, что-то вроде этого:
function checkdate($datein,$posts){ foreach ($posts as $post){ $year = date('Y', strtotime($post->created_at))) $month = date('m', strtotime($post->created_at))) if(($year == $datein->year)||($month == $datein->month)){ //good } else { //bad } } }
Это могло бы сделать трюк, но … что, если бы мы отфильтровали данные в первую очередь. Готов поспорить, у Laravel есть лучший способ справиться с этим.
Ага! http://four.laravel.com/docs/eloquent#query-scopes
продолжать читать о полиморфизме и запросить отношения, динамические свойства …