Issues (2558)

app/Census/AbstractCensusColumn.php (2 issues)

Labels
Severity
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\Census;
21
22
use Fisharebest\Webtrees\Date;
23
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...
24
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...
25
26
use function array_slice;
27
use function explode;
28
use function implode;
29
30
/**
31
 * Definitions for a census column
32
 */
33
class AbstractCensusColumn
34
{
35
    private CensusInterface $census;
36
37
    private string $abbr;
38
39
    private string $title;
40
41
    /**
42
     * Create a column for a census
43
     *
44
     * @param CensusInterface $census The census to which this column forms part.
45
     * @param string          $abbr   The abbreviated on-screen name "BiC"
46
     * @param string          $title  The full column heading "Born in the county"
47
     */
48
    public function __construct(CensusInterface $census, string $abbr, string $title)
49
    {
50
        $this->census = $census;
51
        $this->abbr   = $abbr;
52
        $this->title  = $title;
53
    }
54
55
    /**
56
     * A short version of the column's name.
57
     *
58
     * @return string
59
     */
60
    public function abbreviation(): string
61
    {
62
        return $this->abbr;
63
    }
64
65
    /**
66
     * Find the father of an individual
67
     */
68
    public function father(Individual $individual): Individual|null
69
    {
70
        $family = $individual->childFamilies()->first();
71
72
        if ($family instanceof Family) {
73
            return $family->husband();
74
        }
75
76
        return null;
77
    }
78
79
    /**
80
     * Find the mother of an individual
81
     */
82
    public function mother(Individual $individual): Individual|null
83
    {
84
        $family = $individual->childFamilies()->first();
85
86
        if ($family instanceof Family) {
87
            return $family->wife();
88
        }
89
90
        return null;
91
    }
92
93
    /**
94
     * Find the current spouse family of an individual
95
     */
96
    public function spouseFamily(Individual $individual): Family|null
97
    {
98
        return $individual->spouseFamilies()
99
                // Exclude families that were created after this census date
100
            ->filter(fn (Family $family): bool => Date::compare($family->getMarriageDate(), $this->date()) <= 0)
101
            ->sort(Family::marriageDateComparator())
102
            ->last();
103
    }
104
105
    /**
106
     * What was an individual's likely name on a given date, allowing
107
     * for marriages and married names.
108
     *
109
     * @return array<string>
110
     */
111
    protected function nameAtCensusDate(Individual $individual): array
112
    {
113
        $names  = $individual->getAllNames();
114
        $name   = $names[0];
115
        $family = $this->spouseFamily($individual);
116
117
        if ($family instanceof Family) {
118
            $spouse = $family->spouse($individual);
119
120
            if ($spouse instanceof Individual) {
121
                foreach ($family->facts(['MARR']) as $marriage) {
122
                    if ($marriage->date()->isOK()) {
123
                        foreach ($names as $individual_name) {
124
                            foreach ($spouse->getAllNames() as $spouse_name) {
125
                                if ($individual_name['type'] === '_MARNM' && $individual_name['surn'] === $spouse_name['surn']) {
126
                                    return $individual_name;
127
                                }
128
                            }
129
                        }
130
                    }
131
                }
132
            }
133
        }
134
135
        return $name;
136
    }
137
138
    /**
139
     * When did this census occur
140
     */
141
    public function date(): Date
142
    {
143
        return new Date($this->census->censusDate());
144
    }
145
146
    /**
147
     * The full version of the column's name.
148
     *
149
     * @return string
150
     */
151
    public function title(): string
152
    {
153
        return $this->title;
154
    }
155
156
    /**
157
     * Extract the country (last part) of a place name.
158
     *
159
     * @param string $place e.g. "London, England"
160
     *
161
     * @return string e.g. "England"
162
     */
163
    protected function lastPartOfPlace(string $place): string
164
    {
165
        $parts = explode(', ', $place);
166
167
        return end($parts);
168
    }
169
170
    /**
171
     * Remove the country of a place name, where it is the same as the census place
172
     *
173
     * @param string $place e.g. "London, England"
174
     *
175
     * @return string e.g. "London" (for census of England) and "London, England" elsewhere
176
     */
177
    protected function notCountry(string $place): string
178
    {
179
        $parts = explode(', ', $place);
180
181
        if (end($parts) === $this->place()) {
182
            return implode(', ', array_slice($parts, 0, -1));
183
        }
184
185
        return $place;
186
    }
187
188
    /**
189
     * Where did this census occur
190
     *
191
     * @return string
192
     */
193
    public function place(): string
194
    {
195
        return $this->census->censusPlace();
196
    }
197
}
198