Passed
Push — master ( 179943...1193c4 )
by Darko
09:13
created

TraktPipe::process()   F

Complexity

Conditions 27
Paths 1376

Size

Total Lines 114
Code Lines 63

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 63
c 1
b 0
f 0
dl 0
loc 114
rs 0
cc 27
nc 1376
nop 1

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
namespace App\Services\TvProcessing\Pipes;
4
5
use App\Services\TvProcessing\TvProcessingPassable;
6
use App\Services\TvProcessing\TvProcessingResult;
7
use Blacklight\processing\tv\TraktTv;
8
9
/**
10
 * Pipe for Trakt.tv API lookups.
11
 */
12
class TraktPipe extends AbstractTvProviderPipe
13
{
14
    protected int $priority = 50;
15
    private ?TraktTv $trakt = null;
16
17
    public function getName(): string
18
    {
19
        return 'Trakt';
20
    }
21
22
    public function getStatusCode(): int
23
    {
24
        return -3; // PROCESS_TRAKT
25
    }
26
27
    /**
28
     * Get or create the Trakt instance.
29
     */
30
    private function getTrakt(): TraktTv
31
    {
32
        if ($this->trakt === null) {
33
            $this->trakt = new TraktTv();
34
        }
35
        return $this->trakt;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->trakt could return the type null which is incompatible with the type-hinted return Blacklight\processing\tv\TraktTv. Consider adding an additional type-check to rule them out.
Loading history...
36
    }
37
38
    protected function process(TvProcessingPassable $passable): TvProcessingResult
39
    {
40
        $parsedInfo = $passable->getParsedInfo();
41
        $context = $passable->context;
42
43
        if ($parsedInfo === null || empty($parsedInfo['cleanname'])) {
44
            return TvProcessingResult::notFound($this->getName());
45
        }
46
47
        $cleanName = $parsedInfo['cleanname'];
48
49
        // Check if we've already failed this title
50
        if ($this->isInTitleCache($cleanName)) {
51
            $this->outputSkipped($cleanName);
52
            return TvProcessingResult::skipped('previously failed', $this->getName());
53
        }
54
55
        $trakt = $this->getTrakt();
56
        $siteId = false;
57
58
        // Find the Video ID if it already exists
59
        $videoId = $trakt->getByTitle($cleanName, TraktTv::TYPE_TV, TraktTv::SOURCE_TRAKT);
60
61
        if ($videoId !== 0) {
62
            $siteId = $trakt->getSiteIDFromVideoID('trakt', $videoId);
63
        }
64
65
        if ($videoId === 0) {
66
            // Not in local DB, search Trakt
67
            $this->outputSearching($cleanName);
68
69
            $traktShow = $trakt->getShowInfo((string) $cleanName);
70
71
            if (is_array($traktShow)) {
0 ignored issues
show
introduced by
The condition is_array($traktShow) is always true.
Loading history...
72
                $videoId = $trakt->add($traktShow);
73
                $siteId = (int) $traktShow['trakt'];
74
            }
75
        } else {
76
            $this->outputFoundInDb($cleanName);
77
        }
78
79
        if ((int) $videoId === 0 || (int) $siteId === 0) {
80
            // Show not found
81
            $this->addToTitleCache($cleanName);
82
            $this->outputNotFound($cleanName);
83
            return TvProcessingResult::notFound($this->getName(), ['title' => $cleanName]);
84
        }
85
86
        // Process episode
87
        $seriesNo = ! empty($parsedInfo['season']) ? preg_replace('/^S0*/i', '', (string) $parsedInfo['season']) : '';
88
        $episodeNo = ! empty($parsedInfo['episode']) ? preg_replace('/^E0*/i', '', (string) $parsedInfo['episode']) : '';
89
        $hasAirdate = ! empty($parsedInfo['airdate']);
90
91
        if ($episodeNo === 'all') {
92
            // Full season release
93
            $trakt->setVideoIdFound($videoId, $context->releaseId, 0);
94
            $this->outputFullSeason($cleanName);
95
            return TvProcessingResult::matched($videoId, 0, $this->getName(), ['full_season' => true]);
96
        }
97
98
        // Download all episodes if new show to reduce API/bandwidth usage
99
        if (! $trakt->countEpsByVideoID($videoId)) {
100
            $trakt->getEpisodeInfo($siteId, -1, -1);
0 ignored issues
show
Bug introduced by
It seems like $siteId can also be of type false; however, parameter $siteId of Blacklight\processing\tv\TraktTv::getEpisodeInfo() does only seem to accept integer|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

100
            $trakt->getEpisodeInfo(/** @scrutinizer ignore-type */ $siteId, -1, -1);
Loading history...
101
        }
102
103
        // Check if we have the episode for this video ID
104
        $episode = $trakt->getBySeasonEp($videoId, $seriesNo, $episodeNo, $parsedInfo['airdate'] ?? '');
105
106
        if ($episode === false) {
107
            if ($seriesNo !== '' && $episodeNo !== '') {
108
                // Try to get episode from Trakt
109
                $traktEpisode = $trakt->getEpisodeInfo($siteId, (int) $seriesNo, (int) $episodeNo);
110
111
                if ($traktEpisode) {
0 ignored issues
show
introduced by
$traktEpisode is a non-empty array, thus is always true.
Loading history...
Bug Best Practice introduced by
The expression $traktEpisode of type array<string,integer|mixed|string> is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
112
                    $episode = $trakt->addEpisode($videoId, $traktEpisode);
113
                }
114
            }
115
116
            if ($episode === false && $hasAirdate) {
117
                // Refresh episode cache and attempt airdate match
118
                $trakt->getEpisodeInfo($siteId, -1, -1);
119
                $episode = $trakt->getBySeasonEp($videoId, 0, 0, $parsedInfo['airdate']);
120
            }
121
        }
122
123
        if ($episode !== false && is_numeric($episode) && $episode > 0) {
124
            // Success!
125
            $trakt->setVideoIdFound($videoId, $context->releaseId, $episode);
126
            $this->outputMatch(
127
                $cleanName,
128
                $seriesNo !== '' ? (int) $seriesNo : null,
129
                $episodeNo !== '' ? (int) $episodeNo : null,
130
                $hasAirdate ? $parsedInfo['airdate'] : null
131
            );
132
            return TvProcessingResult::matched($videoId, (int) $episode, $this->getName());
133
        }
134
135
        // Episode not found
136
        $trakt->setVideoIdFound($videoId, $context->releaseId, 0);
137
138
        if ($this->echoOutput) {
139
            $this->colorCli->primaryOver('    → ');
140
            $this->colorCli->alternateOver($this->truncateTitle($cleanName));
141
            if ($hasAirdate) {
142
                $this->colorCli->primaryOver(' | ');
143
                $this->colorCli->warningOver($parsedInfo['airdate']);
144
            }
145
            $this->colorCli->primaryOver(' → ');
146
            $this->colorCli->warning('Episode not found');
147
        }
148
149
        return TvProcessingResult::notFound($this->getName(), [
150
            'video_id' => $videoId,
151
            'episode_not_found' => true,
152
        ]);
153
    }
154
155
    /**
156
     * Output full season match message.
157
     */
158
    private function outputFullSeason(string $title): void
159
    {
160
        if (! $this->echoOutput) {
161
            return;
162
        }
163
164
        $this->colorCli->primaryOver('    → ');
165
        $this->colorCli->headerOver($this->truncateTitle($title));
166
        $this->colorCli->primaryOver(' → ');
167
        $this->colorCli->primary('Full Season matched');
168
    }
169
}
170
171