Issues (2560)

app/Services/ChartService.php (4 issues)

1
<?php
2
3
/**
4
 * webtrees: online genealogy
5
 * Copyright (C) 2025 webtrees development team
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 * GNU General Public License for more details.
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16
 */
17
18
declare(strict_types=1);
19
20
namespace Fisharebest\Webtrees\Services;
21
22
use Fisharebest\Webtrees\Family;
0 ignored issues
show
The type Fisharebest\Webtrees\Family was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
23
use Fisharebest\Webtrees\Individual;
0 ignored issues
show
The type Fisharebest\Webtrees\Individual was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
24
use Illuminate\Support\Collection;
25
26
/**
27
 * Find ancestors, descendants, cousins, etc for drawing charts.
28
 */
29
class ChartService
30
{
31
    /**
32
     * Find the ancestors of an individual, indexed by their Sosa-Stradonitz number.
33
     *
34
     * @param Individual $individual  Start with this individual
35
     * @param int        $generations Fetch this number of generations
36
     *
37
     * @return Collection<int,Individual>
38
     */
39
    public function sosaStradonitzAncestors(Individual $individual, int $generations): Collection
40
    {
41
        $ancestors = [1 => $individual];
42
43
        $queue = [1];
44
45
        $max = 2 ** ($generations - 1);
46
47
        while ($queue !== []) {
48
            $sosa_stradonitz_number = array_shift($queue);
49
50
            if ($sosa_stradonitz_number >= $max) {
51
                break;
52
            }
53
54
            $family = $ancestors[$sosa_stradonitz_number]->childFamilies()->first();
55
56
            if ($family instanceof Family) {
57
                if ($family->husband() instanceof Individual) {
58
                    $ancestors[$sosa_stradonitz_number * 2] = $family->husband();
59
                    $queue[] = $sosa_stradonitz_number * 2;
60
                }
61
62
                if ($family->wife() instanceof Individual) {
63
                    $ancestors[$sosa_stradonitz_number * 2 + 1] = $family->wife();
64
                    $queue[] = $sosa_stradonitz_number * 2 + 1;
65
                }
66
            }
67
        }
68
69
        return new Collection($ancestors);
0 ignored issues
show
$ancestors of type array<integer,Fisharebest\Webtrees\Individual> is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $items of Illuminate\Support\Collection::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

69
        return new Collection(/** @scrutinizer ignore-type */ $ancestors);
Loading history...
70
    }
71
72
    /**
73
     * Find the descendants of an individual.
74
     *
75
     * @param Individual $individual  Start with this individual
76
     * @param int        $generations Fetch this number of generations
77
     *
78
     * @return Collection<int,Individual>
79
     */
80
    public function descendants(Individual $individual, int $generations): Collection
81
    {
82
        $descendants = new Collection([$individual->xref() => $individual]);
0 ignored issues
show
array($individual->xref() => $individual) of type Fisharebest\Webtrees\Individual[] is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $items of Illuminate\Support\Collection::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

82
        $descendants = new Collection(/** @scrutinizer ignore-type */ [$individual->xref() => $individual]);
Loading history...
83
84
        if ($generations > 0) {
85
            foreach ($individual->spouseFamilies() as $family) {
86
                foreach ($family->children() as $child) {
87
                    if (!$descendants->has($child->xref())) {
88
                        $descendants = $descendants->merge($this->descendants($child, $generations - 1));
89
                    }
90
                }
91
            }
92
        }
93
94
        return $descendants->values();
95
    }
96
97
    /**
98
     * Find the descendants of an individual.
99
     *
100
     * @param Individual $individual  Start with this individual
101
     * @param int        $generations Fetch this number of generations
102
     *
103
     * @return Collection<int,Family>
104
     */
105
    public function descendantFamilies(Individual $individual, int $generations): Collection
106
    {
107
        $descendants = $individual->spouseFamilies();
108
109
        if ($generations > 0) {
110
            foreach ($descendants as $family) {
111
                foreach ($family->children() as $child) {
112
                    $descendants = $descendants->merge($this->descendantFamilies($child, $generations - 1));
113
                }
114
            }
115
        }
116
117
        return $descendants;
118
    }
119
}
120