Simple but well-ordered initial user listing

This commit is contained in:
dece 2023-10-01 22:46:37 +02:00
parent 2b1da5098b
commit 0a1714f3ca
5 changed files with 71 additions and 0 deletions

View file

@ -0,0 +1,28 @@
<?php
namespace App\Controller;
use App\Entity\User;
use App\Repository\ReleaseRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class UserReleasesController extends AbstractController
{
#[Route('/@{username}/releases', name: 'app_user_releases')]
public function index(
User $user,
ReleaseRepository $releaseRepository,
): Response
{
$releases = $releaseRepository->getUserListing($user);
return $this->render(
'user_releases/index.html.twig',
[
'username' => $user->getUsername(),
'releases' => $releases,
]
);
}
}

View file

@ -19,6 +19,7 @@ class Release
private ?string $title = null; private ?string $title = null;
#[ORM\ManyToMany(targetEntity: Artist::class, inversedBy: 'releases')] #[ORM\ManyToMany(targetEntity: Artist::class, inversedBy: 'releases')]
#[ORM\OrderBy(['name' => 'ASC'])]
private Collection $artists; private Collection $artists;
#[ORM\ManyToOne(inversedBy: 'releases')] #[ORM\ManyToOne(inversedBy: 'releases')]

View file

@ -34,6 +34,7 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
private ?string $username = null; private ?string $username = null;
#[ORM\OneToMany(mappedBy: 'owner', targetEntity: Release::class)] #[ORM\OneToMany(mappedBy: 'owner', targetEntity: Release::class)]
#[ORM\OrderBy(['title' => 'ASC'])]
private Collection $releases; private Collection $releases;
public function __construct() public function __construct()

View file

@ -3,6 +3,7 @@
namespace App\Repository; namespace App\Repository;
use App\Entity\Release; use App\Entity\Release;
use App\Entity\User;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry; use Doctrine\Persistence\ManagerRegistry;
@ -20,4 +21,31 @@ class ReleaseRepository extends ServiceEntityRepository
{ {
parent::__construct($registry, Release::class); parent::__construct($registry, Release::class);
} }
/**
* Return the user release listing as an array of associative arrays.
*
* The listing includes all releases with this user as owner. Items are sorted by the "artist aggregation" name. An
* artist aggregation is the joint names of all artists linked to a release. Within an artist aggregation (which
* most of the time is probably just an artist name), releases are sorted by title (should be by release date).
*
* Included data is:
* - release_id
* - title
* - artists (artist aggregation)
*
* @return array<int,array<string,mixed>>
*/
public function getUserListing(User $user): array
{
return $this->getEntityManager()->getConnection()->executeQuery('
SELECT r.id AS release_id, title, string_agg(name, \' & \' ORDER BY name) AS artists
FROM release r
JOIN release_artist ra ON ra.release_id = r.id
JOIN artist a ON a.id = ra.artist_id
GROUP BY r.id
--HAVING COUNT(*) > 1
ORDER BY artists, title
')->fetchAllAssociative();
}
} }

View file

@ -0,0 +1,13 @@
{% extends 'base.html.twig' %}
{% block title %}{{ username }} releases{% endblock %}
{% block body %}
<h1>{{ username }} releases</h1>
<ul>
{% for release in releases %}
<li>{{ release.artists }}{{ release.title }}</li>
{% endfor %}
</ul>
{% endblock %}