Simple but well-ordered initial user listing
This commit is contained in:
parent
2b1da5098b
commit
0a1714f3ca
28
src/Controller/UserReleasesController.php
Normal file
28
src/Controller/UserReleasesController.php
Normal 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,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ class Release
|
|||
private ?string $title = null;
|
||||
|
||||
#[ORM\ManyToMany(targetEntity: Artist::class, inversedBy: 'releases')]
|
||||
#[ORM\OrderBy(['name' => 'ASC'])]
|
||||
private Collection $artists;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'releases')]
|
||||
|
|
|
@ -34,6 +34,7 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
|
|||
private ?string $username = null;
|
||||
|
||||
#[ORM\OneToMany(mappedBy: 'owner', targetEntity: Release::class)]
|
||||
#[ORM\OrderBy(['title' => 'ASC'])]
|
||||
private Collection $releases;
|
||||
|
||||
public function __construct()
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Release;
|
||||
use App\Entity\User;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
|
@ -20,4 +21,31 @@ class ReleaseRepository extends ServiceEntityRepository
|
|||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
13
templates/user_releases/index.html.twig
Normal file
13
templates/user_releases/index.html.twig
Normal 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 %}
|
Loading…
Reference in a new issue