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