1: | <?php |
2: | |
3: | namespace Baril\Bonsai\Console; |
4: | |
5: | use Illuminate\Console\Command; |
6: | use Illuminate\Database\Eloquent\Model; |
7: | |
8: | class FixTreeCommand extends Command |
9: | { |
10: | protected $signature = 'bonsai:fix {model : The model class.}'; |
11: | protected $description = 'Rebuilds the closures for a given tree'; |
12: | |
13: | public function handle() |
14: | { |
15: | $model = $this->input->getArgument('model'); |
16: | if ( |
17: | !class_exists($model) |
18: | || !is_subclass_of($model, Model::class) |
19: | || !method_exists($model, 'getClosureTable') |
20: | ) { |
21: | $this->error('{model} must be a valid model class and use the BelongsToTree trait!'); |
22: | return; |
23: | } |
24: | |
25: | $this->rebuildClosures($model); |
26: | } |
27: | |
28: | protected function rebuildClosures($model) |
29: | { |
30: | $instance = new $model(); |
31: | $connection = $instance->getConnection(); |
32: | $connection->transaction(function () use ($instance, $connection) { |
33: | $table = $instance->getTable(); |
34: | $parentKey = $instance->getParentForeignKeyName(); |
35: | $primaryKey = $instance->getKeyName(); |
36: | $closureTable = $instance->getClosureTable(); |
37: | |
38: | |
39: | $connection->table($closureTable)->delete(); |
40: | |
41: | |
42: | $connection->insert(" |
43: | INSERT INTO $closureTable (ancestor_id, descendant_id, depth) |
44: | SELECT $primaryKey, $primaryKey, 0 FROM $table"); |
45: | |
46: | |
47: | $depth = 1; |
48: | $continue = true; |
49: | while ($continue) { |
50: | $connection->insert(" |
51: | INSERT INTO $closureTable (ancestor_id, descendant_id, depth) |
52: | SELECT closure_table.ancestor_id, main_table.$primaryKey, ? |
53: | FROM $table AS main_table |
54: | INNER JOIN $closureTable AS closure_table |
55: | ON main_table.$parentKey = closure_table.descendant_id |
56: | WHERE closure_table.depth = ?", [$depth, $depth - 1]); |
57: | $continue = (bool) $connection->table($closureTable)->where('depth', '=', $depth)->exists(); |
58: | $depth++; |
59: | } |
60: | }); |
61: | |
62: | $this->line("<info>Rebuilt the closures for:</info> $model"); |
63: | } |
64: | } |
65: | |