. */ namespace Fisharebest\Webtrees; use Fisharebest\Webtrees\Controller\PageController; /** @global Tree $WT_TREE */ global $WT_TREE; require 'includes/session.php'; $controller = new PageController; $controller ->restrictAccess(Auth::isManager($WT_TREE)) ->setPageTitle(I18N::translate('Check for errors') . ' — ' . $WT_TREE->getTitleHtml()) ->pageHeader(); // We need to work with raw GEDCOM data, as we are looking for errors // which may prevent the GedcomRecord objects from working. $rows = Database::prepare( "SELECT i_id AS xref, 'INDI' AS type, i_gedcom AS gedrec FROM `##individuals` WHERE i_file=?" . " UNION " . "SELECT f_id AS xref, 'FAM' AS type, f_gedcom AS gedrec FROM `##families` WHERE f_file=?" . " UNION " . "SELECT s_id AS xref, 'SOUR' AS type, s_gedcom AS gedrec FROM `##sources` WHERE s_file=?" . " UNION " . "SELECT m_id AS xref, 'OBJE' AS type, m_gedcom AS gedrec FROM `##media` WHERE m_file=?" . " UNION " . "SELECT o_id AS xref, o_type AS type, o_gedcom AS gedrec FROM `##other` WHERE o_file=? AND o_type NOT IN ('HEAD', 'TRLR')" )->execute([$WT_TREE->getTreeId(), $WT_TREE->getTreeId(), $WT_TREE->getTreeId(), $WT_TREE->getTreeId(), $WT_TREE->getTreeId()])->fetchAll(); $records = []; foreach ($rows as $row) { $records[$row->xref] = $row; } // Need to merge pending new/changed/deleted records $rows = Database::prepare( "SELECT xref, SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(CASE WHEN old_gedcom='' THEN new_gedcom ELSE old_gedcom END, '\n', 1), ' ', 3), ' ', -1) AS type, new_gedcom AS gedrec" . " FROM (" . " SELECT MAX(change_id) AS change_id" . " FROM `##change`" . " WHERE gedcom_id=? AND status='pending'" . " GROUP BY xref" . " ) AS t1" . " JOIN `##change` t2 USING (change_id)" )->execute([$WT_TREE->getTreeId()])->fetchAll(); foreach ($rows as $row) { if ($row->gedrec) { // new/updated record $records[$row->xref] = $row; } else { // deleted record unset($records[$row->xref]); } } // Keep a list of upper case XREFs, to detect mismatches. $ukeys = []; foreach (array_keys($records) as $key) { $ukeys[strtoupper($key)] = $key; } // LOOK FOR BROKEN LINKS $XREF_LINKS = [ 'NOTE' => 'NOTE', 'SOUR' => 'SOUR', 'REPO' => 'REPO', 'OBJE' => 'OBJE', 'SUBM' => 'SUBM', 'FAMC' => 'FAM', 'FAMS' => 'FAM', //'ADOP'=>'FAM', // Need to handle this case specially. We may have both ADOP and FAMC links to the same FAM, but only store one. 'HUSB' => 'INDI', 'WIFE' => 'INDI', 'CHIL' => 'INDI', 'ASSO' => 'INDI', '_ASSO' => 'INDI', // A webtrees extension 'ALIA' => 'INDI', 'AUTH' => 'INDI', // A webtrees extension 'ANCI' => 'SUBM', 'DESI' => 'SUBM', '_WT_OBJE_SORT' => 'OBJE', '_LOC' => '_LOC', ]; $RECORD_LINKS = [ 'INDI' => ['NOTE', 'OBJE', 'SOUR', 'SUBM', 'ASSO', '_ASSO', 'FAMC', 'FAMS', 'ALIA', '_WT_OBJE_SORT', '_LOC'], 'FAM' => ['NOTE', 'OBJE', 'SOUR', 'SUBM', 'ASSO', '_ASSO', 'HUSB', 'WIFE', 'CHIL', '_LOC'], 'SOUR' => ['NOTE', 'OBJE', 'REPO', 'AUTH'], 'REPO' => ['NOTE'], 'OBJE' => ['NOTE'], // The spec also allows SOUR, but we treat this as a warning 'NOTE' => [], // The spec also allows SOUR, but we treat this as a warning 'SUBM' => ['NOTE', 'OBJE'], 'SUBN' => ['SUBM'], '_LOC' => ['SOUR', 'OBJE', '_LOC'], ]; $errors = false; echo Bootstrap4::breadcrumbs([ 'admin.php' => I18N::translate('Control panel'), 'admin_trees_manage.php' => I18N::translate('Manage family trees'), ], $controller->getPageTitle()); ?>

getPageTitle() ?>

'; /** * Create a message linking one record to another. * * @param string $type1 * @param string $xref1 * @param string $type2 * @param string $xref2 * * @return string */ function link_message($type1, $xref1, $type2, $xref2) { return /* I18N: The placeholders are GEDCOM XREFs and tags. e.g. “INDI I123 contains a FAMC link to F234.” */ I18N::translate( '%1$s %2$s has a %3$s link to %4$s.', format_type($type1), format_link($xref1), format_type($type2), format_link($xref2) ); } /** * Format a link to a record. * * @param string $xref * * @return string */ function format_link($xref) { return '' . $xref . ''; } /** * Format a record type. * * @param string $type * * @return string */ function format_type($type) { return '' . $type . ''; } /** * Format an error message. * * @param string $message * * @return string */ function error($message) { global $errors; $errors = true; return '
  • ' . $message . '
  • '; } /** * Format a warning message. * * @param string $message * * @return string */ function warning($message) { global $errors; $errors = true; return '
  • ' . $message . '
  • '; }