xref: /webtrees/app/Http/RequestHandlers/AddChildToFamilyAction.php (revision fb0b33a546a827b49066d2c9fb3c54e18b841508)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2021 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
18declare(strict_types=1);
19
20namespace Fisharebest\Webtrees\Http\RequestHandlers;
21
22use Fisharebest\Webtrees\Auth;
23use Fisharebest\Webtrees\Date;
24use Fisharebest\Webtrees\Individual;
25use Fisharebest\Webtrees\Registry;
26use Fisharebest\Webtrees\Services\GedcomEditService;
27use Fisharebest\Webtrees\Tree;
28use Psr\Http\Message\ResponseInterface;
29use Psr\Http\Message\ServerRequestInterface;
30use Psr\Http\Server\RequestHandlerInterface;
31
32use function assert;
33use function preg_match_all;
34use function redirect;
35
36/**
37 * Add a new child to a family.
38 */
39class AddChildToFamilyAction implements RequestHandlerInterface
40{
41    /** @var GedcomEditService */
42    private $gedcom_edit_service;
43
44    /**
45     * AddChildToFamilyAction constructor.
46     *
47     * @param GedcomEditService $gedcom_edit_service
48     */
49    public function __construct(GedcomEditService $gedcom_edit_service)
50    {
51        $this->gedcom_edit_service = $gedcom_edit_service;
52    }
53
54    /**
55     * @param ServerRequestInterface $request
56     *
57     * @return ResponseInterface
58     */
59    public function handle(ServerRequestInterface $request): ResponseInterface
60    {
61        $tree = $request->getAttribute('tree');
62        assert($tree instanceof Tree);
63
64        $xref = $request->getQueryParams()['xref'];
65
66        $family = Registry::familyFactory()->make($xref, $tree);
67        $family = Auth::checkFamilyAccess($family, true);
68
69        $params = (array) $request->getParsedBody();
70
71        $PEDI      = $params['PEDI'];
72        $keep_chan = (bool) ($params['keep_chan'] ?? false);
73
74        $this->gedcom_edit_service->glevels = $params['glevels'] ?? [];
75        $this->gedcom_edit_service->tag     = $params['tag'] ?? [];
76        $this->gedcom_edit_service->text    = $params['text'] ?? [];
77        $this->gedcom_edit_service->islink  = $params['islink'] ?? [];
78
79        $this->gedcom_edit_service->splitSource();
80        $gedrec = '0 @@ INDI';
81        $gedrec .= $this->gedcom_edit_service->addNewName($request, $tree);
82        $gedrec .= $this->gedcom_edit_service->addNewSex($request);
83        if (preg_match_all('/([A-Z0-9_]+)/', $tree->getPreference('QUICK_REQUIRED_FACTS'), $matches)) {
84            foreach ($matches[1] as $match) {
85                $gedrec .= $this->gedcom_edit_service->addNewFact($request, $tree, $match);
86            }
87        }
88
89        switch ($PEDI) {
90            case '':
91                $gedrec .= "\n1 FAMC @$xref@";
92                break;
93            case 'adopted':
94                $gedrec .= "\n1 FAMC @$xref@\n2 PEDI $PEDI\n1 ADOP\n2 FAMC @$xref@\n3 ADOP BOTH";
95                break;
96            case 'sealing':
97                $gedrec .= "\n1 FAMC @$xref@\n2 PEDI $PEDI\n1 SLGC\n2 FAMC @$xref@";
98                break;
99            case 'foster':
100                $gedrec .= "\n1 FAMC @$xref@\n2 PEDI $PEDI\n1 EVEN\n2 TYPE $PEDI";
101                break;
102            default:
103                $gedrec .= "\n1 FAMC @$xref@\n2 PEDI $PEDI";
104                break;
105        }
106
107        if ($params['SOUR_INDI'] ?? false) {
108            $gedrec = $this->gedcom_edit_service->handleUpdates($gedrec);
109        } else {
110            $gedrec = $this->gedcom_edit_service->updateRest($gedrec);
111        }
112
113        // Create the new child
114        $new_child = $tree->createIndividual($gedrec);
115
116        // Insert new child at the right place
117        $done = false;
118        foreach ($family->facts(['CHIL']) as $fact) {
119            $old_child = $fact->target();
120            if ($old_child instanceof Individual && Date::compare($new_child->getEstimatedBirthDate(), $old_child->getEstimatedBirthDate()) < 0) {
121                // Insert before this child
122                $family->updateFact($fact->id(), '1 CHIL @' . $new_child->xref() . "@\n" . $fact->gedcom(), !$keep_chan);
123                $done = true;
124                break;
125            }
126        }
127        if (!$done) {
128            // Append child at end
129            $family->createFact('1 CHIL @' . $new_child->xref() . '@', !$keep_chan);
130        }
131
132        if (($params['goto'] ?? '') === 'new') {
133            return redirect($new_child->url());
134        }
135
136        return redirect($family->url());
137    }
138}
139