1ce42304aSGreg Roach<?php 2ce42304aSGreg Roach 3ce42304aSGreg Roach/** 4ce42304aSGreg Roach * webtrees: online genealogy 5*d11be702SGreg Roach * Copyright (C) 2023 webtrees development team 6ce42304aSGreg Roach * This program is free software: you can redistribute it and/or modify 7ce42304aSGreg Roach * it under the terms of the GNU General Public License as published by 8ce42304aSGreg Roach * the Free Software Foundation, either version 3 of the License, or 9ce42304aSGreg Roach * (at your option) any later version. 10ce42304aSGreg Roach * This program is distributed in the hope that it will be useful, 11ce42304aSGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 12ce42304aSGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13ce42304aSGreg Roach * GNU General Public License for more details. 14ce42304aSGreg Roach * You should have received a copy of the GNU General Public License 1589f7189bSGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>. 16ce42304aSGreg Roach */ 17ce42304aSGreg Roach 18ce42304aSGreg Roachdeclare(strict_types=1); 19ce42304aSGreg Roach 20ce42304aSGreg Roachnamespace Fisharebest\Webtrees\Services; 21ce42304aSGreg Roach 22ce42304aSGreg Roachuse Fisharebest\Algorithm\MyersDiff; 23ce42304aSGreg Roachuse Fisharebest\Webtrees\Family; 24ce42304aSGreg Roachuse Fisharebest\Webtrees\Gedcom; 25ce42304aSGreg Roachuse Fisharebest\Webtrees\GedcomRecord; 26ce42304aSGreg Roachuse Fisharebest\Webtrees\Individual; 27ce42304aSGreg Roachuse Fisharebest\Webtrees\Media; 28ce42304aSGreg Roachuse Fisharebest\Webtrees\Note; 29f0c88a96SGreg Roachuse Fisharebest\Webtrees\Registry; 30ce42304aSGreg Roachuse Fisharebest\Webtrees\Repository; 31ce42304aSGreg Roachuse Fisharebest\Webtrees\Source; 32ce42304aSGreg Roachuse Fisharebest\Webtrees\Submitter; 33ce42304aSGreg Roachuse Fisharebest\Webtrees\Tree; 34ce42304aSGreg Roach 35ce42304aSGreg Roachuse function e; 36ce42304aSGreg Roachuse function explode; 37ce42304aSGreg Roachuse function implode; 38ce42304aSGreg Roachuse function preg_replace_callback; 39ce42304aSGreg Roachuse function strip_tags; 40ce42304aSGreg Roach 41ce42304aSGreg Roach/** 42ce42304aSGreg Roach * Bulk updates on genealogy data 43ce42304aSGreg Roach */ 44ce42304aSGreg Roachclass DataFixService 45ce42304aSGreg Roach{ 46ce42304aSGreg Roach /** 47d4ac8227SGreg Roach * Since we know the type, this is quicker than calling Registry::gedcomRecordFactory()->make(). 48ce42304aSGreg Roach * 49ce42304aSGreg Roach * @param string $xref 50ce42304aSGreg Roach * @param Tree $tree 51ce42304aSGreg Roach * @param string $type 52ce42304aSGreg Roach * 53ce42304aSGreg Roach * @return GedcomRecord|null 54ce42304aSGreg Roach */ 55ce42304aSGreg Roach public function getRecordByType(string $xref, Tree $tree, string $type): ?GedcomRecord 56ce42304aSGreg Roach { 57ce42304aSGreg Roach switch ($type) { 58ce42304aSGreg Roach case Family::RECORD_TYPE: 596b9cb339SGreg Roach return Registry::familyFactory()->make($xref, $tree); 60ce42304aSGreg Roach 61ce42304aSGreg Roach case Individual::RECORD_TYPE: 626b9cb339SGreg Roach return Registry::individualFactory()->make($xref, $tree); 63ce42304aSGreg Roach 64ce42304aSGreg Roach case Note::RECORD_TYPE: 656b9cb339SGreg Roach return Registry::noteFactory()->make($xref, $tree); 66ce42304aSGreg Roach 67ce42304aSGreg Roach case Media::RECORD_TYPE: 686b9cb339SGreg Roach return Registry::mediaFactory()->make($xref, $tree); 69ce42304aSGreg Roach 70ce42304aSGreg Roach case Repository::RECORD_TYPE: 716b9cb339SGreg Roach return Registry::repositoryFactory()->make($xref, $tree); 72ce42304aSGreg Roach 73ce42304aSGreg Roach case Source::RECORD_TYPE: 746b9cb339SGreg Roach return Registry::sourceFactory()->make($xref, $tree); 75ce42304aSGreg Roach 76ce42304aSGreg Roach case Submitter::RECORD_TYPE: 776b9cb339SGreg Roach return Registry::submitterFactory()->make($xref, $tree); 78ce42304aSGreg Roach 79ce42304aSGreg Roach default: 806b9cb339SGreg Roach return Registry::gedcomRecordFactory()->make($xref, $tree); 81ce42304aSGreg Roach } 82ce42304aSGreg Roach } 83ce42304aSGreg Roach 84ce42304aSGreg Roach /** 85ce42304aSGreg Roach * Default preview generator. 86ce42304aSGreg Roach * 87ce42304aSGreg Roach * @param Tree $tree 88ce42304aSGreg Roach * @param string $old_gedcom 89ce42304aSGreg Roach * @param string $new_gedcom 90ce42304aSGreg Roach * 91ce42304aSGreg Roach * @return string 92ce42304aSGreg Roach */ 93ce42304aSGreg Roach public function gedcomDiff(Tree $tree, string $old_gedcom, string $new_gedcom): string 94ce42304aSGreg Roach { 95ce42304aSGreg Roach $old_lines = explode("\n", $old_gedcom); 96ce42304aSGreg Roach $new_lines = explode("\n", $new_gedcom); 97ce42304aSGreg Roach $algorithm = new MyersDiff(); 98ce42304aSGreg Roach $differences = $algorithm->calculate($old_lines, $new_lines); 99ce42304aSGreg Roach $diff_lines = []; 100ce42304aSGreg Roach 101ce42304aSGreg Roach foreach ($differences as $difference) { 102ce42304aSGreg Roach switch ($difference[1]) { 103ce42304aSGreg Roach case MyersDiff::DELETE: 104ce42304aSGreg Roach $diff_lines[] = '<del>' . e($difference[0]) . '</del><br>'; 105ce42304aSGreg Roach break; 106ce42304aSGreg Roach case MyersDiff::INSERT: 107ce42304aSGreg Roach $diff_lines[] = '<ins>' . e($difference[0]) . '</ins><br>'; 108ce42304aSGreg Roach break; 109ce42304aSGreg Roach case MyersDiff::KEEP: 110ce42304aSGreg Roach $diff_lines[] = e($difference[0]) . '<br>'; 111ce42304aSGreg Roach break; 112ce42304aSGreg Roach } 113ce42304aSGreg Roach } 114ce42304aSGreg Roach 115ce42304aSGreg Roach $html = implode('', $diff_lines); 116ce42304aSGreg Roach 117ce42304aSGreg Roach $html = preg_replace_callback('/@(' . Gedcom::REGEX_XREF . ')@/', static function (array $match) use ($tree): string { 1186b9cb339SGreg Roach $record = Registry::gedcomRecordFactory()->make($match[0], $tree); 119ce42304aSGreg Roach 120ce42304aSGreg Roach if ($record instanceof GedcomRecord) { 121ce42304aSGreg Roach $title = strip_tags($record->fullName()); 122ce42304aSGreg Roach $href = e($record->url()); 123ce42304aSGreg Roach 124ce42304aSGreg Roach return '<a href="' . $href . '" title="' . $title . '">' . $match[0] . '</a>'; 125ce42304aSGreg Roach } 126ce42304aSGreg Roach 127ce42304aSGreg Roach return $match[0]; 128ce42304aSGreg Roach }, $html); 129ce42304aSGreg Roach 130ce42304aSGreg Roach return '<pre class="gedcom-data">' . $html . '</pre>'; 131ce42304aSGreg Roach } 132ce42304aSGreg Roach} 133