1<?php 2 3/** 4 * webtrees: online genealogy 5 * Copyright (C) 2023 webtrees development team 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 */ 17 18declare(strict_types=1); 19 20namespace Fisharebest\Webtrees; 21 22use Fisharebest\Webtrees\Module\ModuleBlockInterface; 23use Fisharebest\Webtrees\Module\ModuleInterface; 24use Fisharebest\Webtrees\Services\ModuleService; 25use Fisharebest\Webtrees\Services\UserService; 26use Fisharebest\Webtrees\Statistics\Repository\BrowserRepository; 27use Fisharebest\Webtrees\Statistics\Repository\ContactRepository; 28use Fisharebest\Webtrees\Statistics\Repository\EventRepository; 29use Fisharebest\Webtrees\Statistics\Repository\FamilyDatesRepository; 30use Fisharebest\Webtrees\Statistics\Repository\FamilyRepository; 31use Fisharebest\Webtrees\Statistics\Repository\FavoritesRepository; 32use Fisharebest\Webtrees\Statistics\Repository\GedcomRepository; 33use Fisharebest\Webtrees\Statistics\Repository\HitCountRepository; 34use Fisharebest\Webtrees\Statistics\Repository\IndividualRepository; 35use Fisharebest\Webtrees\Statistics\Repository\Interfaces\BrowserRepositoryInterface; 36use Fisharebest\Webtrees\Statistics\Repository\Interfaces\ContactRepositoryInterface; 37use Fisharebest\Webtrees\Statistics\Repository\Interfaces\EventRepositoryInterface; 38use Fisharebest\Webtrees\Statistics\Repository\Interfaces\FamilyDatesRepositoryInterface; 39use Fisharebest\Webtrees\Statistics\Repository\Interfaces\FavoritesRepositoryInterface; 40use Fisharebest\Webtrees\Statistics\Repository\Interfaces\GedcomRepositoryInterface; 41use Fisharebest\Webtrees\Statistics\Repository\Interfaces\HitCountRepositoryInterface; 42use Fisharebest\Webtrees\Statistics\Repository\Interfaces\IndividualRepositoryInterface; 43use Fisharebest\Webtrees\Statistics\Repository\Interfaces\LatestUserRepositoryInterface; 44use Fisharebest\Webtrees\Statistics\Repository\Interfaces\MediaRepositoryInterface; 45use Fisharebest\Webtrees\Statistics\Repository\Interfaces\MessageRepositoryInterface; 46use Fisharebest\Webtrees\Statistics\Repository\Interfaces\NewsRepositoryInterface; 47use Fisharebest\Webtrees\Statistics\Repository\Interfaces\PlaceRepositoryInterface; 48use Fisharebest\Webtrees\Statistics\Repository\Interfaces\ServerRepositoryInterface; 49use Fisharebest\Webtrees\Statistics\Repository\Interfaces\UserRepositoryInterface; 50use Fisharebest\Webtrees\Statistics\Repository\LatestUserRepository; 51use Fisharebest\Webtrees\Statistics\Repository\MediaRepository; 52use Fisharebest\Webtrees\Statistics\Repository\MessageRepository; 53use Fisharebest\Webtrees\Statistics\Repository\NewsRepository; 54use Fisharebest\Webtrees\Statistics\Repository\PlaceRepository; 55use Fisharebest\Webtrees\Statistics\Repository\ServerRepository; 56use Fisharebest\Webtrees\Statistics\Repository\UserRepository; 57use Fisharebest\Webtrees\Statistics\Service\CenturyService; 58use Fisharebest\Webtrees\Statistics\Service\ColorService; 59use Fisharebest\Webtrees\Statistics\Service\CountryService; 60use Illuminate\Database\Query\Builder; 61use Illuminate\Support\Collection; 62use ReflectionClass; 63use ReflectionException; 64use ReflectionMethod; 65use ReflectionNamedType; 66use stdClass; 67 68use function count; 69use function in_array; 70use function str_contains; 71 72/** 73 * A selection of pre-formatted statistical queries. 74 * These are primarily used for embedded keywords on HTML blocks, but 75 * are also used elsewhere in the code. 76 */ 77class Statistics implements 78 GedcomRepositoryInterface, 79 IndividualRepositoryInterface, 80 EventRepositoryInterface, 81 MediaRepositoryInterface, 82 UserRepositoryInterface, 83 ServerRepositoryInterface, 84 BrowserRepositoryInterface, 85 HitCountRepositoryInterface, 86 LatestUserRepositoryInterface, 87 FavoritesRepositoryInterface, 88 NewsRepositoryInterface, 89 MessageRepositoryInterface, 90 ContactRepositoryInterface, 91 FamilyDatesRepositoryInterface, 92 PlaceRepositoryInterface 93{ 94 private Tree $tree; 95 96 private GedcomRepository $gedcom_repository; 97 98 private IndividualRepository $individual_repository; 99 100 private FamilyRepository $family_repository; 101 102 private MediaRepository $media_repository; 103 104 private EventRepository $event_repository; 105 106 private UserRepository $user_repository; 107 108 private ServerRepository $server_repository; 109 110 private BrowserRepository $browser_repository; 111 112 private HitCountRepository $hit_count_repository; 113 114 private LatestUserRepository $latest_user_repository; 115 116 private FavoritesRepository $favorites_repository; 117 118 private NewsRepository $news_repository; 119 120 private MessageRepository $message_repository; 121 122 private ContactRepository $contact_repository; 123 124 private FamilyDatesRepository $family_dates_repository; 125 126 private PlaceRepository $place_repository; 127 128 private ModuleService $module_service; 129 130 /** 131 * Create the statistics for a tree. 132 * 133 * @param CenturyService $century_service 134 * @param ColorService $color_service 135 * @param CountryService $country_service 136 * @param ModuleService $module_service 137 * @param Tree $tree Generate statistics for this tree 138 * @param UserService $user_service 139 */ 140 public function __construct( 141 CenturyService $century_service, 142 ColorService $color_service, 143 CountryService $country_service, 144 ModuleService $module_service, 145 Tree $tree, 146 UserService $user_service 147 ) { 148 $this->tree = $tree; 149 $this->gedcom_repository = new GedcomRepository($tree); 150 $this->individual_repository = new IndividualRepository($century_service, $color_service, $tree); 151 $this->family_repository = new FamilyRepository($century_service, $color_service, $tree); 152 $this->family_dates_repository = new FamilyDatesRepository($tree); 153 $this->media_repository = new MediaRepository($color_service, $tree); 154 $this->event_repository = new EventRepository($tree); 155 $this->user_repository = new UserRepository($tree, $user_service); 156 $this->server_repository = new ServerRepository(); 157 $this->browser_repository = new BrowserRepository(); 158 $this->hit_count_repository = new HitCountRepository($tree, $user_service); 159 $this->latest_user_repository = new LatestUserRepository($user_service); 160 $this->favorites_repository = new FavoritesRepository($tree, $module_service); 161 $this->news_repository = new NewsRepository($tree); 162 $this->message_repository = new MessageRepository(); 163 $this->contact_repository = new ContactRepository($tree, $user_service); 164 $this->place_repository = new PlaceRepository($tree, $country_service, $this->individual_repository); 165 $this->module_service = $module_service; 166 } 167 168 /** 169 * Return a string of all supported tags and an example of its output in table row form. 170 * 171 * @return string 172 */ 173 public function getAllTagsTable(): string 174 { 175 try { 176 $class = new ReflectionClass($this); 177 178 $public_methods = $class->getMethods(ReflectionMethod::IS_PUBLIC); 179 180 $examples = Collection::make($public_methods) 181 ->filter(static fn(ReflectionMethod $method): bool => !in_array($method->getName(), ['embedTags', 'getAllTagsTable'], true)) 182 ->filter(static function (ReflectionMethod $method): bool { 183 $type = $method->getReturnType(); 184 185 return $type instanceof ReflectionNamedType && $type->getName() === 'string'; 186 }) 187 ->sort(static fn(ReflectionMethod $x, ReflectionMethod $y): int => $x->getName() <=> $y->getName()) 188 ->map(function (ReflectionMethod $method): string { 189 $tag = $method->getName(); 190 191 return '<dt>#' . $tag . '#</dt><dd>' . $this->$tag() . '</dd>'; 192 }); 193 194 return '<dl>' . $examples->implode('') . '</dl>'; 195 } catch (ReflectionException $ex) { 196 return $ex->getMessage(); 197 } 198 } 199 200 /** 201 * Embed tags in text 202 * 203 * @param string $text 204 * 205 * @return string 206 */ 207 public function embedTags(string $text): string 208 { 209 if (str_contains($text, '#')) { 210 $text = strtr($text, $this->getTags($text)); 211 } 212 213 return $text; 214 } 215 216 /** 217 * @return string 218 */ 219 public function gedcomFilename(): string 220 { 221 return $this->gedcom_repository->gedcomFilename(); 222 } 223 224 /** 225 * @return int 226 */ 227 public function gedcomId(): int 228 { 229 return $this->gedcom_repository->gedcomId(); 230 } 231 232 /** 233 * @return string 234 */ 235 public function gedcomTitle(): string 236 { 237 return $this->gedcom_repository->gedcomTitle(); 238 } 239 240 /** 241 * @return string 242 */ 243 public function gedcomCreatedSoftware(): string 244 { 245 return $this->gedcom_repository->gedcomCreatedSoftware(); 246 } 247 248 /** 249 * @return string 250 */ 251 public function gedcomCreatedVersion(): string 252 { 253 return $this->gedcom_repository->gedcomCreatedVersion(); 254 } 255 256 /** 257 * @return string 258 */ 259 public function gedcomDate(): string 260 { 261 return $this->gedcom_repository->gedcomDate(); 262 } 263 264 /** 265 * @return string 266 */ 267 public function gedcomUpdated(): string 268 { 269 return $this->gedcom_repository->gedcomUpdated(); 270 } 271 272 /** 273 * @return string 274 */ 275 public function gedcomRootId(): string 276 { 277 return $this->gedcom_repository->gedcomRootId(); 278 } 279 280 /** 281 * @return string 282 */ 283 public function totalRecords(): string 284 { 285 return $this->individual_repository->totalRecords(); 286 } 287 288 /** 289 * @return string 290 */ 291 public function totalIndividuals(): string 292 { 293 return $this->individual_repository->totalIndividuals(); 294 } 295 296 /** 297 * @return string 298 */ 299 public function totalIndisWithSources(): string 300 { 301 return $this->individual_repository->totalIndisWithSources(); 302 } 303 304 /** 305 * @return string 306 */ 307 public function totalIndisWithSourcesPercentage(): string 308 { 309 return $this->individual_repository->totalIndisWithSourcesPercentage(); 310 } 311 312 /** 313 * @param string|null $color_from 314 * @param string|null $color_to 315 * 316 * @return string 317 */ 318 public function chartIndisWithSources( 319 string|null $color_from = null, 320 string|null $color_to = null 321 ): string { 322 return $this->individual_repository->chartIndisWithSources($color_from, $color_to); 323 } 324 325 /** 326 * @return string 327 */ 328 public function totalIndividualsPercentage(): string 329 { 330 return $this->individual_repository->totalIndividualsPercentage(); 331 } 332 333 /** 334 * @return string 335 */ 336 public function totalFamilies(): string 337 { 338 return $this->individual_repository->totalFamilies(); 339 } 340 341 /** 342 * @return string 343 */ 344 public function totalFamiliesPercentage(): string 345 { 346 return $this->individual_repository->totalFamiliesPercentage(); 347 } 348 349 /** 350 * @return string 351 */ 352 public function totalFamsWithSources(): string 353 { 354 return $this->individual_repository->totalFamsWithSources(); 355 } 356 357 /** 358 * @return string 359 */ 360 public function totalFamsWithSourcesPercentage(): string 361 { 362 return $this->individual_repository->totalFamsWithSourcesPercentage(); 363 } 364 365 /** 366 * @param string|null $color_from 367 * @param string|null $color_to 368 * 369 * @return string 370 */ 371 public function chartFamsWithSources( 372 string|null $color_from = null, 373 string|null $color_to = null 374 ): string { 375 return $this->individual_repository->chartFamsWithSources($color_from, $color_to); 376 } 377 378 /** 379 * @return string 380 */ 381 public function totalSources(): string 382 { 383 return $this->individual_repository->totalSources(); 384 } 385 386 /** 387 * @return string 388 */ 389 public function totalSourcesPercentage(): string 390 { 391 return $this->individual_repository->totalSourcesPercentage(); 392 } 393 394 /** 395 * @return string 396 */ 397 public function totalNotes(): string 398 { 399 return $this->individual_repository->totalNotes(); 400 } 401 402 /** 403 * @return string 404 */ 405 public function totalNotesPercentage(): string 406 { 407 return $this->individual_repository->totalNotesPercentage(); 408 } 409 410 /** 411 * @return string 412 */ 413 public function totalRepositories(): string 414 { 415 return $this->individual_repository->totalRepositories(); 416 } 417 418 /** 419 * @return string 420 */ 421 public function totalRepositoriesPercentage(): string 422 { 423 return $this->individual_repository->totalRepositoriesPercentage(); 424 } 425 426 /** 427 * @param array<string> ...$params 428 * 429 * @return string 430 */ 431 public function totalSurnames(...$params): string 432 { 433 return $this->individual_repository->totalSurnames(...$params); 434 } 435 436 /** 437 * @param array<string> ...$params 438 * 439 * @return string 440 */ 441 public function totalGivennames(...$params): string 442 { 443 return $this->individual_repository->totalGivennames(...$params); 444 } 445 446 /** 447 * @param array<string> $events 448 * 449 * @return string 450 */ 451 public function totalEvents(array $events = []): string 452 { 453 return $this->event_repository->totalEvents($events); 454 } 455 456 /** 457 * @return string 458 */ 459 public function totalEventsBirth(): string 460 { 461 return $this->event_repository->totalEventsBirth(); 462 } 463 464 /** 465 * @return string 466 */ 467 public function totalBirths(): string 468 { 469 return $this->event_repository->totalBirths(); 470 } 471 472 /** 473 * @return string 474 */ 475 public function totalEventsDeath(): string 476 { 477 return $this->event_repository->totalEventsDeath(); 478 } 479 480 /** 481 * @return string 482 */ 483 public function totalDeaths(): string 484 { 485 return $this->event_repository->totalDeaths(); 486 } 487 488 /** 489 * @return string 490 */ 491 public function totalEventsMarriage(): string 492 { 493 return $this->event_repository->totalEventsMarriage(); 494 } 495 496 /** 497 * @return string 498 */ 499 public function totalMarriages(): string 500 { 501 return $this->event_repository->totalMarriages(); 502 } 503 504 /** 505 * @return string 506 */ 507 public function totalEventsDivorce(): string 508 { 509 return $this->event_repository->totalEventsDivorce(); 510 } 511 512 /** 513 * @return string 514 */ 515 public function totalDivorces(): string 516 { 517 return $this->event_repository->totalDivorces(); 518 } 519 520 /** 521 * @return string 522 */ 523 public function totalEventsOther(): string 524 { 525 return $this->event_repository->totalEventsOther(); 526 } 527 528 /** 529 * @return string 530 */ 531 public function totalSexMales(): string 532 { 533 return $this->individual_repository->totalSexMales(); 534 } 535 536 /** 537 * @return string 538 */ 539 public function totalSexMalesPercentage(): string 540 { 541 return $this->individual_repository->totalSexMalesPercentage(); 542 } 543 544 /** 545 * @return string 546 */ 547 public function totalSexFemales(): string 548 { 549 return $this->individual_repository->totalSexFemales(); 550 } 551 552 /** 553 * @return string 554 */ 555 public function totalSexFemalesPercentage(): string 556 { 557 return $this->individual_repository->totalSexFemalesPercentage(); 558 } 559 560 /** 561 * @return string 562 */ 563 public function totalSexUnknown(): string 564 { 565 return $this->individual_repository->totalSexUnknown(); 566 } 567 568 /** 569 * @return string 570 */ 571 public function totalSexUnknownPercentage(): string 572 { 573 return $this->individual_repository->totalSexUnknownPercentage(); 574 } 575 576 /** 577 * @param string|null $color_female 578 * @param string|null $color_male 579 * @param string|null $color_unknown 580 * 581 * @return string 582 */ 583 public function chartSex( 584 string|null $color_female = null, 585 string|null $color_male = null, 586 string|null $color_unknown = null 587 ): string { 588 return $this->individual_repository->chartSex($color_female, $color_male, $color_unknown); 589 } 590 591 /** 592 * @return string 593 */ 594 public function totalLiving(): string 595 { 596 return $this->individual_repository->totalLiving(); 597 } 598 599 /** 600 * @return string 601 */ 602 public function totalLivingPercentage(): string 603 { 604 return $this->individual_repository->totalLivingPercentage(); 605 } 606 607 /** 608 * @return string 609 */ 610 public function totalDeceased(): string 611 { 612 return $this->individual_repository->totalDeceased(); 613 } 614 615 /** 616 * @return string 617 */ 618 public function totalDeceasedPercentage(): string 619 { 620 return $this->individual_repository->totalDeceasedPercentage(); 621 } 622 623 /** 624 * @param string|null $color_living 625 * @param string|null $color_dead 626 * 627 * @return string 628 */ 629 public function chartMortality(string|null $color_living = null, string|null $color_dead = null): string 630 { 631 return $this->individual_repository->chartMortality($color_living, $color_dead); 632 } 633 634 /** 635 * @return string 636 */ 637 public function totalMedia(): string 638 { 639 return $this->media_repository->totalMedia(); 640 } 641 642 /** 643 * @return string 644 */ 645 public function totalMediaAudio(): string 646 { 647 return $this->media_repository->totalMediaAudio(); 648 } 649 650 /** 651 * @return string 652 */ 653 public function totalMediaBook(): string 654 { 655 return $this->media_repository->totalMediaBook(); 656 } 657 658 /** 659 * @return string 660 */ 661 public function totalMediaCard(): string 662 { 663 return $this->media_repository->totalMediaCard(); 664 } 665 666 /** 667 * @return string 668 */ 669 public function totalMediaCertificate(): string 670 { 671 return $this->media_repository->totalMediaCertificate(); 672 } 673 674 /** 675 * @return string 676 */ 677 public function totalMediaCoatOfArms(): string 678 { 679 return $this->media_repository->totalMediaCoatOfArms(); 680 } 681 682 /** 683 * @return string 684 */ 685 public function totalMediaDocument(): string 686 { 687 return $this->media_repository->totalMediaDocument(); 688 } 689 690 /** 691 * @return string 692 */ 693 public function totalMediaElectronic(): string 694 { 695 return $this->media_repository->totalMediaElectronic(); 696 } 697 698 /** 699 * @return string 700 */ 701 public function totalMediaMagazine(): string 702 { 703 return $this->media_repository->totalMediaMagazine(); 704 } 705 706 /** 707 * @return string 708 */ 709 public function totalMediaManuscript(): string 710 { 711 return $this->media_repository->totalMediaManuscript(); 712 } 713 714 /** 715 * @return string 716 */ 717 public function totalMediaMap(): string 718 { 719 return $this->media_repository->totalMediaMap(); 720 } 721 722 /** 723 * @return string 724 */ 725 public function totalMediaFiche(): string 726 { 727 return $this->media_repository->totalMediaFiche(); 728 } 729 730 /** 731 * @return string 732 */ 733 public function totalMediaFilm(): string 734 { 735 return $this->media_repository->totalMediaFilm(); 736 } 737 738 /** 739 * @return string 740 */ 741 public function totalMediaNewspaper(): string 742 { 743 return $this->media_repository->totalMediaNewspaper(); 744 } 745 746 /** 747 * @return string 748 */ 749 public function totalMediaPainting(): string 750 { 751 return $this->media_repository->totalMediaPainting(); 752 } 753 754 /** 755 * @return string 756 */ 757 public function totalMediaPhoto(): string 758 { 759 return $this->media_repository->totalMediaPhoto(); 760 } 761 762 /** 763 * @return string 764 */ 765 public function totalMediaTombstone(): string 766 { 767 return $this->media_repository->totalMediaTombstone(); 768 } 769 770 /** 771 * @return string 772 */ 773 public function totalMediaVideo(): string 774 { 775 return $this->media_repository->totalMediaVideo(); 776 } 777 778 /** 779 * @return string 780 */ 781 public function totalMediaOther(): string 782 { 783 return $this->media_repository->totalMediaOther(); 784 } 785 786 /** 787 * @return string 788 */ 789 public function totalMediaUnknown(): string 790 { 791 return $this->media_repository->totalMediaUnknown(); 792 } 793 794 /** 795 * @param string|null $color_from 796 * @param string|null $color_to 797 * 798 * @return string 799 */ 800 public function chartMedia(string|null $color_from = null, string|null $color_to = null): string 801 { 802 return $this->media_repository->chartMedia($color_from, $color_to); 803 } 804 805 /** 806 * @return string 807 */ 808 public function totalPlaces(): string 809 { 810 return $this->place_repository->totalPlaces(); 811 } 812 813 /** 814 * @param string $chart_shows 815 * @param string $chart_type 816 * @param string $surname 817 * 818 * @return string 819 */ 820 public function chartDistribution( 821 string $chart_shows = 'world', 822 string $chart_type = '', 823 string $surname = '' 824 ): string { 825 return $this->place_repository->chartDistribution($chart_shows, $chart_type, $surname); 826 } 827 828 /** 829 * @return string 830 */ 831 public function commonCountriesList(): string 832 { 833 return $this->place_repository->commonCountriesList(); 834 } 835 836 /** 837 * @return string 838 */ 839 public function commonBirthPlacesList(): string 840 { 841 return $this->place_repository->commonBirthPlacesList(); 842 } 843 844 /** 845 * @return string 846 */ 847 public function commonDeathPlacesList(): string 848 { 849 return $this->place_repository->commonDeathPlacesList(); 850 } 851 852 /** 853 * @return string 854 */ 855 public function commonMarriagePlacesList(): string 856 { 857 return $this->place_repository->commonMarriagePlacesList(); 858 } 859 860 /** 861 * @return string 862 */ 863 public function firstBirth(): string 864 { 865 return $this->family_dates_repository->firstBirth(); 866 } 867 868 /** 869 * @return string 870 */ 871 public function firstBirthYear(): string 872 { 873 return $this->family_dates_repository->firstBirthYear(); 874 } 875 876 /** 877 * @return string 878 */ 879 public function firstBirthName(): string 880 { 881 return $this->family_dates_repository->firstBirthName(); 882 } 883 884 /** 885 * @return string 886 */ 887 public function firstBirthPlace(): string 888 { 889 return $this->family_dates_repository->firstBirthPlace(); 890 } 891 892 /** 893 * @return string 894 */ 895 public function lastBirth(): string 896 { 897 return $this->family_dates_repository->lastBirth(); 898 } 899 900 /** 901 * @return string 902 */ 903 public function lastBirthYear(): string 904 { 905 return $this->family_dates_repository->lastBirthYear(); 906 } 907 908 /** 909 * @return string 910 */ 911 public function lastBirthName(): string 912 { 913 return $this->family_dates_repository->lastBirthName(); 914 } 915 916 /** 917 * @return string 918 */ 919 public function lastBirthPlace(): string 920 { 921 return $this->family_dates_repository->lastBirthPlace(); 922 } 923 924 /** 925 * @param int $year1 926 * @param int $year2 927 * 928 * @return Builder 929 */ 930 public function statsBirthQuery(int $year1 = -1, int $year2 = -1): Builder 931 { 932 return $this->individual_repository->statsBirthQuery($year1, $year2); 933 } 934 935 /** 936 * @param int $year1 937 * @param int $year2 938 * 939 * @return Builder 940 */ 941 public function statsBirthBySexQuery(int $year1 = -1, int $year2 = -1): Builder 942 { 943 return $this->individual_repository->statsBirthBySexQuery($year1, $year2); 944 } 945 946 /** 947 * @param string|null $color_from 948 * @param string|null $color_to 949 * 950 * @return string 951 */ 952 public function statsBirth(string|null $color_from = null, string|null $color_to = null): string 953 { 954 return $this->individual_repository->statsBirth($color_from, $color_to); 955 } 956 957 /** 958 * @return string 959 */ 960 public function firstDeath(): string 961 { 962 return $this->family_dates_repository->firstDeath(); 963 } 964 965 /** 966 * @return string 967 */ 968 public function firstDeathYear(): string 969 { 970 return $this->family_dates_repository->firstDeathYear(); 971 } 972 973 /** 974 * @return string 975 */ 976 public function firstDeathName(): string 977 { 978 return $this->family_dates_repository->firstDeathName(); 979 } 980 981 /** 982 * @return string 983 */ 984 public function firstDeathPlace(): string 985 { 986 return $this->family_dates_repository->firstDeathPlace(); 987 } 988 989 /** 990 * @return string 991 */ 992 public function lastDeath(): string 993 { 994 return $this->family_dates_repository->lastDeath(); 995 } 996 997 /** 998 * @return string 999 */ 1000 public function lastDeathYear(): string 1001 { 1002 return $this->family_dates_repository->lastDeathYear(); 1003 } 1004 1005 /** 1006 * @return string 1007 */ 1008 public function lastDeathName(): string 1009 { 1010 return $this->family_dates_repository->lastDeathName(); 1011 } 1012 1013 /** 1014 * @return string 1015 */ 1016 public function lastDeathPlace(): string 1017 { 1018 return $this->family_dates_repository->lastDeathPlace(); 1019 } 1020 1021 /** 1022 * @param int $year1 1023 * @param int $year2 1024 * 1025 * @return Builder 1026 */ 1027 public function statsDeathQuery(int $year1 = -1, int $year2 = -1): Builder 1028 { 1029 return $this->individual_repository->statsDeathQuery($year1, $year2); 1030 } 1031 1032 /** 1033 * @param int $year1 1034 * @param int $year2 1035 * 1036 * @return Builder 1037 */ 1038 public function statsDeathBySexQuery(int $year1 = -1, int $year2 = -1): Builder 1039 { 1040 return $this->individual_repository->statsDeathBySexQuery($year1, $year2); 1041 } 1042 1043 /** 1044 * @param string|null $color_from 1045 * @param string|null $color_to 1046 * 1047 * @return string 1048 */ 1049 public function statsDeath(string|null $color_from = null, string|null $color_to = null): string 1050 { 1051 return $this->individual_repository->statsDeath($color_from, $color_to); 1052 } 1053 1054 /** 1055 * General query on ages. 1056 * 1057 * @param string $related 1058 * @param string $sex 1059 * @param int $year1 1060 * @param int $year2 1061 * 1062 * @return array<array<stdClass>> 1063 */ 1064 public function statsAgeQuery(string $related = 'BIRT', string $sex = 'BOTH', int $year1 = -1, int $year2 = -1): array 1065 { 1066 return $this->individual_repository->statsAgeQuery($related, $sex, $year1, $year2); 1067 } 1068 1069 /** 1070 * @return string 1071 */ 1072 public function statsAge(): string 1073 { 1074 return $this->individual_repository->statsAge(); 1075 } 1076 1077 /** 1078 * @return string 1079 */ 1080 public function longestLife(): string 1081 { 1082 return $this->individual_repository->longestLife(); 1083 } 1084 1085 /** 1086 * @return string 1087 */ 1088 public function longestLifeAge(): string 1089 { 1090 return $this->individual_repository->longestLifeAge(); 1091 } 1092 1093 /** 1094 * @return string 1095 */ 1096 public function longestLifeName(): string 1097 { 1098 return $this->individual_repository->longestLifeName(); 1099 } 1100 1101 /** 1102 * @return string 1103 */ 1104 public function longestLifeFemale(): string 1105 { 1106 return $this->individual_repository->longestLifeFemale(); 1107 } 1108 1109 /** 1110 * @return string 1111 */ 1112 public function longestLifeFemaleAge(): string 1113 { 1114 return $this->individual_repository->longestLifeFemaleAge(); 1115 } 1116 1117 /** 1118 * @return string 1119 */ 1120 public function longestLifeFemaleName(): string 1121 { 1122 return $this->individual_repository->longestLifeFemaleName(); 1123 } 1124 1125 /** 1126 * @return string 1127 */ 1128 public function longestLifeMale(): string 1129 { 1130 return $this->individual_repository->longestLifeMale(); 1131 } 1132 1133 /** 1134 * @return string 1135 */ 1136 public function longestLifeMaleAge(): string 1137 { 1138 return $this->individual_repository->longestLifeMaleAge(); 1139 } 1140 1141 /** 1142 * @return string 1143 */ 1144 public function longestLifeMaleName(): string 1145 { 1146 return $this->individual_repository->longestLifeMaleName(); 1147 } 1148 1149 /** 1150 * @param string $total 1151 * 1152 * @return string 1153 */ 1154 public function topTenOldest(string $total = '10'): string 1155 { 1156 return $this->individual_repository->topTenOldest((int) $total); 1157 } 1158 1159 /** 1160 * @param string $total 1161 * 1162 * @return string 1163 */ 1164 public function topTenOldestList(string $total = '10'): string 1165 { 1166 return $this->individual_repository->topTenOldestList((int) $total); 1167 } 1168 1169 /** 1170 * @param string $total 1171 * 1172 * @return string 1173 */ 1174 public function topTenOldestFemale(string $total = '10'): string 1175 { 1176 return $this->individual_repository->topTenOldestFemale((int) $total); 1177 } 1178 1179 /** 1180 * @param string $total 1181 * 1182 * @return string 1183 */ 1184 public function topTenOldestFemaleList(string $total = '10'): string 1185 { 1186 return $this->individual_repository->topTenOldestFemaleList((int) $total); 1187 } 1188 1189 /** 1190 * @param string $total 1191 * 1192 * @return string 1193 */ 1194 public function topTenOldestMale(string $total = '10'): string 1195 { 1196 return $this->individual_repository->topTenOldestMale((int) $total); 1197 } 1198 1199 /** 1200 * @param string $total 1201 * 1202 * @return string 1203 */ 1204 public function topTenOldestMaleList(string $total = '10'): string 1205 { 1206 return $this->individual_repository->topTenOldestMaleList((int) $total); 1207 } 1208 1209 /** 1210 * @param string $total 1211 * 1212 * @return string 1213 */ 1214 public function topTenOldestAlive(string $total = '10'): string 1215 { 1216 return $this->individual_repository->topTenOldestAlive((int) $total); 1217 } 1218 1219 /** 1220 * @param string $total 1221 * 1222 * @return string 1223 */ 1224 public function topTenOldestListAlive(string $total = '10'): string 1225 { 1226 return $this->individual_repository->topTenOldestListAlive((int) $total); 1227 } 1228 1229 /** 1230 * @param string $total 1231 * 1232 * @return string 1233 */ 1234 public function topTenOldestFemaleAlive(string $total = '10'): string 1235 { 1236 return $this->individual_repository->topTenOldestFemaleAlive((int) $total); 1237 } 1238 1239 /** 1240 * @param string $total 1241 * 1242 * @return string 1243 */ 1244 public function topTenOldestFemaleListAlive(string $total = '10'): string 1245 { 1246 return $this->individual_repository->topTenOldestFemaleListAlive((int) $total); 1247 } 1248 1249 /** 1250 * @param string $total 1251 * 1252 * @return string 1253 */ 1254 public function topTenOldestMaleAlive(string $total = '10'): string 1255 { 1256 return $this->individual_repository->topTenOldestMaleAlive((int) $total); 1257 } 1258 1259 /** 1260 * @param string $total 1261 * 1262 * @return string 1263 */ 1264 public function topTenOldestMaleListAlive(string $total = '10'): string 1265 { 1266 return $this->individual_repository->topTenOldestMaleListAlive((int) $total); 1267 } 1268 1269 /** 1270 * @param string $show_years 1271 * 1272 * @return string 1273 */ 1274 public function averageLifespan(string $show_years = ''): string 1275 { 1276 return $this->individual_repository->averageLifespan((bool) $show_years); 1277 } 1278 1279 /** 1280 * @param string $show_years 1281 * 1282 * @return string 1283 */ 1284 public function averageLifespanFemale(string $show_years = ''): string 1285 { 1286 return $this->individual_repository->averageLifespanFemale((bool) $show_years); 1287 } 1288 1289 /** 1290 * @param string $show_years 1291 * 1292 * @return string 1293 */ 1294 public function averageLifespanMale(string $show_years = ''): string 1295 { 1296 return $this->individual_repository->averageLifespanMale((bool) $show_years); 1297 } 1298 1299 /** 1300 * @return string 1301 */ 1302 public function firstEvent(): string 1303 { 1304 return $this->event_repository->firstEvent(); 1305 } 1306 1307 /** 1308 * @return string 1309 */ 1310 public function firstEventYear(): string 1311 { 1312 return $this->event_repository->firstEventYear(); 1313 } 1314 1315 /** 1316 * @return string 1317 */ 1318 public function firstEventType(): string 1319 { 1320 return $this->event_repository->firstEventType(); 1321 } 1322 1323 /** 1324 * @return string 1325 */ 1326 public function firstEventName(): string 1327 { 1328 return $this->event_repository->firstEventName(); 1329 } 1330 1331 /** 1332 * @return string 1333 */ 1334 public function firstEventPlace(): string 1335 { 1336 return $this->event_repository->firstEventPlace(); 1337 } 1338 1339 /** 1340 * @return string 1341 */ 1342 public function lastEvent(): string 1343 { 1344 return $this->event_repository->lastEvent(); 1345 } 1346 1347 /** 1348 * @return string 1349 */ 1350 public function lastEventYear(): string 1351 { 1352 return $this->event_repository->lastEventYear(); 1353 } 1354 1355 /** 1356 * @return string 1357 */ 1358 public function lastEventType(): string 1359 { 1360 return $this->event_repository->lastEventType(); 1361 } 1362 1363 /** 1364 * @return string 1365 */ 1366 public function lastEventName(): string 1367 { 1368 return $this->event_repository->lastEventName(); 1369 } 1370 1371 /** 1372 * @return string 1373 */ 1374 public function lastEventPlace(): string 1375 { 1376 return $this->event_repository->lastEventPlace(); 1377 } 1378 1379 /** 1380 * @return string 1381 */ 1382 public function firstMarriage(): string 1383 { 1384 return $this->family_dates_repository->firstMarriage(); 1385 } 1386 1387 /** 1388 * @return string 1389 */ 1390 public function firstMarriageYear(): string 1391 { 1392 return $this->family_dates_repository->firstMarriageYear(); 1393 } 1394 1395 /** 1396 * @return string 1397 */ 1398 public function firstMarriageName(): string 1399 { 1400 return $this->family_dates_repository->firstMarriageName(); 1401 } 1402 1403 /** 1404 * @return string 1405 */ 1406 public function firstMarriagePlace(): string 1407 { 1408 return $this->family_dates_repository->firstMarriagePlace(); 1409 } 1410 1411 /** 1412 * @return string 1413 */ 1414 public function lastMarriage(): string 1415 { 1416 return $this->family_dates_repository->lastMarriage(); 1417 } 1418 1419 /** 1420 * @return string 1421 */ 1422 public function lastMarriageYear(): string 1423 { 1424 return $this->family_dates_repository->lastMarriageYear(); 1425 } 1426 1427 /** 1428 * @return string 1429 */ 1430 public function lastMarriageName(): string 1431 { 1432 return $this->family_dates_repository->lastMarriageName(); 1433 } 1434 1435 /** 1436 * @return string 1437 */ 1438 public function lastMarriagePlace(): string 1439 { 1440 return $this->family_dates_repository->lastMarriagePlace(); 1441 } 1442 1443 /** 1444 * @param int $year1 1445 * @param int $year2 1446 * 1447 * @return Builder 1448 */ 1449 public function statsMarriageQuery(int $year1 = -1, int $year2 = -1): Builder 1450 { 1451 return $this->family_repository->statsMarriageQuery($year1, $year2); 1452 } 1453 1454 /** 1455 * @param int $year1 1456 * @param int $year2 1457 * 1458 * @return Builder 1459 */ 1460 public function statsFirstMarriageQuery(int $year1 = -1, int $year2 = -1): Builder 1461 { 1462 return $this->family_repository->statsFirstMarriageQuery($year1, $year2); 1463 } 1464 1465 /** 1466 * @param string|null $color_from 1467 * @param string|null $color_to 1468 * 1469 * @return string 1470 */ 1471 public function statsMarr(string|null $color_from = null, string|null $color_to = null): string 1472 { 1473 return $this->family_repository->statsMarr($color_from, $color_to); 1474 } 1475 1476 /** 1477 * @return string 1478 */ 1479 public function firstDivorce(): string 1480 { 1481 return $this->family_dates_repository->firstDivorce(); 1482 } 1483 1484 /** 1485 * @return string 1486 */ 1487 public function firstDivorceYear(): string 1488 { 1489 return $this->family_dates_repository->firstDivorceYear(); 1490 } 1491 1492 /** 1493 * @return string 1494 */ 1495 public function firstDivorceName(): string 1496 { 1497 return $this->family_dates_repository->firstDivorceName(); 1498 } 1499 1500 /** 1501 * @return string 1502 */ 1503 public function firstDivorcePlace(): string 1504 { 1505 return $this->family_dates_repository->firstDivorcePlace(); 1506 } 1507 1508 /** 1509 * @return string 1510 */ 1511 public function lastDivorce(): string 1512 { 1513 return $this->family_dates_repository->lastDivorce(); 1514 } 1515 1516 /** 1517 * @return string 1518 */ 1519 public function lastDivorceYear(): string 1520 { 1521 return $this->family_dates_repository->lastDivorceYear(); 1522 } 1523 1524 /** 1525 * @return string 1526 */ 1527 public function lastDivorceName(): string 1528 { 1529 return $this->family_dates_repository->lastDivorceName(); 1530 } 1531 1532 /** 1533 * @return string 1534 */ 1535 public function lastDivorcePlace(): string 1536 { 1537 return $this->family_dates_repository->lastDivorcePlace(); 1538 } 1539 1540 /** 1541 * @param string|null $color_from 1542 * @param string|null $color_to 1543 * 1544 * @return string 1545 */ 1546 public function statsDiv(string|null $color_from = null, string|null $color_to = null): string 1547 { 1548 return $this->family_repository->statsDiv($color_from, $color_to); 1549 } 1550 1551 /** 1552 * @return string 1553 */ 1554 public function youngestMarriageFemale(): string 1555 { 1556 return $this->family_repository->youngestMarriageFemale(); 1557 } 1558 1559 /** 1560 * @return string 1561 */ 1562 public function youngestMarriageFemaleName(): string 1563 { 1564 return $this->family_repository->youngestMarriageFemaleName(); 1565 } 1566 1567 /** 1568 * @param string $show_years 1569 * 1570 * @return string 1571 */ 1572 public function youngestMarriageFemaleAge(string $show_years = ''): string 1573 { 1574 return $this->family_repository->youngestMarriageFemaleAge($show_years); 1575 } 1576 1577 /** 1578 * @return string 1579 */ 1580 public function oldestMarriageFemale(): string 1581 { 1582 return $this->family_repository->oldestMarriageFemale(); 1583 } 1584 1585 /** 1586 * @return string 1587 */ 1588 public function oldestMarriageFemaleName(): string 1589 { 1590 return $this->family_repository->oldestMarriageFemaleName(); 1591 } 1592 1593 /** 1594 * @param string $show_years 1595 * 1596 * @return string 1597 */ 1598 public function oldestMarriageFemaleAge(string $show_years = ''): string 1599 { 1600 return $this->family_repository->oldestMarriageFemaleAge($show_years); 1601 } 1602 1603 /** 1604 * @return string 1605 */ 1606 public function youngestMarriageMale(): string 1607 { 1608 return $this->family_repository->youngestMarriageMale(); 1609 } 1610 1611 /** 1612 * @return string 1613 */ 1614 public function youngestMarriageMaleName(): string 1615 { 1616 return $this->family_repository->youngestMarriageMaleName(); 1617 } 1618 1619 /** 1620 * @param string $show_years 1621 * 1622 * @return string 1623 */ 1624 public function youngestMarriageMaleAge(string $show_years = ''): string 1625 { 1626 return $this->family_repository->youngestMarriageMaleAge($show_years); 1627 } 1628 1629 /** 1630 * @return string 1631 */ 1632 public function oldestMarriageMale(): string 1633 { 1634 return $this->family_repository->oldestMarriageMale(); 1635 } 1636 1637 /** 1638 * @return string 1639 */ 1640 public function oldestMarriageMaleName(): string 1641 { 1642 return $this->family_repository->oldestMarriageMaleName(); 1643 } 1644 1645 /** 1646 * @param string $show_years 1647 * 1648 * @return string 1649 */ 1650 public function oldestMarriageMaleAge(string $show_years = ''): string 1651 { 1652 return $this->family_repository->oldestMarriageMaleAge($show_years); 1653 } 1654 1655 /** 1656 * @param string $sex 1657 * @param int $year1 1658 * @param int $year2 1659 * 1660 * @return array<stdClass> 1661 */ 1662 public function statsMarrAgeQuery(string $sex, int $year1 = -1, int $year2 = -1): array 1663 { 1664 return $this->family_repository->statsMarrAgeQuery($sex, $year1, $year2); 1665 } 1666 1667 /** 1668 * @return string 1669 */ 1670 public function statsMarrAge(): string 1671 { 1672 return $this->family_repository->statsMarrAge(); 1673 } 1674 1675 /** 1676 * @param string $total 1677 * 1678 * @return string 1679 */ 1680 public function ageBetweenSpousesMF(string $total = '10'): string 1681 { 1682 return $this->family_repository->ageBetweenSpousesMF((int) $total); 1683 } 1684 1685 /** 1686 * @param string $total 1687 * 1688 * @return string 1689 */ 1690 public function ageBetweenSpousesMFList(string $total = '10'): string 1691 { 1692 return $this->family_repository->ageBetweenSpousesMFList((int) $total); 1693 } 1694 1695 /** 1696 * @param string $total 1697 * 1698 * @return string 1699 */ 1700 public function ageBetweenSpousesFM(string $total = '10'): string 1701 { 1702 return $this->family_repository->ageBetweenSpousesFM((int) $total); 1703 } 1704 1705 /** 1706 * @param string $total 1707 * 1708 * @return string 1709 */ 1710 public function ageBetweenSpousesFMList(string $total = '10'): string 1711 { 1712 return $this->family_repository->ageBetweenSpousesFMList((int) $total); 1713 } 1714 1715 /** 1716 * @return string 1717 */ 1718 public function topAgeOfMarriageFamily(): string 1719 { 1720 return $this->family_repository->topAgeOfMarriageFamily(); 1721 } 1722 1723 /** 1724 * @return string 1725 */ 1726 public function topAgeOfMarriage(): string 1727 { 1728 return $this->family_repository->topAgeOfMarriage(); 1729 } 1730 1731 /** 1732 * @param string $total 1733 * 1734 * @return string 1735 */ 1736 public function topAgeOfMarriageFamilies(string $total = '10'): string 1737 { 1738 return $this->family_repository->topAgeOfMarriageFamilies((int) $total); 1739 } 1740 1741 /** 1742 * @param string $total 1743 * 1744 * @return string 1745 */ 1746 public function topAgeOfMarriageFamiliesList(string $total = '10'): string 1747 { 1748 return $this->family_repository->topAgeOfMarriageFamiliesList((int) $total); 1749 } 1750 1751 /** 1752 * @return string 1753 */ 1754 public function minAgeOfMarriageFamily(): string 1755 { 1756 return $this->family_repository->minAgeOfMarriageFamily(); 1757 } 1758 1759 /** 1760 * @return string 1761 */ 1762 public function minAgeOfMarriage(): string 1763 { 1764 return $this->family_repository->minAgeOfMarriage(); 1765 } 1766 1767 /** 1768 * @param string $total 1769 * 1770 * @return string 1771 */ 1772 public function minAgeOfMarriageFamilies(string $total = '10'): string 1773 { 1774 return $this->family_repository->minAgeOfMarriageFamilies((int) $total); 1775 } 1776 1777 /** 1778 * @param string $total 1779 * 1780 * @return string 1781 */ 1782 public function minAgeOfMarriageFamiliesList(string $total = '10'): string 1783 { 1784 return $this->family_repository->minAgeOfMarriageFamiliesList((int) $total); 1785 } 1786 1787 /** 1788 * @return string 1789 */ 1790 public function youngestMother(): string 1791 { 1792 return $this->family_repository->youngestMother(); 1793 } 1794 1795 /** 1796 * @return string 1797 */ 1798 public function youngestMotherName(): string 1799 { 1800 return $this->family_repository->youngestMotherName(); 1801 } 1802 1803 /** 1804 * @param string $show_years 1805 * 1806 * @return string 1807 */ 1808 public function youngestMotherAge(string $show_years = ''): string 1809 { 1810 return $this->family_repository->youngestMotherAge($show_years); 1811 } 1812 1813 /** 1814 * @return string 1815 */ 1816 public function oldestMother(): string 1817 { 1818 return $this->family_repository->oldestMother(); 1819 } 1820 1821 /** 1822 * @return string 1823 */ 1824 public function oldestMotherName(): string 1825 { 1826 return $this->family_repository->oldestMotherName(); 1827 } 1828 1829 /** 1830 * @param string $show_years 1831 * 1832 * @return string 1833 */ 1834 public function oldestMotherAge(string $show_years = ''): string 1835 { 1836 return $this->family_repository->oldestMotherAge($show_years); 1837 } 1838 1839 /** 1840 * @return string 1841 */ 1842 public function youngestFather(): string 1843 { 1844 return $this->family_repository->youngestFather(); 1845 } 1846 1847 /** 1848 * @return string 1849 */ 1850 public function youngestFatherName(): string 1851 { 1852 return $this->family_repository->youngestFatherName(); 1853 } 1854 1855 /** 1856 * @param string $show_years 1857 * 1858 * @return string 1859 */ 1860 public function youngestFatherAge(string $show_years = ''): string 1861 { 1862 return $this->family_repository->youngestFatherAge($show_years); 1863 } 1864 1865 /** 1866 * @return string 1867 */ 1868 public function oldestFather(): string 1869 { 1870 return $this->family_repository->oldestFather(); 1871 } 1872 1873 /** 1874 * @return string 1875 */ 1876 public function oldestFatherName(): string 1877 { 1878 return $this->family_repository->oldestFatherName(); 1879 } 1880 1881 /** 1882 * @param string $show_years 1883 * 1884 * @return string 1885 */ 1886 public function oldestFatherAge(string $show_years = ''): string 1887 { 1888 return $this->family_repository->oldestFatherAge($show_years); 1889 } 1890 1891 /** 1892 * @return string 1893 */ 1894 public function totalMarriedMales(): string 1895 { 1896 return $this->family_repository->totalMarriedMales(); 1897 } 1898 1899 /** 1900 * @return string 1901 */ 1902 public function totalMarriedFemales(): string 1903 { 1904 return $this->family_repository->totalMarriedFemales(); 1905 } 1906 1907 /** 1908 * @param int $year1 1909 * @param int $year2 1910 * 1911 * @return Builder 1912 */ 1913 public function monthFirstChildQuery(int $year1 = -1, int $year2 = -1): Builder 1914 { 1915 return $this->family_repository->monthFirstChildQuery($year1, $year2); 1916 } 1917 1918 /** 1919 * @param int $year1 1920 * @param int $year2 1921 * 1922 * @return Builder 1923 */ 1924 public function monthFirstChildBySexQuery(int $year1 = -1, int $year2 = -1): Builder 1925 { 1926 return $this->family_repository->monthFirstChildBySexQuery($year1, $year2); 1927 } 1928 1929 /** 1930 * @return string 1931 */ 1932 public function largestFamily(): string 1933 { 1934 return $this->family_repository->largestFamily(); 1935 } 1936 1937 /** 1938 * @return string 1939 */ 1940 public function largestFamilySize(): string 1941 { 1942 return $this->family_repository->largestFamilySize(); 1943 } 1944 1945 /** 1946 * @return string 1947 */ 1948 public function largestFamilyName(): string 1949 { 1950 return $this->family_repository->largestFamilyName(); 1951 } 1952 1953 /** 1954 * @param string $total 1955 * 1956 * @return string 1957 */ 1958 public function topTenLargestFamily(string $total = '10'): string 1959 { 1960 return $this->family_repository->topTenLargestFamily((int) $total); 1961 } 1962 1963 /** 1964 * @param string $total 1965 * 1966 * @return string 1967 */ 1968 public function topTenLargestFamilyList(string $total = '10'): string 1969 { 1970 return $this->family_repository->topTenLargestFamilyList((int) $total); 1971 } 1972 1973 /** 1974 * @param string|null $color_from 1975 * @param string|null $color_to 1976 * @param string $total 1977 * 1978 * @return string 1979 */ 1980 public function chartLargestFamilies( 1981 string|null $color_from = null, 1982 string|null $color_to = null, 1983 string $total = '10' 1984 ): string { 1985 return $this->family_repository->chartLargestFamilies($color_from, $color_to, (int) $total); 1986 } 1987 1988 /** 1989 * @return string 1990 */ 1991 public function totalChildren(): string 1992 { 1993 return $this->family_repository->totalChildren(); 1994 } 1995 1996 /** 1997 * @return string 1998 */ 1999 public function averageChildren(): string 2000 { 2001 return $this->family_repository->averageChildren(); 2002 } 2003 2004 /** 2005 * @param int $year1 2006 * @param int $year2 2007 * 2008 * @return array<stdClass> 2009 */ 2010 public function statsChildrenQuery(int $year1 = -1, int $year2 = -1): array 2011 { 2012 return $this->family_repository->statsChildrenQuery($year1, $year2); 2013 } 2014 2015 /** 2016 * @return string 2017 */ 2018 public function statsChildren(): string 2019 { 2020 return $this->family_repository->statsChildren(); 2021 } 2022 2023 /** 2024 * @param string $total 2025 * 2026 * @return string 2027 */ 2028 public function topAgeBetweenSiblingsName(string $total = '10'): string 2029 { 2030 return $this->family_repository->topAgeBetweenSiblingsName((int) $total); 2031 } 2032 2033 /** 2034 * @param string $total 2035 * 2036 * @return string 2037 */ 2038 public function topAgeBetweenSiblings(string $total = '10'): string 2039 { 2040 return $this->family_repository->topAgeBetweenSiblings((int) $total); 2041 } 2042 2043 /** 2044 * @param string $total 2045 * 2046 * @return string 2047 */ 2048 public function topAgeBetweenSiblingsFullName(string $total = '10'): string 2049 { 2050 return $this->family_repository->topAgeBetweenSiblingsFullName((int) $total); 2051 } 2052 2053 /** 2054 * @param string $total 2055 * @param string $one 2056 * 2057 * @return string 2058 */ 2059 public function topAgeBetweenSiblingsList(string $total = '10', string $one = ''): string 2060 { 2061 return $this->family_repository->topAgeBetweenSiblingsList((int) $total, $one); 2062 } 2063 2064 /** 2065 * @return string 2066 */ 2067 public function noChildrenFamilies(): string 2068 { 2069 return $this->family_repository->noChildrenFamilies(); 2070 } 2071 2072 /** 2073 * @param string $type 2074 * 2075 * @return string 2076 */ 2077 public function noChildrenFamiliesList(string $type = 'list'): string 2078 { 2079 return $this->family_repository->noChildrenFamiliesList($type); 2080 } 2081 2082 /** 2083 * @param string $year1 2084 * @param string $year2 2085 * 2086 * @return string 2087 */ 2088 public function chartNoChildrenFamilies( 2089 string $year1 = '-1', 2090 string $year2 = '-1' 2091 ): string { 2092 return $this->family_repository->chartNoChildrenFamilies((int) $year1, (int) $year2); 2093 } 2094 2095 /** 2096 * @param string $total 2097 * 2098 * @return string 2099 */ 2100 public function topTenLargestGrandFamily(string $total = '10'): string 2101 { 2102 return $this->family_repository->topTenLargestGrandFamily((int) $total); 2103 } 2104 2105 /** 2106 * @param string $total 2107 * 2108 * @return string 2109 */ 2110 public function topTenLargestGrandFamilyList(string $total = '10'): string 2111 { 2112 return $this->family_repository->topTenLargestGrandFamilyList((int) $total); 2113 } 2114 2115 /** 2116 * @return string 2117 */ 2118 public function getCommonSurname(): string 2119 { 2120 return $this->individual_repository->getCommonSurname(); 2121 } 2122 2123 /** 2124 * @param string $threshold 2125 * @param string $number_of_surnames 2126 * @param string $sorting 2127 * 2128 * @return string 2129 */ 2130 public function commonSurnames( 2131 string $threshold = '1', 2132 string $number_of_surnames = '10', 2133 string $sorting = 'alpha' 2134 ): string { 2135 return $this->individual_repository->commonSurnames((int) $threshold, (int) $number_of_surnames, $sorting); 2136 } 2137 2138 /** 2139 * @param string $threshold 2140 * @param string $number_of_surnames 2141 * @param string $sorting 2142 * 2143 * @return string 2144 */ 2145 public function commonSurnamesTotals( 2146 string $threshold = '1', 2147 string $number_of_surnames = '10', 2148 string $sorting = 'count' 2149 ): string { 2150 return $this->individual_repository->commonSurnamesTotals((int) $threshold, (int) $number_of_surnames, $sorting); 2151 } 2152 2153 /** 2154 * @param string $threshold 2155 * @param string $number_of_surnames 2156 * @param string $sorting 2157 * 2158 * @return string 2159 */ 2160 public function commonSurnamesList( 2161 string $threshold = '1', 2162 string $number_of_surnames = '10', 2163 string $sorting = 'alpha' 2164 ): string { 2165 return $this->individual_repository->commonSurnamesList((int) $threshold, (int) $number_of_surnames, $sorting); 2166 } 2167 2168 /** 2169 * @param string $threshold 2170 * @param string $number_of_surnames 2171 * @param string $sorting 2172 * 2173 * @return string 2174 */ 2175 public function commonSurnamesListTotals( 2176 string $threshold = '1', 2177 string $number_of_surnames = '10', 2178 string $sorting = 'count' 2179 ): string { 2180 return $this->individual_repository 2181 ->commonSurnamesListTotals((int) $threshold, (int) $number_of_surnames, $sorting); 2182 } 2183 2184 /** 2185 * @param string|null $color_from 2186 * @param string|null $color_to 2187 * @param string $number_of_surnames 2188 * 2189 * @return string 2190 */ 2191 public function chartCommonSurnames( 2192 string|null $color_from = null, 2193 string|null $color_to = null, 2194 string $number_of_surnames = '10' 2195 ): string { 2196 return $this->individual_repository 2197 ->chartCommonSurnames($color_from, $color_to, (int) $number_of_surnames); 2198 } 2199 2200 /** 2201 * @param string $threshold 2202 * @param string $maxtoshow 2203 * 2204 * @return string 2205 */ 2206 public function commonGiven(string $threshold = '1', string $maxtoshow = '10'): string 2207 { 2208 return $this->individual_repository->commonGiven((int) $threshold, (int) $maxtoshow); 2209 } 2210 2211 /** 2212 * @param string $threshold 2213 * @param string $maxtoshow 2214 * 2215 * @return string 2216 */ 2217 public function commonGivenTotals(string $threshold = '1', string $maxtoshow = '10'): string 2218 { 2219 return $this->individual_repository->commonGivenTotals((int) $threshold, (int) $maxtoshow); 2220 } 2221 2222 /** 2223 * @param string $threshold 2224 * @param string $maxtoshow 2225 * 2226 * @return string 2227 */ 2228 public function commonGivenList(string $threshold = '1', string $maxtoshow = '10'): string 2229 { 2230 return $this->individual_repository->commonGivenList((int) $threshold, (int) $maxtoshow); 2231 } 2232 2233 /** 2234 * @param string $threshold 2235 * @param string $maxtoshow 2236 * 2237 * @return string 2238 */ 2239 public function commonGivenListTotals(string $threshold = '1', string $maxtoshow = '10'): string 2240 { 2241 return $this->individual_repository->commonGivenListTotals((int) $threshold, (int) $maxtoshow); 2242 } 2243 2244 /** 2245 * @param string $threshold 2246 * @param string $maxtoshow 2247 * 2248 * @return string 2249 */ 2250 public function commonGivenTable(string $threshold = '1', string $maxtoshow = '10'): string 2251 { 2252 return $this->individual_repository->commonGivenTable((int) $threshold, (int) $maxtoshow); 2253 } 2254 2255 /** 2256 * @param string $threshold 2257 * @param string $maxtoshow 2258 * 2259 * @return string 2260 */ 2261 public function commonGivenFemale(string $threshold = '1', string $maxtoshow = '10'): string 2262 { 2263 return $this->individual_repository->commonGivenFemale((int) $threshold, (int) $maxtoshow); 2264 } 2265 2266 /** 2267 * @param string $threshold 2268 * @param string $maxtoshow 2269 * 2270 * @return string 2271 */ 2272 public function commonGivenFemaleTotals(string $threshold = '1', string $maxtoshow = '10'): string 2273 { 2274 return $this->individual_repository->commonGivenFemaleTotals((int) $threshold, (int) $maxtoshow); 2275 } 2276 2277 /** 2278 * @param string $threshold 2279 * @param string $maxtoshow 2280 * 2281 * @return string 2282 */ 2283 public function commonGivenFemaleList(string $threshold = '1', string $maxtoshow = '10'): string 2284 { 2285 return $this->individual_repository->commonGivenFemaleList((int) $threshold, (int) $maxtoshow); 2286 } 2287 2288 /** 2289 * @param string $threshold 2290 * @param string $maxtoshow 2291 * 2292 * @return string 2293 */ 2294 public function commonGivenFemaleListTotals(string $threshold = '1', string $maxtoshow = '10'): string 2295 { 2296 return $this->individual_repository->commonGivenFemaleListTotals((int) $threshold, (int) $maxtoshow); 2297 } 2298 2299 /** 2300 * @param string $threshold 2301 * @param string $maxtoshow 2302 * 2303 * @return string 2304 */ 2305 public function commonGivenFemaleTable(string $threshold = '1', string $maxtoshow = '10'): string 2306 { 2307 return $this->individual_repository->commonGivenFemaleTable((int) $threshold, (int) $maxtoshow); 2308 } 2309 2310 /** 2311 * @param string $threshold 2312 * @param string $maxtoshow 2313 * 2314 * @return string 2315 */ 2316 public function commonGivenMale(string $threshold = '1', string $maxtoshow = '10'): string 2317 { 2318 return $this->individual_repository->commonGivenMale((int) $threshold, (int) $maxtoshow); 2319 } 2320 2321 /** 2322 * @param string $threshold 2323 * @param string $maxtoshow 2324 * 2325 * @return string 2326 */ 2327 public function commonGivenMaleTotals(string $threshold = '1', string $maxtoshow = '10'): string 2328 { 2329 return $this->individual_repository->commonGivenMaleTotals((int) $threshold, (int) $maxtoshow); 2330 } 2331 2332 /** 2333 * @param string $threshold 2334 * @param string $maxtoshow 2335 * 2336 * @return string 2337 */ 2338 public function commonGivenMaleList(string $threshold = '1', string $maxtoshow = '10'): string 2339 { 2340 return $this->individual_repository->commonGivenMaleList((int) $threshold, (int) $maxtoshow); 2341 } 2342 2343 /** 2344 * @param string $threshold 2345 * @param string $maxtoshow 2346 * 2347 * @return string 2348 */ 2349 public function commonGivenMaleListTotals(string $threshold = '1', string $maxtoshow = '10'): string 2350 { 2351 return $this->individual_repository->commonGivenMaleListTotals((int) $threshold, (int) $maxtoshow); 2352 } 2353 2354 /** 2355 * @param string $threshold 2356 * @param string $maxtoshow 2357 * 2358 * @return string 2359 */ 2360 public function commonGivenMaleTable(string $threshold = '1', string $maxtoshow = '10'): string 2361 { 2362 return $this->individual_repository->commonGivenMaleTable((int) $threshold, (int) $maxtoshow); 2363 } 2364 2365 /** 2366 * @param string $threshold 2367 * @param string $maxtoshow 2368 * 2369 * @return string 2370 */ 2371 public function commonGivenUnknown(string $threshold = '1', string $maxtoshow = '10'): string 2372 { 2373 return $this->individual_repository->commonGivenUnknown((int) $threshold, (int) $maxtoshow); 2374 } 2375 2376 /** 2377 * @param string $threshold 2378 * @param string $maxtoshow 2379 * 2380 * @return string 2381 */ 2382 public function commonGivenUnknownTotals(string $threshold = '1', string $maxtoshow = '10'): string 2383 { 2384 return $this->individual_repository->commonGivenUnknownTotals((int) $threshold, (int) $maxtoshow); 2385 } 2386 2387 /** 2388 * @param string $threshold 2389 * @param string $maxtoshow 2390 * 2391 * @return string 2392 */ 2393 public function commonGivenUnknownList(string $threshold = '1', string $maxtoshow = '10'): string 2394 { 2395 return $this->individual_repository->commonGivenUnknownList((int) $threshold, (int) $maxtoshow); 2396 } 2397 2398 /** 2399 * @param string $threshold 2400 * @param string $maxtoshow 2401 * 2402 * @return string 2403 */ 2404 public function commonGivenUnknownListTotals(string $threshold = '1', string $maxtoshow = '10'): string 2405 { 2406 return $this->individual_repository->commonGivenUnknownListTotals((int) $threshold, (int) $maxtoshow); 2407 } 2408 2409 /** 2410 * @param string $threshold 2411 * @param string $maxtoshow 2412 * 2413 * @return string 2414 */ 2415 public function commonGivenUnknownTable(string $threshold = '1', string $maxtoshow = '10'): string 2416 { 2417 return $this->individual_repository->commonGivenUnknownTable((int) $threshold, (int) $maxtoshow); 2418 } 2419 2420 /** 2421 * @param string|null $color_from 2422 * @param string|null $color_to 2423 * @param string $maxtoshow 2424 * 2425 * @return string 2426 */ 2427 public function chartCommonGiven( 2428 string|null $color_from = null, 2429 string|null $color_to = null, 2430 string $maxtoshow = '7' 2431 ): string { 2432 return $this->individual_repository->chartCommonGiven($color_from, $color_to, (int) $maxtoshow); 2433 } 2434 2435 /** 2436 * @return string 2437 */ 2438 public function usersLoggedIn(): string 2439 { 2440 return $this->user_repository->usersLoggedIn(); 2441 } 2442 2443 /** 2444 * @return string 2445 */ 2446 public function usersLoggedInList(): string 2447 { 2448 return $this->user_repository->usersLoggedInList(); 2449 } 2450 2451 /** 2452 * @return int 2453 */ 2454 public function usersLoggedInTotal(): int 2455 { 2456 return $this->user_repository->usersLoggedInTotal(); 2457 } 2458 2459 /** 2460 * @return int 2461 */ 2462 public function usersLoggedInTotalAnon(): int 2463 { 2464 return $this->user_repository->usersLoggedInTotalAnon(); 2465 } 2466 2467 /** 2468 * @return int 2469 */ 2470 public function usersLoggedInTotalVisible(): int 2471 { 2472 return $this->user_repository->usersLoggedInTotalVisible(); 2473 } 2474 2475 /** 2476 * @return string 2477 */ 2478 public function userId(): string 2479 { 2480 return $this->user_repository->userId(); 2481 } 2482 2483 /** 2484 * @param string $visitor_text 2485 * 2486 * @return string 2487 */ 2488 public function userName(string $visitor_text = ''): string 2489 { 2490 return $this->user_repository->userName($visitor_text); 2491 } 2492 2493 /** 2494 * @return string 2495 */ 2496 public function userFullName(): string 2497 { 2498 return $this->user_repository->userFullName(); 2499 } 2500 2501 /** 2502 * @return string 2503 */ 2504 public function totalUsers(): string 2505 { 2506 return $this->user_repository->totalUsers(); 2507 } 2508 2509 /** 2510 * @return string 2511 */ 2512 public function totalAdmins(): string 2513 { 2514 return $this->user_repository->totalAdmins(); 2515 } 2516 2517 /** 2518 * @return string 2519 */ 2520 public function totalNonAdmins(): string 2521 { 2522 return $this->user_repository->totalNonAdmins(); 2523 } 2524 2525 /** 2526 * @return string 2527 */ 2528 public function latestUserId(): string 2529 { 2530 return $this->latest_user_repository->latestUserId(); 2531 } 2532 2533 /** 2534 * @return string 2535 */ 2536 public function latestUserName(): string 2537 { 2538 return $this->latest_user_repository->latestUserName(); 2539 } 2540 2541 /** 2542 * @return string 2543 */ 2544 public function latestUserFullName(): string 2545 { 2546 return $this->latest_user_repository->latestUserFullName(); 2547 } 2548 2549 /** 2550 * @param string|null $format 2551 * 2552 * @return string 2553 */ 2554 public function latestUserRegDate(string|null $format = null): string 2555 { 2556 return $this->latest_user_repository->latestUserRegDate($format); 2557 } 2558 2559 /** 2560 * @param string|null $format 2561 * 2562 * @return string 2563 */ 2564 public function latestUserRegTime(string|null $format = null): string 2565 { 2566 return $this->latest_user_repository->latestUserRegTime($format); 2567 } 2568 2569 /** 2570 * @param string|null $yes 2571 * @param string|null $no 2572 * 2573 * @return string 2574 */ 2575 public function latestUserLoggedin(string|null $yes = null, string|null $no = null): string 2576 { 2577 return $this->latest_user_repository->latestUserLoggedin($yes, $no); 2578 } 2579 2580 /** 2581 * @return string 2582 */ 2583 public function contactWebmaster(): string 2584 { 2585 return $this->contact_repository->contactWebmaster(); 2586 } 2587 2588 /** 2589 * @return string 2590 */ 2591 public function contactGedcom(): string 2592 { 2593 return $this->contact_repository->contactGedcom(); 2594 } 2595 2596 /** 2597 * @return string 2598 */ 2599 public function serverDate(): string 2600 { 2601 return $this->server_repository->serverDate(); 2602 } 2603 2604 /** 2605 * @return string 2606 */ 2607 public function serverTime(): string 2608 { 2609 return $this->server_repository->serverTime(); 2610 } 2611 2612 /** 2613 * @return string 2614 */ 2615 public function serverTime24(): string 2616 { 2617 return $this->server_repository->serverTime24(); 2618 } 2619 2620 /** 2621 * What is the timezone of the server. 2622 * 2623 * @return string 2624 */ 2625 public function serverTimezone(): string 2626 { 2627 return $this->server_repository->serverTimezone(); 2628 } 2629 2630 /** 2631 * @return string 2632 */ 2633 public function browserDate(): string 2634 { 2635 return $this->browser_repository->browserDate(); 2636 } 2637 2638 /** 2639 * @return string 2640 */ 2641 public function browserTime(): string 2642 { 2643 return $this->browser_repository->browserTime(); 2644 } 2645 2646 /** 2647 * @return string 2648 */ 2649 public function browserTimezone(): string 2650 { 2651 return $this->browser_repository->browserTimezone(); 2652 } 2653 2654 /** 2655 * @param string $page_parameter 2656 * 2657 * @return string 2658 */ 2659 public function hitCount(string $page_parameter = ''): string 2660 { 2661 return $this->hit_count_repository->hitCount($page_parameter); 2662 } 2663 2664 /** 2665 * @param string $page_parameter 2666 * 2667 * @return string 2668 */ 2669 public function hitCountUser(string $page_parameter = ''): string 2670 { 2671 return $this->hit_count_repository->hitCountUser($page_parameter); 2672 } 2673 2674 /** 2675 * @param string $page_parameter 2676 * 2677 * @return string 2678 */ 2679 public function hitCountIndi(string $page_parameter = ''): string 2680 { 2681 return $this->hit_count_repository->hitCountIndi($page_parameter); 2682 } 2683 2684 /** 2685 * @param string $page_parameter 2686 * 2687 * @return string 2688 */ 2689 public function hitCountFam(string $page_parameter = ''): string 2690 { 2691 return $this->hit_count_repository->hitCountFam($page_parameter); 2692 } 2693 2694 /** 2695 * @param string $page_parameter 2696 * 2697 * @return string 2698 */ 2699 public function hitCountSour(string $page_parameter = ''): string 2700 { 2701 return $this->hit_count_repository->hitCountSour($page_parameter); 2702 } 2703 2704 /** 2705 * @param string $page_parameter 2706 * 2707 * @return string 2708 */ 2709 public function hitCountRepo(string $page_parameter = ''): string 2710 { 2711 return $this->hit_count_repository->hitCountRepo($page_parameter); 2712 } 2713 2714 /** 2715 * @param string $page_parameter 2716 * 2717 * @return string 2718 */ 2719 public function hitCountNote(string $page_parameter = ''): string 2720 { 2721 return $this->hit_count_repository->hitCountNote($page_parameter); 2722 } 2723 2724 /** 2725 * @param string $page_parameter 2726 * 2727 * @return string 2728 */ 2729 public function hitCountObje(string $page_parameter = ''): string 2730 { 2731 return $this->hit_count_repository->hitCountObje($page_parameter); 2732 } 2733 2734 /** 2735 * @return string 2736 */ 2737 public function gedcomFavorites(): string 2738 { 2739 return $this->favorites_repository->gedcomFavorites(); 2740 } 2741 2742 /** 2743 * @return string 2744 */ 2745 public function userFavorites(): string 2746 { 2747 return $this->favorites_repository->userFavorites(); 2748 } 2749 2750 /** 2751 * @return string 2752 */ 2753 public function totalGedcomFavorites(): string 2754 { 2755 return $this->favorites_repository->totalGedcomFavorites(); 2756 } 2757 2758 /** 2759 * @return string 2760 */ 2761 public function totalUserFavorites(): string 2762 { 2763 return $this->favorites_repository->totalUserFavorites(); 2764 } 2765 2766 /** 2767 * @return string 2768 */ 2769 public function totalUserMessages(): string 2770 { 2771 return $this->message_repository->totalUserMessages(); 2772 } 2773 2774 /** 2775 * @return string 2776 */ 2777 public function totalUserJournal(): string 2778 { 2779 return $this->news_repository->totalUserJournal(); 2780 } 2781 2782 /** 2783 * @return string 2784 */ 2785 public function totalGedcomNews(): string 2786 { 2787 return $this->news_repository->totalGedcomNews(); 2788 } 2789 2790 /** 2791 * Create any of the other blocks. 2792 * Use as #callBlock:block_name# 2793 * 2794 * @param string $block 2795 * @param string ...$params 2796 * 2797 * @return string|null 2798 */ 2799 public function callBlock(string $block = '', ...$params): string|null 2800 { 2801 /** @var ModuleBlockInterface|null $module */ 2802 $module = $this->module_service 2803 ->findByComponent(ModuleBlockInterface::class, $this->tree, Auth::user()) 2804 ->first(static fn(ModuleInterface $module): bool => $module->name() === $block && $module->name() !== 'html'); 2805 2806 if ($module === null) { 2807 return ''; 2808 } 2809 2810 // Build the config array 2811 $cfg = []; 2812 foreach ($params as $config) { 2813 $bits = explode('=', $config); 2814 2815 if (count($bits) < 2) { 2816 continue; 2817 } 2818 2819 $v = array_shift($bits); 2820 $cfg[$v] = implode('=', $bits); 2821 } 2822 2823 return $module->getBlock($this->tree, 0, ModuleBlockInterface::CONTEXT_EMBED, $cfg); 2824 } 2825 2826 /** 2827 * What is the current version of webtrees. 2828 * 2829 * @return string 2830 */ 2831 public function webtreesVersion(): string 2832 { 2833 return Webtrees::VERSION; 2834 } 2835 2836 /** 2837 * Get tags and their parsed results. 2838 * 2839 * @param string $text 2840 * 2841 * @return array<string> 2842 */ 2843 private function getTags(string $text): array 2844 { 2845 $tags = []; 2846 $matches = []; 2847 2848 preg_match_all('/#([^#\n]+)(?=#)/', $text, $matches, PREG_SET_ORDER); 2849 2850 foreach ($matches as $match) { 2851 $params = explode(':', $match[1]); 2852 $method = array_shift($params); 2853 2854 if (method_exists($this, $method)) { 2855 $tags[$match[0] . '#'] = $this->$method(...$params); 2856 } 2857 } 2858 2859 return $tags; 2860 } 2861} 2862