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