Completed
Push — dev ( fc4c42...9aa3a7 )
by Darko
08:57
created

Console::_getGenreKey()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 1
dl 0
loc 11
ccs 0
cts 4
cp 0
crap 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Blacklight;
4
5
use ApaiIO\ApaiIO;
6
use App\Models\Genre;
7
use GuzzleHttp\Client;
8
use App\Models\Release;
9
use App\Models\Category;
10
use App\Models\Settings;
11
use App\Models\ConsoleInfo;
12
use ApaiIO\Operations\Search;
13
use Illuminate\Support\Carbon;
14
use ApaiIO\Configuration\Country;
15
use ApaiIO\Request\GuzzleRequest;
16
use Messerli90\IGDB\Facades\IGDB;
17
use Illuminate\Support\Facades\DB;
18
use Illuminate\Support\Facades\Log;
19
use Illuminate\Support\Facades\Cache;
20
use GuzzleHttp\Exception\ClientException;
21
use GuzzleHttp\Exception\ServerException;
22
use ApaiIO\Configuration\GenericConfiguration;
23
use ApaiIO\ResponseTransformer\XmlToSimpleXmlObject;
24
25
/**
26
 * Class Console.
27
 */
28
class Console
29
{
30
    public const CONS_UPROC = 0; // Release has not been processed.
31
    public const CONS_NTFND = -2;
32
33
    protected const MATCH_PERCENT = 60;
34
35
    /**
36
     * @var
37
     */
38
    protected $igdbSleep;
39
40
    /**
41
     * @var bool
42
     */
43
    public $echooutput;
44
45
    /**
46
     * @var null|string
47
     */
48
    public $pubkey;
49
50
    /**
51
     * @var null|string
52
     */
53
    public $privkey;
54
55
    /**
56
     * @var null|string
57
     */
58
    public $asstag;
59
60
    /**
61
     * @var int|null|string
62
     */
63
    public $gameqty;
64
65
    /**
66
     * @var int|null|string
67
     */
68
    public $sleeptime;
69
70
    /**
71
     * @var string
72
     */
73
    public $imgSavePath;
74
75
    /**
76
     * @var string
77
     */
78
    public $renamed;
79
80
    /**
81
     * @var string
82
     */
83
    public $catWhere;
84
85
    /**
86
     * Store names of failed Amazon lookup items.
87
     * @var array
88
     */
89
    public $failCache;
90
91
    /**
92
     * @var \Blacklight\ColorCLI
93
     */
94
    protected $colorCli;
95
96
    /**
97
     * @param array $options Class instances / Echo to cli.
98
     * @throws \Exception
99
     */
100
    public function __construct(array $options = [])
101
    {
102
        $defaults = [
103
            'Echo'     => false,
104
            'Settings' => null,
105
        ];
106
        $options += $defaults;
107
108
        $this->echooutput = ($options['Echo'] && config('nntmux.echocli'));
109
110
        $this->colorCli = new ColorCLI();
111
112
        $this->pubkey = Settings::settingValue('APIs..amazonpubkey');
113
        $this->privkey = Settings::settingValue('APIs..amazonprivkey');
114
        $this->asstag = Settings::settingValue('APIs..amazonassociatetag');
115
        $this->gameqty = (Settings::settingValue('..maxgamesprocessed') !== '') ? (int) Settings::settingValue('..maxgamesprocessed') : 150;
0 ignored issues
show
introduced by
The condition App\Models\Settings::set...gamesprocessed') !== '' is always true.
Loading history...
116
        $this->sleeptime = (Settings::settingValue('..amazonsleep') !== '') ? (int) Settings::settingValue('..amazonsleep') : 1000;
0 ignored issues
show
introduced by
The condition App\Models\Settings::set...'..amazonsleep') !== '' is always true.
Loading history...
117
        $this->imgSavePath = NN_COVERS.'console'.DS;
118
        $this->renamed = (int) Settings::settingValue('..lookupgames') === 2;
0 ignored issues
show
Documentation Bug introduced by
The property $renamed was declared of type string, but (int)App\Models\Settings...('..lookupgames') === 2 is of type boolean. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
119
120
        $this->failCache = [];
121
    }
122
123
    /**
124
     * @param $id
125
     * @return \Illuminate\Database\Eloquent\Model|null|static
126
     */
127
    public function getConsoleInfo($id)
128
    {
129
        return ConsoleInfo::query()->where('consoleinfo.id', $id)->select('consoleinfo.*', 'genres.title as genres')->leftJoin('genres', 'genres.id', '=', 'consoleinfo.genres_id')->first();
130
    }
131
132
    /**
133
     * @param string $title
134
     * @param string $platform
135
     *
136
     * @return false|\Illuminate\Database\Eloquent\Model
137
     */
138
    public function getConsoleInfoByName($title, $platform)
139
    {
140
        //only used to get a count of words
141
        $searchWords = '';
142
143
        $title = preg_replace('/( - | -|\(.+\)|\(|\))/', ' ', $title);
144
        $title = preg_replace('/[^\w ]+/', '', $title);
145
        $title = trim(trim(preg_replace('/\s\s+/i', ' ', $title)));
146
        foreach (explode(' ', $title) as $word) {
147
            $word = trim(rtrim(trim($word), '-'));
148
            if ($word !== '' && $word !== '-') {
149
                $word = '+'.$word;
150
                $searchWords .= sprintf('%s ', $word);
151
            }
152
        }
153
        $searchWords = trim($searchWords.'+'.$platform);
154
155
        return ConsoleInfo::search($searchWords)->first() ?? false;
156
    }
157
158
    /**
159
     * @param       $page
160
     * @param       $cat
161
     * @param       $start
162
     * @param       $num
163
     * @param       $orderBy
164
     * @param array $excludedCats
165
     *
166
     * @return array
167
     * @throws \Exception
168
     */
169
    public function getConsoleRange($page, $cat, $start, $num, $orderBy, array $excludedCats = []): array
170
    {
171
        $browseBy = $this->getBrowseBy();
172
        $catsrch = '';
173
        if (\count($cat) > 0 && (int) $cat[0] !== -1) {
174
            $catsrch = Category::getCategorySearch($cat);
175
        }
176
        $exccatlist = '';
177
        if (\count($excludedCats) > 0) {
178
            $exccatlist = ' AND r.categories_id NOT IN ('.implode(',', $excludedCats).')';
179
        }
180
        $order = $this->getConsoleOrder($orderBy);
181
        $calcSql = sprintf(
182
            "
183
					SELECT SQL_CALC_FOUND_ROWS
184
						con.id,
185
						GROUP_CONCAT(r.id ORDER BY r.postdate DESC SEPARATOR ',') AS grp_release_id
186
					FROM consoleinfo con
187
					LEFT JOIN releases r ON con.id = r.consoleinfo_id
188
					WHERE r.nzbstatus = 1
189
					AND con.title != ''
190
					AND con.cover = 1
191
					AND r.passwordstatus %s
192
					%s %s %s
193
					GROUP BY con.id
194
					ORDER BY %s %s %s",
195
            (new Releases())->showPasswords(),
196
            $browseBy,
197
            $catsrch,
198
            $exccatlist,
199
            $order[0],
200
            $order[1],
201
            ($start === false ? '' : ' LIMIT '.$num.' OFFSET '.$start)
202
        );
203
        $cached = Cache::get(md5($calcSql.$page));
204
        if ($cached !== null) {
205
            $consoles = $cached;
206
        } else {
207
            $data = DB::select($calcSql);
208
            $consoles = ['total' => DB::select('SELECT FOUND_ROWS() AS total'), 'result' => $data];
209
            $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_medium'));
210
            Cache::put(md5($calcSql.$page), $consoles, $expiresAt);
211
        }
212
        $consoleIDs = $releaseIDs = false;
213
        if (\is_array($consoles['result'])) {
214
            foreach ($consoles['result'] as $console => $id) {
215
                $consoleIDs[] = $id->id;
216
                $releaseIDs[] = $id->grp_release_id;
217
            }
218
        }
219
        $sql = sprintf(
220
            '
221
				SELECT
222
					r.id, r.rarinnerfilecount, r.grabs, r.comments, r.totalpart, r.size, r.postdate, r.searchname, r.haspreview, r.passwordstatus, r.guid, rn.releases_id, g.name AS group_name, df.failed AS failed,
223
				con.*,
224
				r.consoleinfo_id,
225
				g.name AS group_name,
226
				genres.title AS genre,
227
				rn.releases_id AS nfoid
228
				FROM releases r
229
				LEFT OUTER JOIN groups g ON g.id = r.groups_id
230
				LEFT OUTER JOIN release_nfos rn ON rn.releases_id = r.id
231
				LEFT OUTER JOIN dnzb_failures df ON df.release_id = r.id
232
				INNER JOIN consoleinfo con ON con.id = r.consoleinfo_id
233
				INNER JOIN genres ON con.genres_id = genres.id
234
				WHERE con.id IN (%s)
235
				AND r.id IN (%s)
236
				%s
237
				GROUP BY con.id
238
				ORDER BY %s %s',
239
            (\is_array($consoleIDs) ? implode(',', $consoleIDs) : -1),
0 ignored issues
show
introduced by
The condition is_array($consoleIDs) is always false.
Loading history...
240
            (\is_array($releaseIDs) ? implode(',', $releaseIDs) : -1),
0 ignored issues
show
introduced by
The condition is_array($releaseIDs) is always false.
Loading history...
241
            $catsrch,
242
            $order[0],
243
            $order[1]
244
        );
245
        $return = Cache::get(md5($sql.$page));
246
        if ($return !== null) {
247
            return $return;
248
        }
249
        $return = DB::select($sql);
250
        if (\count($return) > 0) {
251
            $return[0]->_totalcount = $consoles['total'][0]->total ?? 0;
252
        }
253
        $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_long'));
254
        Cache::put(md5($sql.$page), $return, $expiresAt);
255
256
        return $return;
257
    }
258
259
    /**
260
     * @param $orderBy
261
     * @return array
262
     */
263
    public function getConsoleOrder($orderBy): array
264
    {
265
        $order = ($orderBy === '') ? 'r.postdate' : $orderBy;
266
        $orderArr = explode('_', $order);
267
        switch ($orderArr[0]) {
268
            case 'title':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
269
                $orderfield = 'con.title';
270
                break;
271
            case 'platform':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
272
                $orderfield = 'con.platform';
273
                break;
274
            case 'releasedate':
275
                $orderfield = 'con.releasedate';
276
                break;
277
            case 'genre':
278
                $orderfield = 'con.genres_id';
279
                break;
280
            case 'size':
281
                $orderfield = 'r.size';
282
                break;
283
            case 'files':
284
                $orderfield = 'r.totalpart';
285
                break;
286
            case 'stats':
287
                $orderfield = 'r.grabs';
288
                break;
289
            case 'posted':
290
            default:
291
                $orderfield = 'r.postdate';
292
                break;
293
        }
294
        $ordersort = (isset($orderArr[1]) && preg_match('/^asc|desc$/i', $orderArr[1])) ? $orderArr[1] : 'desc';
295
296
        return [$orderfield, $ordersort];
297
    }
298
299
    /**
300
     * @return array
301
     */
302
    public function getConsoleOrdering(): array
303
    {
304
        return ['title_asc', 'title_desc', 'posted_asc', 'posted_desc', 'size_asc', 'size_desc', 'files_asc', 'files_desc', 'stats_asc', 'stats_desc', 'platform_asc', 'platform_desc', 'releasedate_asc', 'releasedate_desc', 'genre_asc', 'genre_desc'];
305
    }
306
307
    /**
308
     * @return array
309
     */
310
    public function getBrowseByOptions(): array
311
    {
312
        return ['platform' => 'platform', 'title' => 'title', 'genre' => 'genres_id'];
313
    }
314
315
    /**
316
     * @return string
317
     */
318
    public function getBrowseBy(): string
319
    {
320
        $browseBy = ' ';
321
        foreach ($this->getBrowseByOptions() as $bbk => $bbv) {
322
            if (isset($_REQUEST[$bbk]) && ! empty($_REQUEST[$bbk])) {
323
                $bbs = stripslashes($_REQUEST[$bbk]);
324
                $browseBy .= 'AND con.'.$bbv.' LIKE '.escapeString('%'.$bbs.'%');
325
            }
326
        }
327
328
        return $browseBy;
329
    }
330
331
    /**
332
     * @param $id
333
     * @param $title
334
     * @param $asin
335
     * @param $url
336
     * @param $salesrank
337
     * @param $platform
338
     * @param $publisher
339
     * @param $releasedate
340
     * @param $esrb
341
     * @param $cover
342
     * @param $genres_id
343
     * @param string $review
344
     */
345
    public function update($id, $title, $asin, $url, $salesrank, $platform, $publisher, $releasedate, $esrb, $cover, $genres_id, $review = 'review'): void
346
    {
347
        $releasedate = $releasedate !== '' ? $releasedate : 'null';
348
        $review = $review === 'review' ? $review : substr($review, 0, 3000);
349
        ConsoleInfo::query()
350
            ->where('id', $id)
351
            ->update(compact('title', 'asin', 'url', 'salesrank', 'platform', 'publisher', 'releasedate', 'esrb', 'cover', 'genres_id', 'review'));
352
    }
353
354
    /**
355
     * @param $gameInfo
356
     * @return int|mixed
357
     * @throws \Exception
358
     */
359
    public function updateConsoleInfo($gameInfo)
360
    {
361
        $consoleId = self::CONS_NTFND;
362
363
        /*$amaz = $this->fetchAmazonProperties($gameInfo['title'], $gameInfo['node']);
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
364
365
        if ($amaz) {
366
            $gameInfo['platform'] = $this->_replacePlatform($gameInfo['platform']);
367
368
            $con = $this->_setConBeforeMatch($amaz, $gameInfo);
369
370
            // Basically the XBLA names contain crap, this is to reduce the title down far enough to be usable.
371
            if (stripos('xbla', $gameInfo['platform']) !== false) {
372
                $gameInfo['title'] = substr($gameInfo['title'], 0, 10);
373
                $con['substr'] = $gameInfo['title'];
374
            }
375
376
            if ($this->_matchConToGameInfo($gameInfo, $con)) {
377
                $con += $this->_setConAfterMatch($amaz);
378
                $con += $this->_matchGenre($amaz);
379
380
                // Set covers properties
381
                $con['coverurl'] = (string) $amaz->LargeImage->URL;
382
383
                if ($con['coverurl'] !== '') {
384
                    $con['cover'] = 1;
385
                } else {
386
                    $con['cover'] = 0;
387
                }
388
389
                $consoleId = $this->_updateConsoleTable($con);
390
391
                if ($this->echooutput && $consoleId !== -2) {
392
                    $this->colorCli->header('Added/updated game: ').
393
                        $this->colorCli->alternateOver('   Title:    ').
394
                        $this->colorCli->primary($con['title']).
395
                        $this->colorCli->alternateOver('   Platform: ').
396
                        $this->colorCli->primary($con['platform']).
397
                        $this->colorCli->alternateOver('   Genre: ').
398
                        $this->colorCli->primary($con['consolegenre']);
399
                }
400
            }
401
        } */
402
403
        $igdb = $this->fetchIGDBProperties($gameInfo['title'], $gameInfo['node']);
404
        if ($igdb !== false) {
0 ignored issues
show
introduced by
The condition $igdb !== false is always true.
Loading history...
405
            if ($igdb['coverurl'] !== '') {
406
                $igdb['cover'] = 1;
407
            } else {
408
                $igdb['cover'] = 0;
409
            }
410
411
            $consoleId = $this->_updateConsoleTable($igdb);
412
413
            if ($this->echooutput && $consoleId !== -2) {
414
                $this->colorCli->header('Added/updated game: ').$this->colorCli->alternateOver('   Title:    ').$this->colorCli->primary($igdb['title']).$this->colorCli->alternateOver('   Platform: ').$this->colorCli->primary($igdb['platform']).$this->colorCli->alternateOver('   Genre: ').$this->colorCli->primary($igdb['consolegenre']);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->colorCli->alternateOver(' Genre: ') targeting Blacklight\ColorCLI::alternateOver() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Bug introduced by
Are you sure $this->colorCli->primary($igdb['title']) of type void can be used in concatenation? ( Ignorable by Annotation )

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

414
                $this->colorCli->header('Added/updated game: ').$this->colorCli->alternateOver('   Title:    ')./** @scrutinizer ignore-type */ $this->colorCli->primary($igdb['title']).$this->colorCli->alternateOver('   Platform: ').$this->colorCli->primary($igdb['platform']).$this->colorCli->alternateOver('   Genre: ').$this->colorCli->primary($igdb['consolegenre']);
Loading history...
Bug introduced by
Are you sure the usage of $this->colorCli->alternateOver(' Title: ') targeting Blacklight\ColorCLI::alternateOver() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Bug introduced by
Are you sure $this->colorCli->alternateOver(' Genre: ') of type void can be used in concatenation? ( Ignorable by Annotation )

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

414
                $this->colorCli->header('Added/updated game: ').$this->colorCli->alternateOver('   Title:    ').$this->colorCli->primary($igdb['title']).$this->colorCli->alternateOver('   Platform: ').$this->colorCli->primary($igdb['platform'])./** @scrutinizer ignore-type */ $this->colorCli->alternateOver('   Genre: ').$this->colorCli->primary($igdb['consolegenre']);
Loading history...
Bug introduced by
Are you sure $this->colorCli->primary($igdb['consolegenre']) of type void can be used in concatenation? ( Ignorable by Annotation )

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

414
                $this->colorCli->header('Added/updated game: ').$this->colorCli->alternateOver('   Title:    ').$this->colorCli->primary($igdb['title']).$this->colorCli->alternateOver('   Platform: ').$this->colorCli->primary($igdb['platform']).$this->colorCli->alternateOver('   Genre: ')./** @scrutinizer ignore-type */ $this->colorCli->primary($igdb['consolegenre']);
Loading history...
Bug introduced by
Are you sure $this->colorCli->alternateOver(' Platform: ') of type void can be used in concatenation? ( Ignorable by Annotation )

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

414
                $this->colorCli->header('Added/updated game: ').$this->colorCli->alternateOver('   Title:    ').$this->colorCli->primary($igdb['title'])./** @scrutinizer ignore-type */ $this->colorCli->alternateOver('   Platform: ').$this->colorCli->primary($igdb['platform']).$this->colorCli->alternateOver('   Genre: ').$this->colorCli->primary($igdb['consolegenre']);
Loading history...
Bug introduced by
Are you sure the usage of $this->colorCli->header('Added/updated game: ') targeting Blacklight\ColorCLI::header() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Bug introduced by
Are you sure the usage of $this->colorCli->primary($igdb['title']) targeting Blacklight\ColorCLI::primary() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Bug introduced by
Are you sure the usage of $this->colorCli->primary($igdb['platform']) targeting Blacklight\ColorCLI::primary() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Bug introduced by
Are you sure $this->colorCli->primary($igdb['platform']) of type void can be used in concatenation? ( Ignorable by Annotation )

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

414
                $this->colorCli->header('Added/updated game: ').$this->colorCli->alternateOver('   Title:    ').$this->colorCli->primary($igdb['title']).$this->colorCli->alternateOver('   Platform: ')./** @scrutinizer ignore-type */ $this->colorCli->primary($igdb['platform']).$this->colorCli->alternateOver('   Genre: ').$this->colorCli->primary($igdb['consolegenre']);
Loading history...
Bug introduced by
Are you sure $this->colorCli->header('Added/updated game: ') of type void can be used in concatenation? ( Ignorable by Annotation )

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

414
                /** @scrutinizer ignore-type */ $this->colorCli->header('Added/updated game: ').$this->colorCli->alternateOver('   Title:    ').$this->colorCli->primary($igdb['title']).$this->colorCli->alternateOver('   Platform: ').$this->colorCli->primary($igdb['platform']).$this->colorCli->alternateOver('   Genre: ').$this->colorCli->primary($igdb['consolegenre']);
Loading history...
Bug introduced by
Are you sure the usage of $this->colorCli->primary($igdb['consolegenre']) targeting Blacklight\ColorCLI::primary() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Bug introduced by
Are you sure the usage of $this->colorCli->alternateOver(' Platform: ') targeting Blacklight\ColorCLI::alternateOver() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
415
            }
416
        }
417
418
        return $consoleId;
419
    }
420
421
    /**
422
     * @param array $gameInfo
423
     * @param array $con
424
     * @return bool
425
     */
426
    protected function _matchConToGameInfo(array $gameInfo = [], array $con = []): bool
427
    {
428
        $matched = false;
429
430
        // This actual compares the two strings and outputs a percentage value.
431
        $titlepercent = $platformpercent = '';
432
433
        //Remove import tags from console title for match
434
        $con['title'] = trim(preg_replace('/([\[|\(]).{2,} import([\]|\)])$/i', '', $con['title']));
435
436
        similar_text(strtolower($gameInfo['title']), strtolower($con['title']), $titlepercent);
0 ignored issues
show
Bug introduced by
$titlepercent of type string is incompatible with the type double expected by parameter $percent of similar_text(). ( Ignorable by Annotation )

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

436
        similar_text(strtolower($gameInfo['title']), strtolower($con['title']), /** @scrutinizer ignore-type */ $titlepercent);
Loading history...
437
        similar_text(strtolower($gameInfo['platform']), strtolower($con['platform']), $platformpercent);
438
439
        // Since Wii Ware games and XBLA have inconsistent original platforms, as long as title is 50% its ok.
440
        if ($titlepercent >= 50 && preg_match('/wiiware|xbla/i', trim($gameInfo['platform']))) {
441
            $titlepercent = 100;
442
            $platformpercent = 100;
443
        }
444
445
        // If the release is DLC matching will be difficult, so assume anything over 50% is legit.
446
        if ($titlepercent >= 50 && isset($gameInfo['dlc']) && (int) $gameInfo['dlc'] === 1) {
447
            $titlepercent = 100;
448
            $platformpercent = 100;
449
        }
450
451
        if ($titlepercent < 70) {
452
            $gameInfo['title'] .= ' - '.$gameInfo['platform'];
453
            similar_text(strtolower($gameInfo['title']), strtolower($con['title']), $titlepercent);
454
        }
455
456
        // Platform must equal 100%.
457
458
        if ((int) $platformpercent === 100 && (int) $titlepercent >= 70) {
459
            $matched = true;
460
        }
461
462
        return $matched;
463
    }
464
465
    /**
466
     * @param $amaz
467
     * @param $gameInfo
468
     * @return array
469
     */
470
    protected function _setConBeforeMatch($amaz, $gameInfo): array
471
    {
472
        $con = [];
473
        $con['platform'] = (string) $amaz->ItemAttributes->Platform;
474
        if (empty($con['platform'])) {
475
            $con['platform'] = $gameInfo['platform'];
476
        }
477
478
        if (stripos('Super', $con['platform']) !== false) {
479
            $con['platform'] = 'SNES';
480
        }
481
482
        $con['title'] = (string) $amaz->ItemAttributes->Title;
483
        if (empty($con['title'])) {
484
            $con['title'] = $gameInfo['title'];
485
        }
486
487
        // Remove Download strings
488
        $dlStrings = [' [Online Game Code]', ' [Download]', ' [Digital Code]', ' [Digital Download]'];
489
        $con['title'] = str_ireplace($dlStrings, '', $con['title']);
490
491
        return $con;
492
    }
493
494
    /**
495
     * @param $amaz
496
     * @return array
497
     */
498
    protected function _setConAfterMatch($amaz): array
499
    {
500
        $con = [];
501
        $con['asin'] = (string) $amaz->ASIN;
502
503
        $con['url'] = (string) $amaz->DetailPageURL;
504
        $con['url'] = str_replace('%26tag%3Dws', '%26tag%3Dopensourceins%2D21', $con['url']);
505
506
        $con['salesrank'] = (string) $amaz->SalesRank;
507
        if ($con['salesrank'] === '') {
508
            $con['salesrank'] = 'null';
509
        }
510
511
        $con['publisher'] = (string) $amaz->ItemAttributes->Publisher;
512
        $con['esrb'] = (string) $amaz->ItemAttributes->ESRBAgeRating;
513
        $con['releasedate'] = (string) $amaz->ItemAttributes->ReleaseDate;
514
515
        if (! isset($con['releasedate'])) {
516
            $con['releasedate'] = '';
517
        }
518
519
        if ($con['releasedate'] === "''") {
520
            $con['releasedate'] = '';
521
        }
522
523
        $con['review'] = '';
524
        if (isset($amaz->EditorialReviews)) {
525
            $con['review'] = trim(strip_tags((string) $amaz->EditorialReviews->EditorialReview->Content));
526
        }
527
528
        return $con;
529
    }
530
531
    /**
532
     * @param $amaz
533
     *
534
     * @return array
535
     * @throws \Exception
536
     */
537
    protected function _matchGenre($amaz): array
538
    {
539
        $genreName = '';
540
541
        if (isset($amaz->BrowseNodes)) {
542
            //had issues getting this out of the browsenodes obj
543
            //workaround is to get the xml and load that into its own obj
544
            $amazGenresXml = $amaz->BrowseNodes->asXml();
545
            $amazGenresObj = simplexml_load_string($amazGenresXml);
546
            $amazGenres = $amazGenresObj->xpath('//Name');
547
548
            foreach ($amazGenres as $amazGenre) {
549
                $currName = trim($amazGenre[0]);
550
                if (empty($genreName)) {
551
                    $genreMatch = $this->matchBrowseNode($currName);
552
                    if ($genreMatch !== false) {
553
                        $genreName = $genreMatch;
554
                        break;
555
                    }
556
                }
557
            }
558
        }
559
560
        if ($genreName === '' && isset($amaz->ItemAttributes->Genre)) {
561
            $a = (string) $amaz->ItemAttributes->Genre;
562
            $b = str_replace('-', ' ', $a);
563
            $tmpGenre = explode(' ', $b);
564
565
            foreach ($tmpGenre as $tg) {
566
                $genreMatch = $this->matchBrowseNode(ucwords($tg));
567
                if ($genreMatch !== false) {
568
                    $genreName = $genreMatch;
569
                    break;
570
                }
571
            }
572
        }
573
574
        if (empty($genreName)) {
575
            $genreName = 'Unknown';
576
        }
577
578
        $genreKey = $this->_getGenreKey($genreName);
579
580
        return ['consolegenre' => $genreName, 'consolegenreid' => $genreKey];
581
    }
582
583
    /**
584
     * @param $genreName
585
     *
586
     * @return false|int|string
587
     * @throws \Exception
588
     */
589
    protected function _getGenreKey($genreName)
590
    {
591
        $genreassoc = $this->_loadGenres();
592
593
        if (\in_array(strtolower($genreName), $genreassoc, false)) {
594
            $genreKey = array_search(strtolower($genreName), $genreassoc, false);
595
        } else {
596
            $genreKey = Genre::query()->insertGetId(['title' => $genreName, 'type' => Genres::CONSOLE_TYPE]);
597
        }
598
599
        return $genreKey;
600
    }
601
602
    /**
603
     * @return array
604
     * @throws \Exception
605
     */
606
    protected function _loadGenres(): array
607
    {
608
        $gen = new Genres(['Settings' => null]);
609
610
        return $gen->loadGenres(Genres::CONSOLE_TYPE);
611
    }
612
613
    /** This function sets the platform retrieved
614
     *  from the release to the Amazon equivalent.
615
     *
616
     * @param string $platform
617
     *
618
     *
619
     * @return string
620
     */
621
    protected function _replacePlatform($platform): string
622
    {
623
        switch (strtoupper($platform)) {
624
625
            case 'X360':
626
            case 'XBOX360':
627
                $platform = 'Xbox 360';
628
                break;
629
            case 'XBOXONE':
630
            case 'XBOX ONE':
631
                $platform = 'Xbox One';
632
                break;
633
            case 'DSi':
634
            case 'NDS':
635
                $platform = 'Nintendo DS';
636
                break;
637
            case '3DS':
638
                $platform = 'Nintendo 3DS';
639
                break;
640
            case 'PS2':
641
                $platform = 'PlayStation2';
642
                break;
643
            case 'PS3':
644
                $platform = 'PlayStation 3';
645
                break;
646
            case 'PS4':
647
                $platform = 'PlayStation 4';
648
                break;
649
            case 'PSP':
650
                $platform = 'Sony PSP';
651
                break;
652
            case 'PSVITA':
653
                $platform = 'PlayStation Vita';
654
                break;
655
            case 'PSX':
656
            case 'PSX2PSP':
657
                $platform = 'PlayStation';
658
                break;
659
            case 'WIIU':
660
                $platform = 'Nintendo Wii U';
661
                break;
662
            case 'WII':
663
                $platform = 'Nintendo Wii';
664
                break;
665
            case 'NGC':
666
                $platform = 'GameCube';
667
                break;
668
            case 'N64':
669
                $platform = 'Nintendo 64';
670
                break;
671
            case 'NES':
672
                $platform = 'Nintendo NES';
673
                break;
674
            case 'SUPER NINTENDO':
675
            case 'NINTENDO SUPER NES':
676
            case 'SNES':
677
                $platform = 'SNES';
678
                break;
679
        }
680
681
        return $platform;
682
    }
683
684
    /**
685
     * @param array $con
686
     * @return int|mixed
687
     */
688
    protected function _updateConsoleTable(array $con = [])
689
    {
690
        $ri = new ReleaseImage();
691
692
        $check = ConsoleInfo::query()->where('asin', $con['asin'])->first();
693
694
        if ($check === null) {
695
            $consoleId = ConsoleInfo::query()
696
                ->insertGetId(
697
                    [
698
                        'title' => $con['title'],
699
                        'asin' => $con['asin'],
700
                        'url' => $con['url'],
701
                        'salesrank' => $con['salesrank'],
702
                        'platform' => $con['platform'],
703
                        'publisher' => $con['publisher'],
704
                        'genres_id' => (int) $con['consolegenreid'] === -1 ? 'null' : $con['consolegenreid'],
705
                        'esrb' => $con['esrb'],
706
                        'releasedate' => $con['releasedate'] !== '' ? $con['releasedate'] : 'null',
707
                        'review' => substr($con['review'], 0, 3000),
708
                        'created_at' => now(),
709
                        'updated_at' => now(),
710
                    ]
711
                );
712
            if ($con['cover'] === 1) {
713
                $con['cover'] = $ri->saveImage($consoleId, $con['coverurl'], $this->imgSavePath, 250, 250);
0 ignored issues
show
Bug introduced by
It seems like $consoleId can also be of type Illuminate\Database\Eloquent\Builder; however, parameter $imgName of Blacklight\ReleaseImage::saveImage() does only seem to accept 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

713
                $con['cover'] = $ri->saveImage(/** @scrutinizer ignore-type */ $consoleId, $con['coverurl'], $this->imgSavePath, 250, 250);
Loading history...
714
            }
715
        } else {
716
            $consoleId = $check['id'];
717
718
            if ($con['cover'] === 1) {
719
                $con['cover'] = $ri->saveImage($consoleId, $con['coverurl'], $this->imgSavePath, 250, 250);
0 ignored issues
show
Bug introduced by
It seems like $consoleId can also be of type Illuminate\Database\Eloq...uent\Relations\Relation and Illuminate\Database\Eloquent\Relations\Relation; however, parameter $imgName of Blacklight\ReleaseImage::saveImage() does only seem to accept 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

719
                $con['cover'] = $ri->saveImage(/** @scrutinizer ignore-type */ $consoleId, $con['coverurl'], $this->imgSavePath, 250, 250);
Loading history...
720
            }
721
722
            $this->update(
723
                $consoleId,
724
                $con['title'],
725
                $con['asin'],
726
                $con['url'],
727
                $con['salesrank'],
728
                $con['platform'],
729
                $con['publisher'],
730
                $con['releasedate'] ?? null,
731
                $con['esrb'],
732
                $con['cover'],
733
                $con['consolegenreid'],
734
                $con['review'] ?? null
735
            );
736
        }
737
738
        return $consoleId;
739
    }
740
741
    /**
742
     * @param $title
743
     * @param $node
744
     *
745
     * @return false|mixed
746
     */
747
    public function fetchAmazonProperties($title, $node)
748
    {
749
        $conf = new GenericConfiguration();
750
        $client = new Client();
751
        $request = new GuzzleRequest($client);
752
753
        try {
754
            $conf
755
                ->setCountry(Country::INTERNATIONAL)
756
                ->setAccessKey($this->pubkey)
757
                ->setSecretKey($this->privkey)
758
                ->setAssociateTag($this->asstag)
759
                ->setRequest($request)
760
                ->setResponseTransformer(new XmlToSimpleXmlObject());
761
        } catch (\Throwable $e) {
762
            if (config('app.debug') === true) {
763
                Log::error($e->getMessage());
764
            }
765
        } catch (ServerException $e) {
766
            if (config('app.debug') === true) {
767
                Log::error($e->getMessage());
768
            }
769
        }
770
771
        $search = new Search();
772
        $search->setCategory('VideoGames');
773
        $search->setKeywords($title);
774
        $search->setBrowseNode($node);
775
        $search->setResponseGroup(['Large']);
776
777
        $apaiIo = new ApaiIO($conf);
778
779
        $this->colorCli->info('Trying to find info on Amazon');
780
        $responses = $apaiIo->runOperation($search);
781
782
        if ($responses === false) {
783
            throw new \RuntimeException('Could not connect to Amazon');
784
        }
785
786
        foreach ($responses->Items->Item as $response) {
787
            similar_text($title, $response->ItemAttributes->Title, $percent);
788
            if ($percent > self::MATCH_PERCENT && isset($response->ItemAttributes->Title)) {
789
                $this->colorCli->info('Found matching info on Amazon: '.$response->ItemAttributes->Title);
790
791
                return $response;
792
            }
793
        }
794
795
        $this->colorCli->info('Could not find match on Amazon');
796
797
        return false;
798
    }
799
800
    /**
801
     * @param $gameInfo
802
     * @param $gamePlatform
803
     *
804
     * @return array|bool|\StdClass
805
     * @throws \Exception
806
     */
807
    public function fetchIGDBProperties($gameInfo, $gamePlatform)
808
    {
809
        $bestMatch = false;
810
811
        $gamePlatform = $this->_replacePlatform($gamePlatform);
812
        if (now() > $this->igdbSleep) {
813
            $this->igdbSleep = null;
814
        }
815
        if ($this->igdbSleep === null && config('services.igdb.key') !== '') {
816
            try {
817
                $result = IGDB::searchGames($gameInfo);
818
                if (! empty($result)) {
819
                    foreach ($result as $res) {
820
                        similar_text(strtolower($gameInfo), strtolower($res->name), $percent);
821
                        if ($percent >= 90) {
822
                            $bestMatch = $res->id;
823
                        }
824
                    }
825
                    if ($bestMatch !== false) {
826
                        $game = IGDB::getGame($bestMatch, [
827
                            'id',
828
                            'name',
829
                            'first_release_date',
830
                            'aggregated_rating',
831
                            'summary',
832
                            'cover',
833
                            'url',
834
                            'screenshots',
835
                            'publishers.name',
836
                            'themes.name',
837
                            'platforms.name',
838
                        ]);
839
840
                        $publishers = [];
841
                        if (! empty($game->publishers)) {
842
                            foreach ($game->publishers as $publisher) {
843
                                $publishers[] = IGDB::getCompany($publisher)->name;
844
                            }
845
                        }
846
847
                        $genres = [];
848
849
                        if (! empty($game->themes)) {
850
                            foreach ($game->themes as $theme) {
851
                                $genres[] = IGDB::getTheme($theme)->name;
852
                            }
853
                        }
854
855
                        $genreKey = $this->_getGenreKey(implode(',', $genres));
856
857
                        $platform = '';
858
859
                        if (! empty($game->platforms)) {
860
                            foreach ($game->platforms as $platforms) {
861
                                $platforms = IGDB::getPlatform($platforms);
862
                                similar_text($platforms->name, $gamePlatform, $percent);
863
                                if ($percent >= 85) {
864
                                    $platform = $platforms->name;
865
                                    break;
866
                                }
867
                            }
868
                        }
869
870
                        $game = [
871
                            'title' => $game->name,
872
                            'asin' => $game->id,
873
                            'review' => $game->summary ?? '',
874
                            'coverurl' => ! empty($game->cover->url) ? 'https:'.$game->cover->url : '',
875
                            'releasedate' => ! empty($game->first_release_date) ? Carbon::createFromTimestamp(substr($game->first_release_date, 0, -3))->format('Y-m-d') : now()->format('Y-m-d'),
0 ignored issues
show
Bug introduced by
substr($game->first_release_date, 0, -3) of type string is incompatible with the type integer expected by parameter $timestamp of Carbon\Carbon::createFromTimestamp(). ( Ignorable by Annotation )

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

875
                            'releasedate' => ! empty($game->first_release_date) ? Carbon::createFromTimestamp(/** @scrutinizer ignore-type */ substr($game->first_release_date, 0, -3))->format('Y-m-d') : now()->format('Y-m-d'),
Loading history...
876
                            'esrb' => ! empty($game->aggregated_rating) ? round($game->aggregated_rating).'%' : 'Not Rated',
877
                            'url' => $game->url ?? '',
878
                            'publisher' => ! empty($publishers) ? implode(',', $publishers) : 'Unknown',
879
                            'platform' => $platform ?? '',
880
                            'consolegenre' => ! empty($genres) ? implode(',', $genres) : 'Unknown',
881
                            'consolegenreid' => $genreKey ?? '',
882
                            'salesrank' => '',
883
                        ];
884
885
                        return $game;
886
                    }
887
888
                    $this->colorCli->notice('IGDB returned no valid results');
889
890
                    return false;
891
                }
892
893
                $this->colorCli->notice('IGDB found no valid results');
894
895
                return false;
896
            } catch (ClientException $e) {
897
                if ($e->getCode() === 429) {
898
                    $this->igdbSleep = now()->endOfMonth();
899
                }
900
            }
901
        }
902
903
        return false;
904
    }
905
906
    /**
907
     * @throws \Exception
908
     */
909
    public function processConsoleReleases(): void
910
    {
911
        $query = Release::query()->select(['searchname', 'id'])->whereBetween('categories_id', [Category::GAME_ROOT, Category::GAME_OTHER])->where('nzbstatus', '=', NZB::NZB_ADDED)->whereNull('consoleinfo_id');
912
        if ($this->renamed === true) {
0 ignored issues
show
introduced by
The condition $this->renamed === true is always false.
Loading history...
913
            $query->where('isrenamed', '=', 1);
914
        }
915
        $res = $query->limit($this->gameqty)->orderBy('postdate')->get();
0 ignored issues
show
Bug introduced by
It seems like $this->gameqty can also be of type string; however, parameter $value of Illuminate\Database\Query\Builder::limit() does only seem to accept integer, 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

915
        $res = $query->limit(/** @scrutinizer ignore-type */ $this->gameqty)->orderBy('postdate')->get();
Loading history...
916
917
        $releaseCount = $res->count();
918
        if ($res instanceof \Traversable && $releaseCount > 0) {
919
            if ($this->echooutput) {
920
                $this->colorCli->header('Processing '.$releaseCount.' console release(s).');
921
            }
922
923
            foreach ($res as $arr) {
924
                $startTime = now()->timestamp;
925
                $usedAmazon = false;
926
                $gameId = self::CONS_NTFND;
927
                $gameInfo = $this->parseTitle($arr['searchname']);
928
929
                if ($gameInfo !== false) {
930
                    if ($this->echooutput) {
931
                        $this->colorCli->headerOver('Looking up: ').
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->colorCli->headerOver('Looking up: ') targeting Blacklight\ColorCLI::headerOver() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Bug introduced by
Are you sure $this->colorCli->headerOver('Looking up: ') of type void can be used in concatenation? ( Ignorable by Annotation )

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

931
                        /** @scrutinizer ignore-type */ $this->colorCli->headerOver('Looking up: ').
Loading history...
932
                            $this->colorCli->primary(
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->colorCli->primary...Info['platform'] . ')') targeting Blacklight\ColorCLI::primary() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
933
                                $gameInfo['title'].
934
                                ' ('.
935
                                $gameInfo['platform'].')'
936
                            );
937
                    }
938
939
                    // Check for existing console entry.
940
                    $gameCheck = $this->getConsoleInfoByName($gameInfo['title'], $gameInfo['platform']);
941
942
                    if ($gameCheck === false && \in_array($gameInfo['title'].$gameInfo['platform'], $this->failCache, false)) {
943
                        // Lookup recently failed, no point trying again
944
                        if ($this->echooutput) {
945
                            $this->colorCli->headerOver('Cached previous failure. Skipping.');
946
                        }
947
                        $gameId = -2;
948
                    } elseif ($gameCheck === false) {
949
                        $gameId = $this->updateConsoleInfo($gameInfo);
950
                        $usedAmazon = true;
951
                        if ($gameId === null) {
952
                            $gameId = -2;
953
                            $this->failCache[] = $gameInfo['title'].$gameInfo['platform'];
954
                        }
955
                    } else {
956
                        if ($this->echooutput) {
957
                            $this->colorCli->headerOver('Found Local: ').
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->colorCli->headerOver('Found Local: ') targeting Blacklight\ColorCLI::headerOver() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Bug introduced by
Are you sure $this->colorCli->headerOver('Found Local: ') of type void can be used in concatenation? ( Ignorable by Annotation )

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

957
                            /** @scrutinizer ignore-type */ $this->colorCli->headerOver('Found Local: ').
Loading history...
958
                                $this->colorCli->primary("{$gameCheck['title']} - {$gameCheck['platform']}");
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->colorCli->primary...$gameCheck['platform']) targeting Blacklight\ColorCLI::primary() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
959
                        }
960
                        $gameId = $gameCheck['id'];
961
                    }
962
                } elseif ($this->echooutput) {
963
                    echo '.';
964
                }
965
966
                // Update release.
967
                Release::query()->where('id', $arr['id'])->update(['consoleinfo_id'=> $gameId]);
968
969
                // Sleep to not flood amazon.
970
                $diff = floor((now()->timestamp - $startTime) * 1000000);
971
                if ($this->sleeptime * 1000 - $diff > 0 && $usedAmazon === true) {
972
                    usleep($this->sleeptime * 1000 - $diff);
0 ignored issues
show
Bug introduced by
$this->sleeptime * 1000 - $diff of type double is incompatible with the type integer expected by parameter $micro_seconds of usleep(). ( Ignorable by Annotation )

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

972
                    usleep(/** @scrutinizer ignore-type */ $this->sleeptime * 1000 - $diff);
Loading history...
973
                }
974
            }
975
        } elseif ($this->echooutput) {
976
            $this->colorCli->header('No console releases to process.');
977
        }
978
    }
979
980
    /**
981
     * @param $releaseName
982
     *
983
     * @return array|false
984
     */
985
    public function parseTitle($releaseName)
986
    {
987
        $releaseName = preg_replace('/\sMulti\d?\s/i', '', $releaseName);
988
        $result = [];
989
990
        // Get name of the game from name of release.
991
        if (preg_match('/^(.+((abgx360EFNet|EFNet\sFULL|FULL\sabgxEFNet|abgx\sFULL|abgxbox360EFNet)\s|illuminatenboard\sorg|Place2(hom|us)e.net|united-forums? co uk|\(\d+\)))?(?P<title>.*?)[\.\-_ ](v\.?\d\.\d|PAL|NTSC|EUR|USA|JP|ASIA|JAP|JPN|AUS|MULTI(\.?\d{1,2})?|PATCHED|FULLDVD|DVD5|DVD9|DVDRIP|PROPER|REPACK|RETAIL|DEMO|DISTRIBUTION|REGIONFREE|[\. ]RF[\. ]?|READ\.?NFO|NFOFIX|PSX(2PSP)?|PS[2-4]|PSP|PSVITA|WIIU|WII|X\-?BOX|XBLA|X360|3DS|NDS|N64|NGC)/i', $releaseName, $matches)) {
992
            $title = $matches['title'];
993
994
            // Replace dots, underscores, or brackets with spaces.
995
            $result['title'] = str_replace(['.', '_', '%20', '[', ']'], ' ', $title);
996
            $result['title'] = str_replace([' RF ', '.RF.', '-RF-', '_RF_'], ' ', $result['title']);
997
            //Remove format tags from release title for match
998
            $result['title'] = trim(preg_replace('/PAL|MULTI(\d)?|NTSC-?J?|\(JAPAN\)/i', '', $result['title']));
999
            //Remove disc tags from release title for match
1000
            $result['title'] = trim(preg_replace('/Dis[ck] \d.*$/i', '', $result['title']));
1001
1002
            // Needed to add code to handle DLC Properly.
1003
            if (stripos('dlc', $result['title']) !== false) {
1004
                $result['dlc'] = '1';
1005
                if (stripos('Rock Band Network', $result['title']) !== false) {
1006
                    $result['title'] = 'Rock Band';
1007
                } elseif (strpos('-', $result['title']) !== false) {
1008
                    $dlc = explode('-', $result['title']);
1009
                    $result['title'] = $dlc[0];
1010
                } elseif (preg_match('/(.*? .*?) /i', $result['title'], $dlc)) {
1011
                    $result['title'] = $dlc[0];
1012
                }
1013
            }
1014
        } else {
1015
            $title = '';
1016
        }
1017
1018
        // Get the platform of the release.
1019
        if (preg_match('/[\.\-_ ](?P<platform>XBLA|WiiWARE|N64|SNES|NES|PS[2-4]|PS 3|PSX(2PSP)?|PSP|WIIU|WII|XBOX360|XBOXONE|X\-?BOX|X360|3DS|NDS|N?GC)/i', $releaseName, $matches)) {
1020
            $platform = $matches['platform'];
1021
1022
            if (preg_match('/^N?GC$/i', $platform)) {
1023
                $platform = 'NGC';
1024
            }
1025
1026
            if (stripos('PSX2PSP', $platform) === 0) {
1027
                $platform = 'PSX';
1028
            }
1029
1030
            if (! empty($title) && stripos('XBLA', $platform) === 0 && stripos('dlc', $title) !== false) {
1031
                $platform = 'XBOX360';
1032
            }
1033
1034
            $browseNode = $this->getBrowseNode($platform);
1035
            $result['platform'] = $platform;
1036
            $result['node'] = $browseNode;
1037
        }
1038
        $result['release'] = $releaseName;
1039
        array_map('trim', $result);
1040
1041
        /* Make sure we got a title and platform otherwise the resulting lookup will probably be shit.
1042
           Other option is to pass the $release->categories_id here if we don't find a platform but that
1043
           would require an extra lookup to determine the name. In either case we should have a title at the minimum. */
1044
1045
        return (isset($result['title'], $result['platform']) && ! empty($result['title'])) ? $result : false;
1046
    }
1047
1048
    /**
1049
     * @param $platform
1050
     *
1051
     * @return string
1052
     */
1053
    public function getBrowseNode($platform): string
1054
    {
1055
        switch ($platform) {
1056
            case 'PS2':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1057
                $nodeId = '301712';
1058
                break;
1059
            case 'PS3':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1060
                $nodeId = '14210751';
1061
                break;
1062
            case 'PS4':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1063
                $nodeId = '6427814011';
1064
                break;
1065
            case 'PSP':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1066
                $nodeId = '11075221';
1067
                break;
1068
            case 'PSVITA':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1069
                $nodeId = '3010556011';
1070
                break;
1071
            case 'PSX':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1072
                $nodeId = '294940';
1073
                break;
1074
            case 'WII':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1075
            case 'Wii':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1076
                $nodeId = '14218901';
1077
                break;
1078
            case 'WIIU':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1079
            case 'WiiU':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1080
                $nodeId = '3075112011';
1081
                break;
1082
            case 'XBOX360':
1083
            case 'X360':
1084
                $nodeId = '14220161';
1085
                break;
1086
            case 'XBOXONE':
1087
                $nodeId = '6469269011';
1088
                break;
1089
            case 'XBOX':
1090
            case 'X-BOX':
1091
                $nodeId = '537504';
1092
                break;
1093
            case 'NDS':
1094
                $nodeId = '11075831';
1095
                break;
1096
            case '3DS':
1097
                $nodeId = '2622269011';
1098
                break;
1099
            case 'GC':
1100
            case 'NGC':
1101
                $nodeId = '541022';
1102
                break;
1103
            case 'N64':
1104
                $nodeId = '229763';
1105
                break;
1106
            case 'SNES':
1107
                $nodeId = '294945';
1108
                break;
1109
            case 'NES':
1110
                $nodeId = '566458';
1111
                break;
1112
            default:
1113
                $nodeId = '468642';
1114
                break;
1115
        }
1116
1117
        return $nodeId;
1118
    }
1119
1120
    /**
1121
     * @param $nodeName
1122
     *
1123
     * @return bool|string
1124
     */
1125
    public function matchBrowseNode($nodeName)
1126
    {
1127
        $str = '';
1128
1129
        //music nodes above mp3 download nodes
1130
        switch ($nodeName) {
1131
            case 'Action_shooter':
1132
            case 'Action_Games':
1133
            case 'Action_games':
1134
                $str = 'Action';
1135
                break;
1136
            case 'Action/Adventure':
1137
            case 'Action\Adventure':
1138
            case 'Adventure_games':
1139
                $str = 'Adventure';
1140
                break;
1141
            case 'Boxing_games':
1142
            case 'Sports_games':
1143
                $str = 'Sports';
1144
                break;
1145
            case 'Fantasy_action_games':
1146
                $str = 'Fantasy';
1147
                break;
1148
            case 'Fighting_action_games':
1149
                $str = 'Fighting';
1150
                break;
1151
            case 'Flying_simulation_games':
1152
                $str = 'Flying';
1153
                break;
1154
            case 'Horror_action_games':
1155
                $str = 'Horror';
1156
                break;
1157
            case 'Kids & Family':
1158
                $str = 'Family';
1159
                break;
1160
            case 'Role_playing_games':
1161
                $str = 'Role-Playing';
1162
                break;
1163
            case 'Shooter_action_games':
1164
                $str = 'Shooter';
1165
                break;
1166
            case 'Singing_games':
1167
                $str = 'Music';
1168
                break;
1169
            case 'Action':
1170
            case 'Adventure':
1171
            case 'Arcade':
1172
            case 'Board Games':
1173
            case 'Cards':
1174
            case 'Casino':
1175
            case 'Collections':
1176
            case 'Family':
1177
            case 'Fantasy':
1178
            case 'Fighting':
1179
            case 'Flying':
1180
            case 'Horror':
1181
            case 'Music':
1182
            case 'Puzzle':
1183
            case 'Racing':
1184
            case 'Rhythm':
1185
            case 'Role-Playing':
1186
            case 'Simulation':
1187
            case 'Shooter':
1188
            case 'Shooting':
1189
            case 'Sports':
1190
            case 'Strategy':
1191
            case 'Trivia':
1192
                $str = $nodeName;
1193
                break;
1194
        }
1195
1196
        return ($str !== '') ? $str : false;
1197
    }
1198
}
1199