xref: /webtrees/app/Http/RequestHandlers/EditFactAction.php (revision 49a2c9dc10450a2c87a90ccd44117031df6ab02d)
155749c76SGreg Roach<?php
255749c76SGreg Roach
355749c76SGreg Roach/**
455749c76SGreg Roach * webtrees: online genealogy
555749c76SGreg Roach * Copyright (C) 2020 webtrees development team
655749c76SGreg Roach * This program is free software: you can redistribute it and/or modify
755749c76SGreg Roach * it under the terms of the GNU General Public License as published by
855749c76SGreg Roach * the Free Software Foundation, either version 3 of the License, or
955749c76SGreg Roach * (at your option) any later version.
1055749c76SGreg Roach * This program is distributed in the hope that it will be useful,
1155749c76SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
1255749c76SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1355749c76SGreg Roach * GNU General Public License for more details.
1455749c76SGreg Roach * You should have received a copy of the GNU General Public License
1555749c76SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>.
1655749c76SGreg Roach */
1755749c76SGreg Roach
1855749c76SGreg Roachdeclare(strict_types=1);
1955749c76SGreg Roach
2055749c76SGreg Roachnamespace Fisharebest\Webtrees\Http\RequestHandlers;
2155749c76SGreg Roach
2255749c76SGreg Roachuse Fisharebest\Webtrees\Auth;
2355749c76SGreg Roachuse Fisharebest\Webtrees\Factory;
2455749c76SGreg Roachuse Fisharebest\Webtrees\Individual;
2555749c76SGreg Roachuse Fisharebest\Webtrees\Module\CensusAssistantModule;
2655749c76SGreg Roachuse Fisharebest\Webtrees\Services\GedcomEditService;
2755749c76SGreg Roachuse Fisharebest\Webtrees\Services\ModuleService;
2855749c76SGreg Roachuse Fisharebest\Webtrees\Tree;
2955749c76SGreg Roachuse Psr\Http\Message\ResponseInterface;
3055749c76SGreg Roachuse Psr\Http\Message\ServerRequestInterface;
3155749c76SGreg Roachuse Psr\Http\Server\RequestHandlerInterface;
3255749c76SGreg Roach
3355749c76SGreg Roachuse function array_merge;
3455749c76SGreg Roachuse function array_unique;
3555749c76SGreg Roachuse function assert;
3655749c76SGreg Roachuse function explode;
3755749c76SGreg Roachuse function in_array;
3855749c76SGreg Roachuse function is_string;
3955749c76SGreg Roachuse function preg_match_all;
4055749c76SGreg Roachuse function redirect;
4155749c76SGreg Roachuse function trim;
4255749c76SGreg Roach
4355749c76SGreg Roach/**
4455749c76SGreg Roach * Save an updated GEDCOM fact.
4555749c76SGreg Roach */
4655749c76SGreg Roachclass EditFactAction implements RequestHandlerInterface
4755749c76SGreg Roach{
4855749c76SGreg Roach    /** @var GedcomEditService */
4955749c76SGreg Roach    private $gedcom_edit_service;
5055749c76SGreg Roach
5155749c76SGreg Roach    /** @var ModuleService */
5255749c76SGreg Roach    private $module_service;
5355749c76SGreg Roach
5455749c76SGreg Roach    /**
55*49a2c9dcSGreg Roach     * EditFactAction constructor.
5655749c76SGreg Roach     *
5755749c76SGreg Roach     * @param GedcomEditService $gedcom_edit_service
5855749c76SGreg Roach     * @param ModuleService     $module_service
5955749c76SGreg Roach     */
6055749c76SGreg Roach    public function __construct(GedcomEditService $gedcom_edit_service, ModuleService $module_service)
6155749c76SGreg Roach    {
6255749c76SGreg Roach        $this->gedcom_edit_service = $gedcom_edit_service;
6355749c76SGreg Roach        $this->module_service      = $module_service;
6455749c76SGreg Roach    }
6555749c76SGreg Roach
6655749c76SGreg Roach    /**
6755749c76SGreg Roach     * @param ServerRequestInterface $request
6855749c76SGreg Roach     *
6955749c76SGreg Roach     * @return ResponseInterface
7055749c76SGreg Roach     */
7155749c76SGreg Roach    public function handle(ServerRequestInterface $request): ResponseInterface
7255749c76SGreg Roach    {
7355749c76SGreg Roach        $tree = $request->getAttribute('tree');
7455749c76SGreg Roach        assert($tree instanceof Tree);
7555749c76SGreg Roach
7655749c76SGreg Roach        $xref = $request->getAttribute('xref');
7755749c76SGreg Roach        assert(is_string($xref));
7855749c76SGreg Roach
79*49a2c9dcSGreg Roach        $fact_id = $request->getAttribute('fact_id') ?? '';
80*49a2c9dcSGreg Roach        assert(is_string($fact_id));
8155749c76SGreg Roach
8255749c76SGreg Roach        $record = Factory::gedcomRecord()->make($xref, $tree);
8355749c76SGreg Roach        $record = Auth::checkRecordAccess($record, true);
8455749c76SGreg Roach
85*49a2c9dcSGreg Roach        $params    = (array) $request->getParsedBody();
8655749c76SGreg Roach        $keep_chan = (bool) ($params['keep_chan'] ?? false);
8755749c76SGreg Roach
8855749c76SGreg Roach        $this->gedcom_edit_service->glevels = $params['glevels'];
8955749c76SGreg Roach        $this->gedcom_edit_service->tag     = $params['tag'];
9055749c76SGreg Roach        $this->gedcom_edit_service->text    = $params['text'];
9155749c76SGreg Roach        $this->gedcom_edit_service->islink  = $params['islink'];
9255749c76SGreg Roach
9355749c76SGreg Roach        // If the fact has a DATE or PLAC, then delete any value of Y
9455749c76SGreg Roach        if ($this->gedcom_edit_service->text[0] === 'Y') {
9555749c76SGreg Roach            foreach ($this->gedcom_edit_service->tag as $n => $value) {
9655749c76SGreg Roach                if ($this->gedcom_edit_service->glevels[$n] == 2 && ($value === 'DATE' || $value === 'PLAC') && $this->gedcom_edit_service->text[$n] !== '') {
9755749c76SGreg Roach                    $this->gedcom_edit_service->text[0] = '';
9855749c76SGreg Roach                    break;
9955749c76SGreg Roach                }
10055749c76SGreg Roach            }
10155749c76SGreg Roach        }
10255749c76SGreg Roach
10355749c76SGreg Roach        $newged = '';
10455749c76SGreg Roach
10555749c76SGreg Roach        $NAME = $params['NAME'] ?? '';
10655749c76SGreg Roach
10755749c76SGreg Roach        if ($NAME !== '') {
10855749c76SGreg Roach            $newged     .= "\n1 NAME " . $NAME;
10955749c76SGreg Roach            $name_facts = [
11055749c76SGreg Roach                'TYPE',
11155749c76SGreg Roach                'NPFX',
11255749c76SGreg Roach                'GIVN',
11355749c76SGreg Roach                'NICK',
11455749c76SGreg Roach                'SPFX',
11555749c76SGreg Roach                'SURN',
11655749c76SGreg Roach                'NSFX',
11755749c76SGreg Roach            ];
11855749c76SGreg Roach            foreach ($name_facts as $name_fact) {
11955749c76SGreg Roach                $NAME_FACT = $params[$name_fact] ?? '';
12055749c76SGreg Roach                if ($NAME_FACT !== '') {
12155749c76SGreg Roach                    $newged .= "\n2 " . $name_fact . ' ' . $NAME_FACT;
12255749c76SGreg Roach                }
12355749c76SGreg Roach            }
12455749c76SGreg Roach        }
12555749c76SGreg Roach
12655749c76SGreg Roach        $newged = $this->gedcom_edit_service->handleUpdates($newged);
12755749c76SGreg Roach
12855749c76SGreg Roach        // Add new names after existing names
12955749c76SGreg Roach        if ($NAME !== '') {
13055749c76SGreg Roach            preg_match_all('/[_0-9A-Z]+/', $tree->getPreference('ADVANCED_NAME_FACTS'), $match);
13155749c76SGreg Roach            $name_facts = array_unique(array_merge(['_MARNM'], $match[0]));
13255749c76SGreg Roach            foreach ($name_facts as $name_fact) {
13355749c76SGreg Roach                $NAME_FACT = $params[$name_fact] ?? '';
13455749c76SGreg Roach                // Ignore advanced facts that duplicate standard facts.
13555749c76SGreg Roach                if ($NAME_FACT !== '' && !in_array($name_fact, ['TYPE', 'NPFX', 'GIVN', 'NICK', 'SPFX', 'SURN', 'NSFX'], true)) {
13655749c76SGreg Roach                    $newged .= "\n2 " . $name_fact . ' ' . $NAME_FACT;
13755749c76SGreg Roach                }
13855749c76SGreg Roach            }
13955749c76SGreg Roach        }
14055749c76SGreg Roach
14155749c76SGreg Roach        $newged = trim($newged); // Remove leading newline
14255749c76SGreg Roach
14355749c76SGreg Roach        $census_assistant = $this->module_service->findByInterface(CensusAssistantModule::class)->first();
14455749c76SGreg Roach        if ($census_assistant instanceof CensusAssistantModule && $record instanceof Individual) {
14555749c76SGreg Roach            $newged = $census_assistant->updateCensusAssistant($request, $record, $fact_id, $newged, $keep_chan);
14655749c76SGreg Roach        }
14755749c76SGreg Roach
14855749c76SGreg Roach        $record->updateFact($fact_id, $newged, !$keep_chan);
14955749c76SGreg Roach
15055749c76SGreg Roach        // For the GEDFact_assistant module
15155749c76SGreg Roach        $pid_array = $params['pid_array'] ?? '';
15255749c76SGreg Roach        if ($pid_array !== '') {
15355749c76SGreg Roach            foreach (explode(',', $pid_array) as $pid) {
15455749c76SGreg Roach                if ($pid !== $xref) {
15555749c76SGreg Roach                    $indi = Factory::individual()->make($pid, $tree);
15655749c76SGreg Roach                    if ($indi && $indi->canEdit()) {
15755749c76SGreg Roach                        $indi->updateFact($fact_id, $newged, !$keep_chan);
15855749c76SGreg Roach                    }
15955749c76SGreg Roach                }
16055749c76SGreg Roach            }
16155749c76SGreg Roach        }
16255749c76SGreg Roach
1639db6d3cbSGreg Roach        return redirect($params['url'] ?? $record->url());
16455749c76SGreg Roach    }
16555749c76SGreg Roach}
166