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