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\Forum\Forum;
9use Illuminate\Console\Command;
10
11class FixForumDisplayOrder extends Command
12{
13 /**
14 * The name and signature of the console command.
15 *
16 * @var string
17 */
18 protected $signature = 'fix:forum-display-order';
19
20 /**
21 * The console command description.
22 *
23 * @var string
24 */
25 protected $description = 'Correctly sort forum based on parent tree.';
26
27 /**
28 * Execute the console command.
29 *
30 * @return mixed
31 */
32 public function handle()
33 {
34 $continue = $this->confirm('Proceed?');
35
36 if (!$continue) {
37 $this->error('Aborted.');
38 return;
39 }
40
41 $this->startReorder();
42 $this->info('Done.');
43 }
44
45 public function startReorder()
46 {
47 $this->info('Preparing data...');
48
49 $all = Forum::orderBy('left_id')->get();
50
51 $byParentId = [];
52
53 foreach ($all as $forum) {
54 $byParentId[$forum->parent_id][] = $forum->getKey();
55 }
56
57 $sorted = [];
58 $byId = $all->keyBy('forum_id');
59
60 $this->info('Sorting...');
61
62 $this->reorder($byParentId[0], $byParentId, $sorted, $byId);
63
64 foreach ($sorted as $left => $forum) {
65 $forum->update(['left_id' => $left * 10, 'right_id' => 0]);
66 }
67 }
68
69 public function reorder($ids, $byParentId, &$sorted, &$byId)
70 {
71 foreach ($ids as $id) {
72 $forum = $byId->pull($id);
73
74 if ($forum === null) {
75 continue;
76 }
77
78 $sorted[] = $forum;
79
80 if (isset($byParentId[$id])) {
81 $this->reorder($byParentId[$id], $byParentId, $sorted, $byId);
82 }
83 }
84 }
85}