Passed
Push — master ( 9b5c95...5229ea )
by Greg
06:55
created

EditFamilyController::addChild()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 15
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 20
rs 9.7666
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
declare(strict_types=1);
18
19
namespace Fisharebest\Webtrees\Http\Controllers;
20
21
use Fisharebest\Webtrees\Auth;
22
use Fisharebest\Webtrees\Date;
23
use Fisharebest\Webtrees\Fact;
24
use Fisharebest\Webtrees\Family;
25
use Fisharebest\Webtrees\GedcomCode\GedcomCodePedi;
26
use Fisharebest\Webtrees\I18N;
27
use Fisharebest\Webtrees\Individual;
28
use Psr\Http\Message\ResponseInterface;
29
use Psr\Http\Message\ServerRequestInterface;
30
31
/**
32
 * Controller for edit forms and responses.
33
 */
34
class EditFamilyController extends AbstractEditController
35
{
36
    /**
37
     * @param ServerRequestInterface $request
38
     *
39
     * @return ResponseInterface
40
     */
41
    public function addChild(ServerRequestInterface $request): ResponseInterface
42
    {
43
        $tree   = $request->getAttribute('tree');
44
        $xref   = $request->getQueryParams()['xref'];
45
        $gender = $request->getQueryParams()['gender'];
46
        $family = Family::getInstance($xref, $tree);
47
48
        Auth::checkFamilyAccess($family, true);
49
50
        $title = $family->fullName() . ' - ' . I18N::translate('Add a child');
51
52
        return $this->viewResponse('edit/new-individual', [
53
            'next_action' => 'add-child-to-family-action',
54
            'tree'       => $tree,
55
            'title'      => $title,
56
            'individual' => null,
57
            'family'     => $family,
58
            'name_fact'  => null,
59
            'famtag'     => 'CHIL',
60
            'gender'     => $gender,
61
        ]);
62
    }
63
64
    /**
65
     * @param ServerRequestInterface $request
66
     *
67
     * @return ResponseInterface
68
     */
69
    public function addChildAction(ServerRequestInterface $request): ResponseInterface
70
    {
71
        $tree   = $request->getAttribute('tree');
72
        $xref   = $request->getParsedBody()['xref'];
73
74
        $family = Family::getInstance($xref, $tree);
75
76
        Auth::checkFamilyAccess($family, true);
77
78
        $PEDI      = $request->getParsedBody()['PEDI'];
79
        $keep_chan = (bool) ($request->getParsedBody()['keep_chan'] ?? false);
80
81
        $this->glevels = $request->getParsedBody()['glevels'] ?? [];
82
        $this->tag     = $request->getParsedBody()['tag'] ?? [];
83
        $this->text    = $request->getParsedBody()['text'] ?? [];
84
        $this->islink  = $request->getParsedBody()['islink'] ?? [];
85
86
        $this->splitSource();
87
        $gedrec = '0 @@ INDI';
88
        $gedrec .= $this->addNewName($request, $tree);
89
        $gedrec .= $this->addNewSex($request);
90
        if (preg_match_all('/([A-Z0-9_]+)/', $tree->getPreference('QUICK_REQUIRED_FACTS'), $matches)) {
91
            foreach ($matches[1] as $match) {
92
                $gedrec .= $this->addNewFact($request, $tree, $match);
93
            }
94
        }
95
        $gedrec .= "\n" . GedcomCodePedi::createNewFamcPedi($PEDI, $xref);
96
        if ($request->getParsedBody()['SOUR_INDI'] ?? false) {
97
            $gedrec = $this->handleUpdates($gedrec);
98
        } else {
99
            $gedrec = $this->updateRest($gedrec);
100
        }
101
102
        // Create the new child
103
        $new_child = $tree->createIndividual($gedrec);
104
105
        // Insert new child at the right place
106
        $done = false;
107
        foreach ($family->facts(['CHIL']) as $fact) {
108
            $old_child = $fact->target();
109
            if ($old_child instanceof Individual && Date::compare($new_child->getEstimatedBirthDate(), $old_child->getEstimatedBirthDate()) < 0) {
110
                // Insert before this child
111
                $family->updateFact($fact->id(), '1 CHIL @' . $new_child->xref() . "@\n" . $fact->gedcom(), !$keep_chan);
112
                $done = true;
113
                break;
114
            }
115
        }
116
        if (!$done) {
117
            // Append child at end
118
            $family->createFact('1 CHIL @' . $new_child->xref() . '@', !$keep_chan);
119
        }
120
121
        if (($request->getParsedBody()['goto'] ?? '') === 'new') {
122
            return redirect($new_child->url());
123
        }
124
125
        return redirect($family->url());
126
    }
127
128
    /**
129
     * @param ServerRequestInterface $request
130
     *
131
     * @return ResponseInterface
132
     */
133
    public function addSpouse(ServerRequestInterface $request): ResponseInterface
134
    {
135
        $tree   = $request->getAttribute('tree');
136
        $xref   = $request->getQueryParams()['xref'];
137
        $famtag = $request->getQueryParams()['famtag'];
138
        $family = Family::getInstance($xref, $tree);
139
140
        Auth::checkFamilyAccess($family, true);
141
142
        if ($famtag === 'WIFE') {
143
            $title  = I18N::translate('Add a wife');
144
            $gender = 'F';
145
        } else {
146
            $title  = I18N::translate('Add a husband');
147
            $gender = 'M';
148
        }
149
150
        return $this->viewResponse('edit/new-individual', [
151
            'next_action' => 'add-spouse-to-family-action',
152
            'tree'       => $tree,
153
            'title'      => $title,
154
            'individual' => null,
155
            'family'     => $family,
156
            'name_fact'  => null,
157
            'famtag'     => $famtag,
158
            'gender'     => $gender,
159
        ]);
160
    }
161
162
    /**
163
     * @param ServerRequestInterface $request
164
     *
165
     * @return ResponseInterface
166
     */
167
    public function addSpouseAction(ServerRequestInterface $request): ResponseInterface
168
    {
169
        $tree   = $request->getAttribute('tree');
170
        $xref   = $request->getParsedBody()['xref'];
171
172
        $family = Family::getInstance($xref, $tree);
173
174
        Auth::checkFamilyAccess($family, true);
175
176
        $this->glevels = $request->getParsedBody()['glevels'] ?? [];
177
        $this->tag     = $request->getParsedBody()['tag'] ?? [];
178
        $this->text    = $request->getParsedBody()['text'] ?? [];
179
        $this->islink  = $request->getParsedBody()['islink'] ?? [];
180
181
        // Create the new spouse
182
        $this->splitSource(); // separate SOUR record from the rest
183
184
        $gedrec = '0 @@ INDI';
185
        $gedrec .= $this->addNewName($request, $tree);
186
        $gedrec .= $this->addNewSex($request);
187
        if (preg_match_all('/([A-Z0-9_]+)/', $tree->getPreference('QUICK_REQUIRED_FACTS'), $matches)) {
188
            foreach ($matches[1] as $match) {
189
                $gedrec .= $this->addNewFact($request, $tree, $match);
190
            }
191
        }
192
193
        if ($request->getParsedBody()['SOUR_INDI'] ?? false) {
194
            $gedrec = $this->handleUpdates($gedrec);
195
        } else {
196
            $gedrec = $this->updateRest($gedrec);
197
        }
198
        $gedrec .= "\n1 FAMS @" . $family->xref() . '@';
199
        $spouse = $tree->createIndividual($gedrec);
200
201
        // Update the existing family - add marriage, etc
202
        if ($family->facts(['HUSB'])->first() instanceof Fact) {
203
            $family->createFact('1 WIFE @' . $spouse->xref() . '@', true);
204
        } else {
205
            $family->createFact('1 HUSB @' . $spouse->xref() . '@', true);
206
        }
207
        $famrec = '';
208
        if (preg_match_all('/([A-Z0-9_]+)/', $tree->getPreference('QUICK_REQUIRED_FAMFACTS'), $matches)) {
209
            foreach ($matches[1] as $match) {
210
                $famrec .= $this->addNewFact($request, $tree, $match);
211
            }
212
        }
213
        if ($request->getParsedBody()['SOUR_FAM'] ?? false) {
214
            $famrec = $this->handleUpdates($famrec);
215
        } else {
216
            $famrec = $this->updateRest($famrec);
217
        }
218
        $family->createFact(trim($famrec), true); // trim leading \n
219
220
        if (($request->getParsedBody()['goto'] ?? '') === 'new') {
221
            return redirect($spouse->url());
222
        }
223
224
        return redirect($family->url());
225
    }
226
227
    /**
228
     * @param ServerRequestInterface $request
229
     *
230
     * @return ResponseInterface
231
     */
232
    public function changeFamilyMembers(ServerRequestInterface $request): ResponseInterface
233
    {
234
        $tree   = $request->getAttribute('tree');
235
        $xref   = $request->getQueryParams()['xref'];
236
        $family = Family::getInstance($xref, $tree);
237
        Auth::checkFamilyAccess($family, true);
238
239
        $title = I18N::translate('Change family members') . ' – ' . $family->fullName();
240
241
        return $this->viewResponse('edit/change-family-members', [
242
            'tree'     => $tree,
243
            'title'    => $title,
244
            'family'   => $family,
245
            'father'   => $family->husband(),
246
            'mother'   => $family->wife(),
247
            'children' => $family->children(),
248
        ]);
249
    }
250
251
    /**
252
     * @param ServerRequestInterface $request
253
     *
254
     * @return ResponseInterface
255
     */
256
    public function changeFamilyMembersAction(ServerRequestInterface $request): ResponseInterface
257
    {
258
        $tree   = $request->getAttribute('tree');
259
        $xref   = $request->getParsedBody()['xref'];
260
        $family = Family::getInstance($xref, $tree);
261
        Auth::checkFamilyAccess($family, true);
262
263
        $HUSB = $request->getParsedBody()['HUSB'] ?? '';
264
        $WIFE = $request->getParsedBody()['WIFE'] ?? '';
265
        $CHIL = $request->getParsedBody()['CHIL'] ?? [];
266
267
        // Current family members
268
        $old_father   = $family->husband();
269
        $old_mother   = $family->wife();
270
        $old_children = $family->children();
271
272
        // New family members
273
        $new_father   = Individual::getInstance($HUSB, $tree);
274
        $new_mother   = Individual::getInstance($WIFE, $tree);
275
        $new_children = [];
276
        foreach ($CHIL as $child) {
277
            $new_children[] = Individual::getInstance($child, $tree);
278
        }
279
280
        if ($old_father !== $new_father) {
281
            if ($old_father instanceof Individual) {
282
                // Remove old FAMS link
283
                foreach ($old_father->facts(['FAMS']) as $fact) {
284
                    if ($fact->target() === $family) {
285
                        $old_father->deleteFact($fact->id(), true);
286
                    }
287
                }
288
                // Remove old HUSB link
289
                foreach ($family->facts(['HUSB', 'WIFE']) as $fact) {
290
                    if ($fact->target() === $old_father) {
291
                        $family->deleteFact($fact->id(), true);
292
                    }
293
                }
294
            }
295
            if ($new_father instanceof Individual) {
296
                // Add new FAMS link
297
                $new_father->createFact('1 FAMS @' . $family->xref() . '@', true);
298
                // Add new HUSB link
299
                $family->createFact('1 HUSB @' . $new_father->xref() . '@', true);
300
            }
301
        }
302
303
        if ($old_mother !== $new_mother) {
304
            if ($old_mother instanceof Individual) {
305
                // Remove old FAMS link
306
                foreach ($old_mother->facts(['FAMS']) as $fact) {
307
                    if ($fact->target() === $family) {
308
                        $old_mother->deleteFact($fact->id(), true);
309
                    }
310
                }
311
                // Remove old WIFE link
312
                foreach ($family->facts(['HUSB', 'WIFE']) as $fact) {
313
                    if ($fact->target() === $old_mother) {
314
                        $family->deleteFact($fact->id(), true);
315
                    }
316
                }
317
            }
318
            if ($new_mother instanceof Individual) {
319
                // Add new FAMS link
320
                $new_mother->createFact('1 FAMS @' . $family->xref() . '@', true);
321
                // Add new WIFE link
322
                $family->createFact('1 WIFE @' . $new_mother->xref() . '@', true);
323
            }
324
        }
325
326
        foreach ($old_children as $old_child) {
327
            if (!in_array($old_child, $new_children, true)) {
328
                // Remove old FAMC link
329
                foreach ($old_child->facts(['FAMC']) as $fact) {
330
                    if ($fact->target() === $family) {
331
                        $old_child->deleteFact($fact->id(), true);
332
                    }
333
                }
334
                // Remove old CHIL link
335
                foreach ($family->facts(['CHIL']) as $fact) {
336
                    if ($fact->target() === $old_child) {
337
                        $family->deleteFact($fact->id(), true);
338
                    }
339
                }
340
            }
341
        }
342
343
        foreach ($new_children as $new_child) {
344
            if ($new_child instanceof Individual && !$old_children->contains($new_child)) {
345
                // Add new FAMC link
346
                $new_child->createFact('1 FAMC @' . $family->xref() . '@', true);
347
                // Add new CHIL link
348
                $family->createFact('1 CHIL @' . $new_child->xref() . '@', true);
349
            }
350
        }
351
352
        return redirect($family->url());
353
    }
354
}
355