Passed
Push — master ( 96ef05...f81447 )
by Darko
09:59
created

GetArticleRange   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 18
eloc 74
c 1
b 0
f 0
dl 0
loc 139
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
B handle() 0 48 8
A getNntp() 0 11 3
B updateGroupRecords() 0 46 7
1
<?php
2
3
namespace App\Console\Commands;
4
5
use App\Models\Settings;
6
use App\Models\UsenetGroup;
7
use Blacklight\Binaries;
8
use Blacklight\NNTP;
9
use Illuminate\Console\Command;
10
use Illuminate\Support\Facades\DB;
11
use Illuminate\Support\Facades\Log;
12
13
class GetArticleRange extends Command
14
{
15
    /**
16
     * The name and signature of the console command.
17
     *
18
     * @var string
19
     */
20
    protected $signature = 'articles:get-range
21
                            {mode : Mode: binaries or backfill}
22
                            {group : Group name}
23
                            {first : First article number}
24
                            {last : Last article number}';
25
26
    /**
27
     * The console command description.
28
     *
29
     * @var string
30
     */
31
    protected $description = 'Get a range of article headers for a group';
32
33
    /**
34
     * Execute the console command.
35
     */
36
    public function handle(): int
37
    {
38
        $mode = $this->argument('mode');
39
        $groupName = $this->argument('group');
40
        $firstArticle = (int) $this->argument('first');
41
        $lastArticle = (int) $this->argument('last');
42
43
        if (! \in_array($mode, ['binaries', 'backfill'], true)) {
44
            $this->error('Mode must be either "binaries" or "backfill".');
45
46
            return self::FAILURE;
47
        }
48
49
        try {
50
            $nntp = $this->getNntp();
51
            $groupMySQL = UsenetGroup::getByName($groupName)->toArray();
52
53
            if ($groupMySQL === null) {
0 ignored issues
show
introduced by
The condition $groupMySQL === null is always false.
Loading history...
54
                $this->error("Group not found: {$groupName}");
55
56
                return self::FAILURE;
57
            }
58
59
            if (NNTP::isError($nntp->selectGroup($groupMySQL['name']))
60
                && NNTP::isError($nntp->dataError($nntp, $groupMySQL['name']))) {
61
                return self::FAILURE;
62
            }
63
64
            $binaries = new Binaries(['NNTP' => $nntp, 'Groups' => null]);
0 ignored issues
show
Unused Code introduced by
The call to Blacklight\Binaries::__construct() has too many arguments starting with array('NNTP' => $nntp, 'Groups' => null). ( Ignorable by Annotation )

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

64
            $binaries = /** @scrutinizer ignore-call */ new Binaries(['NNTP' => $nntp, 'Groups' => null]);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
65
            $return = $binaries->scan(
66
                $groupMySQL,
67
                $firstArticle,
68
                $lastArticle,
69
                ((int) Settings::settingValue('safepartrepair') === 1 ? 'update' : 'backfill')
70
            );
71
72
            if (empty($return)) {
73
                return self::SUCCESS;
74
            }
75
76
            $this->updateGroupRecords($mode, $groupMySQL, $return);
77
78
            return self::SUCCESS;
79
        } catch (\Throwable $e) {
80
            Log::error($e->getTraceAsString());
81
            $this->error($e->getMessage());
82
83
            return self::FAILURE;
84
        }
85
    }
86
87
    /**
88
     * Update group records based on mode.
89
     */
90
    private function updateGroupRecords(string $mode, array $groupMySQL, array $return): void
91
    {
92
        $columns = [];
93
94
        switch ($mode) {
95
            case 'binaries':
96
                if ($return['lastArticleNumber'] <= $groupMySQL['last_record']) {
97
                    return;
98
                }
99
                $unixTime = is_numeric($return['lastArticleDate'])
100
                    ? $return['lastArticleDate']
101
                    : strtotime($return['lastArticleDate']);
102
                $columns[1] = sprintf('last_record_postdate = FROM_UNIXTIME(%s)', $unixTime);
103
                $columns[2] = sprintf('last_record = %s', $return['lastArticleNumber']);
104
                $query = sprintf(
105
                    'UPDATE usenet_groups SET %s, %s, last_updated = NOW() WHERE id = %d AND last_record < %s',
106
                    $columns[1],
107
                    $columns[2],
108
                    $groupMySQL['id'],
109
                    $return['lastArticleNumber']
110
                );
111
                break;
112
113
            case 'backfill':
114
                if ($return['firstArticleNumber'] >= $groupMySQL['first_record']) {
115
                    return;
116
                }
117
                $unixTime = is_numeric($return['firstArticleDate'])
118
                    ? $return['firstArticleDate']
119
                    : strtotime($return['firstArticleDate']);
120
                $columns[1] = sprintf('first_record_postdate = FROM_UNIXTIME(%s)', $unixTime);
121
                $columns[2] = sprintf('first_record = %s', $return['firstArticleNumber']);
122
                $query = sprintf(
123
                    'UPDATE usenet_groups SET %s, %s, last_updated = NOW() WHERE id = %d AND first_record > %s',
124
                    $columns[1],
125
                    $columns[2],
126
                    $groupMySQL['id'],
127
                    $return['firstArticleNumber']
128
                );
129
                break;
130
131
            default:
132
                return;
133
        }
134
135
        DB::update($query);
136
    }
137
138
    /**
139
     * Get NNTP connection.
140
     */
141
    private function getNntp(): NNTP
142
    {
143
        $nntp = new NNTP;
144
145
        if ((config('nntmux_nntp.use_alternate_nntp_server') === true
146
            ? $nntp->doConnect(false, true)
147
            : $nntp->doConnect()) !== true) {
148
            throw new \Exception('Unable to connect to usenet.');
149
        }
150
151
        return $nntp;
152
    }
153
}
154