| Conditions | 4 |
| Paths | 6 |
| Total Lines | 68 |
| 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 |
||
| 197 | private function getPeriodicStats(Carbon $startMonth, Carbon $endMonth, string $periodType, string $periodLabelFormat): array |
||
| 198 | { |
||
| 199 | // Stats per month or year. It would be most efficient to write some complicated SQL query |
||
| 200 | // that groups the lot together, including filling in months with missing data using some kind |
||
| 201 | // of row generator or date dimension table, but frankly this is still fast enough, |
||
| 202 | // especially as it's cached and invalidated quite sensibly. |
||
| 203 | $sql = 'SELECT |
||
| 204 | COUNT(*) AS number_of_wanders, |
||
| 205 | COALESCE(SUM(w.distance), 0) AS total_distance_metres, |
||
| 206 | COALESCE(SUM(w.distance), 0) / 1000.0 AS total_distance_km, |
||
| 207 | COALESCE(SUM((SELECT COUNT(*) FROM image i WHERE i.wander_id = w.id)), 0) AS number_of_images, |
||
| 208 | COALESCE(SUM((SELECT COUNT(*) FROM image i WHERE (rating IS NULL or rating = 0) AND i.wander_id = w.id)), 0) AS rating_0_images, |
||
| 209 | COALESCE(SUM((SELECT COUNT(*) FROM image i WHERE rating = 1 AND i.wander_id = w.id)), 0) AS rating_1_images, |
||
| 210 | COALESCE(SUM((SELECT COUNT(*) FROM image i WHERE rating = 2 AND i.wander_id = w.id)), 0) AS rating_2_images, |
||
| 211 | COALESCE(SUM((SELECT COUNT(*) FROM image i WHERE rating = 3 AND i.wander_id = w.id)), 0) AS rating_3_images, |
||
| 212 | COALESCE(SUM((SELECT COUNT(*) FROM image i WHERE rating = 4 AND i.wander_id = w.id)), 0) AS rating_4_images, |
||
| 213 | COALESCE(SUM((SELECT COUNT(*) FROM image i WHERE rating = 5 AND i.wander_id = w.id)), 0) AS rating_5_images, |
||
| 214 | COALESCE(SUM(TIME_TO_SEC(TIMEDIFF(w.end_time, w.start_time))), 0) AS total_duration_seconds, |
||
| 215 | COALESCE(AVG(TIME_TO_SEC(TIMEDIFF(w.end_time, w.start_time))), 0) AS average_duration_seconds |
||
| 216 | FROM |
||
| 217 | wander w |
||
| 218 | WHERE |
||
| 219 | w.start_time >= :start AND |
||
| 220 | w.start_time < :end'; |
||
| 221 | |||
| 222 | $stmt = $this->entityManager->getConnection()->prepare($sql); |
||
| 223 | |||
| 224 | $periodicStats = []; |
||
| 225 | |||
| 226 | $periodLengthMonths = $periodType === 'year' ? 12 : 1; |
||
| 227 | |||
| 228 | for ($rangeStartMonth = $startMonth->copy(); $rangeStartMonth <= $endMonth; $rangeStartMonth->addMonths($periodLengthMonths)) { |
||
| 229 | $rangeEndMonth = $rangeStartMonth->copy()->addMonths($periodLengthMonths); |
||
| 230 | $result = $stmt->executeQuery([ |
||
| 231 | 'start' => $rangeStartMonth, |
||
| 232 | 'end' => $rangeEndMonth |
||
| 233 | ]); |
||
| 234 | $row = $result->fetchAssociative(); |
||
| 235 | if ($row === false) { |
||
| 236 | // It's entirely aggregated, so even if no rows match the WHERE there should always be a row |
||
| 237 | // returned. |
||
| 238 | throw new Exception("Expected to get a row back from the database no matter what with this query."); |
||
| 239 | } |
||
| 240 | $duration = CarbonInterval::seconds($row['total_duration_seconds'])->cascade(); |
||
| 241 | $periodicStats[] = [ |
||
| 242 | 'periodType' => $periodType, |
||
| 243 | 'periodStartDate' => new CarbonImmutable($rangeStartMonth), |
||
| 244 | 'periodEndDate' => new CarbonImmutable($rangeEndMonth->copy()->addDays(-1)), |
||
| 245 | //'year' => $rangeStartMonth->year, |
||
| 246 | //'month' => $rangeStartMonth->month, |
||
| 247 | 'periodLabel' => $rangeStartMonth->isoFormat($periodLabelFormat), |
||
| 248 | 'numberOfWanders' => (int) $row['number_of_wanders'], |
||
| 249 | 'totalDistance' => (float) $row['total_distance_metres'], |
||
| 250 | 'numberOfImages' => (int) $row['number_of_images'], |
||
| 251 | 'numberOfImagesByRating' => [ |
||
| 252 | 0 => (int) $row['rating_0_images'], |
||
| 253 | 1 => (int) $row['rating_1_images'], |
||
| 254 | 2 => (int) $row['rating_2_images'], |
||
| 255 | 3 => (int) $row['rating_3_images'], |
||
| 256 | 4 => (int) $row['rating_4_images'], |
||
| 257 | 5 => (int) $row['rating_5_images'], |
||
| 258 | ], |
||
| 259 | 'totalDurationInterval' => $duration, |
||
| 260 | 'totalDurationForHumans' => $duration->forHumans(['short' => true, 'options' => 0]), |
||
| 261 | 'averageDurationInterval' => CarbonInterval::seconds($row['average_duration_seconds'])->cascade(), |
||
| 262 | ]; |
||
| 263 | } |
||
| 264 | return $periodicStats; |
||
| 265 | } |
||
| 267 |