Passed
Push — master ( fc1d53...291777 )
by Greg
05:01
created

DeleteRecord::removeLinks()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 6
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 9
rs 10
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\Auth;
23
use Fisharebest\Webtrees\FlashMessages;
24
use Fisharebest\Webtrees\Gedcom;
25
use Fisharebest\Webtrees\GedcomRecord;
26
use Fisharebest\Webtrees\I18N;
27
use Fisharebest\Webtrees\Tree;
28
use Psr\Http\Message\ResponseInterface;
29
use Psr\Http\Message\ServerRequestInterface;
30
use Psr\Http\Server\RequestHandlerInterface;
31
32
use function assert;
33
use function preg_match;
34
use function preg_match_all;
35
use function preg_replace;
36
use function response;
37
38
/**
39
 * Controller for edit forms and responses.
40
 */
41
class DeleteRecord implements RequestHandlerInterface
42
{
43
    /**
44
     * Delete a record.
45
     *
46
     * @param ServerRequestInterface $request
47
     *
48
     * @return ResponseInterface
49
     */
50
    public function handle(ServerRequestInterface $request): ResponseInterface
51
    {
52
        $tree = $request->getAttribute('tree');
53
        assert($tree instanceof Tree);
54
55
        $xref   = $request->getAttribute('xref');
56
        $record = GedcomRecord::getInstance($xref, $tree);
57
58
        Auth::checkRecordAccess($record, true);
59
60
        if ($record && Auth::isEditor($record->tree()) && $record->canShow() && $record->canEdit()) {
61
            // Delete links to this record
62
            foreach ($record->linkingRecords() as $linker) {
63
                $old_gedcom = $linker->gedcom();
64
                $new_gedcom = $this->removeLinks($old_gedcom, $record->xref());
65
                if ($old_gedcom !== $new_gedcom) {
66
                    // If we have removed a link from a family to an individual, and it has only one member
67
                    if (preg_match('/^0 @' . Gedcom::REGEX_XREF . '@ FAM/', $new_gedcom) && preg_match_all('/\n1 (HUSB|WIFE|CHIL) @(' . Gedcom::REGEX_XREF . ')@/', $new_gedcom, $match) == 1) {
68
                        // Delete the family
69
                        $family = GedcomRecord::getInstance($xref, $tree);
70
                        /* I18N: %s is the name of a family group, e.g. “Husband name + Wife name” */
71
                        FlashMessages::addMessage(I18N::translate('The family “%s” has been deleted because it only has one member.', $family->fullName()));
72
                        $family->deleteRecord();
73
                        // Delete any remaining link to this family
74
                        if ($match) {
75
                            $relict     = GedcomRecord::getInstance($match[2][0], $tree);
76
                            $new_gedcom = $relict->gedcom();
77
                            $new_gedcom = $this->removeLinks($new_gedcom, $linker->xref());
78
                            $relict->updateRecord($new_gedcom, false);
79
                            /* I18N: %s are names of records, such as sources, repositories or individuals */
80
                            FlashMessages::addMessage(I18N::translate('The link from “%1$s” to “%2$s” has been deleted.', $relict->fullName(), $family->fullName()));
81
                        }
82
                    } else {
83
                        // Remove links from $linker to $record
84
                        /* I18N: %s are names of records, such as sources, repositories or individuals */
85
                        FlashMessages::addMessage(I18N::translate('The link from “%1$s” to “%2$s” has been deleted.', $linker->fullName(), $record->fullName()));
86
                        $linker->updateRecord($new_gedcom, false);
87
                    }
88
                }
89
            }
90
            // Delete the record itself
91
            $record->deleteRecord();
92
        }
93
94
        return response();
95
    }
96
97
    /**
98
     * Remove all links from $gedrec to $xref, and any sub-tags.
99
     *
100
     * @param string $gedrec
101
     * @param string $xref
102
     *
103
     * @return string
104
     */
105
    private function removeLinks($gedrec, $xref): string
106
    {
107
        $gedrec = preg_replace('/\n1 ' . Gedcom::REGEX_TAG . ' @' . $xref . '@(\n[2-9].*)*/', '', $gedrec);
108
        $gedrec = preg_replace('/\n2 ' . Gedcom::REGEX_TAG . ' @' . $xref . '@(\n[3-9].*)*/', '', $gedrec);
109
        $gedrec = preg_replace('/\n3 ' . Gedcom::REGEX_TAG . ' @' . $xref . '@(\n[4-9].*)*/', '', $gedrec);
110
        $gedrec = preg_replace('/\n4 ' . Gedcom::REGEX_TAG . ' @' . $xref . '@(\n[5-9].*)*/', '', $gedrec);
111
        $gedrec = preg_replace('/\n5 ' . Gedcom::REGEX_TAG . ' @' . $xref . '@(\n[6-9].*)*/', '', $gedrec);
112
113
        return $gedrec;
114
    }
115
}
116