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;
|
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')]
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
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