Passed
Branch feature/2.1-geodispersion-dev (1d61a8)
by Jonathan
61:21
created

SosaByGenerationGeoAnalysis::results()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 30
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 20
c 1
b 0
f 0
nc 5
nop 2
dl 0
loc 30
rs 8.9777
1
<?php
2
3
/**
4
 * webtrees-lib: MyArtJaub library for webtrees
5
 *
6
 * @package MyArtJaub\Webtrees
7
 * @subpackage GeoDispersion
8
 * @author Jonathan Jaubart <[email protected]>
9
 * @copyright Copyright (c) 2021, Jonathan Jaubart
10
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License, version 3
11
 */
12
13
declare(strict_types=1);
14
15
namespace MyArtJaub\Webtrees\Module\Sosa\GeoAnalyses;
16
17
use Fisharebest\Webtrees\Auth;
18
use Fisharebest\Webtrees\I18N;
19
use Fisharebest\Webtrees\Individual;
20
use Fisharebest\Webtrees\Registry;
21
use Fisharebest\Webtrees\Tree;
22
use MyArtJaub\Webtrees\Common\GeoDispersion\GeoAnalysis\GeoAnalysisPlace;
23
use MyArtJaub\Webtrees\Common\GeoDispersion\GeoAnalysis\GeoAnalysisResults;
24
use MyArtJaub\Webtrees\Contracts\GeoDispersion\GeoAnalysisInterface;
25
use MyArtJaub\Webtrees\Module\Sosa\Services\SosaRecordsService;
26
use Generator;
27
use stdClass;
28
29
/**
30
 * Analyse the geographical dispersion of the ancestors, detailed by century.
31
 */
32
class SosaByGenerationGeoAnalysis implements GeoAnalysisInterface
33
{
34
    private SosaRecordsService $records_service;
35
36
    /**
37
     * Constructor for SosaByGenerationGeoAnalysis
38
     *
39
     * @param SosaRecordsService $records_service
40
     */
41
    public function __construct(SosaRecordsService $records_service)
42
    {
43
        $this->records_service = $records_service;
44
    }
45
46
    /**
47
     * {@inheritDoc}
48
     * @see \MyArtJaub\Webtrees\Contracts\GeoDispersion\GeoAnalysisInterface::title()
49
     */
50
    public function title(): string
51
    {
52
        return I18N::translate('Sosa ancestors places');
53
    }
54
55
    /**
56
     * {@inheritDoc}
57
     * @see \MyArtJaub\Webtrees\Contracts\GeoDispersion\GeoAnalysisInterface::itemsDescription()
58
     */
59
    public function itemsDescription(): callable
60
    {
61
        return fn(int $count): string => I18N::plural('ancestor', 'ancestors', $count);
62
    }
63
64
    /**
65
     * {@inheritDoc}
66
     * @see \MyArtJaub\Webtrees\Contracts\GeoDispersion\GeoAnalysisInterface::results()
67
     */
68
    public function results(Tree $tree, int $depth): GeoAnalysisResults
69
    {
70
        $results = new GeoAnalysisResults();
71
72
        $unique_ancestors = $this->records_service
73
            ->listAncestors($tree, Auth::user())
74
            ->uniqueStrict(fn(stdClass $item): string => $item->majs_i_id);
75
76
        foreach ($unique_ancestors as $item) {
77
            $ancestor = Registry::individualFactory()->make($item->majs_i_id, $tree);
78
            if ($ancestor === null || !$ancestor->canShow()) {
79
                continue;
80
            }
81
            $generation = $this->records_service->generation((int) $item->majs_sosa);
82
            $significantplace = new GeoAnalysisPlace($tree, null, $depth);
83
            foreach ($this->significantPlaces($ancestor) as $place) {
84
                $significantplace = new GeoAnalysisPlace($tree, $place, $depth, true);
85
                if ($significantplace->isKnown()) {
86
                    break;
87
                }
88
            }
89
            $results->addPlace($significantplace);
90
            $results->addPlaceInCategory(
91
                I18N::translate('Generation %s', I18N::number($generation)),
92
                $generation,
93
                $significantplace
94
            );
95
        }
96
97
        return $results;
98
    }
99
100
    /**
101
     * Returns significant places in order of priority for an individual
102
     *
103
     * @param Individual $individual
104
     * @return Generator<\Fisharebest\Webtrees\Place>
105
     */
106
    protected function significantPlaces(Individual $individual): Generator
107
    {
108
        yield $individual->getBirthPlace();
109
110
        /** @var \Fisharebest\Webtrees\Fact $fact */
111
        foreach ($individual->facts(['RESI']) as $fact) {
112
            yield $fact->place();
113
        }
114
115
        yield $individual->getDeathPlace();
116
117
        /** @var \Fisharebest\Webtrees\Family $family */
118
        foreach ($individual->childFamilies() as $family) {
119
            foreach ($family->facts(['RESI']) as $fact) {
120
                yield $fact->place();
121
            }
122
        }
123
124
        /** @var \Fisharebest\Webtrees\Family $family */
125
        foreach ($individual->spouseFamilies() as $family) {
126
            foreach ($family->facts(['RESI']) as $fact) {
127
                yield $fact->place();
128
            }
129
        }
130
    }
131
}
132