Passed
Push — main ( 7dcca1...e70bce )
by Daniel
04:22
created

CatalogCleaner::clean()   B

Complexity

Conditions 10
Paths 50

Size

Total Lines 74
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 45
CRAP Score 10

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 40
c 1
b 0
f 0
dl 0
loc 74
ccs 45
cts 45
cp 1
rs 7.6666
cc 10
nc 50
nop 2
crap 10

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Uxmp\Core\Component\Catalog\Manage;
6
7
use Ahc\Cli\IO\Interactor;
8
use Uxmp\Core\Component\Album\AlbumDeleterInterface;
9
use Uxmp\Core\Component\Catalog\Manage\Update\AudioFileRetrieverInterface;
10
use Uxmp\Core\Component\Song\SongDeleterInterface;
11
use Uxmp\Core\Orm\Model\AlbumInterface;
12
use Uxmp\Core\Orm\Repository\AlbumRepositoryInterface;
13
use Uxmp\Core\Orm\Repository\ArtistRepositoryInterface;
14
use Uxmp\Core\Orm\Repository\CatalogRepositoryInterface;
15
use Uxmp\Core\Orm\Repository\DiscRepositoryInterface;
16
use Uxmp\Core\Orm\Repository\SongRepositoryInterface;
17
18
final readonly class CatalogCleaner implements CatalogCleanerInterface
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected T_READONLY, expecting T_CLASS on line 18 at column 6
Loading history...
19
{
20 3
    public function __construct(
21
        private CatalogRepositoryInterface $catalogRepository,
22
        private AlbumDeleterInterface $albumDeleter,
23
        private SongRepositoryInterface $songRepository,
24
        private SongDeleterInterface $songDeleter,
25
        private DiscRepositoryInterface $discRepository,
26
        private AlbumRepositoryInterface $albumRepository,
27
        private AudioFileRetrieverInterface $audioFileRetriever,
28
        private ArtistRepositoryInterface $artistRepository,
29
    ) {
30 3
    }
31
32 3
    public function clean(Interactor $io, int $catalogId): void
33
    {
34 3
        $catalog = $this->catalogRepository->find($catalogId);
35 3
        if ($catalog === null) {
36 1
            $io->error(
37 1
                sprintf('Catalog `%d` not found', $catalogId),
38 1
                true
39 1
            );
40 1
            return;
41
        }
42
43 2
        $directory = $catalog->getPath();
44
45 2
        if (!is_dir($directory)) {
46 1
            $io->error(
47 1
                sprintf('The path `%s` is not accessible', $directory),
48 1
                true
49 1
            );
50 1
            return;
51
        }
52
53 1
        $io->info('Cleaning catalog', true);
54
55 1
        $songs = $this->songRepository->findBy(['catalog' => $catalog]);
56
57 1
        foreach ($songs as $song) {
58 1
            $audioFile = $this->audioFileRetriever->build($song->getFilename());
59
60
            // File is no longer readable
61 1
            if ($audioFile === null) {
62 1
                $io->info(
63 1
                    sprintf('Delete `%s - %s`', $song->getArtist()->getTitle(), $song->getTitle()),
64 1
                    true
65 1
                );
66
67 1
                $this->songDeleter->delete($song);
68 1
                continue;
69
            }
70
71
            // File's mbid has been changed
72 1
            if ($song->getMbid() !== $audioFile->getMbid()) {
73 1
                $this->songDeleter->delete($song);
74
            }
75
        }
76
77 1
        $discs = $this->discRepository->findEmptyDiscs($catalog);
78
79 1
        foreach ($discs as $disc) {
80 1
            $album = $disc->getAlbum();
81
82 1
            $io->info(
83 1
                sprintf('Delete disc number `%d` of `%s`', $disc->getNumber(), $album->getTitle()),
84 1
                true
85 1
            );
86
87 1
            $this->discRepository->delete($disc);
88
89 1
            if ($album->getDiscCount() === 0) {
90 1
                $this->deleteAlbum($album, $io);
91
            }
92
        }
93
94 1
        $albums = $this->albumRepository->findEmptyAlbums($catalog);
95 1
        foreach ($albums as $album) {
96 1
            $this->deleteAlbum($album, $io);
97
        }
98
99
        // delete empty artists
100 1
        $artists = $this->artistRepository->getAllHavingNoRelations();
101 1
        foreach ($artists as $artist) {
102 1
            $this->artistRepository->delete($artist);
103
        }
104
105 1
        $io->ok('Done', true);
106
    }
107
108 1
    private function deleteAlbum(AlbumInterface $album, Interactor $io): void
109
    {
110 1
        $io->info(
111 1
            sprintf('Delete orphaned album `%s`', $album->getTitle()),
112 1
            true
113 1
        );
114
115 1
        $this->albumDeleter->delete($album);
116
    }
117
}
118