| Conditions | 61 | 
| Paths | > 20000 | 
| Total Lines | 289 | 
| Code Lines | 200 | 
| Lines | 0 | 
| Ratio | 0 % | 
| Changes | 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  | 
            ||
| 214 | public function calendar(ServerRequestInterface $request): ResponseInterface  | 
            ||
| 215 |     { | 
            ||
| 216 |         $tree = $request->getAttribute('tree'); | 
            ||
| 217 | assert($tree instanceof Tree);  | 
            ||
| 218 | |||
| 219 |         $locale = $request->getAttribute('locale'); | 
            ||
| 220 | assert($locale instanceof LocaleInterface);  | 
            ||
| 221 | |||
| 222 |         $view            = $request->getAttribute('view'); | 
            ||
| 223 |         $CALENDAR_FORMAT = $tree->getPreference('CALENDAR_FORMAT'); | 
            ||
| 224 | |||
| 225 | $cal = $request->getQueryParams()['cal'] ?? '';  | 
            ||
| 226 | $day = $request->getQueryParams()['day'] ?? '';  | 
            ||
| 227 | $month = $request->getQueryParams()['month'] ?? '';  | 
            ||
| 228 | $year = $request->getQueryParams()['year'] ?? '';  | 
            ||
| 229 | $filterev = $request->getQueryParams()['filterev'] ?? 'BIRT-MARR-DEAT';  | 
            ||
| 230 | $filterof = $request->getQueryParams()['filterof'] ?? 'all';  | 
            ||
| 231 | $filtersx = $request->getQueryParams()['filtersx'] ?? '';  | 
            ||
| 232 | |||
| 233 |         if ($cal . $day . $month . $year === '') { | 
            ||
| 234 | // No date specified? Use the most likely calendar  | 
            ||
| 235 | $cal = $this->localization_service->calendar($locale)->gedcomCalendarEscape();  | 
            ||
| 236 | }  | 
            ||
| 237 | |||
| 238 | // Create a CalendarDate from the parameters  | 
            ||
| 239 | |||
| 240 | // We cannot display new-style/old-style years, so convert to new style  | 
            ||
| 241 |         if (preg_match('/^(\d\d)\d\d\/(\d\d)$/', $year, $match)) { | 
            ||
| 242 | $year = $match[1] . $match[2];  | 
            ||
| 243 | }  | 
            ||
| 244 | |||
| 245 | // advanced-year "year range"  | 
            ||
| 246 |         if (preg_match('/^(\d+)-(\d+)$/', $year, $match)) { | 
            ||
| 247 |             if (strlen($match[1]) > strlen($match[2])) { | 
            ||
| 248 | $match[2] = substr($match[1], 0, strlen($match[1]) - strlen($match[2])) . $match[2];  | 
            ||
| 249 | }  | 
            ||
| 250 |             $ged_date = new Date("FROM {$cal} {$match[1]} TO {$cal} {$match[2]}"); | 
            ||
| 251 | $view = 'year';  | 
            ||
| 252 |         } elseif (preg_match('/^(\d+)(\?+)$/', $year, $match)) { | 
            ||
| 253 | // advanced-year "decade/century wildcard"  | 
            ||
| 254 |             $y1       = $match[1] . str_replace('?', '0', $match[2]); | 
            ||
| 255 |             $y2       = $match[1] . str_replace('?', '9', $match[2]); | 
            ||
| 256 |             $ged_date = new Date("FROM {$cal} {$y1} TO {$cal} {$y2}"); | 
            ||
| 257 | $view = 'year';  | 
            ||
| 258 |         } else { | 
            ||
| 259 |             if ($year < 0) { | 
            ||
| 260 | $year = (-$year) . ' B.C.';  | 
            ||
| 261 | } // need BC to parse date  | 
            ||
| 262 |             $ged_date = new Date("{$cal} {$day} {$month} {$year}"); | 
            ||
| 263 | }  | 
            ||
| 264 | $cal_date = $ged_date->minimumDate();  | 
            ||
| 265 | |||
| 266 | // Fill in any missing bits with todays date  | 
            ||
| 267 | $today = $cal_date->today();  | 
            ||
| 268 |         if ($cal_date->day === 0) { | 
            ||
| 269 | $cal_date->day = $today->day;  | 
            ||
| 270 | }  | 
            ||
| 271 |         if ($cal_date->month === 0) { | 
            ||
| 272 | $cal_date->month = $today->month;  | 
            ||
| 273 | }  | 
            ||
| 274 |         if ($cal_date->year === 0) { | 
            ||
| 275 | $cal_date->year = $today->year;  | 
            ||
| 276 | }  | 
            ||
| 277 | |||
| 278 | $cal_date->setJdFromYmd();  | 
            ||
| 279 | |||
| 280 | // Extract values from date  | 
            ||
| 281 | $days_in_month = $cal_date->daysInMonth();  | 
            ||
| 282 | $days_in_week = $cal_date->daysInWeek();  | 
            ||
| 283 | |||
| 284 | // Invalid dates? Go to monthly view, where they'll be found.  | 
            ||
| 285 |         if ($cal_date->day > $days_in_month && $view === 'day') { | 
            ||
| 286 | $view = 'month';  | 
            ||
| 287 | }  | 
            ||
| 288 | |||
| 289 | /** @var Fact[]|Fact[][] $found_facts */  | 
            ||
| 290 | $found_facts = [];  | 
            ||
| 291 | |||
| 292 |         switch ($view) { | 
            ||
| 293 | case 'day':  | 
            ||
| 294 | $found_facts = $this->applyFilter($this->calendar_service->getAnniversaryEvents($cal_date->minimumJulianDay(), $filterev, $tree), $filterof, $filtersx);  | 
            ||
| 295 | break;  | 
            ||
| 296 | case 'month':  | 
            ||
| 297 | $cal_date->day = 0;  | 
            ||
| 298 | $cal_date->setJdFromYmd();  | 
            ||
| 299 | // Make a separate list for each day. Unspecified/invalid days go in day 0.  | 
            ||
| 300 |                 for ($d = 0; $d <= $days_in_month; ++$d) { | 
            ||
| 301 | $found_facts[$d] = [];  | 
            ||
| 302 | }  | 
            ||
| 303 | // Fetch events for each day  | 
            ||
| 304 | $jds = range($cal_date->minimumJulianDay(), $cal_date->maximumJulianDay());  | 
            ||
| 305 | |||
| 306 |                 foreach ($jds as $jd) { | 
            ||
| 307 |                     foreach ($this->applyFilter($this->calendar_service->getAnniversaryEvents($jd, $filterev, $tree), $filterof, $filtersx) as $fact) { | 
            ||
| 308 | $tmp = $fact->date()->minimumDate();  | 
            ||
| 309 |                         if ($tmp->day >= 1 && $tmp->day <= $tmp->daysInMonth()) { | 
            ||
| 310 | // If the day is valid (for its own calendar), display it in the  | 
            ||
| 311 | // anniversary day (for the display calendar).  | 
            ||
| 312 | $found_facts[$jd - $cal_date->minimumJulianDay() + 1][] = $fact;  | 
            ||
| 313 |                         } else { | 
            ||
| 314 | // Otherwise, display it in the "Day not set" box.  | 
            ||
| 315 | $found_facts[0][] = $fact;  | 
            ||
| 316 | }  | 
            ||
| 317 | }  | 
            ||
| 318 | }  | 
            ||
| 319 | break;  | 
            ||
| 320 | case 'year':  | 
            ||
| 321 | $cal_date->month = 0;  | 
            ||
| 322 | $cal_date->setJdFromYmd();  | 
            ||
| 323 | $found_facts = $this->applyFilter($this->calendar_service->getCalendarEvents($ged_date->minimumJulianDay(), $ged_date->maximumJulianDay(), $filterev, $tree), $filterof, $filtersx);  | 
            ||
| 324 | // Eliminate duplicates (e.g. BET JUL 1900 AND SEP 1900 will appear twice in 1900)  | 
            ||
| 325 | $found_facts = array_unique($found_facts);  | 
            ||
| 326 | break;  | 
            ||
| 327 | }  | 
            ||
| 328 | |||
| 329 | // Group the facts by family/individual  | 
            ||
| 330 | $indis = [];  | 
            ||
| 331 | $fams = [];  | 
            ||
| 332 | $cal_facts = [];  | 
            ||
| 333 | |||
| 334 |         switch ($view) { | 
            ||
| 335 | case 'year':  | 
            ||
| 336 | case 'day':  | 
            ||
| 337 |                 foreach ($found_facts as $fact) { | 
            ||
| 338 | $record = $fact->record();  | 
            ||
| 339 | $xref = $record->xref();  | 
            ||
| 340 |                     if ($record instanceof Individual) { | 
            ||
| 341 |                         if (empty($indis[$xref])) { | 
            ||
| 342 | $indis[$xref] = $this->calendarFactText($fact, true);  | 
            ||
| 343 |                         } else { | 
            ||
| 344 | $indis[$xref] .= '<br>' . $this->calendarFactText($fact, true);  | 
            ||
| 345 | }  | 
            ||
| 346 |                     } elseif ($record instanceof Family) { | 
            ||
| 347 |                         if (empty($indis[$xref])) { | 
            ||
| 348 | $fams[$xref] = $this->calendarFactText($fact, true);  | 
            ||
| 349 |                         } else { | 
            ||
| 350 | $fams[$xref] .= '<br>' . $this->calendarFactText($fact, true);  | 
            ||
| 351 | }  | 
            ||
| 352 | }  | 
            ||
| 353 | }  | 
            ||
| 354 | break;  | 
            ||
| 355 | case 'month':  | 
            ||
| 356 |                 foreach ($found_facts as $d => $facts) { | 
            ||
| 357 | $cal_facts[$d] = [];  | 
            ||
| 358 |                     foreach ($facts as $fact) { | 
            ||
| 359 | $xref = $fact->record()->xref();  | 
            ||
| 360 |                         if (empty($cal_facts[$d][$xref])) { | 
            ||
| 361 | $cal_facts[$d][$xref] = $this->calendarFactText($fact, false);  | 
            ||
| 362 |                         } else { | 
            ||
| 363 | $cal_facts[$d][$xref] .= '<br>' . $this->calendarFactText($fact, false);  | 
            ||
| 364 | }  | 
            ||
| 365 | }  | 
            ||
| 366 | }  | 
            ||
| 367 | break;  | 
            ||
| 368 | }  | 
            ||
| 369 | |||
| 370 | ob_start();  | 
            ||
| 371 | |||
| 372 |         switch ($view) { | 
            ||
| 373 | case 'year':  | 
            ||
| 374 | case 'day':  | 
            ||
| 375 | echo '<table class="w-100"><tr>';  | 
            ||
| 376 |                 echo '<td class="descriptionbox center"><i class="icon-indis"></i>', I18N::translate('Individuals'), '</td>'; | 
            ||
| 377 |                 echo '<td class="descriptionbox center"><i class="icon-cfamily"></i>', I18N::translate('Families'), '</td>'; | 
            ||
| 378 | echo '</tr><tr>';  | 
            ||
| 379 | echo '<td class="optionbox wrap">';  | 
            ||
| 380 | |||
| 381 | $content = $this->calendarListText($indis, '<li>', '</li>', $tree);  | 
            ||
| 382 |                 if ($content) { | 
            ||
| 383 | echo '<ul>', $content, '</ul>';  | 
            ||
| 384 | }  | 
            ||
| 385 | |||
| 386 | echo '</td>';  | 
            ||
| 387 | echo '<td class="optionbox wrap">';  | 
            ||
| 388 | |||
| 389 | $content = $this->calendarListText($fams, '<li>', '</li>', $tree);  | 
            ||
| 390 |                 if ($content) { | 
            ||
| 391 | echo '<ul>', $content, '</ul>';  | 
            ||
| 392 | }  | 
            ||
| 393 | |||
| 394 | echo '</td>';  | 
            ||
| 395 | echo '</tr><tr>';  | 
            ||
| 396 |                 echo '<td class="descriptionbox">', I18N::translate('Total individuals: %s', I18N::number(count($indis))), '</td>'; | 
            ||
| 397 |                 echo '<td class="descriptionbox">', I18N::translate('Total families: %s', I18N::number(count($fams))), '</td>'; | 
            ||
| 398 | echo '</tr></table>';  | 
            ||
| 399 | |||
| 400 | break;  | 
            ||
| 401 | case 'month':  | 
            ||
| 402 | // We use JD%7 = 0/Mon…6/Sun. Standard definitions use 0/Sun…6/Sat.  | 
            ||
| 403 | $week_start = (I18N::firstDay() + 6) % 7;  | 
            ||
| 404 | $weekend_start = ($locale->territory()->weekendStart() + 6) % 7;  | 
            ||
| 405 | $weekend_end = ($locale->territory()->weekendEnd() + 6) % 7;  | 
            ||
| 406 | // The french calendar has a 10-day week, which starts on primidi  | 
            ||
| 407 |                 if ($days_in_week === 10) { | 
            ||
| 408 | $week_start = 0;  | 
            ||
| 409 | $weekend_start = -1;  | 
            ||
| 410 | $weekend_end = -1;  | 
            ||
| 411 | }  | 
            ||
| 412 | echo '<table class="w-100"><thead><tr>';  | 
            ||
| 413 |                 for ($week_day = 0; $week_day < $days_in_week; ++$week_day) { | 
            ||
| 414 | $day_name = $cal_date->dayNames(($week_day + $week_start) % $days_in_week);  | 
            ||
| 415 |                     if ($week_day == $weekend_start || $week_day == $weekend_end) { | 
            ||
| 416 | echo '<th class="descriptionbox weekend" width="' . (100 / $days_in_week) . '%">', $day_name, '</th>';  | 
            ||
| 417 |                     } else { | 
            ||
| 418 | echo '<th class="descriptionbox" width="' . (100 / $days_in_week) . '%">', $day_name, '</th>';  | 
            ||
| 419 | }  | 
            ||
| 420 | }  | 
            ||
| 421 | echo '</tr>';  | 
            ||
| 422 | echo '</thead>';  | 
            ||
| 423 | echo '<tbody>';  | 
            ||
| 424 | // Print days 1 to n of the month, but extend to cover "empty" days before/after the month to make whole weeks.  | 
            ||
| 425 | // e.g. instead of 1 -> 30 (=30 days), we might have -1 -> 33 (=35 days)  | 
            ||
| 426 | $start_d = 1 - ($cal_date->minimumJulianDay() - $week_start) % $days_in_week;  | 
            ||
| 427 | $end_d = $days_in_month + ($days_in_week - ($cal_date->maximumJulianDay() - $week_start + 1) % $days_in_week) % $days_in_week;  | 
            ||
| 428 | // Make sure that there is an empty box for any leap/missing days  | 
            ||
| 429 |                 if ($start_d === 1 && $end_d === $days_in_month && count($found_facts[0]) > 0) { | 
            ||
| 430 | $end_d += $days_in_week;  | 
            ||
| 431 | }  | 
            ||
| 432 |                 for ($d = $start_d; $d <= $end_d; ++$d) { | 
            ||
| 433 |                     if (($d + $cal_date->minimumJulianDay() - $week_start) % $days_in_week === 1) { | 
            ||
| 434 | echo '<tr>';  | 
            ||
| 435 | }  | 
            ||
| 436 | echo '<td class="optionbox wrap">';  | 
            ||
| 437 |                     if ($d < 1 || $d > $days_in_month) { | 
            ||
| 438 |                         if (count($cal_facts[0]) > 0) { | 
            ||
| 439 |                             echo '<span class="cal_day">', I18N::translate('Day not set'), '</span><br style="clear: both;">'; | 
            ||
| 440 | echo '<div class="details1" style="height: 180px; overflow: auto;">';  | 
            ||
| 441 | echo $this->calendarListText($cal_facts[0], '', '', $tree);  | 
            ||
| 442 | echo '</div>';  | 
            ||
| 443 | $cal_facts[0] = [];  | 
            ||
| 444 | }  | 
            ||
| 445 |                     } else { | 
            ||
| 446 | // Format the day number using the calendar  | 
            ||
| 447 |                         $tmp   = new Date($cal_date->format("%@ {$d} %O %E")); | 
            ||
| 448 |                         $d_fmt = $tmp->minimumDate()->format('%j'); | 
            ||
| 449 |                         if ($d === $today->day && $cal_date->month === $today->month) { | 
            ||
| 450 | echo '<span class="cal_day current_day">', $d_fmt, '</span>';  | 
            ||
| 451 |                         } else { | 
            ||
| 452 | echo '<span class="cal_day">', $d_fmt, '</span>';  | 
            ||
| 453 | }  | 
            ||
| 454 | // Show a converted date  | 
            ||
| 455 |                         foreach (explode('_and_', $CALENDAR_FORMAT) as $convcal) { | 
            ||
| 456 |                             switch ($convcal) { | 
            ||
| 457 | case 'french':  | 
            ||
| 458 | $alt_date = new FrenchDate($cal_date->minimumJulianDay() + $d - 1);  | 
            ||
| 459 | break;  | 
            ||
| 460 | case 'gregorian':  | 
            ||
| 461 | $alt_date = new GregorianDate($cal_date->minimumJulianDay() + $d - 1);  | 
            ||
| 462 | break;  | 
            ||
| 463 | case 'jewish':  | 
            ||
| 464 | $alt_date = new JewishDate($cal_date->minimumJulianDay() + $d - 1);  | 
            ||
| 465 | break;  | 
            ||
| 466 | case 'julian':  | 
            ||
| 467 | $alt_date = new JulianDate($cal_date->minimumJulianDay() + $d - 1);  | 
            ||
| 468 | break;  | 
            ||
| 469 | case 'hijri':  | 
            ||
| 470 | $alt_date = new HijriDate($cal_date->minimumJulianDay() + $d - 1);  | 
            ||
| 471 | break;  | 
            ||
| 472 | case 'jalali':  | 
            ||
| 473 | $alt_date = new JalaliDate($cal_date->minimumJulianDay() + $d - 1);  | 
            ||
| 474 | break;  | 
            ||
| 475 | case 'none':  | 
            ||
| 476 | default:  | 
            ||
| 477 | $alt_date = $cal_date;  | 
            ||
| 478 | break;  | 
            ||
| 479 | }  | 
            ||
| 480 |                             if (get_class($alt_date) !== get_class($cal_date) && $alt_date->inValidRange()) { | 
            ||
| 481 |                                 echo '<span class="rtl_cal_day">' . $alt_date->format('%j %M') . '</span>'; | 
            ||
| 482 | // Just show the first conversion  | 
            ||
| 483 | break;  | 
            ||
| 484 | }  | 
            ||
| 485 | }  | 
            ||
| 486 | echo '<br style="clear: both;"><div class="details1" style="height: 180px; overflow: auto;">';  | 
            ||
| 487 | echo $this->calendarListText($cal_facts[$d], '', '', $tree);  | 
            ||
| 488 | echo '</div>';  | 
            ||
| 489 | }  | 
            ||
| 490 | echo '</td>';  | 
            ||
| 491 |                     if (($d + $cal_date->minimumJulianDay() - $week_start) % $days_in_week === 0) { | 
            ||
| 492 | echo '</tr>';  | 
            ||
| 493 | }  | 
            ||
| 494 | }  | 
            ||
| 495 | echo '</tbody>';  | 
            ||
| 496 | echo '</table>';  | 
            ||
| 497 | break;  | 
            ||
| 498 | }  | 
            ||
| 499 | |||
| 500 | $html = ob_get_clean();  | 
            ||
| 501 | |||
| 502 | return response($html);  | 
            ||
| 503 | }  | 
            ||
| 597 |