1<?php
2
3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0.
4// See the LICENCE file in the repository root for full licence text.
5
6namespace App\Console\Commands;
7
8use App\Models\Chat\UserChannel;
9use DB;
10use Illuminate\Console\Command;
11
12class FixMissingUserChannels extends Command
13{
14 /**
15 * The name and signature of the console command.
16 *
17 * @var string
18 */
19 protected $signature = 'fix:missing-userchannels';
20
21 /**
22 * The console command description.
23 *
24 * @var string
25 */
26 protected $description = 'Recreates UserChannels that were deleted.';
27
28 /**
29 * Execute the console command.
30 *
31 * @return mixed
32 */
33 public function handle()
34 {
35 $continue = $this->confirm('Proceed?');
36
37 if (!$continue) {
38 $this->error('Aborted.');
39 return;
40 }
41
42 $start = time();
43
44 $this->info('Getting a list of channels that need fixing...');
45
46 $channels =
47 DB::connection('mysql-chat')
48 ->table('channels')
49 ->select(
50 'channels.channel_id',
51 'channels.name',
52 DB::raw('(SELECT count(*) FROM user_channels WHERE user_channels.channel_id = channels.channel_id) AS user_count')
53 )
54 ->where('channels.type', 'PM')
55 ->having('user_count', '<', 2)
56 ->get();
57
58 $count = count($channels);
59 $this->warn("Total {$count}");
60 $this->warn((time() - $start).'s to scan.');
61
62 // reconfirm
63 if (!$this->confirm("{$count} channels need to be repaired, proceed?")) {
64 $this->error('Aborted.');
65 return;
66 }
67
68 $start = time();
69 $bar = $this->output->createProgressBar($count);
70
71 foreach ($channels as $channel) {
72 $userIds = explode('-', str_replace('#pm_', '', $channel->name));
73 foreach ($userIds as $userId) {
74 $userChannel = UserChannel::where([
75 'channel_id' => $channel->channel_id,
76 'user_id' => $userId,
77 ]);
78
79 if (!$userChannel->exists()) {
80 $userChannel = new UserChannel();
81 $userChannel->channel_id = $channel->channel_id;
82 $userChannel->user_id = $userId;
83 $userChannel->hidden = true;
84 $userChannel->save();
85 }
86 }
87
88 $bar->advance();
89 }
90
91 $this->warn("\n".(time() - $start).'s taken.');
92 $bar->finish();
93 }
94}