Conditions | 10 |
Paths | 29 |
Total Lines | 72 |
Code Lines | 32 |
Lines | 0 |
Ratio | 0 % |
Changes | 2 | ||
Bugs | 0 | Features | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
1 | <?php |
||
130 | public function withAggregate($relations, $column, $function = null) |
||
131 | { |
||
132 | if (empty($relations)) { |
||
133 | return $this; |
||
134 | } |
||
135 | |||
136 | $table = (string) $this->query->grammar->getValue($this->query->from); |
||
137 | |||
138 | if (empty($this->query->columns)) { |
||
139 | $this->query->select([$table . '.*']); |
||
140 | } |
||
141 | |||
142 | $relations = is_array($relations) ? $relations : [$relations]; |
||
143 | |||
144 | foreach ($this->parseWithRelations($relations) as $name => $constraints) { |
||
145 | // First we will determine if the name has been aliased using an "as" clause on the name |
||
146 | // and if it has we will extract the actual relationship name and the desired name of |
||
147 | // the resulting column. This allows multiple aggregates on the same relationships. |
||
148 | $segments = explode(' ', $name); |
||
149 | |||
150 | [$name, $alias] = $this->extractNameAndAlias($segments, $name); |
||
151 | |||
152 | $relation = $this->getRelationWithoutConstraints((string) $name); |
||
153 | |||
154 | $expression = $column; |
||
155 | |||
156 | if ($function) { |
||
157 | $hashedColumn = $this->getRelationHashedColumn($column, $relation); |
||
158 | |||
159 | $wrappedColumn = $this->getQuery()->getGrammar()->wrap( |
||
160 | $column === '*' ? $column : $relation->getRelated()->qualifyColumn($hashedColumn), |
||
161 | ); |
||
162 | |||
163 | $expression = $function === 'exists' ? $wrappedColumn : sprintf('%s(%s)', $function, $wrappedColumn); |
||
164 | } |
||
165 | |||
166 | // Here, we will grab the relationship sub-query and prepare to add it to the main query |
||
167 | // as a sub-select. First, we'll get the "has" query and use that to get the relation |
||
168 | // sub-query. We'll format this relationship name and append this column if needed. |
||
169 | $query = $relation->getRelationExistenceQuery( |
||
170 | $relation->getRelated()->newQuery(), |
||
171 | $this, |
||
172 | [$expression], |
||
173 | )->setBindings([], 'select'); |
||
174 | |||
175 | $query->callScope($constraints); |
||
176 | |||
177 | $query = $query->mergeConstraintsFrom($relation->getQuery())->toBase(); |
||
178 | |||
179 | // If the query contains certain elements like orderings / more than one column selected |
||
180 | // then we will remove those elements from the query so that it will execute properly |
||
181 | // when given to the database. Otherwise, we may receive SQL errors or poor syntax. |
||
182 | $query->orders = null; |
||
183 | |||
184 | $query->setBindings([], 'order'); |
||
185 | |||
186 | if (is_array($query->columns) && count($query->columns) > 1) { |
||
187 | $query->columns = [$query->columns[0]]; |
||
188 | $query->bindings['select'] = []; |
||
189 | } |
||
190 | |||
191 | // Finally, we will make the proper column alias to the query and run this sub-select on |
||
192 | // the query builder. Then, we will return the builder instance back to the developer |
||
193 | // for further constraint chaining that needs to take place on the query as needed. |
||
194 | $alias = Str::snake( |
||
195 | (string) preg_replace('/[^[:alnum:][:space:]_]/u', '', "$name $function $column"), |
||
196 | ); |
||
197 | |||
198 | $this->handleAggregateFunction($query, $function, $alias); |
||
199 | } |
||
200 | |||
201 | return $this; |
||
202 | } |
||
204 |