| Conditions | 19 |
| Paths | 531 |
| Total Lines | 138 |
| Code Lines | 70 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 1 | ||
| 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 |
||
| 270 | private function getPagerCount(string $query): int |
||
| 271 | { |
||
| 272 | $maxResults = (int) config('nntmux.max_pager_results'); |
||
| 273 | $cacheExpiry = config('nntmux.cache_expiry_short'); |
||
| 274 | |||
| 275 | // Generate cache key from original query |
||
| 276 | $cacheKey = 'pager_count_'.md5($query); |
||
| 277 | |||
| 278 | // Check cache first |
||
| 279 | $count = Cache::get($cacheKey); |
||
| 280 | if ($count !== null) { |
||
| 281 | return (int) $count; |
||
| 282 | } |
||
| 283 | |||
| 284 | // Check if this is already a COUNT query |
||
| 285 | if (preg_match('/SELECT\s+COUNT\s*\(/is', $query)) { |
||
| 286 | // It's already a COUNT query, just execute it |
||
| 287 | try { |
||
| 288 | $result = DB::select($query); |
||
| 289 | if (isset($result[0])) { |
||
| 290 | // Handle different possible column names |
||
| 291 | $count = $result[0]->count ?? $result[0]->total ?? 0; |
||
| 292 | // Check for COUNT(*) result without alias |
||
| 293 | if ($count === 0) { |
||
| 294 | foreach ($result[0] as $value) { |
||
| 295 | $count = (int) $value; |
||
| 296 | break; |
||
| 297 | } |
||
| 298 | } |
||
| 299 | } else { |
||
| 300 | $count = 0; |
||
| 301 | } |
||
| 302 | |||
| 303 | // Cap the count at max results if applicable |
||
| 304 | if ($maxResults > 0 && $count > $maxResults) { |
||
| 305 | $count = $maxResults; |
||
| 306 | } |
||
| 307 | |||
| 308 | // Cache the result |
||
| 309 | Cache::put($cacheKey, $count, now()->addMinutes($cacheExpiry)); |
||
| 310 | |||
| 311 | return $count; |
||
| 312 | } catch (\Exception $e) { |
||
| 313 | return 0; |
||
| 314 | } |
||
| 315 | } |
||
| 316 | |||
| 317 | // For regular SELECT queries, optimize for counting |
||
| 318 | $countQuery = $query; |
||
| 319 | |||
| 320 | // Remove ORDER BY clause (not needed for COUNT) |
||
| 321 | $countQuery = preg_replace('/ORDER\s+BY\s+[^)]+$/is', '', $countQuery); |
||
| 322 | |||
| 323 | // Remove GROUP BY if it's only grouping by r.id |
||
| 324 | $countQuery = preg_replace('/GROUP\s+BY\s+r\.id\s*$/is', '', $countQuery); |
||
| 325 | |||
| 326 | // Check if query has DISTINCT in SELECT |
||
| 327 | $hasDistinct = preg_match('/SELECT\s+DISTINCT/is', $countQuery); |
||
| 328 | |||
| 329 | // Replace SELECT clause with COUNT |
||
| 330 | if ($hasDistinct || preg_match('/GROUP\s+BY/is', $countQuery)) { |
||
| 331 | // For queries with DISTINCT or GROUP BY, count distinct r.id |
||
| 332 | $countQuery = preg_replace( |
||
| 333 | '/SELECT\s+.+?\s+FROM/is', |
||
| 334 | 'SELECT COUNT(DISTINCT r.id) as count FROM', |
||
| 335 | $countQuery |
||
| 336 | ); |
||
| 337 | } else { |
||
| 338 | // For simple queries, use COUNT(*) |
||
| 339 | $countQuery = preg_replace( |
||
| 340 | '/SELECT\s+.+?\s+FROM/is', |
||
| 341 | 'SELECT COUNT(*) as count FROM', |
||
| 342 | $countQuery |
||
| 343 | ); |
||
| 344 | } |
||
| 345 | |||
| 346 | // Remove LIMIT/OFFSET from the count query |
||
| 347 | $countQuery = preg_replace('/LIMIT\s+\d+(\s+OFFSET\s+\d+)?$/is', '', $countQuery); |
||
| 348 | |||
| 349 | try { |
||
| 350 | // If max results is set and query might return too many results |
||
| 351 | if ($maxResults > 0) { |
||
| 352 | // First check if count would exceed max |
||
| 353 | $testQuery = sprintf('SELECT 1 FROM (%s) as test LIMIT %d', |
||
| 354 | preg_replace('/SELECT\s+COUNT.+?\s+FROM/is', 'SELECT 1 FROM', $countQuery), |
||
| 355 | $maxResults + 1 |
||
| 356 | ); |
||
| 357 | |||
| 358 | $testResult = DB::select($testQuery); |
||
| 359 | if (count($testResult) > $maxResults) { |
||
| 360 | Cache::put($cacheKey, $maxResults, now()->addMinutes($cacheExpiry)); |
||
| 361 | |||
| 362 | return $maxResults; |
||
| 363 | } |
||
| 364 | } |
||
| 365 | |||
| 366 | // Execute the count query |
||
| 367 | $result = DB::select($countQuery); |
||
| 368 | $count = isset($result[0]) ? (int) $result[0]->count : 0; |
||
| 369 | |||
| 370 | // Cache the result |
||
| 371 | Cache::put($cacheKey, $count, now()->addMinutes($cacheExpiry)); |
||
| 372 | |||
| 373 | return $count; |
||
| 374 | } catch (\Exception $e) { |
||
| 375 | // If optimization fails, try a simpler approach |
||
| 376 | try { |
||
| 377 | // Extract the core table and WHERE conditions |
||
| 378 | if (preg_match('/FROM\s+releases\s+r\s+(.+?)(?:ORDER\s+BY|LIMIT|$)/is', $query, $matches)) { |
||
| 379 | $conditions = $matches[1]; |
||
| 380 | // Remove JOINs but keep WHERE |
||
| 381 | $conditions = preg_replace('/(?:LEFT\s+|INNER\s+)?(?:OUTER\s+)?JOIN\s+.+?(?=WHERE|LEFT|INNER|JOIN|$)/is', '', $conditions); |
||
| 382 | |||
| 383 | $fallbackQuery = sprintf('SELECT COUNT(*) as count FROM releases r %s', trim($conditions)); |
||
| 384 | |||
| 385 | if ($maxResults > 0) { |
||
| 386 | $fallbackQuery = sprintf('SELECT COUNT(*) as count FROM (SELECT 1 FROM releases r %s LIMIT %d) as limited', |
||
| 387 | trim($conditions), |
||
| 388 | $maxResults |
||
| 389 | ); |
||
| 390 | } |
||
| 391 | |||
| 392 | $result = DB::select($fallbackQuery); |
||
| 393 | $count = isset($result[0]) ? (int) $result[0]->count : 0; |
||
| 394 | |||
| 395 | Cache::put($cacheKey, $count, now()->addMinutes($cacheExpiry)); |
||
| 396 | |||
| 397 | return $count; |
||
| 398 | } |
||
| 399 | } catch (\Exception $fallbackException) { |
||
| 400 | // Log the error for debugging |
||
| 401 | \Illuminate\Support\Facades\Log::error('getPagerCount failed', [ |
||
| 402 | 'query' => $query, |
||
| 403 | 'error' => $fallbackException->getMessage(), |
||
| 404 | ]); |
||
| 405 | } |
||
| 406 | |||
| 407 | return 0; |
||
| 408 | } |
||
| 412 |