Passed
Push — master ( 10d345...2ea33a )
by Darko
09:27
created

RSS::getRss()   C

Complexity

Conditions 11
Paths 8

Size

Total Lines 61
Code Lines 51

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 51
dl 0
loc 61
rs 6.9224
c 0
b 0
f 0
cc 11
nc 8
nop 7

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\Http\Controllers\Api;
4
5
use App\Models\Category;
6
use App\Models\Release;
7
use Blacklight\Releases;
8
use Illuminate\Database\Eloquent\Builder;
9
use Illuminate\Database\Eloquent\Collection;
10
use Illuminate\Support\Facades\Cache;
11
use Illuminate\Support\Facades\DB;
12
13
/**
14
 * Class RSS -- contains specific functions for RSS.
15
 */
16
class RSS extends ApiController
17
{
18
    public Releases $releases;
19
20
    /**
21
     * @throws \Exception
22
     */
23
    public function __construct()
24
    {
25
        parent::__construct();
26
        $this->releases = new Releases;
27
    }
28
29
    /**
30
     * @return Release[]|Collection|mixed
31
     */
32
    public function getRss($cat, $videosId, $aniDbID, int $userID = 0, int $airDate = -1, int $limit = 100, int $offset = 0)
33
    {
34
        $catSearch = $cartSearch = '';
35
        $catLimit = 'AND r.categories_id BETWEEN '.Category::TV_ROOT.' AND '.Category::TV_OTHER;
36
        if (\count($cat)) {
37
            if ((int) $cat[0] === -2) {
38
                $cartSearch = sprintf(
39
                    'INNER JOIN users_releases ON users_releases.users_id = %d AND users_releases.releases_id = r.id',
40
                    $userID
41
                );
42
            } elseif ((int) $cat[0] !== -1) {
43
                $catSearch = Category::getCategorySearch($cat);
44
            }
45
        }
46
        $sql =
47
            sprintf(
48
                "SELECT r.searchname, r.guid, r.postdate, r.categories_id, r.size, r.totalpart, r.fromname, r.passwordstatus, r.grabs, r.comments, r.adddate, r.videos_id, r.tv_episodes_id,
49
					m.cover, m.imdbid, m.rating, m.plot, m.year, m.genre, m.director, m.actors,
50
					g.name AS group_name,
51
					CONCAT(cp.title, ' > ', c.title) AS category_name,
52
					COALESCE(cp.id,0) AS parentid,
53
					mu.title AS mu_title, mu.url AS mu_url, mu.artist AS mu_artist,
54
					mu.publisher AS mu_publisher, mu.releasedate AS mu_releasedate,
55
					mu.review AS mu_review, mu.tracks AS mu_tracks, mu.cover AS mu_cover,
56
					mug.title AS mu_genre, co.title AS co_title, co.url AS co_url,
57
					co.publisher AS co_publisher, co.releasedate AS co_releasedate,
58
					co.review AS co_review, co.cover AS co_cover, cog.title AS co_genre,
59
					bo.cover AS bo_cover
60
				FROM releases r
61
				LEFT JOIN categories c ON c.id = r.categories_id
62
				INNER JOIN root_categories cp ON cp.id = c.root_categories_id
63
				LEFT JOIN usenet_groups g ON g.id = r.groups_id
64
				LEFT OUTER JOIN musicinfo mu ON mu.id = r.musicinfo_id
65
				LEFT OUTER JOIN genres mug ON mug.id = mu.genres_id
66
				LEFT OUTER JOIN consoleinfo co ON co.id = r.consoleinfo_id
67
				LEFT JOIN movieinfo m ON m.id = r.movieinfo_id
68
				LEFT OUTER JOIN genres cog ON cog.id = co.genres_id %s
69
				LEFT OUTER JOIN tv_episodes tve ON tve.id = r.tv_episodes_id
70
				LEFT OUTER JOIN bookinfo bo ON bo.id = r.bookinfo_id
71
				WHERE r.passwordstatus %s
72
				%s %s %s %s
73
				ORDER BY postdate DESC %s",
74
                $cartSearch,
75
                $this->releases->showPasswords(),
76
                $catSearch,
77
                ($videosId > 0 ? sprintf('AND r.videos_id = %d %s', $videosId, ($catSearch === '' ? $catLimit : '')) : ''),
78
                ($aniDbID > 0 ? sprintf('AND r.anidbid = %d %s', $aniDbID, ($catSearch === '' ? $catLimit : '')) : ''),
79
                ($airDate > -1 ? sprintf('AND tve.firstaired >= DATE_SUB(CURDATE(), INTERVAL %d DAY)', $airDate) : ''),
80
                $limit === -1 ? '' : ' LIMIT '.$limit.' OFFSET '.$offset
81
            );
82
83
        $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_medium'));
84
        $result = Cache::get(md5($sql));
85
        if ($result !== null) {
86
            return $result;
87
        }
88
89
        $result = Release::fromQuery($sql);
90
        Cache::put(md5($sql), $result, $expiresAt);
91
92
        return $result;
93
    }
94
95
    /**
96
     * @return Builder|Collection
97
     */
98
    public function getShowsRss(int $limit, int $userID = 0, array $excludedCats = [], int $airDate = -1)
99
    {
100
        $sql = sprintf(
101
102
            "SELECT DISTINCT r.searchname, r.guid, r.postdate, r.categories_id, r.size, r.totalpart, r.fromname, r.passwordstatus, r.grabs, r.comments, r.adddate, r.videos_id, r.tv_episodes_id, v.id, v.title, g.name AS group_name, CONCAT(cp.title, '-', c.title) AS category_name, COALESCE(cp.id,0) AS parentid FROM releases r INNER JOIN user_series us ON us.videos_id = r.videos_id AND us.users_id = %d LEFT JOIN categories c ON c.id = r.categories_id INNER JOIN root_categories cp ON cp.id = c.root_categories_id LEFT JOIN usenet_groups g ON g.id = r.groups_id LEFT OUTER JOIN videos v ON v.id = r.videos_id LEFT OUTER JOIN tv_episodes tve ON tve.id = r.tv_episodes_id WHERE (us.categories IS NULL OR us.categories = '' OR us.categories = 'NULL' OR FIND_IN_SET(r.categories_id, REPLACE(us.categories,'|',',')) > 0)%s%s AND r.categories_id BETWEEN %d AND %d AND r.passwordstatus %s ORDER BY postdate DESC %s",
103
            $userID,
104
            (\count($excludedCats) ? ' AND r.categories_id NOT IN ('.implode(',', $excludedCats).')' : ''),
105
            ($airDate > -1 ? sprintf(' AND tve.firstaired >= DATE_SUB(CURDATE(), INTERVAL %d DAY)', $airDate) : ''),
106
            Category::TV_ROOT,
107
            Category::TV_OTHER,
108
            $this->releases->showPasswords(),
109
            ! empty($limit) ? sprintf(' LIMIT %d OFFSET 0', min($limit, 100)) : ''
110
        );
111
112
        $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_medium'));
113
        $result = Cache::get(md5($sql));
114
        if ($result !== null) {
115
            return $result;
116
        }
117
118
        $result = Release::fromQuery($sql);
119
        Cache::put(md5($sql), $result, $expiresAt);
120
121
        return $result;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result also could return the type Illuminate\Database\Eloq...gHasThroughRelationship which is incompatible with the documented return type Illuminate\Database\Eloq...ase\Eloquent\Collection.
Loading history...
122
    }
123
124
    /**
125
     * @return Release[]|Collection|mixed
126
     */
127
    public function getMyMoviesRss(int $limit, int $userID = 0, array $excludedCats = [])
128
    {
129
        // Use stricter joins: movieinfo joined by imdbid, require non-null imdbid; prevents unrelated titles sharing incorrect links.
130
        $sql = sprintf(
131
            "SELECT DISTINCT r.searchname, r.guid, r.postdate, r.categories_id, r.size, r.totalpart, r.fromname, r.passwordstatus, r.grabs, r.comments, r.adddate, r.videos_id, r.tv_episodes_id, mi.title AS releasetitle, g.name AS group_name, CONCAT(cp.title, '-', c.title) AS category_name, COALESCE(cp.id,0) AS parentid FROM releases r INNER JOIN user_movies um ON um.imdbid = r.imdbid AND um.users_id = %d LEFT JOIN categories c ON c.id = r.categories_id INNER JOIN root_categories cp ON cp.id = c.root_categories_id LEFT JOIN usenet_groups g ON g.id = r.groups_id LEFT JOIN movieinfo mi ON mi.imdbid = r.imdbid WHERE r.imdbid IS NOT NULL AND (um.categories IS NULL OR um.categories = '' OR um.categories = 'NULL' OR FIND_IN_SET(r.categories_id, REPLACE(um.categories,'|',',')) > 0)%s AND r.categories_id BETWEEN %d AND %d AND r.passwordstatus %s ORDER BY postdate DESC %s",
132
            $userID,
133
            (\count($excludedCats) > 0 ? ' AND r.categories_id NOT IN ('.implode(',', $excludedCats).')' : ''),
134
            Category::MOVIE_ROOT,
135
            Category::MOVIE_OTHER,
136
            $this->releases->showPasswords(),
137
            ! empty($limit) ? sprintf(' LIMIT %d OFFSET 0', min($limit, 100)) : ''
138
        );
139
140
        $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_medium'));
141
        $result = Cache::get(md5($sql));
142
        if ($result !== null) {
143
            return $result;
144
        }
145
        $result = Release::fromQuery($sql);
146
147
        Cache::put(md5($sql), $result, $expiresAt);
148
149
        return $result;
150
    }
151
152
    /**
153
     * Get trending movies RSS (top 15 most downloaded in last 48 hours)
154
     *
155
     * @return \Illuminate\Support\Collection
156
     */
157
    public function getTrendingMoviesRss()
158
    {
159
        $cacheKey = 'rss_trending_movies_48h';
160
161
        return Cache::remember($cacheKey, 3600, function () {
162
            $fortyEightHoursAgo = \Illuminate\Support\Carbon::now()->subHours(48);
163
164
            $sql = sprintf(
165
                "SELECT DISTINCT
166
                    r.searchname, r.guid, r.postdate, r.categories_id, r.size,
167
                    r.totalpart, r.fromname, r.passwordstatus, r.grabs, r.comments,
168
                    r.adddate, r.imdbid,
169
                    m.title, m.year, m.rating, m.plot, m.genre, m.cover, m.tmdbid, m.traktid,
170
                    g.name AS group_name,
171
                    CONCAT(cp.title, ' > ', c.title) AS category_name,
172
                    COALESCE(cp.id,0) AS parentid,
173
                    COUNT(DISTINCT ud.id) as total_downloads,
174
                    COUNT(DISTINCT r.id) as release_count
175
                FROM releases r
176
                INNER JOIN movieinfo m ON m.imdbid = r.imdbid
177
                LEFT JOIN user_downloads ud ON r.id = ud.releases_id
178
                LEFT JOIN categories c ON c.id = r.categories_id
179
                INNER JOIN root_categories cp ON cp.id = c.root_categories_id
180
                LEFT JOIN usenet_groups g ON g.id = r.groups_id
181
                WHERE m.title != ''
182
                    AND m.imdbid != '0000000'
183
                    AND ud.timestamp >= '%s'
184
                    AND r.passwordstatus %s
185
                GROUP BY r.id, r.searchname, r.guid, r.postdate, r.categories_id, r.size,
186
                    r.totalpart, r.fromname, r.passwordstatus, r.grabs, r.comments,
187
                    r.adddate, r.imdbid, m.title, m.year, m.rating, m.plot, m.genre,
188
                    m.cover, m.tmdbid, m.traktid, g.name, cp.title, c.title, cp.id
189
                HAVING COUNT(DISTINCT ud.id) > 0
190
                ORDER BY total_downloads DESC, r.postdate DESC
191
                LIMIT 15",
192
                $fortyEightHoursAgo->format('Y-m-d H:i:s'),
193
                $this->releases->showPasswords()
194
            );
195
196
            return Release::fromQuery($sql);
197
        });
198
    }
199
200
    /**
201
     * Get trending TV shows RSS (top 15 most downloaded in last 48 hours)
202
     *
203
     * @return \Illuminate\Support\Collection
204
     */
205
    public function getTrendingShowsRss()
206
    {
207
        $cacheKey = 'rss_trending_shows_48h';
208
209
        return Cache::remember($cacheKey, 3600, function () {
210
            $fortyEightHoursAgo = \Illuminate\Support\Carbon::now()->subHours(48);
211
212
            $sql = sprintf(
213
                "SELECT DISTINCT
214
                    r.searchname, r.guid, r.postdate, r.categories_id, r.size,
215
                    r.totalpart, r.fromname, r.passwordstatus, r.grabs, r.comments,
216
                    r.adddate, r.videos_id, r.tv_episodes_id,
217
                    v.title, v.started, v.tvdb, v.tvmaze, v.trakt, v.tmdb, v.countries_id,
218
                    ti.summary, ti.image,
219
                    g.name AS group_name,
220
                    CONCAT(cp.title, ' > ', c.title) AS category_name,
221
                    COALESCE(cp.id,0) AS parentid,
222
                    COUNT(DISTINCT ud.id) as total_downloads,
223
                    COUNT(DISTINCT r.id) as release_count
224
                FROM releases r
225
                INNER JOIN videos v ON v.id = r.videos_id
226
                INNER JOIN tv_info ti ON ti.videos_id = v.id
227
                LEFT JOIN user_downloads ud ON r.id = ud.releases_id
228
                LEFT JOIN categories c ON c.id = r.categories_id
229
                INNER JOIN root_categories cp ON cp.id = c.root_categories_id
230
                LEFT JOIN usenet_groups g ON g.id = r.groups_id
231
                WHERE v.type = 0
232
                    AND v.title != ''
233
                    AND ud.timestamp >= '%s'
234
                    AND r.passwordstatus %s
235
                GROUP BY r.id, r.searchname, r.guid, r.postdate, r.categories_id, r.size,
236
                    r.totalpart, r.fromname, r.passwordstatus, r.grabs, r.comments,
237
                    r.adddate, r.videos_id, r.tv_episodes_id, v.title, v.started, v.tvdb,
238
                    v.tvmaze, v.trakt, v.tmdb, v.countries_id, ti.summary, ti.image,
239
                    g.name, cp.title, c.title, cp.id
240
                HAVING COUNT(DISTINCT ud.id) > 0
241
                ORDER BY total_downloads DESC, r.postdate DESC
242
                LIMIT 15",
243
                $fortyEightHoursAgo->format('Y-m-d H:i:s'),
244
                $this->releases->showPasswords()
245
            );
246
247
            return Release::fromQuery($sql);
248
        });
249
    }
250
251
    /**
252
     * Get the first instance of a column from a table where the column is greater than 0, ordered by a specified column.
253
     *
254
     * @param  string  $column  The column to select and check
255
     * @param  string  $table  The table to query
256
     * @param  string  $order  The column to order by
257
     * @return object|null The first instance found or null if none found
258
     */
259
    public function getFirstInstance(string $column, string $table, string $order)
260
    {
261
        return DB::table($table)
262
            ->select([$column])
263
            ->where($column, '>', 0)
264
            ->orderBy($order)
0 ignored issues
show
Bug introduced by
$order of type string is incompatible with the type Closure|Illuminate\Datab...\Database\Query\Builder expected by parameter $column of Illuminate\Database\Query\Builder::orderBy(). ( Ignorable by Annotation )

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

264
            ->orderBy(/** @scrutinizer ignore-type */ $order)
Loading history...
265
            ->first();
266
    }
267
}
268