Groups notes by year and month

This commit is contained in:
2025-05-24 09:25:38 +01:00
parent 4ad17f126b
commit a8b6d8674b
2 changed files with 129 additions and 6 deletions

View File

@@ -30,14 +30,108 @@ class GuiController extends AbstractController {
EntityManagerInterface $entityManager, EntityManagerInterface $entityManager,
): array { ): array {
$notes = $entityManager->getRepository(Note::class)->findAllOrderedBySlugDesc(); $notes = $entityManager->getRepository(Note::class)->findAllOrderedBySlugDesc();
$years = $this->getYears($notes);
$notesByYear = $this->groupByYear($notes);
$months = array_map(array: $years, callback: fn($year) => $this->getMonths($notesByYear[$year]));
$monthsByYear = array_combine(keys: $years, values: $months);
$groupByMonth = fn($notes) => $this->groupByMonth($notes);
$notesByYearAndMonth = array_map(
array: $notesByYear,
callback: $groupByMonth,
);
return [ return [
'title' => 'Joe Carstairs\' notes', 'title' => 'Joe Carstairs\' notes',
'description' => 'Joe Carstairs\' notes', 'description' => 'Joe Carstairs\' notes',
'notes' => $notes, 'notes' => $notesByYearAndMonth,
'years' => $years,
'months' => $monthsByYear,
'monthNames' => [
'01' => 'January',
'02' => 'February',
'03' => 'March',
'04' => 'April',
'05' => 'May',
'06' => 'June',
'07' => 'July',
'08' => 'August',
'09' => 'September',
'10' => 'October',
'11' => 'November',
'12' => 'December',
],
]; ];
} }
/**
* @param $notes Note[]
* @return Note[][]
*/
function groupByYear(array $notes): array {
$years = $this->getYears($notes);
$filterByYear = fn(string $year) =>
fn($note) => ($note->getPublishedDate()->format('Y') == $year);
$notesForYear = fn(string $year) =>
array_filter(array: $notes, callback: $filterByYear($year));
$notesByYear = array_map(
array: $years,
callback: $notesForYear,
);
return array_combine(keys: $years, values: $notesByYear);
}
/**
* @param $notes Note[]
* @return string[]
*/
function getYears(array $notes): array {
$getYear = fn(Note $note): string => $note->getPublishedDate()->format('Y');
$years = array_map(array: $notes, callback: $getYear);
$years = array_unique($years);
arsort($years);
return $years;
}
/**
* @param $notes Note[]
* @return Note[]
*/
function groupByMonth(array $notes): array {
$months = $this->getMonths($notes);
$filterByMonth = fn(string $month) =>
fn($note) => ($note->getPublishedDate()->format('m') == $month);
$notesByMonth = array_map(
array: $months,
callback: fn(string $month) =>
array_filter(array: $notes, callback: $filterByMonth($month)),
);
return array_combine(keys: $months, values: $notesByMonth);
}
/**
* @param $notes Note[]
* @return string[]
*/
function getMonths(array $notes): array {
$getMonth = fn(Note $note): string => $note->getPublishedDate()->format('m');
$months = array_map(array: $notes, callback: $getMonth);
$months = array_unique($months);
arsort($months);
return $months;
}
/**
* @param $notes Note[]
* @return Note[]
*/
function sortBySlug(array $notes): array {
$getSlug = fn(Note $note): string => $note->getSlug();
$slugs = array_map(array: $notes, callback: $getSlug);
$notesBySlug = array_combine(keys: $slugs, values: $notes);
krsort($notesBySlug);
return array_values($notesBySlug);
}
#[IsGranted('ROLE_EDITOR')] #[IsGranted('ROLE_EDITOR')]
#[Route('/notes/write')] #[Route('/notes/write')]
#[Template('/write_note.html.twig')] #[Template('/write_note.html.twig')]

View File

@@ -3,12 +3,41 @@
{% block content %} {% block content %}
<section> <section>
<h1>Notes</h1> <h1>Notes</h1>
<p>
Skip to:
<ul>
{% for year in years %}
<li><a href="#{{ year }}">{{ year }}</a></li>
{% endfor %}
</ul>
</p>
{% for note in notes %} {% for year in years %}
<h2><a href="/notes/{{ note.slug }}">Note {{ note.slug }}</a></h2> <h2 id="{{ year }}">{{ year }}</h2>
{% apply markdown_to_html %}
{{ note.content }} <p>
{% endapply %} Skip to:
<ul>
{% for month in months[year] %}
<li><a href="#{{ year }}-{{ month }}">{{ monthNames[month] }} {{ year }}</a></li>
{% endfor %}
</ul>
</p>
{% for month in months[year] %}
<h3 id="{{ year }}-{{ month }}">{{ monthNames[month] }}</h3>
{% for note in notes[year][month] %}
<h4><a href="/notes/{{ note.slug }}">Note {{ note.slug }}</a></h4>
<time datetime="{{ note.publishedDate.format('c') }}">
{{ note.publishedDate.format('j F Y') }}
</time>
{% apply markdown_to_html %}
{{ note.content }}
{% endapply %}
{% endfor %}
{% endfor %}
{% else %} {% else %}
<p>I have no notes.</p> <p>I have no notes.</p>
{% endfor %} {% endfor %}