Pivot   A
last analyzed

Complexity

Total Complexity 22

Size/Duplication

Total Lines 203
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 56
c 1
b 0
f 0
dl 0
loc 203
ccs 65
cts 65
cp 1
rs 10
wmc 22

9 Methods

Rating   Name   Duplication   Size   Complexity  
A isSimple() 0 3 2
A chunk() 0 16 2
A get() 0 7 2
A simplePaginate() 0 12 2
A paginate() 0 13 2
A getSimple() 0 17 3
A cleanSimplePivotAttributes() 0 14 3
A matchSimple() 0 24 4
A hydrateSimplePivotRelation() 0 8 2
1
<?php
2
3
namespace Volosyuk\SimpleEloquent\Relations;
4
5
use Exception;
6
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
7
use Illuminate\Contracts\Pagination\Paginator;
8
use Illuminate\Database\Eloquent\Builder;
9
use Illuminate\Database\Eloquent\Model;
10
use Illuminate\Support\Collection;
11
use stdClass;
12
use Volosyuk\SimpleEloquent\ModelAccessor;
13
14
/**
15
 * @package Volosyuk\SimpleEloquent
16
 *
17
 * @property Builder|\Volosyuk\SimpleEloquent\Builder $query
18
 * @property Model $related
19
 * @property Model $parent
20
 */
21
trait Pivot
22
{
23
    /**
24
     * Match the eagerly loaded results to their parents.
25
     *
26
     * @param  array   $models
27
     * @param  Collection  $results
28
     * @param  string  $relation
29
     * @return array
30
     */
31 3
    public function matchSimple(array &$models, Collection $results, $relation)
32
    {
33 3
        $foreign = $this->foreignPivotKey;
34
35 3
        $dictionary = [];
36
37 3
        foreach ($results as $result) {
38 3
            $dictionaryKey = ModelAccessor::get(ModelAccessor::get($result, 'pivot'), $foreign);
39
40 3
            $dictionary[$dictionaryKey][] = $result;
41
        }
42
43 3
        foreach ($models as &$model) {
44 3
            $collection = Collection::make();
45
46 3
            if (isset($dictionary[$key = ModelAccessor::get($model, $this->parent->getKeyName())])) {
47 3
                $collection = Collection::make($dictionary[$key]);
48
            }
49
50 3
            ModelAccessor::set($model, $relation, $collection);
51
        }
52 3
        unset($model);
53
54 3
        return $models;
55
    }
56
57
    /**
58
     * Execute the query as a "select" statement.
59
     *
60
     * @param array $columns
61
     *
62
     * @return Collection
63
     *
64
     * @throws Exception
65
     */
66 10
    public function getSimple($columns = ['*'])
67
    {
68 10
        $columns = $this->query->getQuery()->columns ? [] : $columns;
69
70 10
        $builder = $this->query->applyScopes();
71
72 10
        $models = $builder->addSelect(
73 10
            $this->shouldSelect($columns)
0 ignored issues
show
Bug introduced by
It seems like shouldSelect() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

73
            $this->/** @scrutinizer ignore-call */ 
74
                   shouldSelect($columns)
Loading history...
74 10
        )->getSimpleModels();
75
76 10
        $this->hydrateSimplePivotRelation($models);
0 ignored issues
show
Bug introduced by
It seems like $models can also be of type Illuminate\Database\Eloquent\Builder and Illuminate\Database\Query\Builder; however, parameter $models of Volosyuk\SimpleEloquent\...teSimplePivotRelation() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

76
        $this->hydrateSimplePivotRelation(/** @scrutinizer ignore-type */ $models);
Loading history...
77
78 10
        if (count($models) > 0) {
79 10
            $models = $builder->eagerLoadRelationsSimple($models);
80
        }
81
82 10
        return $this->related->newCollection($models);
83
    }
84
85
    /**
86
     * Get a paginator for the "select" statement.
87
     *
88
     * @param  int  $perPage
89
     * @param  array  $columns
90
     * @param  string  $pageName
91
     * @param  int|null  $page
92
     * @return LengthAwarePaginator
93
     */
94 4
    public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
95
    {
96 4
        if ($this->isSimple()) {
97 4
            $this->query->addSelect($this->shouldSelect($columns));
98
99
            return tap($this->query->paginate($perPage, $columns, $pageName, $page), function ($paginator) {
100 4
                $items = $paginator->items();
101
102 4
                $this->hydrateSimplePivotRelation($items);
103 4
            });
104
        }
105
106 4
        return parent::paginate($perPage, $columns, $pageName, $page);
107
    }
108
109
    /**
110
     * Paginate the given query into a simple paginator.
111
     *
112
     * @param  int  $perPage
113
     * @param  array  $columns
114
     * @param  string  $pageName
115
     * @param  int|null  $page
116
     * @return Paginator
117
     */
118 4
    public function simplePaginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
119
    {
120 4
        if ($this->isSimple()) {
121 4
            $this->query->addSelect($this->shouldSelect($columns));
122
            return tap($this->query->simplePaginate($perPage, $columns, $pageName, $page), function ($paginator) {
123 4
                $items = $paginator->items();
124
125 4
                $this->hydrateSimplePivotRelation($items);
126 4
            });
127
        }
128
129 4
        return parent::simplePaginate($perPage, $columns, $pageName, $page);
130
    }
131
132
133
    /**
134
     * Chunk the results of the query.
135
     *
136
     * @param  int  $count
137
     * @param  callable  $callback
138
     * @return bool
139
     */
140 1
    public function chunk($count, callable $callback)
141
    {
142 1
        if ($this->isSimple()) {
143
144 1
            $this->query->addSelect($this->shouldSelect());
145
146
            return $this->query->chunk($count, function ($results) use ($callback) {
147 1
                $items = $results->all();
148
149 1
                $this->hydrateSimplePivotRelation($items);
150
151 1
                return $callback($results);
152 1
            });
153
        }
154
155 1
        return parent::chunk($count, $callback);
156
    }
157
158
    /**
159
     * @param array $columns
160
     *
161
     * @return Collection
162
     *
163
     * @throws Exception
164
     */
165 11
    public function get($columns = ['*'])
166
    {
167 11
        if ($this->isSimple()) {
168 5
            return $this->getSimple($columns);
169
        }
170
171 11
        return parent::get($columns);
172
    }
173
174
    /**
175
     * Hydrate the pivot table relationship on the models.
176
     *
177
     * @param array $models
178
     *
179
     * @return void
180
     *
181
     * @throws Exception
182
     */
183 10
    protected function hydrateSimplePivotRelation(array &$models)
184
    {
185 10
        foreach ($models as &$model) {
186 10
            $pivot = $this->cleanSimplePivotAttributes($model);
187
188 10
            ModelAccessor::set($model, 'pivot', $pivot);
189
        }
190 10
        unset($model);
191 10
    }
192
193
    /**
194
     * Get the pivot attributes from a model.
195
     *
196
     * @param  stdClass|array $model
197
     *
198
     * @return array
199
     *
200
     * @throws Exception
201
     */
202 10
    protected function cleanSimplePivotAttributes(&$model)
203
    {
204 10
        $values = ModelAccessor::createBasedOnModel($model);
205
206 10
        foreach ($model as $key => &$value) {
207 10
            if (strpos($key, 'pivot_') === 0) {
208 6
                ModelAccessor::set($values, substr($key, 6), $value);
209
210 6
                ModelAccessor::delete($model, $key);
211
            }
212
        }
213 10
        unset($value);
214
215 10
        return $values;
216
    }
217
218
    /**
219
     * @return bool
220
     */
221 11
    protected function isSimple()
222
    {
223 11
        return method_exists($this->query, 'isSimple') && $this->query->isSimple();
224
    }
225
}
226