1: <?php
2:
3: namespace Baril\Bonsai\Relations;
4:
5: use Baril\Bonsai\TreeException;
6: use Illuminate\Database\Eloquent\Model;
7: use Illuminate\Database\Eloquent\Relations\BelongsToMany;
8:
9: class Closure extends BelongsToMany
10: {
11: protected $depth = null;
12:
13: public function orderByDepth($direction = 'asc')
14: {
15: return $this->orderBy($this->table . '.depth', $direction);
16: }
17:
18: public function upToDepth($depth)
19: {
20: $this->depth = $depth;
21: return $this->wherePivot('depth', '<=', $depth);
22: }
23:
24: public function excludingSelf()
25: {
26: $this->pivotWheres[] = ['depth', '>', 0];
27: return $this->whereRaw("$this->table.depth > 0"); // whereRaw makes it easier to remove the clause if needed
28: }
29:
30: public function includingSelf()
31: {
32: foreach ($this->pivotWheres as $k => $where) {
33: if ($where === ['depth', '>', 0]) {
34: unset($this->pivotWheres[$k]);
35: }
36: }
37: $this->pivotWheres = array_values($this->pivotWheres);
38:
39: $query = $this->getBaseQuery();
40: $sql = "$this->table.depth > 0";
41: foreach ($query->wheres as $k => $where) {
42: if ($where === ['type' => 'raw', 'sql' => $sql, 'boolean' => 'and']) {
43: unset($query->wheres[$k]);
44: }
45: }
46: $query->wheres = array_values($query->wheres);
47: return $this;
48: }
49:
50: /**
51: * Get the pivot attributes from a model.
52: *
53: * @param \Illuminate\Database\Eloquent\Model $model
54: * @return array
55: */
56: protected function migratePivotAttributes(Model $model)
57: {
58: $values = parent::migratePivotAttributes($model);
59: if (array_key_exists('depth', $values) && $this->depth !== null) {
60: $values['_remaining_depth'] = $this->depth - $values['depth'];
61: }
62:
63: return $values;
64: }
65:
66: // Since the Closure relation is read-only, all the methods below will
67: // throw an exception.
68:
69: protected function readOnly()
70: {
71: throw new TreeException("The $this->relationName relation is read-only!");
72: }
73:
74: public function save(Model $model, array $pivotAttributes = [], $touch = true)
75: {
76: $this->readOnly();
77: }
78:
79: public function saveMany($models, array $pivotAttributes = [])
80: {
81: $this->readOnly();
82: }
83:
84: public function create(array $attributes = [], array $joining = [], $touch = true)
85: {
86: $this->readOnly();
87: }
88:
89: public function createMany(iterable $records, array $joinings = [])
90: {
91: $this->readOnly();
92: }
93:
94: public function toggle($ids, $touch = true)
95: {
96: $this->readOnly();
97: }
98:
99: public function syncWithoutDetaching($ids)
100: {
101: $this->readOnly();
102: }
103:
104: public function sync($ids, $detaching = true)
105: {
106: $this->readOnly();
107: }
108:
109: public function attach($id, array $attributes = [], $touch = true)
110: {
111: $this->readOnly();
112: }
113:
114: public function detach($ids = null, $touch = true)
115: {
116: $this->readOnly();
117: }
118: }
119: