Passed
Push — master ( 94abca...7bb122 )
by Greg
05:28
created

DataFixService::gedcomDiff()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 38
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 6
eloc 26
nc 5
nop 3
dl 0
loc 38
rs 8.8817
c 1
b 1
f 0
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\Services;
21
22
use Fisharebest\Algorithm\MyersDiff;
23
use Fisharebest\Webtrees\Family;
24
use Fisharebest\Webtrees\Gedcom;
25
use Fisharebest\Webtrees\GedcomRecord;
26
use Fisharebest\Webtrees\Individual;
27
use Fisharebest\Webtrees\Media;
28
use Fisharebest\Webtrees\Note;
29
use Fisharebest\Webtrees\Repository;
30
use Fisharebest\Webtrees\Source;
31
use Fisharebest\Webtrees\Submitter;
32
use Fisharebest\Webtrees\Tree;
33
34
use function e;
35
use function explode;
36
use function implode;
37
use function preg_replace_callback;
38
use function strip_tags;
39
40
/**
41
 * Bulk updates on genealogy data
42
 */
43
class DataFixService
44
{
45
    /**
46
     * Since we know the type, this is quicker than calling GedcomRecord::getInstance().
47
     *
48
     * @param string $xref
49
     * @param Tree   $tree
50
     * @param string $type
51
     *
52
     * @return GedcomRecord|null
53
     */
54
    public function getRecordByType(string $xref, Tree $tree, string $type): ?GedcomRecord
55
    {
56
        switch ($type) {
57
            case Family::RECORD_TYPE:
58
                return Family::getInstance($xref, $tree);
59
60
            case Individual::RECORD_TYPE:
61
                return Individual::getInstance($xref, $tree);
62
63
            case Note::RECORD_TYPE:
64
                return Note::getInstance($xref, $tree);
65
66
            case Media::RECORD_TYPE:
67
                return Media::getInstance($xref, $tree);
68
69
            case Repository::RECORD_TYPE:
70
                return Repository::getInstance($xref, $tree);
71
72
            case Source::RECORD_TYPE:
73
                return Source::getInstance($xref, $tree);
74
75
            case Submitter::RECORD_TYPE:
76
                return Submitter::getInstance($xref, $tree);
77
78
            default:
79
                return GedcomRecord::getInstance($xref, $tree);
80
        }
81
    }
82
83
    /**
84
     * Default preview generator.
85
     *
86
     * @param Tree   $tree
87
     * @param string $old_gedcom
88
     * @param string $new_gedcom
89
     *
90
     * @return string
91
     */
92
    public function gedcomDiff(Tree $tree, string $old_gedcom, string $new_gedcom): string
93
    {
94
        $old_lines   = explode("\n", $old_gedcom);
95
        $new_lines   = explode("\n", $new_gedcom);
96
        $algorithm   = new MyersDiff();
97
        $differences = $algorithm->calculate($old_lines, $new_lines);
98
        $diff_lines  = [];
99
100
        foreach ($differences as $difference) {
101
            switch ($difference[1]) {
102
                case MyersDiff::DELETE:
103
                    $diff_lines[] = '<del>' . e($difference[0]) . '</del><br>';
104
                    break;
105
                case MyersDiff::INSERT:
106
                    $diff_lines[] = '<ins>' . e($difference[0]) . '</ins><br>';
107
                    break;
108
                case MyersDiff::KEEP:
109
                    $diff_lines[] = e($difference[0]) . '<br>';
110
                    break;
111
            }
112
        }
113
114
        $html = implode('', $diff_lines);
115
116
        $html = preg_replace_callback('/@(' . Gedcom::REGEX_XREF . ')@/', static function (array $match) use ($tree): string {
117
            $record = GedcomRecord::getInstance($match[0], $tree);
118
119
            if ($record instanceof GedcomRecord) {
0 ignored issues
show
introduced by
$record is always a sub-type of Fisharebest\Webtrees\GedcomRecord.
Loading history...
120
                $title = strip_tags($record->fullName());
121
                $href  = e($record->url());
122
123
                return '<a href="' . $href . '" title="' . $title . '">' . $match[0] . '</a>';
124
            }
125
126
            return $match[0];
127
        }, $html);
128
129
        return '<pre class="gedcom-data">' . $html . '</pre>';
130
    }
131
}
132