GenreRepository::save()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 2
c 1
b 0
f 1
nc 1
nop 1
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Uxmp\Core\Orm\Repository;
6
7
use Doctrine\Common\Collections\ArrayCollection;
8
use Doctrine\ORM\EntityRepository;
9
use Doctrine\ORM\Query\Expr\Join;
10
use Doctrine\ORM\Query\Parameter;
11
use Generator;
12
use Uxmp\Core\Orm\Model\Genre;
13
use Uxmp\Core\Orm\Model\GenreInterface;
14
use Uxmp\Core\Orm\Model\GenreMap;
15
use Uxmp\Core\Orm\Model\GenreMapEnum;
16
17
/**
18
 * @extends EntityRepository<Genre>
19
 *
20
 * @method null|GenreInterface findOneBy(mixed[] $criteria)
21
 */
22
final class GenreRepository extends EntityRepository implements GenreRepositoryInterface
23
{
24 1
    public function prototype(): GenreInterface
25
    {
26 1
        return new Genre();
27
    }
28
29 1
    public function save(GenreInterface $genre): void
30
    {
31 1
        $this->getEntityManager()->persist($genre);
32 1
        $this->getEntityManager()->flush();
33
    }
34
35 1
    public function delete(GenreInterface $genre): void
36
    {
37 1
        $this->getEntityManager()->remove($genre);
38 1
        $this->getEntityManager()->flush();
39
    }
40
41
    /**
42
     * Retrieve a list of all genres and the number of albums/songs associated
43
     *
44
     * @return Generator<array{
45
     *  id: int,
46
     *  value: string,
47
     *  albumCount: int,
48
     *  songCount: int
49
     * }>
50
     */
51 1
    public function getGenreStatistics(): Generator
52
    {
53 1
        $query = $this->getEntityManager()
54 1
            ->createQueryBuilder()
55 1
            ->select(
56 1
                'a.id',
57 1
                'a.title',
58 1
                'count(b.id) as albumCount',
59 1
                'count(c.id) as songCount'
60 1
            )
61 1
            ->from(Genre::class, 'a')
62 1
            ->leftJoin(
63 1
                GenreMap::class,
64 1
                'b',
65 1
                Join::WITH,
66 1
                'b.genre_id = a.id AND b.mapped_item_type = :album_index_name'
67 1
            )
68 1
            ->leftJoin(
69 1
                GenreMap::class,
70 1
                'c',
71 1
                Join::WITH,
72 1
                'c.genre_id = a.id AND c.mapped_item_type = :song_index_name'
73 1
            )
74 1
            ->setParameters(new ArrayCollection([
75 1
                new Parameter('album_index_name', GenreMapEnum::ALBUM),
76 1
                new Parameter('song_index_name', GenreMapEnum::SONG),
77 1
            ]))
78 1
            ->groupBy('a.title')
79 1
            ->groupBy('a.id')
80 1
            ->having('COUNT(b.id) > 0')
81 1
            ->orderBy('a.title', 'ASC')
82 1
            ->getQuery();
83
84 1
        foreach ($query->toIterable() as $data) {
85 1
            yield [
86 1
                'id' => $data['id'],
87 1
                'value' => $data['title'],
88 1
                'albumCount' => (int) $data['albumCount'],
89 1
                'songCount' => (int) $data['songCount'],
90 1
            ];
91
        }
92
    }
93
}
94