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