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