2013-05-11 17 views
5

Blog makaleleri için bir arşiv listesi oluşturmaya çalışıyorum. aşağıdaki gibi arşiv listesi ters kronolojik sırayla yıl ve tarih göstermesi gerekir:Laravel'de bir blog için arşiv listesi oluşturuluyor

2013 (21) 
    - May (2) 
    - April (3) 
    - March (5) 
    - February (1) 
    - January (10) 
2012 (10) 
    - December (6) 
    - November (4) 

() içindeki sayı bu süre içinde mesajların sayısıdır. Yılın yılı veya ayı seçildiğinde, yalnızca seçilen zaman aralığındaki blog yayınları görüntülenmelidir.

Bugüne kadar yalnızca yaparak her blog yayınının yılı ve ayı öğrenmek mümkün oldum:

$posts = Post::all(); 
$archive = array(); 
foreach ($posts as $post) { 
    $year = date('Y', strtotime($post->created_at)); 
    $month = date('m', strtotime($post->created_at)); 
} 

nasıl Yukarıda belirtilen amaçlara ulaşmada gidiyorsun?

cevap

14

Bu

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; 

Çıktı gibi bir sorgu ile:

| 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 | 

ben laravel konusunda uzman değilim, ama bu s

| 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

+0

Teşekkür

arşiv oluşturmak için: Biraz daha laravel işlevini kullanarak derken şu çözüm geldi . SQL sorgusu çalıştı, ama Laravel'de işlenmemiş sorguların yolu olduğunu düşünmüyorum, bu yüzden işe yaramadı. – SUB0DH

+0

Bu benim için Laravel 4.2'de harika çalıştı. Teşekkürler! – NightMICU

0

Sanırım yakınsınız ama verileri test etmeniz gerekiyor, sorduğunuz şey bu mu?

Ayrıca verileri sorgulayabilirsiniz.

Bu sorunun çözülmesinin tek yolu olduğunu söylemiyorum ama nasıl çalışır? Biz ilk etapta verileri filtreden olsaydı ... ne hile yapacağını

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 
     } 
    } 
} 

ama: her ifade için, bir diziye böyle bir şey verilerini saklamak için olabilir. Laravel'in bunu halletmenin daha iyi bir yolu olduğuna bahse girerim.

Evet! polimorfizm ve sorgulama ilişkiler, dinamik özellikleri hakkında okuma http://four.laravel.com/docs/eloquent#query-scopes

tutmak ... gezinme panelinin çeşit DB tarafında işleme çoğunu yapmak ve tüm blog yayınları kayıtları getirilirken edemez bir bağlantıları oluşturmak için

14

: hould Bunu

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; 

Çıktı gibi yıl satırlara alt toplamları ekleyebilir istiyorsanız bu

$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(); 

benzer bir şey ile sağlanabilir Bu en şık yol t o bunu groupBy() toplama yöntemine bir kapatma geçirmek olurdu.

$posts_by_date = Post::all()->groupBy(function($date) { 
    return Carbon::parse($date->created_at)->format('Y-m'); 
}); 

Sonra yapabilirsiniz buna benzer blade şablonda içinden döngü: Ben de bir süre için bu tıkanmıştım

@foreach ($posts_by_date as $date => $posts) 
    <h2>{{ $date }}</h2> 
    @foreach ($posts as $post) 
     <h3>{{ $post->title }}</h3> 
     {{ $post->content }} 
    @endforeach 
@endforeach 
+0

Çok zarif! Varsayılan olarak bir problem, sıralama asc! 2013'e, 2014'e, vs… Başlamak nasıl? – kesm0

+0

Çözümü buluyorum: Haberler :: orderBy ('created_at', 'desc') -> get() -> groupBy (işlev ($ date) – kesm0

+1

Bu OP'nin sorduğu tam olarak geri gelmiyor, bir liste istedi ayların her birindeki mesajların sayısı ile, bu aylar içinde düzenlenmiş gönderilerin kendilerini döndürürken, buradaki sorunu çözmek için 'count()' ı kullanabilirsiniz, ama yine de birçok gereksiz bilgiyi verir ... Ama belki de hala daha hızlı bir özel SQL sorgusu? Bilmiyorum ... – amosmos

0

.

$archive = Post::orderBy('created_at', 'desc') 
     ->whereNotNull('created_at') 
     ->get() 
     ->groupBy(function(Post $post) { 
      return $post->created_at->format('Y'); 
     }) 
     ->map(function ($item) { 
      return $item 
       ->sortByDesc('created_at') 
       ->groupBy(function ($item) { 
        return $item->created_at->format('F'); 
       }); 
     }); 

Sonra (Bootstrap 4 sınıfları dahil) Görüntülü:

<div class="archive mt-5"> 
<h4>Archive</h4> 

@foreach($archive as $year => $months) 
    <div> 
     <div id="heading_{{ $loop->index }}"> 
      <h6 class="mb-0"> 
       <button class="btn btn-link py-0 my-0" data-toggle="collapse" 
         data-target="#collapse_{{ $loop->index }}" 
         aria-expanded="true" 
         aria-controls="collapse_{{ $loop->index }}"> 
        > 
       </button> 
       {{ $year }} 
      </h6> 
     </div> 

     <div id="collapse_{{ $loop->index }}" class="collapse" aria-labelledby="heading_{{ $loop->index }}" 
      data-parent="#accordion"> 
      <div> 
       <ul style="list-style-type: none;"> 
        @foreach($months as $month => $posts) 
         <li class=""> 
           {{ $month }} ({{ count($posts) }}) 
         </li> 

        @endforeach 
       </ul> 
      </div> 
     </div> 
    </div> 
@endforeach 

İlgili konular