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