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

RonasIT / laravel-helpers / 17398353014

02 Sep 2025 08:51AM UTC coverage: 78.127% (-0.05%) from 78.181%
17398353014

push

github

web-flow
Merge pull request #129 from RonasIT/fix-codestyle-and-legacy-code

Fix codestyle and legacy code

33 of 40 new or added lines in 8 files covered. (82.5%)

2 existing lines in 2 files now uncovered.

1118 of 1431 relevant lines covered (78.13%)

13.04 hits per line

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

70.77
/src/Traits/ModelTrait.php
1
<?php
2

3
namespace RonasIT\Support\Traits;
4

5
use Illuminate\Support\Facades\Schema;
6
use Illuminate\Support\Str;
7
use BadMethodCallException;
8
use Illuminate\Support\Arr;
9
use Illuminate\Database\Eloquent\Relations\Relation;
10

11
trait ModelTrait
12
{
13
    protected bool $disableLazyLoading = true;
14

15
    public static function getFields(): array
16
    {
17
        $model = (new static());
23✔
18

19
        $keyName = $model->getKeyName();
23✔
20
        $guarded = $model->getGuarded();
23✔
21
        $fillable = $model->getFillable();
23✔
22
        $timeStamps = ($model->timestamps) ? ['created_at', 'updated_at'] : [];
23✔
23

24
        array_unshift($fillable, $keyName);
23✔
25

26
        return array_merge($fillable, $guarded, $timeStamps);
23✔
27
    }
28

29
    public function getAllFieldsWithTable(): array
30
    {
31
        $tableName = $this->getTable();
×
32
        $fields = Schema::getColumnListing($tableName);
×
33

NEW
34
        return array_map(fn ($field) => "{$tableName}.{$field}", $fields);
×
35
    }
36

37
    protected function getRelationshipFromMethod($method)
38
    {
39
        if ($this->disableLazyLoading) {
×
40
            $modelName = static::class;
×
41

42
            throw new BadMethodCallException(
×
NEW
43
                message: "Attempting to lazy-load relation '{$method}' on model '{$modelName}'. "
×
NEW
44
                . 'See property $disableLazyLoading.',
×
UNCOV
45
            );
×
46
        }
47

48
        return parent::getRelationshipFromMethod($method);
×
49
    }
50

51
    /**
52
     * This method was added, because native Laravel's method addSelect
53
     * overwrites existed select clause
54
     * @param $query
55
     * @param array $fields
56
     *
57
     * @return mixed
58
     */
59
    public function scopeAddFieldsToSelect($query, array $fields = [])
60
    {
61
        if (is_null($query->getQuery()->columns)) {
1✔
62
            $query->addSelect("{$this->getTable()}.*");
1✔
63
        }
64

65
        if (empty($fields)) {
1✔
66
            return $query;
1✔
67
        }
68

69
        return $query->addSelect($fields);
×
70
    }
71

72
    /**
73
     * Add orderBy By related field,
74
     * $manyToManyStrategy is affect oneToMany and ManyToMany Relations make orderBy('id', ASC/DESC)
75
     *
76
     * @param $query
77
     * @param $relations
78
     * @param string $desc
79
     * @param string|null $asField
80
     * @param string $manyToManyStrategy
81
     *
82
     * @return mixed $query
83
     */
84
    public function scopeOrderByRelated(
85
        $query,
86
        $relations,
87
        string $desc = 'DESC',
88
        ?string $asField = null,
89
        string $manyToManyStrategy = 'max',
90
    ) {
91
        if (empty($asField)) {
1✔
92
            $asField = str_replace('.', '_', $relations);
1✔
93
        }
94

95
        $relations = $this->prepareRelations($relations);
1✔
96
        $orderField = $this->getOrderedField($relations);
1✔
97

98
        if (!empty($relations)) {
1✔
99
            $queries = $this->getQueriesList($query, $relations);
1✔
100
            $prevQuery = array_shift($queries);
1✔
101
            array_pop($queries);
1✔
102

103
            $this
1✔
104
                ->applyManyToManyStrategy($prevQuery, $manyToManyStrategy)
1✔
105
                ->select($orderField);
1✔
106

107
            foreach ($queries as $queryInCollection) {
1✔
108
                $prevQuery = $this
×
109
                    ->applyManyToManyStrategy($queryInCollection, $manyToManyStrategy)
×
110
                    ->selectSub($prevQuery, $asField);
×
111
            }
112

113
            $query->addFieldsToSelect();
1✔
114
            $query->selectSub($prevQuery, $asField);
1✔
115
        }
116

117
        return $query->orderBy($asField ?? $orderField, $desc);
1✔
118
    }
119

120
    protected function getRelationWithoutConstraints($query, $relation)
121
    {
122
        return Relation::noConstraints(fn () => call_user_func([$query->getModel(), $relation]));
1✔
123
    }
124

125
    protected function prepareRelations(string $relations): array
126
    {
127
        if (Str::contains($relations, '.')) {
1✔
128
            return explode('.', $relations);
1✔
129
        } else {
130
            return [
×
131
                $relations,
×
132
            ];
×
133
        }
134
    }
135

136
    protected function getOrderedField(&$relations): string
137
    {
138
        if (is_array($relations)) {
1✔
139
            return array_pop($relations);
1✔
140
        }
141

142
        return $relations;
×
143
    }
144

145
    protected function getQueriesList($query, array $relations): array
146
    {
147
        $requiredColumns = [];
1✔
148
        $queryCollection = [$query];
1✔
149

150
        foreach ($relations as $relationString) {
1✔
151
            $query = Arr::last($queryCollection);
1✔
152

153
            $relation = $this->getRelationWithoutConstraints($query, $relationString);
1✔
154
            $subQuery = $relation->getRelationExistenceQuery(
1✔
155
                $relation->getQuery(),
1✔
156
                $query,
1✔
157
                $requiredColumns
1✔
158
            );
1✔
159

160
            $queryCollection[] = $subQuery;
1✔
161
        }
162

163
        return array_reverse($queryCollection);
1✔
164
    }
165

166
    protected function applyManyToManyStrategy($query, string $strategy)
167
    {
168
        if ($strategy === 'max') {
1✔
169
            $query->orderBy('id', 'ASC')->limit(1);
1✔
170
        } else {
171
            $query->orderBy('id', 'DESC')->limit(1);
×
172
        }
173

174
        return $query;
1✔
175
    }
176
}
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

© 2025 Coveralls, Inc