Passed
Push — master ( 0f755c...8f995b )
by Ben
10:33
created

Relation   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 125
Duplicated Lines 0 %

Test Coverage

Coverage 81.63%

Importance

Changes 0
Metric Value
wmc 14
eloc 58
c 0
b 0
f 0
dl 0
loc 125
ccs 40
cts 49
cp 0.8163
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A parent() 0 3 1
A parents() 0 11 1
A children() 0 30 3
A delete() 0 7 1
A child() 0 3 1
A setKeysForSaveQuery() 0 8 1
A deleteRelationsOf() 0 12 2
A deleteAllParentRelationsOf() 0 9 2
A deleteAllChildRelationsOf() 0 9 2
1
<?php
2
3
namespace Thinktomorrow\Chief\Relations;
4
5
use Illuminate\Database\Eloquent\Builder;
6
use Illuminate\Database\Eloquent\Model;
7
8
class Relation extends Model
9
{
10
    public $timestamps = false;
11
    public $guarded = [];
12
13
    /**
14
     * Set the keys for a save update query.
15
     * We override the default save setup since we do not have a primary key in relation table.
16
     * There should however always be the parent and child references so we can use
17
     * those to target the record in database.
18
     *
19
     * @param Builder $query
20
     * @return Builder
21
     */
22
    protected function setKeysForSaveQuery(Builder $query)
23
    {
24
        $query->where('parent_type', $this->getMorphClass())
25
                ->where('parent_id', $this->getKey())
26
                ->where('child_type', $this->child_type)
27
                ->where('child_id', $this->child_id);
28
29
        return $query;
30
    }
31
32 7
    public function parent()
33
    {
34 7
        return $this->morphTo('parent', 'parent_type', 'parent_id');
35
    }
36
37 34
    public function child()
38
    {
39 34
        return $this->morphTo('child', 'child_type', 'child_id');
40
    }
41
42 7
    public static function parents($child_type, $child_id)
43
    {
44 7
        $relations = static::where('child_type', $child_type)
45 7
            ->where('child_id', $child_id)
46 7
            ->orderBy('sort', 'ASC')
47 7
            ->get();
48
49
        return $relations->map(function (Relation $relation) {
50 6
            $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...
51 6
            $parent->relation = $relation;
52 6
            return $parent;
53 7
        });
54
    }
55
56 65
    public static function children($parent_type, $parent_id)
57
    {
58 65
        $relations = static::where('parent_type', $parent_type)
59 65
                            ->where('parent_id', $parent_id)
60 65
                            ->orderBy('sort', 'ASC')
61 65
                            ->get();
62
63
        return $relations->map(function (Relation $relation) use ($parent_type, $parent_id) {
64
65
            // It could be that the child itself is soft-deleted, if this is the case, we will ignore it and move on.
66 33
            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...
67
                if (!$relation->child()->withTrashed()->first()) {
68
//                if ((!method_exists($childInstance, 'trashed')) || ! $childInstance->onlyTrashed()->find($relation->child_id)) {
69
                    // If we cannot retrieve it then he collection type is possibly off, this is a database inconsistency and should be addressed
70
                    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.');
71
                }
72
73
                return null;
74
            }
75
76 33
            $child->relation = $relation;
77
78 33
            return $child;
79 65
        })
80
81
        // 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
82
        ->reject(function ($child) {
83 33
            return is_null($child);
84 65
        })
85 65
        ->values();
86
    }
87
88 1
    public function delete()
89
    {
90 1
        return static::where('parent_type', $this->parent_type)
91 1
                ->where('parent_id', $this->parent_id)
92 1
                ->where('child_type', $this->child_type)
93 1
                ->where('child_id', $this->child_id)
94 1
                ->delete();
95
    }
96
97 2
    public static function deleteRelationsOf($type, $id)
98
    {
99
        $relations = static::where(function ($query) use ($type, $id) {
100 2
            return $query->where('parent_type', $type)
101 2
                         ->where('parent_id', $id);
102
        })->orWhere(function ($query) use ($type, $id) {
103 2
            return $query->where('child_type', $type)
104 2
                ->where('child_id', $id);
105 2
        })->get();
106
107 2
        foreach ($relations as $relation) {
108 1
            $relation->delete();
109
        }
110 2
    }
111
112
    public static function deleteAllChildRelationsOf($type, $id)
113
    {
114
        $relations = static::where(function ($query) use ($type, $id) {
115
            return $query->where('parent_type', $type)
116
                ->where('parent_id', $id);
117
        })->get();
118
119
        foreach ($relations as $relation) {
120
            $relation->delete();
121
        }
122
    }
123
124
    public static function deleteAllParentRelationsOf($type, $id)
125
    {
126
        $relations = static::where(function ($query) use ($type, $id) {
127
            return $query->where('child_type', $type)
128
                ->where('child_id', $id);
129
        })->get();
130
131
        foreach ($relations as $relation) {
132
            $relation->delete();
133
        }
134
    }
135
}
136