Passed
Push — master ( cb43c0...55749c )
by Greg
05:22
created

EditFactAction   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 118
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 59
dl 0
loc 118
rs 10
c 0
b 0
f 0
wmc 22

2 Methods

Rating   Name   Duplication   Size   Complexity  
D handle() 0 93 21
A __construct() 0 4 1
1
<?php
2
3
/**
4
 * webtrees: online genealogy
5
 * Copyright (C) 2020 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\Auth;
23
use Fisharebest\Webtrees\Factory;
24
use Fisharebest\Webtrees\Individual;
25
use Fisharebest\Webtrees\Module\CensusAssistantModule;
26
use Fisharebest\Webtrees\Services\GedcomEditService;
27
use Fisharebest\Webtrees\Services\ModuleService;
28
use Fisharebest\Webtrees\Tree;
29
use Psr\Http\Message\ResponseInterface;
30
use Psr\Http\Message\ServerRequestInterface;
31
use Psr\Http\Server\RequestHandlerInterface;
32
33
use function array_merge;
34
use function array_unique;
35
use function assert;
36
use function explode;
37
use function in_array;
38
use function is_string;
39
use function preg_match_all;
40
use function redirect;
41
use function trim;
42
43
/**
44
 * Save an updated GEDCOM fact.
45
 */
46
class EditFactAction implements RequestHandlerInterface
47
{
48
    /** @var GedcomEditService */
49
    private $gedcom_edit_service;
50
51
    /** @var ModuleService */
52
    private $module_service;
53
54
    /**
55
     * EditGedcomRecordController constructor.
56
     *
57
     * @param GedcomEditService $gedcom_edit_service
58
     * @param ModuleService     $module_service
59
     */
60
    public function __construct(GedcomEditService $gedcom_edit_service, ModuleService $module_service)
61
    {
62
        $this->gedcom_edit_service = $gedcom_edit_service;
63
        $this->module_service = $module_service;
64
    }
65
66
    /**
67
     * @param ServerRequestInterface $request
68
     *
69
     * @return ResponseInterface
70
     */
71
    public function handle(ServerRequestInterface $request): ResponseInterface
72
    {
73
        $tree = $request->getAttribute('tree');
74
        assert($tree instanceof Tree);
75
76
        $xref = $request->getAttribute('xref');
77
        assert(is_string($xref));
78
79
        $params = (array) $request->getParsedBody();
80
81
        $fact_id = $params['fact_id'] ?? '';
82
83
        $record = Factory::gedcomRecord()->make($xref, $tree);
84
        $record = Auth::checkRecordAccess($record, true);
85
86
        $keep_chan = (bool) ($params['keep_chan'] ?? false);
87
88
        $this->gedcom_edit_service->glevels = $params['glevels'];
89
        $this->gedcom_edit_service->tag     = $params['tag'];
90
        $this->gedcom_edit_service->text    = $params['text'];
91
        $this->gedcom_edit_service->islink  = $params['islink'];
92
93
        // If the fact has a DATE or PLAC, then delete any value of Y
94
        if ($this->gedcom_edit_service->text[0] === 'Y') {
95
            foreach ($this->gedcom_edit_service->tag as $n => $value) {
96
                if ($this->gedcom_edit_service->glevels[$n] == 2 && ($value === 'DATE' || $value === 'PLAC') && $this->gedcom_edit_service->text[$n] !== '') {
97
                    $this->gedcom_edit_service->text[0] = '';
98
                    break;
99
                }
100
            }
101
        }
102
103
        $newged = '';
104
105
        $NAME = $params['NAME'] ?? '';
106
107
        if ($NAME !== '') {
108
            $newged     .= "\n1 NAME " . $NAME;
109
            $name_facts = [
110
                'TYPE',
111
                'NPFX',
112
                'GIVN',
113
                'NICK',
114
                'SPFX',
115
                'SURN',
116
                'NSFX',
117
            ];
118
            foreach ($name_facts as $name_fact) {
119
                $NAME_FACT = $params[$name_fact] ?? '';
120
                if ($NAME_FACT !== '') {
121
                    $newged .= "\n2 " . $name_fact . ' ' . $NAME_FACT;
122
                }
123
            }
124
        }
125
126
        $newged = $this->gedcom_edit_service->handleUpdates($newged);
127
128
        // Add new names after existing names
129
        if ($NAME !== '') {
130
            preg_match_all('/[_0-9A-Z]+/', $tree->getPreference('ADVANCED_NAME_FACTS'), $match);
131
            $name_facts = array_unique(array_merge(['_MARNM'], $match[0]));
132
            foreach ($name_facts as $name_fact) {
133
                $NAME_FACT = $params[$name_fact] ?? '';
134
                // Ignore advanced facts that duplicate standard facts.
135
                if ($NAME_FACT !== '' && !in_array($name_fact, ['TYPE', 'NPFX', 'GIVN', 'NICK', 'SPFX', 'SURN', 'NSFX'], true)) {
136
                    $newged .= "\n2 " . $name_fact . ' ' . $NAME_FACT;
137
                }
138
            }
139
        }
140
141
        $newged = trim($newged); // Remove leading newline
142
143
        $census_assistant = $this->module_service->findByInterface(CensusAssistantModule::class)->first();
144
        if ($census_assistant instanceof CensusAssistantModule && $record instanceof Individual) {
145
            $newged = $census_assistant->updateCensusAssistant($request, $record, $fact_id, $newged, $keep_chan);
146
        }
147
148
        $record->updateFact($fact_id, $newged, !$keep_chan);
149
150
        // For the GEDFact_assistant module
151
        $pid_array = $params['pid_array'] ?? '';
152
        if ($pid_array !== '') {
153
            foreach (explode(',', $pid_array) as $pid) {
154
                if ($pid !== $xref) {
155
                    $indi = Factory::individual()->make($pid, $tree);
156
                    if ($indi && $indi->canEdit()) {
157
                        $indi->updateFact($fact_id, $newged, !$keep_chan);
158
                    }
159
                }
160
            }
161
        }
162
163
        return redirect($record->url());
164
    }
165
}
166