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