Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
73.86% covered (warning)
73.86%
65 / 88
71.43% covered (warning)
71.43%
5 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
HasOrderableRelationships
73.86% covered (warning)
73.86%
65 / 88
71.43% covered (warning)
71.43%
5 / 7
27.14
0.00% covered (danger)
0.00%
0 / 1
 bootHasOrderableRelationships
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 belongsToManyOrderable
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
1 / 1
7
 belongsToManyOrdered
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
 morphToManyOrderable
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
1 / 1
6
 morphToManyOrdered
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
1
 morphedByManyOrderable
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
12
 morphedByManyOrdered
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace Baril\Orderly\Concerns;
4
5use Baril\Orderly\Relations\BelongsToManyOrderable;
6use Baril\Orderly\Relations\MorphToManyOrderable;
7use Illuminate\Support\Arr;
8use Illuminate\Support\Str;
9
10trait HasOrderableRelationships
11{
12    public static function bootHasOrderableRelationships()
13    {
14        static::$manyMethods = array_merge(static::$manyMethods, [
15            'belongsToManyOrderable',
16            'morphToManyOrderable',
17            'morphedByManyOrderable',
18            'belongsToManyOrdered',
19            'morphToManyOrdered',
20            'morphedByManyOrdered',
21        ]);
22    }
23
24    /**
25     * Define a many-to-many orderable relationship.
26     * The prototype is similar as the belongsToMany method, with the
27     * $orderColumn added as the 2nd parameter.
28     *
29     * @param string $related
30     * @param string $orderColumn
31     * @param string $table
32     * @param string $foreignPivotKey
33     * @param string $relatedPivotKey
34     * @param string $parentKey
35     * @param string $relatedKey
36     * @param string $relation
37     *
38     * @return BelongsToSortedMany
39     */
40    public function belongsToManyOrderable(
41        $related,
42        $orderColumn = 'position',
43        $table = null,
44        $foreignPivotKey = null,
45        $relatedPivotKey = null,
46        $parentKey = null,
47        $relatedKey = null,
48        $relation = null
49    ) {
50
51        // If no relationship name was passed, we will pull backtraces to get the
52        // name of the calling function. We will use that function name as the
53        // title of this relation since that is a great convention to apply.
54        if (is_null($relation)) {
55            $relation = $this->guessBelongsToManyRelation();
56        }
57
58        // First, we'll need to determine the foreign key and "other key" for the
59        // relationship. Once we have determined the keys we'll make the query
60        // instances as well as the relationship instances we need for this.
61        $instance = $this->newRelatedInstance($related);
62
63        $foreignPivotKey = $foreignPivotKey ?: $this->getForeignKey();
64
65        $relatedPivotKey = $relatedPivotKey ?: $instance->getForeignKey();
66
67        // If no table name was provided, we can guess it by concatenating the two
68        // models using underscores in alphabetical order. The two model names
69        // are transformed to snake case from their default CamelCase also.
70        if (is_null($table)) {
71            $table = $this->joiningTable($related);
72        }
73
74        return new BelongsToManyOrderable(
75            $instance->newQuery(),
76            $this,
77            $orderColumn,
78            $table,
79            $foreignPivotKey,
80            $relatedPivotKey,
81            $parentKey ?: $this->getKeyName(),
82            $relatedKey ?: $instance->getKeyName(),
83            $relation
84        );
85    }
86
87    public function belongsToManyOrdered(
88        $related,
89        $orderColumn = 'position',
90        $table = null,
91        $foreignPivotKey = null,
92        $relatedPivotKey = null,
93        $parentKey = null,
94        $relatedKey = null,
95        $relation = null
96    ) {
97
98        return $this->belongsToManyOrderable(
99            $related,
100            $orderColumn,
101            $table,
102            $foreignPivotKey,
103            $relatedPivotKey,
104            $parentKey,
105            $relatedKey,
106            $relation
107        )->ordered();
108    }
109
110    /**
111     * Define a polymorphic orderable many-to-many relationship.
112     *
113     * @param  string  $related
114     * @param  string  $name
115     * @param  string  $table
116     * @param  string  $foreignPivotKey
117     * @param  string  $relatedPivotKey
118     * @param  string  $parentKey
119     * @param  string  $relatedKey
120     * @param  bool  $inverse
121     * @return \Baril\Orderly\Relations\MorphToManyOrderable
122     */
123    public function morphToManyOrderable(
124        $related,
125        $name,
126        $orderColumn = 'position',
127        $table = null,
128        $foreignPivotKey = null,
129        $relatedPivotKey = null,
130        $parentKey = null,
131        $relatedKey = null,
132        $inverse = false
133    ) {
134
135        $caller = $this->guessBelongsToManyRelation();
136
137        // First, we will need to determine the foreign key and "other key" for the
138        // relationship. Once we have determined the keys we will make the query
139        // instances, as well as the relationship instances we need for these.
140        $instance = $this->newRelatedInstance($related);
141
142        $foreignPivotKey = $foreignPivotKey ?: $name . '_id';
143
144        $relatedPivotKey = $relatedPivotKey ?: $instance->getForeignKey();
145
146        // Now we're ready to create a new query builder for this related model and
147        // the relationship instances for this relation. This relations will set
148        // appropriate query constraints then entirely manages the hydrations.
149        $table = $table ?: Str::plural($name);
150
151        return new MorphToManyOrderable(
152            $instance->newQuery(),
153            $this,
154            $name,
155            $orderColumn,
156            $table,
157            $foreignPivotKey,
158            $relatedPivotKey,
159            $parentKey ?: $this->getKeyName(),
160            $relatedKey ?: $instance->getKeyName(),
161            $caller,
162            $inverse
163        );
164    }
165
166    public function morphToManyOrdered(
167        $related,
168        $name,
169        $orderColumn = 'position',
170        $table = null,
171        $foreignPivotKey = null,
172        $relatedPivotKey = null,
173        $parentKey = null,
174        $relatedKey = null,
175        $inverse = false
176    ) {
177
178        return $this->morphToManyOrderable(
179            $related,
180            $name,
181            $orderColumn,
182            $table,
183            $foreignPivotKey,
184            $relatedPivotKey,
185            $parentKey,
186            $relatedKey,
187            $inverse
188        )->ordered();
189    }
190
191    /**
192     * Define a polymorphic, inverse, orderable many-to-many relationship.
193     * The prototype is similar as the morphedByMany method, with the
194     * $orderColumn added as the 3rd parameter.
195     *
196     * @param string $related
197     * @param string $name
198     * @param string $orderColumn
199     * @param string $table
200     * @param string $foreignPivotKey
201     * @param string $relatedPivotKey
202     * @param string $parentKey
203     * @param string $relatedKey
204     * @return \Baril\Orderly\Relations\MorphToManyOrderable
205     */
206    public function morphedByManyOrderable(
207        $related,
208        $name,
209        $orderColumn = 'position',
210        $table = null,
211        $foreignPivotKey = null,
212        $relatedPivotKey = null,
213        $parentKey = null,
214        $relatedKey = null
215    ) {
216
217        $foreignPivotKey = $foreignPivotKey ?: $this->getForeignKey();
218
219        // For the inverse of the polymorphic many-to-many relations, we will change
220        // the way we determine the foreign and other keys, as it is the opposite
221        // of the morph-to-many method since we're figuring out these inverses.
222        $relatedPivotKey = $relatedPivotKey ?: $name . '_id';
223
224        return $this->morphToManyOrderable(
225            $related,
226            $name,
227            $orderColumn,
228            $table,
229            $foreignPivotKey,
230            $relatedPivotKey,
231            $parentKey,
232            $relatedKey,
233            true
234        );
235    }
236
237    public function morphedByManyOrdered(
238        $related,
239        $name,
240        $orderColumn = 'position',
241        $table = null,
242        $foreignPivotKey = null,
243        $relatedPivotKey = null,
244        $parentKey = null,
245        $relatedKey = null
246    ) {
247
248        return $this->morphedByManyOrderable(
249            $related,
250            $name,
251            $orderColumn,
252            $table,
253            $foreignPivotKey,
254            $relatedPivotKey,
255            $parentKey,
256            $relatedKey
257        )->ordered();
258    }
259}