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