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