1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace Umbrellio\LTree\Helpers; |
6
|
|
|
|
7
|
|
|
use Illuminate\Database\Eloquent\Model; |
8
|
|
|
use Illuminate\Support\Facades\DB; |
9
|
|
|
use Umbrellio\LTree\Interfaces\LTreeInterface; |
10
|
|
|
use Umbrellio\LTree\Interfaces\LTreeModelInterface; |
11
|
|
|
use Umbrellio\LTree\Types\LTreeType; |
12
|
|
|
|
13
|
|
|
class LTreeHelper |
14
|
|
|
{ |
15
|
|
|
/** |
16
|
|
|
* @param LTreeInterface|Model $model |
17
|
|
|
*/ |
18
|
3 |
|
public function buildPath($model): void |
19
|
|
|
{ |
20
|
3 |
|
$pathValue = []; |
21
|
3 |
|
if ($model->getLtreeParentId()) { |
|
|
|
|
22
|
1 |
|
$parent = $model->ltreeParent; |
23
|
1 |
|
$pathValue = array_merge($pathValue, $parent->getLtreePath()); |
24
|
|
|
} |
25
|
3 |
|
$pathValue[] = $model->getKey(); |
|
|
|
|
26
|
3 |
|
DB::statement(sprintf( |
27
|
3 |
|
"UPDATE %s SET %s = text2ltree('%s') WHERE %s = %s", |
28
|
3 |
|
$model->getTable(), |
|
|
|
|
29
|
3 |
|
$model->getLtreePathColumn(), |
|
|
|
|
30
|
3 |
|
implode(LTreeType::TYPE_SEPARATE, $pathValue), |
31
|
3 |
|
$model->getKeyName(), |
|
|
|
|
32
|
3 |
|
$model->getKey() |
33
|
3 |
|
)); |
34
|
3 |
|
$model->refresh(); |
|
|
|
|
35
|
|
|
} |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* @param LTreeInterface|Model $model |
39
|
|
|
* @param LTreeInterface|Model|null $to |
40
|
|
|
*/ |
41
|
2 |
|
public function moveNode($model, $to = null, array $columns = []): void |
42
|
|
|
{ |
43
|
2 |
|
$pathName = $model->getLtreePathColumn(); |
44
|
2 |
|
$oldPath = $model->getLtreePath(LTreeModelInterface::AS_STRING); |
|
|
|
|
45
|
2 |
|
$newPath = $to ? $to->getLtreePath(LTreeModelInterface::AS_STRING) : ''; |
46
|
2 |
|
$expressions = static::wrapExpressions($columns); |
|
|
|
|
47
|
2 |
|
$expressions[] = " |
48
|
2 |
|
\"${pathName}\" = (text2ltree('${newPath}') || subpath(\"${pathName}\", (nlevel(text2ltree('${oldPath}')) - 1))) |
49
|
2 |
|
"; |
50
|
|
|
|
51
|
2 |
|
DB::statement(sprintf( |
52
|
2 |
|
"UPDATE %s SET %s WHERE (%s <@ text2ltree('%s')) = true", |
53
|
2 |
|
$model->getTable(), |
54
|
2 |
|
implode(', ', $expressions), |
55
|
2 |
|
$pathName, |
56
|
2 |
|
$oldPath |
57
|
2 |
|
)); |
58
|
2 |
|
$model->refresh(); |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* @param LTreeInterface|Model $model |
63
|
|
|
*/ |
64
|
1 |
|
public function dropDescendants($model, array $columns = []): void |
65
|
|
|
{ |
66
|
1 |
|
$sql = sprintf( |
67
|
1 |
|
"UPDATE %s SET %s WHERE (%s <@ text2ltree('%s')) = true", |
68
|
1 |
|
$model->getTable(), |
69
|
1 |
|
implode(', ', static::wrapExpressions($columns)), |
|
|
|
|
70
|
1 |
|
$model->getLtreePathColumn(), |
71
|
1 |
|
$model->getLtreePath(LTreeModelInterface::AS_STRING) |
72
|
1 |
|
); |
73
|
1 |
|
DB::statement($sql); |
74
|
1 |
|
$model->refresh(); |
75
|
|
|
} |
76
|
|
|
|
77
|
3 |
|
private function wrapExpressions(array $columns): array |
78
|
|
|
{ |
79
|
3 |
|
$expressions = []; |
80
|
3 |
|
foreach ($columns as $column => $value) { |
81
|
|
|
switch (true) { |
82
|
|
|
case $value === null: |
83
|
1 |
|
$expressions[] = sprintf('%s = null', (string) $column); |
84
|
1 |
|
break; |
85
|
3 |
|
case is_string($value): |
86
|
3 |
|
$expressions[] = sprintf("%s = '%s'", (string) $column, (string) $value); |
87
|
3 |
|
break; |
88
|
|
|
default: |
89
|
1 |
|
$expressions[] = sprintf('%s = %s', (string) $column, (string) $value); |
90
|
|
|
} |
91
|
|
|
} |
92
|
3 |
|
return $expressions; |
93
|
|
|
} |
94
|
|
|
} |
95
|
|
|
|