Passed
Push — master ( 4f5b3b...1c5d75 )
by Darko
09:48
created

Release::updateRelease()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 29
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 22
c 0
b 0
f 0
dl 0
loc 29
rs 9.568
cc 4
nc 4
nop 14

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace App\Models;
4
5
use Blacklight\ElasticSearchSiteSearch;
6
use Blacklight\ManticoreSearch;
7
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
8
use Illuminate\Database\Eloquent\Factories\HasFactory;
9
use Illuminate\Database\Eloquent\Model;
10
use Illuminate\Database\Eloquent\Relations\BelongsTo;
11
use Illuminate\Database\Eloquent\Relations\HasMany;
12
use Illuminate\Database\Eloquent\Relations\HasOne;
13
use Illuminate\Support\Arr;
14
use Illuminate\Support\Facades\Cache;
15
use Illuminate\Support\Facades\DB;
16
17
class Release extends Model
18
{
19
    use HasFactory;
0 ignored issues
show
Bug introduced by
The trait Illuminate\Database\Eloquent\Factories\HasFactory requires the property $factoryClass which is not provided by App\Models\Release.
Loading history...
20
21
    /**
22
     * @var bool
23
     */
24
    protected $dateFormat = false;
25
26
    /**
27
     * @var bool
28
     */
29
    public $timestamps = false;
30
31
    /**
32
     * @var array
33
     */
34
    protected $guarded = [];
35
36
    public function group(): BelongsTo
37
    {
38
        return $this->belongsTo(UsenetGroup::class, 'groups_id');
39
    }
40
41
    public function download(): HasMany
42
    {
43
        return $this->hasMany(UserDownload::class, 'releases_id');
44
    }
45
46
    public function userRelease(): HasMany
47
    {
48
        return $this->hasMany(UsersRelease::class, 'releases_id');
49
    }
50
51
    public function file(): HasMany
52
    {
53
        return $this->hasMany(ReleaseFile::class, 'releases_id');
54
    }
55
56
    public function category(): BelongsTo
57
    {
58
        return $this->belongsTo(Category::class, 'categories_id');
59
    }
60
61
    public function predb(): BelongsTo
62
    {
63
        return $this->belongsTo(Predb::class, 'predb_id');
64
    }
65
66
    public function failed(): HasMany
67
    {
68
        return $this->hasMany(DnzbFailure::class, 'release_id');
69
    }
70
71
    public function nfo(): HasOne
72
    {
73
        return $this->hasOne(ReleaseNfo::class, 'releases_id');
74
    }
75
76
    public function comment(): HasMany
77
    {
78
        return $this->hasMany(ReleaseComment::class, 'releases_id');
79
    }
80
81
    public function releaseGroup(): HasMany
82
    {
83
        return $this->hasMany(ReleasesGroups::class, 'releases_id');
84
    }
85
86
    public function video(): BelongsTo
87
    {
88
        return $this->belongsTo(Video::class, 'videos_id');
89
    }
90
91
    public function videoData(): HasOne
92
    {
93
        return $this->hasOne(VideoData::class, 'releases_id');
94
    }
95
96
    public function episode(): BelongsTo
97
    {
98
        return $this->belongsTo(TvEpisode::class, 'tv_episodes_id');
99
    }
100
101
    /**
102
     * Insert a single release returning the ID on success or false on failure.
103
     *
104
     * @param  array  $parameters  Insert parameters, must be escaped if string.
105
     * @return bool|int
106
     *
107
     * @throws \Exception
108
     */
109
    public static function insertRelease(array $parameters = [])
110
    {
111
        $passwordStatus = config('nntmux_settings.check_passworded_rars') === true ? -1 : 0;
112
        $parameters['id'] = self::query()
113
            ->insertGetId(
114
                [
115
                    'name' => $parameters['name'],
116
                    'searchname' => $parameters['searchname'],
117
                    'totalpart' => $parameters['totalpart'],
118
                    'groups_id' => $parameters['groups_id'],
119
                    'adddate' => now(),
120
                    'guid' => $parameters['guid'],
121
                    'leftguid' => $parameters['guid'][0],
122
                    'postdate' => $parameters['postdate'],
123
                    'fromname' => $parameters['fromname'],
124
                    'size' => $parameters['size'],
125
                    'passwordstatus' => $passwordStatus,
126
                    'haspreview' => -1,
127
                    'categories_id' => $parameters['categories_id'],
128
                    'nfostatus' => -1,
129
                    'nzbstatus' => $parameters['nzbstatus'],
130
                    'isrenamed' => $parameters['isrenamed'],
131
                    'iscategorized' => 1,
132
                    'predb_id' => $parameters['predb_id'],
133
                    'source' => $parameters['source'] ?? null,
134
                    'ishashed' => $parameters['ishashed'] ?? 0,
135
                ]
136
            );
137
138
        if (config('nntmux.elasticsearch_enabled') === true) {
139
            (new ElasticSearchSiteSearch)->insertRelease($parameters);
140
        } else {
141
            (new ManticoreSearch)->insertRelease($parameters);
142
        }
143
144
        return $parameters['id'];
0 ignored issues
show
Bug Best Practice introduced by
The expression return $parameters['id'] also could return the type Illuminate\Database\Eloquent\Builder which is incompatible with the documented return type boolean|integer.
Loading history...
145
    }
146
147
    /**
148
     * @throws \Exception
149
     */
150
    public static function updateRelease($id, $name, $searchName, $fromName, $categoryId, $parts, $grabs, $size, $postedDate, $addedDate, $videoId, $episodeId, $imDbId, $aniDbId): void
151
    {
152
        $movieInfoId = null;
153
        if (! empty($imDbId)) {
154
            $movieInfoId = MovieInfo::whereImdbid($imDbId)->first(['id']);
155
        }
156
        self::whereId($id)->update(
157
            [
158
                'name' => $name,
159
                'searchname' => $searchName,
160
                'fromname' => $fromName,
161
                'categories_id' => $categoryId,
162
                'totalpart' => $parts,
163
                'grabs' => $grabs,
164
                'size' => $size,
165
                'postdate' => $postedDate,
166
                'adddate' => $addedDate,
167
                'videos_id' => $videoId,
168
                'tv_episodes_id' => $episodeId,
169
                'imdbid' => $imDbId,
170
                'anidbid' => $aniDbId,
171
                'movieinfo_id' => $movieInfoId !== null ? $movieInfoId->id : $movieInfoId,
172
            ]
173
        );
174
175
        if (config('nntmux.elasticsearch_enabled') === true) {
176
            (new ElasticSearchSiteSearch)->updateRelease($id);
177
        } else {
178
            (new ManticoreSearch)->updateRelease($id);
179
        }
180
    }
181
182
    /**
183
     * @throws \Exception
184
     */
185
    public static function updateGrab(string $guid): void
186
    {
187
        $updateGrabs = ((int) Settings::settingValue('grabstatus') !== 0);
188
        if ($updateGrabs) {
189
            self::whereGuid($guid)->increment('grabs');
190
        }
191
    }
192
193
    /**
194
     * @return Model|null|static
195
     */
196
    public static function getCatByRelId($id)
197
    {
198
        return self::whereId($id)->first(['categories_id']);
199
    }
200
201
    public static function removeVideoIdFromReleases($videoId): int
202
    {
203
        return self::whereVideosId($videoId)->update(['videos_id' => 0, 'tv_episodes_id' => 0]);
204
    }
205
206
    public static function removeAnidbIdFromReleases($anidbID): int
207
    {
208
        return self::whereAnidbid($anidbID)->update(['anidbid' => -1]);
209
    }
210
211
    /**
212
     * @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Support\Collection|static[]
213
     */
214
    public static function getTopDownloads()
215
    {
216
        $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_long'));
217
        $releases = Cache::get(md5('topDownloads'));
218
        if ($releases !== null) {
219
            return $releases;
220
        }
221
        $releases = self::query()
222
            ->where('grabs', '>', 0)
223
            ->select(['id', 'searchname', 'guid', 'adddate'])
224
            ->selectRaw('SUM(grabs) as grabs')
225
            ->groupBy('id', 'searchname', 'adddate')
226
            ->havingRaw('SUM(grabs) > 0')
227
            ->orderByDesc('grabs')
0 ignored issues
show
Bug introduced by
'grabs' of type string is incompatible with the type Closure|Illuminate\Datab...\Database\Query\Builder expected by parameter $column of Illuminate\Database\Query\Builder::orderByDesc(). ( Ignorable by Annotation )

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

227
            ->orderByDesc(/** @scrutinizer ignore-type */ 'grabs')
Loading history...
228
            ->limit(10)
229
            ->get();
230
231
        Cache::put(md5('topDownloads'), $releases, $expiresAt);
232
233
        return $releases;
234
    }
235
236
    /**
237
     * @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Support\Collection|static[]
238
     */
239
    public static function getTopComments()
240
    {
241
        $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_long'));
242
        $releases = Cache::get(md5('topComments'));
243
        if ($releases !== null) {
244
            return $releases;
245
        }
246
        $releases = self::query()
247
            ->where('comments', '>', 0)
248
            ->select(['id', 'guid', 'searchname'])
249
            ->selectRaw('SUM(comments) AS comments')
250
            ->groupBy('id', 'searchname', 'adddate')
251
            ->havingRaw('SUM(comments) > 0')
252
            ->orderByDesc('comments')
0 ignored issues
show
Bug introduced by
'comments' of type string is incompatible with the type Closure|Illuminate\Datab...\Database\Query\Builder expected by parameter $column of Illuminate\Database\Query\Builder::orderByDesc(). ( Ignorable by Annotation )

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

252
            ->orderByDesc(/** @scrutinizer ignore-type */ 'comments')
Loading history...
253
            ->limit(10)
254
            ->get();
255
256
        Cache::put(md5('topComments'), $releases, $expiresAt);
257
258
        return $releases;
259
    }
260
261
    /**
262
     * @return \Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Query\Builder[]|\Illuminate\Support\Collection|mixed
263
     */
264
    public static function getReleases()
265
    {
266
        $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_long'));
267
        $releases = Cache::get(md5('releases'));
268
        if ($releases !== null) {
269
            return $releases;
270
        }
271
272
        $releases = self::query()
273
            ->select(['releases.*', 'g.name as group_name', 'c.title as category_name'])
274
            ->leftJoin('categories as c', 'c.id', '=', 'releases.categories_id')
275
            ->leftJoin('usenet_groups as g', 'g.id', '=', 'releases.groups_id')
276
            ->get();
277
278
        Cache::put(md5('releases'), $releases, $expiresAt);
279
280
        return $releases;
281
    }
282
283
    /**
284
     * Used for admin page release-list.
285
     *
286
     * @param  int  $page  The page number to retrieve
287
     * @return LengthAwarePaginator|mixed
288
     */
289
    public static function getReleasesRange(int $page = 1): mixed
290
    {
291
        $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_long'));
292
        $cacheKey = md5('releasesRange_'.$page);
293
        $releases = Cache::get($cacheKey);
294
        if ($releases !== null) {
295
            return $releases;
296
        }
297
298
        $releases = self::query()
299
            ->select(
300
                [
301
                    'releases.id',
302
                    'releases.name',
303
                    'releases.searchname',
304
                    'releases.size',
305
                    'releases.guid',
306
                    'releases.totalpart',
307
                    'releases.postdate',
308
                    'releases.adddate',
309
                    'releases.grabs',
310
                    'cp.title as parent_category',
311
                    'c.title as sub_category',
312
                    DB::raw('CONCAT(cp.title, \' > \', c.title) AS category_name'),
313
                ]
314
            )
315
            ->leftJoin('categories as c', 'c.id', '=', 'releases.categories_id')
316
            ->leftJoin('root_categories as cp', 'cp.id', '=', 'c.root_categories_id')
317
            ->orderByDesc('releases.postdate')
0 ignored issues
show
Bug introduced by
'releases.postdate' of type string is incompatible with the type Closure|Illuminate\Datab...\Database\Query\Builder expected by parameter $column of Illuminate\Database\Query\Builder::orderByDesc(). ( Ignorable by Annotation )

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

317
            ->orderByDesc(/** @scrutinizer ignore-type */ 'releases.postdate')
Loading history...
318
            ->paginate(config('nntmux.items_per_page'), ['*'], 'page', $page);
319
320
        Cache::put($cacheKey, $releases, $expiresAt);
321
322
        return $releases;
323
    }
324
325
    public static function getByGuid($guid)
326
    {
327
        $query = self::with([
328
            'group:id,name',
329
            'category:id,title,root_categories_id',
330
            'category.parent:id,title',
331
            'video:id,title,tvdb,trakt,tvrage,tvmaze,source',
332
            'video.tvInfo:videos_id,summary,image',
333
            'episode:id,title,firstaired,se_complete',
334
        ]);
335
336
        if (is_array($guid)) {
337
            $query->whereIn('guid', $guid);
338
        } else {
339
            $query->where('guid', $guid);
340
        }
341
342
        $releases = $query->get();
343
344
        $releases->each(function ($release) {
345
            $release->group_name = $release->group->name ?? null;
346
            $release->showtitle = $release->video->title ?? null;
347
            $release->tvdb = $release->video->tvdb ?? null;
348
            $release->trakt = $release->video->trakt ?? null;
349
            $release->tvrage = $release->video->tvrage ?? null;
350
            $release->tvmaze = $release->video->tvmaze ?? null;
351
            $release->source = $release->video->source ?? null;
352
            $release->summary = $release->video->tvInfo->summary ?? null;
353
            $release->image = $release->video->tvInfo->image ?? null;
354
            $release->title = $release->episode->title ?? null;
355
            $release->firstaired = $release->episode->firstaired ?? null;
356
            $release->se_complete = $release->episode->se_complete ?? null;
357
            $release->parent_category = $release->category->parent->title ?? null;
358
            $release->sub_category = $release->category->title ?? null;
359
            $release->category_name = $release->parent_category.' > '.$release->sub_category;
360
            $release->category_ids = $release->category ? ($release->category->parentid.','.$release->category->id) : '';
361
            $release->group_names = $release->releaseGroup->map(function ($relGroup) {
362
                return $relGroup->group ? $relGroup->group->name : null;
363
            })->implode(',');
364
        });
365
366
        return is_array($guid) ? $releases : $releases->first();
367
    }
368
369
    /**
370
     * Get a range of releases. used in admin manage list.
371
     */
372
    public static function getFailedRange(): LengthAwarePaginator
373
    {
374
        $failedList = self::query()
375
            ->select(['name', 'searchname', 'size', 'guid', 'totalpart', 'postdate', 'adddate', 'grabs', 'cp.title as parent_category', 'c.title as sub_category', DB::raw("CONCAT(cp.title, ' > ', c.title) AS category_name")])
376
            ->rightJoin('dnzb_failures', 'dnzb_failures.release_id', '=', 'releases.id')
377
            ->leftJoin('categories as c', 'c.id', '=', 'releases.categories_id')
378
            ->leftJoin('root_categories as cp', 'cp.id', '=', 'c.root_categories_id')
379
            ->orderByDesc('postdate');
0 ignored issues
show
Bug introduced by
'postdate' of type string is incompatible with the type Closure|Illuminate\Datab...\Database\Query\Builder expected by parameter $column of Illuminate\Database\Query\Builder::orderByDesc(). ( Ignorable by Annotation )

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

379
            ->orderByDesc(/** @scrutinizer ignore-type */ 'postdate');
Loading history...
380
381
        return $failedList->paginate(config('nntmux.items_per_page'));
382
    }
383
384
    /**
385
     * @return Release|false|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|\Illuminate\Database\Query\Builder|object|null
386
     */
387
    public static function getAlternate(string $guid, int $userid)
388
    {
389
        $rel = self::whereGuid($guid)->first(['id', 'searchname', 'categories_id']);
390
391
        if ($rel === null) {
392
            return false;
393
        }
394
        DnzbFailure::insertOrIgnore(['release_id' => $rel['id'], 'users_id' => $userid, 'failed' => 1]);
395
396
        preg_match('/(^\w+[-_. ].+?\.(\d+p)).+/i', $rel['searchname'], $similar);
397
398
        if (! empty($similar)) {
399
            if (config('nntmux.elasticsearch_enabled') === true) {
400
                $searchResult = (new ElasticSearchSiteSearch)->indexSearch($similar[1], 10);
401
            } else {
402
                $searchResult = (new ManticoreSearch)->searchIndexes('releases_rt', $similar[1]);
403
                if (! empty($searchResult)) {
404
                    $searchResult = Arr::wrap(Arr::get($searchResult, 'id'));
405
                }
406
            }
407
408
            if (empty($searchResult)) {
409
                return false;
410
            }
411
412
            return self::query()->leftJoin('dnzb_failures as df', 'df.release_id', '=', 'releases.id')->whereIn('releases.id', $searchResult)->where('df.release_id', '=', null)->where('releases.categories_id', $rel['categories_id'])->where('id', '<>', $rel['id'])->orderByDesc('releases.postdate')->first(['guid']);
0 ignored issues
show
Bug introduced by
'releases.postdate' of type string is incompatible with the type Closure|Illuminate\Datab...\Database\Query\Builder expected by parameter $column of Illuminate\Database\Query\Builder::orderByDesc(). ( Ignorable by Annotation )

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

412
            return self::query()->leftJoin('dnzb_failures as df', 'df.release_id', '=', 'releases.id')->whereIn('releases.id', $searchResult)->where('df.release_id', '=', null)->where('releases.categories_id', $rel['categories_id'])->where('id', '<>', $rel['id'])->orderByDesc(/** @scrutinizer ignore-type */ 'releases.postdate')->first(['guid']);
Loading history...
413
        }
414
415
        return false;
416
    }
417
418
    public static function checkGuidForApi($guid): bool
419
    {
420
        $check = self::whereGuid($guid)->first();
421
422
        return $check !== null;
423
    }
424
}
425