• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

RonasIT / laravel-helpers / 4249189191

pending completion
4249189191

push

github

GitHub
Merge pull request #56 from RonasIT/46_reset_all_repository_flags_after_getting_results

59 of 59 new or added lines in 2 files covered. (100.0%)

367 of 955 relevant lines covered (38.43%)

4.35 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.74
/src/Traits/EntityControlTrait.php
1
<?php
2

3
namespace RonasIT\Support\Traits;
4

5
use Closure;
6
use Illuminate\Support\Arr;
7
use Illuminate\Support\Collection;
8
use Illuminate\Database\Eloquent\Model;
9
use Illuminate\Database\Eloquent\SoftDeletes;
10
use Illuminate\Database\Eloquent\Builder as Query;
11
use RonasIT\Support\Exceptions\InvalidModelException;
12

13
/**
14
 * @property Model model
15
 */
16
trait EntityControlTrait
17
{
18
    use SearchTrait;
19

20
    protected $model;
21
    protected $fields;
22
    protected $primaryKey;
23

24
    protected $withTrashed = false;
25
    protected $onlyTrashed = false;
26
    protected $forceMode = false;
27

28
    protected $shouldSettablePropertiesBeReset = true;
29

30
    public function all(): Collection
31
    {
32
        return $this->get();
2✔
33
    }
34

35
    public function truncate(): self
36
    {
37
        $modelInstance = $this->model;
×
38

39
        $modelInstance::truncate();
×
40

41
        return $this;
×
42
    }
43

44
    public function force($value = true): self
45
    {
46
        $this->forceMode = $value;
38✔
47

48
        return $this;
38✔
49
    }
50

51
    public function setModel($modelClass): self
52
    {
53
        $this->model = new $modelClass();
41✔
54

55
        $this->fields = $modelClass::getFields();
41✔
56

57
        $this->primaryKey = $this->model->getKeyName();
41✔
58

59
        $this->checkPrimaryKey();
41✔
60

61
        return $this;
41✔
62
    }
63

64
    protected function getQuery($where = []): Query
65
    {
66
        $query = $this->model->query();
36✔
67

68
        if ($this->onlyTrashed) {
36✔
69
            $query->onlyTrashed();
33✔
70

71
            $this->withTrashed = false;
33✔
72
        }
73

74
        if ($this->withTrashed && $this->hasSoftDeleteTrait()) {
36✔
75
            $query->withTrashed();
1✔
76
        }
77

78
        if (!empty($this->attachedRelations)) {
36✔
79
            $query->with($this->attachedRelations);
33✔
80
        }
81

82
        if (!empty($this->attachedRelationsCount)) {
36✔
83
            foreach ($this->attachedRelationsCount as $requestedRelations) {
33✔
84
                list ($countRelation, $relation) = extract_last_part($requestedRelations);
33✔
85

86
                if (empty($relation)) {
33✔
87
                    $query->withCount($countRelation);
33✔
88
                } else {
89
                    $query->with([
×
90
                        $relation => function ($query) use ($countRelation) {
×
91
                            $query->withCount($countRelation);
×
92
                        }
×
93
                    ]);
×
94
                }
95
            }
96
        }
97

98
        return $this->constructWhere($query, $where);
36✔
99
    }
100

101
    /**
102
     * Check entity existing in database.
103
     *
104
     * @param mixed $where
105
     *
106
     * @return boolean
107
     */
108
    public function exists($where): bool
109
    {
110
        $result = $this->getQuery($where)->exists();
3✔
111

112
        $this->postQueryHook();
3✔
113

114
        return $result;
3✔
115
    }
116

117
    /**
118
     * Checking that record with this key value exists
119
     *
120
     * @param string $field
121
     * @param $value
122
     *
123
     * @return boolean
124
     */
125
    public function existsBy(string $field, $value): bool
126
    {
127
        $result = $this->getQuery([$field => $value])->exists();
1✔
128

129
        $this->postQueryHook();
1✔
130

131
        return $result;
1✔
132
    }
133

134
    public function create(array $data): Model
135
    {
136
        $entityData = Arr::only($data, $this->fields);
3✔
137
        $modelClass = get_class($this->model);
3✔
138
        $model = new $modelClass();
3✔
139

140
        if ($this->forceMode) {
3✔
141
            $model->forceFill($entityData);
3✔
142
        } else {
143
            $model->fill(Arr::only($entityData, $model->getFillable()));
×
144
        }
145

146
        $model->save();
3✔
147
        $model->refresh();
3✔
148

149
        $this->afterCreateHook($model, $data);
3✔
150

151
        if (!empty($this->attachedRelations)) {
3✔
152
            $model->load($this->attachedRelations);
3✔
153
        }
154

155
        $this->postQueryHook();
3✔
156

157
        return $model;
3✔
158
    }
159

160
    /**
161
     * Update rows by condition or primary key
162
     *
163
     * @param mixed $where
164
     * @param array $data
165
     *
166
     * @return int
167
     */
168
    public function updateMany($where, array $data): int
169
    {
170
        $modelClass = get_class($this->model);
1✔
171
        $fields = $this->forceMode ? $modelClass::getFields() : $this->model->getFillable();
1✔
172
        $entityData = Arr::only($data, $fields);
1✔
173

174
        $result = $this->getQuery($where)->update($entityData);
1✔
175

176
        $this->postQueryHook();
1✔
177

178
        return $result;
1✔
179
    }
180

181
    /**
182
     * Update only one row by condition or primary key value
183
     *
184
     * @param array|integer $where
185
     * @param array $data
186
     *
187
     * @return Model
188
     */
189
    public function update($where, array $data): ?Model
190
    {
191
        $item = $this->getQuery($where)->first();
3✔
192

193
        if (empty($item)) {
3✔
194
            $this->postQueryHook();
1✔
195

196
            return null;
1✔
197
        }
198

199
        if ($this->forceMode) {
2✔
200
            $item->forceFill(Arr::only($data, $this->fields));
2✔
201
        } else {
202
            $item->fill(Arr::only($data, $item->getFillable()));
×
203
        }
204

205
        $item->save();
2✔
206
        $item->refresh();
2✔
207

208
        $this->afterUpdateHook($item, $data);
2✔
209

210
        if (!empty($this->attachedRelations)) {
2✔
211
            $item->load($this->attachedRelations);
2✔
212
        }
213

214
        $this->postQueryHook();
2✔
215

216
        return $item;
2✔
217
    }
218

219
    public function updateOrCreate($where, $data): Model
220
    {
221
        $this->resetSettableProperties(false);
2✔
222

223
        if ($this->exists($where)) {
2✔
224
            $this->resetSettableProperties();
1✔
225

226
            return $this->update($where, $data);
1✔
227
        }
228

229
        if (!is_array($where)) {
1✔
230
            $where = [$this->primaryKey => $where];
1✔
231
        }
232

233
        $this->resetSettableProperties();
1✔
234

235
        return $this->create(array_merge($data, $where));
1✔
236
    }
237

238
    public function count($where = []): int
239
    {
240
        $result = $this->getQuery($where)->count();
1✔
241

242
        $this->postQueryHook();
1✔
243

244
        return $result;
1✔
245
    }
246

247
    public function get(array $where = []): Collection
248
    {
249
        $result = $this->getQuery($where)->get();
4✔
250

251
        $this->postQueryHook();
4✔
252

253
        return $result;
4✔
254
    }
255

256
    public function first($where = []): ?Model
257
    {
258
        $result = $this->getQuery($where)->first();
8✔
259

260
        $this->postQueryHook();
8✔
261

262
        return $result;
8✔
263
    }
264

265
    public function findBy(string $field, $value): ?Model
266
    {
267
        return $this->first([$field => $value]);
2✔
268
    }
269

270
    public function find($id): ?Model
271
    {
272
        return $this->first($id);
2✔
273
    }
274

275
    /**
276
     * @param array|string|int $where array of conditions or primary key value
277
     * @param array $data
278
     *
279
     * @return Model
280
     */
281
    public function firstOrCreate($where, array $data = []): Model
282
    {
283
        $this->resetSettableProperties(false);
2✔
284

285
        $entity = $this->first($where);
2✔
286

287
        $this->resetSettableProperties();
2✔
288

289
        if (empty($entity)) {
2✔
290
            return $this->create(array_merge($data, $where));
1✔
291
        }
292

293
        $this->postQueryHook();
1✔
294

295
        return $entity;
1✔
296
    }
297

298
    /**
299
     * Delete rows by condition or primary key
300
     *
301
     * @param array|integer|string $where
302
     *
303
     * @return integer count of deleted rows
304
     */
305
    public function delete($where): int
306
    {
307
        $query = $this->getQuery($where);
1✔
308

309
        if ($this->forceMode) {
1✔
310
            $result = $query->forceDelete();
1✔
311
        } else {
312
            $result = $query->delete();
×
313
        }
314

315
        $this->postQueryHook();
1✔
316

317
        return $result;
1✔
318
    }
319

320
    public function withTrashed($enable = true): self
321
    {
322
        $this->withTrashed = $enable;
38✔
323

324
        return $this;
38✔
325
    }
326

327
    public function onlyTrashed($enable = true): self
328
    {
329
        $this->onlyTrashed = $enable;
38✔
330

331
        return $this;
38✔
332
    }
333

334
    public function restore($where): int
335
    {
336
        $result = $this->getQuery($where)->onlyTrashed()->restore();
1✔
337

338
        $this->postQueryHook();
1✔
339

340
        return $result;
1✔
341
    }
342

343
    public function chunk(int $limit, Closure $callback, array $where = []): void
344
    {
345
        $this
2✔
346
            ->getQuery($where)
2✔
347
            ->orderBy($this->primaryKey)
2✔
348
            ->chunk($limit, $callback);
2✔
349

350
        $this->postQueryHook();
2✔
351
    }
352

353
    /**
354
     * Delete rows by list of values a particular field or primary key
355
     *
356
     * @param array $values
357
     * @param ?string $field condition field, primary key is default value
358
     *
359
     * @return integer count of deleted rows
360
     */
361
    public function deleteByList(array $values, ?string $field = null): int
362
    {
363
        $field = (empty($field)) ? $this->primaryKey : $field;
1✔
364

365
        $query = $this
1✔
366
            ->getQuery()
1✔
367
            ->whereIn($field, $values);
1✔
368

369
        if ($this->forceMode && $this->hasSoftDeleteTrait()) {
1✔
370
            $result = $query->forceDelete();
1✔
371
        } else {
372
            $result = $query->delete();
×
373
        }
374

375
        $this->postQueryHook();
1✔
376

377
        return $result;
1✔
378
    }
379

380
    public function restoreByList(array $values, ?string $field = null): int
381
    {
382
        $field = (empty($field)) ? $this->primaryKey : $field;
1✔
383

384
        $result = $this
1✔
385
            ->getQuery()
1✔
386
            ->onlyTrashed()
1✔
387
            ->whereIn($field, $values)
1✔
388
            ->restore();
1✔
389

390
        $this->postQueryHook();
1✔
391

392
        return $result;
1✔
393
    }
394

395
    public function getByList(array $values, ?string $field = null): Collection
396
    {
397
        $field = (empty($field)) ? $this->primaryKey : $field;
2✔
398

399
        $result = $this
2✔
400
            ->getQuery()
2✔
401
            ->whereIn($field, $values)
2✔
402
            ->get();
2✔
403

404
        $this->postQueryHook();
2✔
405

406
        return $result;
2✔
407
    }
408

409
    public function countByList(array $values, ?string $field = null): int
410
    {
411
        $field = (empty($field)) ? $this->primaryKey : $field;
1✔
412

413
        $result = $this->getQuery()->whereIn($field, $values)->count();
1✔
414

415
        $this->postQueryHook();
1✔
416

417
        return $result;
1✔
418
    }
419

420
    public function updateByList(array $values, array $data, $field = null): int
421
    {
422
        $field = (empty($field)) ? $this->primaryKey : $field;
1✔
423

424
        $query = $this->getQuery()->whereIn($field, $values);
1✔
425

426
        $fields = $this->forceMode ? $this->fields : $this->model->getFillable();
1✔
427

428
        $this->postQueryHook();
1✔
429

430
        return $query->update(Arr::only($data, $fields));
1✔
431
    }
432

433
    protected function getEntityName(): string
434
    {
435
        $explodedModel = explode('\\', get_class($this->model));
×
436

437
        return end($explodedModel);
×
438
    }
439

440
    protected function hasSoftDeleteTrait(): bool
441
    {
442
        $traits = class_uses(get_class($this->model));
2✔
443

444
        return in_array(SoftDeletes::class, $traits);
2✔
445
    }
446

447
    protected function checkPrimaryKey(): void
448
    {
449
        if (is_null($this->primaryKey)) {
41✔
450
            $modelClass = get_class($this->model);
×
451

452
            throw new InvalidModelException("Model {$modelClass} must have primary key.");
×
453
        }
454
    }
455

456
    /**
457
     * @deprecated Method was implemented to have an ability to call some model-related methods inside the services class
458
     * but since version 2.0 services classes works with he models directly and no need to call hooks
459
     * @param Model|null $entity
460
     * @param array $data
461
     * @return void
462
     */
463
    protected function afterUpdateHook(?Model $entity, array $data)
464
    {
465
        // implement it yourself if you need it
466
    }
2✔
467

468
    /**
469
     * @deprecated Method was implemented to have an ability to call some model-related methods inside the services class
470
     * but since version 2.0 services classes works with he models directly and no need to call hooks
471
     * @param Model|null $entity
472
     * @param array $data
473
     * @return void
474
     */
475
    protected function afterCreateHook(?Model $entity, array $data)
476
    {
477
        // implement it yourself if you need it
478
    }
3✔
479

480
    protected function resetSettableProperties(bool $value = true): void
481
    {
482
        $this->shouldSettablePropertiesBeReset = $value;
4✔
483
    }
484
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc