Passed
Push — main ( e933de...5ef56a )
by Daniel
03:35
created

CatalogCleaner::clean()   B

Complexity

Conditions 9
Paths 26

Size

Total Lines 69
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 42
CRAP Score 9

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 37
c 1
b 0
f 0
dl 0
loc 69
ccs 42
cts 42
cp 1
rs 7.7724
cc 9
nc 26
nop 2
crap 9

How to fix   Long Method   

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\CatalogRepositoryInterface;
14
use Uxmp\Core\Orm\Repository\DiscRepositoryInterface;
15
use Uxmp\Core\Orm\Repository\SongRepositoryInterface;
16
17
final class CatalogCleaner implements CatalogCleanerInterface
18
{
19 3
    public function __construct(
20
        private readonly CatalogRepositoryInterface $catalogRepository,
21
        private readonly AlbumDeleterInterface $albumDeleter,
22
        private readonly SongRepositoryInterface $songRepository,
23
        private readonly SongDeleterInterface $songDeleter,
24
        private readonly DiscRepositoryInterface $discRepository,
25
        private readonly AlbumRepositoryInterface $albumRepository,
26
        private readonly AudioFileRetrieverInterface $audioFileRetriever
27
    ) {
28 3
    }
29
30 3
    public function clean(Interactor $io, int $catalogId): void
31
    {
32 3
        $catalog = $this->catalogRepository->find($catalogId);
33 3
        if ($catalog === null) {
34 1
            $io->error(
35 1
                sprintf('Catalog `%d` not found', $catalogId),
36 1
                true
37 1
            );
38 1
            return;
39
        }
40
41 2
        $directory = $catalog->getPath();
42
43 2
        if (!is_dir($directory)) {
44 1
            $io->error(
45 1
                sprintf('The path `%s` is not accessible', $directory),
46 1
                true
47 1
            );
48 1
            return;
49
        }
50
51 1
        $io->info('Cleaning catalog', true);
52
53 1
        $songs = $this->songRepository->findBy(['catalog' => $catalog]);
54
55 1
        foreach ($songs as $song) {
56 1
            $audioFile = $this->audioFileRetriever->build($song->getFilename());
57
58
            // File is no longer readable
59 1
            if ($audioFile === null) {
60 1
                $io->info(
61 1
                    sprintf('Delete `%s - %s`', $song->getArtist()->getTitle(), $song->getTitle()),
62 1
                    true
63 1
                );
64
65 1
                $this->songDeleter->delete($song);
66 1
                continue;
67
            }
68
69
            // File's mbid has been changed
70 1
            if ($song->getMbid() !== $audioFile->getMbid()) {
71 1
                $this->songDeleter->delete($song);
72
            }
73
        }
74
75 1
        $discs = $this->discRepository->findEmptyDiscs($catalog);
76
77 1
        foreach ($discs as $disc) {
78 1
            $album = $disc->getAlbum();
79
80 1
            $io->info(
81 1
                sprintf('Delete disc number `%d` of `%s`', $disc->getNumber(), $album->getTitle()),
82 1
                true
83 1
            );
84
85 1
            $this->discRepository->delete($disc);
86
87 1
            if ($album->getDiscCount() === 0) {
88 1
                $this->deleteAlbum($album, $io);
89
            }
90
        }
91
92 1
        $albums = $this->albumRepository->findEmptyAlbums($catalog);
93
94 1
        foreach ($albums as $album) {
95 1
            $this->deleteAlbum($album, $io);
96
        }
97
98 1
        $io->ok('Done', true);
99
    }
100
101 1
    private function deleteAlbum(AlbumInterface $album, Interactor $io): void
102
    {
103 1
        $io->info(
104 1
            sprintf('Delete orphaned album `%s`', $album->getTitle()),
105 1
            true
106 1
        );
107
108 1
        $this->albumDeleter->delete($album);
109
    }
110
}
111