Issues (52)

src/MasterService.php (9 issues)

1
<?php
2
3
namespace Turahe\Master;
4
5
/**
6
 * Class MasterService.
7
 */
8
class MasterService
9
{
10
    /**
11
     * @var
12
     */
13
    protected $search;
14
15
    /**
16
     * @param $location
17
     *
18
     * @return $this
19
     */
20
    public function search($location)
21
    {
22
        $this->search = strtoupper($location);
23
24
        return $this;
25
    }
26
27
    /**
28
     * @return \Illuminate\Support\Collection
29
     */
30
    public function all()
31
    {
32
        $result = collect([]);
33
34
        if ($this->search) {
35
            $provinces = Models\Province::search($this->search)->get();
36
            $cities = Models\City::search($this->search)->get();
37
            $districts = Models\District::search($this->search)->get();
38
            $villages = Models\Village::search($this->search)->get();
39
            $result->push($provinces);
40
            $result->push($cities);
41
            $result->push($districts);
42
            $result->push($villages);
43
        }
44
45
        return $result->collapse();
46
    }
47
48
    /**
49
     * @return \Illuminate\Database\Eloquent\Collection|Models\Province[]
50
     */
51
    public function allProvinces()
52
    {
53
        if ($this->search) {
54
            return Models\Province::search($this->search)->get();
55
        }
56
57
        return Models\Province::all();
58
    }
59
60
    /**
61
     * @param int $numRows
62
     *
63
     * @return mixed
64
     */
65
    public function paginateProvinces($numRows = 15)
66
    {
67
        if ($this->search) {
68
            return Models\Province::search($this->search)->paginate();
69
        }
70
71
        return Models\Province::paginate($numRows);
72
    }
73
74
    /**
75
     * @return \Illuminate\Database\Eloquent\Collection|Models\City[]
76
     */
77
    public function allCities()
78
    {
79
        if ($this->search) {
80
            return Models\City::search($this->search)->get();
81
        }
82
83
        return Models\City::all();
84
    }
85
86
    /**
87
     * @param int $numRows
88
     *
89
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
90
     */
91
    public function paginateCities($numRows = 15)
92
    {
93
        if ($this->search) {
94
            return Models\City::search($this->search)->paginate();
95
        }
96
97
        return Models\City::paginate($numRows);
98
    }
99
100
    /**
101
     * @return \Illuminate\Database\Eloquent\Collection|Models\District[]
102
     */
103
    public function allDistricts()
104
    {
105
        if ($this->search) {
106
            return Models\District::search($this->search)->get();
107
        }
108
109
        return Models\District::all();
110
    }
111
112
    /**
113
     * @param int $numRows
114
     *
115
     * @return mixed
116
     */
117
    public function paginateDistricts($numRows = 15)
118
    {
119
        if ($this->search) {
120
            return Models\District::search($this->search)->paginate();
121
        }
122
123
        return Models\District::paginate($numRows);
124
    }
125
126
    /**
127
     * @return \Illuminate\Database\Eloquent\Collection|Models\Village[]
128
     */
129
    public function allVillages()
130
    {
131
        if ($this->search) {
132
            return Models\Village::search($this->search)->get();
133
        }
134
135
        return Models\Village::all();
136
    }
137
138
    /**
139
     * @param int $numRows
140
     *
141
     * @return mixed
142
     */
143
    public function paginateVillages($numRows = 15)
144
    {
145
        if ($this->search) {
146
            return Models\Village::search($this->search)->paginate();
147
        }
148
149
        return Models\Village::paginate($numRows);
150
    }
151
152
    /**
153
     * @param $provinceId
154
     * @param null $with
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $with is correct as it would always require null to be passed?
Loading history...
155
     *
156
     * @return null|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|mixed
157
     */
158
    public function findProvince($provinceId, $with = null)
159
    {
160
        $with = (array) $with;
161
162
        if ($with) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $with of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
163
            $withVillages = array_search('villages', $with);
164
165
            if ($withVillages !== false) {
166
                unset($with[$withVillages]);
167
168
                $province = Models\Province::with($with)->find($provinceId);
169
170
                $province = $this->loadRelation($province, 'cities.districts.villages');
171
            } else {
172
                $province = Models\Province::with($with)->find($provinceId);
173
            }
174
175
            return $province;
176
        }
177
178
        return Models\Province::find($provinceId);
179
    }
180
181
    /**
182
     * @param $cityId
183
     * @param null $with
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $with is correct as it would always require null to be passed?
Loading history...
184
     *
185
     * @return null|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|Models\City|Models\City[]
186
     */
187
    public function findCity($cityId, $with = null)
188
    {
189
        $with = (array) $with;
190
191
        if ($with) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $with of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
192
            return Models\City::with($with)->find($cityId);
193
        }
194
195
        return Models\City::find($cityId);
196
    }
197
198
    /**
199
     * @param $districtId
200
     * @param null $with
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $with is correct as it would always require null to be passed?
Loading history...
201
     *
202
     * @return null|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|mixed
203
     */
204
    public function findDistrict($districtId, $with = null)
205
    {
206
        $with = (array) $with;
207
208
        if ($with) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $with of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
209
            $withProvince = array_search('provinces', $with);
210
211
            if ($withProvince !== false) {
212
                unset($with[$withProvince]);
213
214
                $district = Models\District::with($with)->find($districtId);
215
216
                $district = $this->loadRelation($district, 'cities.provinces', true);
217
            } else {
218
                $district = Models\District::with($with)->find($districtId);
219
            }
220
221
            return $district;
222
        }
223
224
        return Models\District::find($districtId);
225
    }
226
227
    /**
228
     * @param $villageId
229
     * @param null $with
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $with is correct as it would always require null to be passed?
Loading history...
230
     *
231
     * @return null|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|mixed
232
     */
233
    public function findVillage($villageId, $with = null)
234
    {
235
        $with = (array) $with;
236
237
        if ($with) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $with of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
238
            $withCity = array_search('cities', $with);
239
            $withProvince = array_search('provinces', $with);
240
241
            if ($withCity !== false && $withProvince !== false) {
242
                unset($with[$withCity]);
243
                unset($with[$withProvince]);
244
245
                $village = Models\Village::with($with)->find($villageId);
246
247
                $village = $this->loadRelation($village, 'districts.cities', true);
248
249
                $village = $this->loadRelation($village, 'districts.cities.provinces', true);
250
            } elseif ($withCity !== false) {
251
                unset($with[$withCity]);
252
253
                $village = Models\Village::with($with)->find($villageId);
254
255
                $village = $this->loadRelation($village, 'districts.cities', true);
256
            } elseif ($withProvince !== false) {
257
                unset($with[$withProvince]);
258
259
                $village = Models\Village::with($with)->find($villageId);
260
261
                $village = $this->loadRelation($village, 'districts.cities.provinces', true);
262
            } else {
263
                $village = Models\Village::with($with)->find($villageId);
264
            }
265
266
            return $village;
267
        }
268
269
        return Models\Village::find($villageId);
270
    }
271
272
    /**
273
     * @param $object
274
     * @param $relation
275
     * @param false $belongsTo
276
     *
277
     * @return mixed
278
     */
279
    private function loadRelation($object, $relation, $belongsTo = false)
280
    {
281
        $exploded = explode('.', $relation);
282
        $targetRelationName = end($exploded);
283
284
        // We need to clone it first because $object->load() below will call related relation.
285
        // I don't know why
286
        $newObject = clone $object;
287
288
        // https://softonsofa.com/laravel-querying-any-level-far-relations-with-simple-trick/
289
        // because Eloquent hasManyThrough cannot get through more than one deep relationship
290
        $object->load([$relation => function ($q) use (&$createdValue, $belongsTo) {
291
            if ($belongsTo) {
0 ignored issues
show
The condition $belongsTo is always false.
Loading history...
292
                $createdValue = $q->first();
293
            } else {
294
                $createdValue = $q->get()->unique();
295
            }
296
        }]);
297
298
        $newObject[$targetRelationName] = $createdValue;
299
300
        return $newObject;
301
    }
302
}
303