Test Setup Failed
Push — dependabot/composer/thinktomor... ( e86b85...256c6d )
by
unknown
67:00 queued 59:01
created

Relation::isOnline()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Thinktomorrow\Chief\Relations;
6
7
use Illuminate\Database\Eloquent\Builder;
8
use Illuminate\Database\Eloquent\Model;
9
10
/**
11
 * @property string $child_type
12
 * @property string $child_id
13
 * @property string $parent_type
14
 * @property string $parent_id
15
 */
16
class Relation extends Model
17
{
18
    public $timestamps = false;
19
    public $guarded = [];
20
21
    public function isOnline(): bool
22
    {
23
        // Default is online, except explicitly set offline
24
        return ($this->online_status != 0);
25
    }
26
27
    public function isOffline(): bool
28
    {
29
        return !$this->isOnline();
30
    }
31
32
    /**
33
     * Set the keys for a save update query.
34
     * We override the default save setup since we do not have a primary key in relation table.
35
     * There should however always be the parent and child references so we can use
36
     * those to target the record in database.
37
     *
38
     * @param Builder $query
39
     * @return Builder
40
     */
41
    protected function setKeysForSaveQuery(Builder $query)
42
    {
43
        $query->where('parent_type', $this->parent_type)
44
            ->where('parent_id', $this->parent_id)
45
            ->where('child_type', $this->child_type)
46
            ->where('child_id', $this->child_id);
47
48
        return $query;
49
    }
50
51
    public function parent()
52
    {
53
        return $this->morphTo('parent', 'parent_type', 'parent_id');
54
    }
55
56
    public function child()
57
    {
58
        return $this->morphTo('child', 'child_type', 'child_id');
59
    }
60
61
    public static function parents($child_type, $child_id)
62
    {
63
        $relations = static::where('child_type', $child_type)
64
            ->where('child_id', $child_id)
65
            ->orderBy('sort', 'ASC')
66
            ->get();
67
68
        return $relations->map(function (Relation $relation) {
69
            $parent = $relation->parent;
0 ignored issues
show
Bug introduced by
The property parent does not exist on Thinktomorrow\Chief\Relations\Relation. Did you mean parent_id?
Loading history...
70
            $parent->relation = $relation;
71
72
            return $parent;
73
        });
74
    }
75
76
    public static function children($parent_type, $parent_id)
77
    {
78
        $relations = static::where('parent_type', $parent_type)
79
            ->where('parent_id', $parent_id)
80
            ->with('child')
81
            ->orderBy('sort', 'ASC')
82
            ->get();
83
84
        return $relations->map(function (Relation $relation) use ($parent_type, $parent_id) {
85
86
            // It could be that the child itself is soft-deleted, if this is the case, we will ignore it and move on.
87
            if (!$child = $relation->child) {
0 ignored issues
show
Bug introduced by
The property child does not exist on Thinktomorrow\Chief\Relations\Relation. Did you mean child_id?
Loading history...
88
                if (!$relation->child()->withTrashed()->first()) {
89
                    // If we cannot retrieve it then the relation type is possibly wrong, this is a database inconsistency and should be addressed
90
                    throw new \DomainException('Corrupt relation reference. Related child [' . $relation->child_type . '@' . $relation->child_id . '] could not be retrieved for parent [' . $parent_type . '@' . $parent_id . ']. Make sure the morph key can resolve to a valid class.');
91
                }
92
93
                return null;
94
            }
95
96
            $child->relation = $relation;
97
98
            return $child;
99
        })
100
101
            // In case of soft-deleted entries, this will be null and should be ignored. We make sure that keys are reset in case of removed child
102
            ->reject(function ($child) {
103
                return is_null($child);
104
            })
105
            ->values();
106
    }
107
108
    public function delete()
109
    {
110
        return static::where('parent_type', $this->parent_type)
111
            ->where('parent_id', $this->parent_id)
112
            ->where('child_type', $this->child_type)
113
            ->where('child_id', $this->child_id)
114
            ->delete();
115
    }
116
117
    public static function deleteRelationsOf($type, $id)
118
    {
119
        $relations = static::where(function ($query) use ($type, $id) {
120
            return $query->where('parent_type', $type)
121
                ->where('parent_id', $id);
122
        })->orWhere(function ($query) use ($type, $id) {
123
            return $query->where('child_type', $type)
124
                ->where('child_id', $id);
125
        })->get();
126
127
        foreach ($relations as $relation) {
128
            $relation->delete();
129
        }
130
    }
131
132
    public static function deleteAllChildRelationsOf($type, $id)
133
    {
134
        $relations = static::where(function ($query) use ($type, $id) {
135
            return $query->where('parent_type', $type)
136
                ->where('parent_id', $id);
137
        })->get();
138
139
        foreach ($relations as $relation) {
140
            $relation->delete();
141
        }
142
    }
143
144
    public static function deleteAllParentRelationsOf($type, $id)
145
    {
146
        $relations = static::where(function ($query) use ($type, $id) {
147
            return $query->where('child_type', $type)
148
                ->where('child_id', $id);
149
        })->get();
150
151
        foreach ($relations as $relation) {
152
            $relation->delete();
153
        }
154
    }
155
}
156