1
votes

PHP Laravel comment regrouper les données de date en mois et ajouter un en-tête

Je suis en train de créer une petite application Laravel dans laquelle je souhaite afficher des versions spécifiques regroupées par mois. Quelque chose comme ceci:

@foreach ($releases as $release)
     <div>
        <p>
            <span>{{ \Carbon\Carbon::parse($release->release_date)->format('d. M')}}</span>&nbsp;
            <span>{{$release->artist}} - {{$release->album_title}} </span>
        </p>
    </div>
@endforeach

Donc, dans mon contrôleur, je fais juste ceci:

public function index() {

  $releases = Release::orderBy('release_date', 'asc')->get();

  return view('pages.index')->with('releases', $releases);
}

Et dans mon fichier de vue en lame, je loppe le data:

January
11.1 - blabla
       more blablabla the same day

15.1 - blablabla

February
05.2 - blabla

etc...

Cela me donne les données correctes, par exemple une liste des entrées de base de données, mais comme mentionné précédemment, je veux les regrouper par mois et ajouter en plus un en-tête pour chaque mois. Comment puis-je y parvenir?

J'utilise Laravel 5.5 si cela compte ...


0 commentaires

8 Réponses :


0
votes

UNION ALL est le meilleur moyen de regrouper les données d'en-tête et de date en mois


0 commentaires

0
votes

Vous pouvez utiliser la méthode Collection :: groupBy () comme ceci:

[
    "January" => Collection{Release, Release, Release},
    "February" => Collection{Release, Release, Release},
    ...
]

Maintenant $ releases est Collection avec le nom du mois comme clé et Collection (tableau de Releases ) comme valeur comme celle-ci:

$releases->groupBy(function(Release $release) {
     return $release->release_date->format('F');
});

N'oubliez pas les années;)


0 commentaires

0
votes

Si vous utilisez la méthode -> get () -> groupBy ('release_date'), elle renvoie les objets par date.

Par exemple;

public function index() {

  $releases = Release::orderBy('release_date', 'asc')->get()->groupBy('release_date');

  return view('pages.index')->with('releases', $releases);
}

Je pense résoudre votre problème.


0 commentaires

1
votes
public function index() {

    $releases = Release::orderBy('release_date', 'asc')
            ->get()->groupBy('release_date.month');

    return view('pages.index')->with('releases_groups', $releases);
}

@foreach ($releases_groups as $month => $releases_group)
    // just place group info here...
    @foreach ($releases_group as $release)
    <div>
        <p>
          <span>{{ \Carbon\Carbon::parse($release->release_date)->format('d. M')}}</span>&nbsp;
          <span>{{$release->artist}} - {{$release->album_title}} </span>
        </p>
    </div>
  @endforeach
@endforeach
Try this.

11 commentaires

La clé est groupBy ('release_date.month')


hmm, j'obtiens Colonne introuvable en essayant ceci: - /


Je l'avais corrigé, placez -> groupBy ('release_date.month') après get () , et tout ira bien.


ah je vois mais hmm ... je ne tire pas le nom des mois de ça ...: s


Ouais, j'avais édité le code, la clé de collection est month , et c'est un entier de 1 ~ 12 , mais je ne sais pas si ce format est ce que vous vouloir.


Tous les formats disponibles sont month , localeMonth , shortLocaleMonth , englishMonth , shortEnglishMonth , vous peut essayer et voir ce que tu veux


Ah alors comment puis-je faire sortir les informations du groupe?


@foreach ($ releases_groups as $ month => $ releases_group) , le $ month est la seule information de groupe à ce jour, hmm, n'est-ce pas suffisant?


ah mon mauvais, je viens de le voir :-) Alors maintenant, je dois juste comparer la valeur entière et renvoyer la chaîne correcte comme 1 = janvier, 2 = février, etc.?


Vous n'avez pas besoin de faire cela, utilisez plutôt un format différent, par exemple, -> groupBy ('release_date.englishMonth') , le $ month serait 'January ',' Février ', etc. Tous les formats de mois disponibles ont déjà été répertoriés


Après avoir examiné les autres réponses, une chose importante que vous devez savoir est que groupBy est utilisé pour regrouper votre ensemble de résultats. Cela signifie que si vous utilisez paginer au lieu de get , le même mois de la vie réelle peut ne pas être groupé correctement.



1
votes

Je suggère que votre contrôleur fasse plus de travail:

// For each release date first
@foreach ($releaseDates as $releaseDate)
     <div>
        <p>
            //Print out the date as requested
            <span>{{ \Carbon\Carbon::parse($releaseDate->Date)->format('d. M')}}</span>&nbsp;
            // Now loop through each record nested as an array inside the date
            @foreach($releaseDate['data'] as $data)
                 <span>{{$data->artist}} - {{$data->album_title}} </span>
                 <br>
            @endforeach
        </p>
    </div>
@endforeach

Ensuite, à votre avis:

public function index() {

  // Here we get a distinct list of dates in your format
  $releaseDates = Release::Selectraw('date_format(date(release_date),"%d.%m") as Date')->distinct()->get();

  // For each date we now get the elements for each date and put them as an array entry in to the date under a 'data' section
  foreach($releaseDates as $releaseDate){
     $releaseDate['data'] = Release::whereraw('date_format(date(release_date),"%d.%m") = '.$releaseDate->Date)->get();
  }

  // Pass the data to the view as before but with new name
  return view('pages.index')->with('releaseDates', $releaseDates );
}


2 commentaires

Maintenant, chaque entrée a la même date :-)


@ ST80 J'ai ajouté quelques commentaires, notez la deuxième boucle foreach dans votre vue en lame maintenant qui est nécessaire pour extraire les enregistrements sous chaque date.



0
votes

Qu'en est-il de quelque chose comme ça (dans votre contrôleur)?

$groupedReleases = null;

foreach ($releases as $release) {
    $date = $release->release_date->format('your desired format');
    $groupedReleases[$date][] = $release;
}

return $groupedReleases;


0 commentaires

2
votes

Vous pouvez le faire comme ceci:

Tableau: versions

@foreach($month_headers as $header)
    {{getMonthName($header->month)." (".$header->header.")"}}
    <ul>
        @foreach($month_headers->releases() as $release)
            <li>{{date('d.m', strtotime($release->released_at))." - ".$release->bla_details}}</li>
        @endforeach
    </ul>
@endforeach

Tableau: en-têtes_mois p>

public function temp()
{
    $response['month_headers'] = MonthHeader::all();
    return view('tempView', $response);
}

Modèle: Release.php

public function releases() 
{
    return $this->hasMany('App\Models\Release');
}

Modèle: MonthHeader.php strong>

public function month_header() 
{
    return $this->belongsTo('App\Models\Month');
}

Aide: getMonthName ($ integer)

Controller: TempController.php

id    |    month(specific length int)    |    year(specific length int)    |    header

Affichage de la lame: tempView.blade.php

id    |    released_at    |    bla_details    |    month_header_id

Afficher la sortie

Janvier (en-tête de janvier)

  • 11.1 - blabla
  • 15.1 - blablabla

Février (en-tête de février)

  • 05.2 - blabla
  • 06.2 - blabla

etc...


2 commentaires

Explication ajoutée.


Très belle solution aussi! :-)



0
votes

Voir la fonction de sélection ci-dessous avec une requête brute où j'ai ajouté "Nom du mois" et "numéro du mois" pour votre référence. Veuillez vérifier la sortie. J'espère que cela vous aidera

    $releaseArray=[];
    if(!empty($releases)) {
        foreach($releases as $release){
            $releaseArray[$release->month][] = $release;
        }
    }

    print_r($releaseArray);

Vous pouvez utiliser GroupBy si vous êtes sûr qu'il n'y a pas plus d'une version à la même date.

$releases = Release::select(DB::raw('some_field, MONTHNAME(release_date) as month_name, MONTHNAME(release_date) as month'))
                          ->orderBy('release_date', 'asc')->get();

Vous pouvez maintenant passer le $ releaseArray à la vue et itérer pour les versions regroupées par mois.


0 commentaires