Passed
Push — master ( 00a79d...f5402f )
by Greg
05:33
created

SearchAdvancedPage   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 193
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 124
c 1
b 0
f 0
dl 0
loc 193
rs 10
wmc 7

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A otherFields() 0 11 2
A nameOptions() 0 7 1
A handle() 0 32 2
A dateOptions() 0 7 1
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
18
declare(strict_types=1);
19
20
namespace Fisharebest\Webtrees\Http\RequestHandlers;
21
22
use Fisharebest\Webtrees\GedcomTag;
23
use Fisharebest\Webtrees\Http\ViewResponseTrait;
24
use Fisharebest\Webtrees\I18N;
25
use Fisharebest\Webtrees\Services\SearchService;
26
use Fisharebest\Webtrees\Tree;
27
use InvalidArgumentException;
28
use Psr\Http\Message\ResponseInterface;
29
use Psr\Http\Message\ServerRequestInterface;
30
use Psr\Http\Server\RequestHandlerInterface;
31
32
/**
33
 * Search for genealogy data
34
 */
35
class SearchAdvancedPage implements RequestHandlerInterface
36
{
37
    use ViewResponseTrait;
38
39
    private const DEFAULT_ADVANCED_FIELDS = [
40
        'NAME:GIVN',
41
        'NAME:SURN',
42
        'BIRT:DATE',
43
        'BIRT:PLAC',
44
        'FAMS:MARR:DATE',
45
        'FAMS:MARR:PLAC',
46
        'DEAT:DATE',
47
        'DEAT:PLAC',
48
        'FAMC:HUSB:NAME:GIVN',
49
        'FAMC:HUSB:NAME:SURN',
50
        'FAMC:WIFE:NAME:GIVN',
51
        'FAMC:WIFE:NAME:SURN',
52
    ];
53
54
    private const OTHER_ADVANCED_FIELDS = [
55
        'ADOP:DATE',
56
        'ADOP:PLAC',
57
        'AFN',
58
        'BAPL:DATE',
59
        'BAPL:PLAC',
60
        'BAPM:DATE',
61
        'BAPM:PLAC',
62
        'BARM:DATE',
63
        'BARM:PLAC',
64
        'BASM:DATE',
65
        'BASM:PLAC',
66
        'BLES:DATE',
67
        'BLES:PLAC',
68
        'BURI:DATE',
69
        'BURI:PLAC',
70
        'CAST',
71
        'CENS:DATE',
72
        'CENS:PLAC',
73
        'CHAN:DATE',
74
        'CHAN:_WT_USER',
75
        'CHR:DATE',
76
        'CHR:PLAC',
77
        'CREM:DATE',
78
        'CREM:PLAC',
79
        'DSCR',
80
        'EMAIL',
81
        'EMIG:DATE',
82
        'EMIG:PLAC',
83
        'ENDL:DATE',
84
        'ENDL:PLAC',
85
        'EVEN',
86
        'EVEN:TYPE',
87
        'EVEN:DATE',
88
        'EVEN:PLAC',
89
        'FACT',
90
        'FACT:TYPE',
91
        'FAMS:CENS:DATE',
92
        'FAMS:CENS:PLAC',
93
        'FAMS:DIV:DATE',
94
        'FAMS:NOTE',
95
        'FAMS:SLGS:DATE',
96
        'FAMS:SLGS:PLAC',
97
        'FAX',
98
        'FCOM:DATE',
99
        'FCOM:PLAC',
100
        'IMMI:DATE',
101
        'IMMI:PLAC',
102
        'NAME:NICK',
103
        'NAME:_MARNM',
104
        'NAME:_HEB',
105
        'NAME:ROMN',
106
        'NATI',
107
        'NATU:DATE',
108
        'NATU:PLAC',
109
        'NOTE',
110
        'OCCU',
111
        'ORDN:DATE',
112
        'ORDN:PLAC',
113
        'REFN',
114
        'RELI',
115
        'RESI',
116
        'RESI:DATE',
117
        'RESI:PLAC',
118
        'SLGC:DATE',
119
        'SLGC:PLAC',
120
        'TITL',
121
        '_BRTM:DATE',
122
        '_BRTM:PLAC',
123
        '_MILI',
124
    ];
125
126
    /** @var SearchService */
127
    private $search_service;
128
129
    /**
130
     * SearchController constructor.
131
     *
132
     * @param SearchService $search_service
133
     */
134
    public function __construct(SearchService $search_service)
135
    {
136
        $this->search_service = $search_service;
137
    }
138
139
    /**
140
     * A structured search.
141
     *
142
     * @param ServerRequestInterface $request
143
     *
144
     * @return ResponseInterface
145
     */
146
    public function handle(ServerRequestInterface $request): ResponseInterface
147
    {
148
        $tree = $request->getAttribute('tree');
149
        assert($tree instanceof Tree, new InvalidArgumentException());
150
151
        $default_fields = array_fill_keys(self::DEFAULT_ADVANCED_FIELDS, '');
152
153
        $params = $request->getQueryParams();
154
155
        $fields      = $params['fields'] ?? $default_fields;
156
        $modifiers   = $params['modifiers'] ?? [];
157
158
        $other_fields = $this->otherFields($fields);
159
        $date_options = $this->dateOptions();
160
        $name_options = $this->nameOptions();
161
162
        if (!empty(array_filter($fields))) {
163
            $individuals = $this->search_service->searchIndividualsAdvanced([$tree], $fields, $modifiers);
164
        } else {
165
            $individuals = [];
166
        }
167
168
        $title = I18N::translate('Advanced search');
169
170
        return $this->viewResponse('search-advanced-page', [
171
            'date_options' => $date_options,
172
            'fields'       => $fields,
173
            'individuals'  => $individuals,
174
            'modifiers'    => $modifiers,
175
            'name_options' => $name_options,
176
            'other_fields' => $other_fields,
177
            'title'        => $title,
178
        ]);
179
    }
180
181
    /**
182
     * Extra search fields to add to the advanced search
183
     *
184
     * @param string[] $fields
185
     *
186
     * @return string[]
187
     */
188
    private function otherFields(array $fields): array
189
    {
190
        $unused = array_diff(self::OTHER_ADVANCED_FIELDS, array_keys($fields));
191
192
        $other_fields = [];
193
194
        foreach ($unused as $tag) {
195
            $other_fields[$tag] = GedcomTag::getLabel($tag);
196
        }
197
198
        return $other_fields;
199
    }
200
201
    /**
202
     * For the advanced search
203
     *
204
     * @return string[]
205
     */
206
    private function dateOptions(): array
207
    {
208
        return [
209
            0  => I18N::translate('Exact date'),
210
            2  => I18N::plural('±%s year', '±%s years', 2, I18N::number(2)),
211
            5  => I18N::plural('±%s year', '±%s years', 5, I18N::number(5)),
212
            10 => I18N::plural('±%s year', '±%s years', 10, I18N::number(10)),
213
        ];
214
    }
215
216
    /**
217
     * For the advanced search
218
     *
219
     * @return string[]
220
     */
221
    private function nameOptions(): array
222
    {
223
        return [
224
            'EXACT'    => I18N::translate('Exact'),
225
            'BEGINS'   => I18N::translate('Begins with'),
226
            'CONTAINS' => I18N::translate('Contains'),
227
            'SDX'      => I18N::translate('Sounds like'),
228
        ];
229
    }
230
}
231