. */ declare(strict_types=1); namespace Fisharebest\Webtrees\Services; use Fisharebest\Algorithm\MyersDiff; use Fisharebest\Webtrees\Family; use Fisharebest\Webtrees\Gedcom; use Fisharebest\Webtrees\GedcomRecord; use Fisharebest\Webtrees\Individual; use Fisharebest\Webtrees\Media; use Fisharebest\Webtrees\Note; use Fisharebest\Webtrees\Repository; use Fisharebest\Webtrees\Source; use Fisharebest\Webtrees\Submitter; use Fisharebest\Webtrees\Tree; use function e; use function explode; use function implode; use function preg_replace_callback; use function strip_tags; /** * Bulk updates on genealogy data */ class DataFixService { /** * Since we know the type, this is quicker than calling GedcomRecord::getInstance(). * * @param string $xref * @param Tree $tree * @param string $type * * @return GedcomRecord|null */ public function getRecordByType(string $xref, Tree $tree, string $type): ?GedcomRecord { switch ($type) { case Family::RECORD_TYPE: return Family::getInstance($xref, $tree); case Individual::RECORD_TYPE: return Individual::getInstance($xref, $tree); case Note::RECORD_TYPE: return Note::getInstance($xref, $tree); case Media::RECORD_TYPE: return Media::getInstance($xref, $tree); case Repository::RECORD_TYPE: return Repository::getInstance($xref, $tree); case Source::RECORD_TYPE: return Source::getInstance($xref, $tree); case Submitter::RECORD_TYPE: return Submitter::getInstance($xref, $tree); default: return GedcomRecord::getInstance($xref, $tree); } } /** * Default preview generator. * * @param Tree $tree * @param string $old_gedcom * @param string $new_gedcom * * @return string */ public function gedcomDiff(Tree $tree, string $old_gedcom, string $new_gedcom): string { $old_lines = explode("\n", $old_gedcom); $new_lines = explode("\n", $new_gedcom); $algorithm = new MyersDiff(); $differences = $algorithm->calculate($old_lines, $new_lines); $diff_lines = []; foreach ($differences as $difference) { switch ($difference[1]) { case MyersDiff::DELETE: $diff_lines[] = '' . e($difference[0]) . '
'; break; case MyersDiff::INSERT: $diff_lines[] = '' . e($difference[0]) . '
'; break; case MyersDiff::KEEP: $diff_lines[] = e($difference[0]) . '
'; break; } } $html = implode('', $diff_lines); $html = preg_replace_callback('/@(' . Gedcom::REGEX_XREF . ')@/', static function (array $match) use ($tree): string { $record = GedcomRecord::getInstance($match[0], $tree); if ($record instanceof GedcomRecord) { $title = strip_tags($record->fullName()); $href = e($record->url()); return '' . $match[0] . ''; } return $match[0]; }, $html); return '
' . $html . '
'; } }